Serial output from python to SAML21 yields garbage data

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi there,

 

Yes this is an issue with serial :). I'm trying to send some bytes to a USART buffer that will be stored on an external flash.

 

I have verified that my write method to the flash works as intended. The strange thing is that I am able to send other commands through UART which are recognized in the infinite loop. The code never fails to recognize the command "fsh_page" to jump into the condition - but once it is inside the condition it seems like the USART is not writing the proper data.

 

else if(!strcmp("fsh_page", (char*)usart_buffer)){
            static int pageNumber = 3;
            uint8_t page_buffer[PROGRAM_PAGE_SIZE+4];
            usart_read_buffer_wait(&usart_module, page_buffer, PROGRAM_PAGE_SIZE+4);
            if( flash_WriteBuffer(PROGRAM_PAGE_SIZE*pageNumber,PROGRAM_PAGE_SIZE+4,
                                    page_buffer) == true ) {

				usart_write_buffer_wait(&usart_module, (unsigned char*)

									"Page Write to memory complete.\n", 31);
            }
            //pageNumber++;
        }

 

 

 

The python code:

try:
    import serial
except ImportError:
    print("failed to import serial")

#open the image file and read the data
try:
    file = open("test_rgb565.bmp", "rb")
    data = file.read()
    file.close()
except:
    print("file error")

#calculations to divie the data in page-sized buffers
byteNumber = 0
pageNumber = 0
fullPages  = len(data)/256  #flash page-size is 256 bytes
leftoverBytes = len(data)%256
print(fullPages)
print(leftoverBytes)
#four first bytes are reserved for command/address to SPI (handled in the MCU code)
page_data = [b'\x00'] * 260
for i in range(256):
    page_data[i+4] = data[i]

ser = serial.Serial('/dev/ttymxc2', 115200)
ser.write("fsh_page") #send command for mcu to start reading byte data and storing it in the flash
ser.write(page_data)

 

The hex values that I am trying to send:

0x0 0x0 0x0 0x0 0x42 0x4d 0x62 0x1 0x0 0x0 
0x0 0x0 0x0 0x0 0x42 0x0 0x0 0x0 0x28 0x0 
0x0 0x0 0xc 0x0 0x0 0x0 0xc 0x0 0x0 0x0 
0x1 0x0 0x10 0x0 0x3 0x0 0x0 0x0 0x20 0x1 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xf8 
0x0 0x0 0xe0 0x7 0x0 0x0 0x1f 0x0 0x0 0x0 
0xe4 0xe8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xff 0xff 0xe4 0xe8 0xe4 0xe8 0xff 0xff 
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xe4 0xe8 
0xe4 0xe8 0xe4 0xe8 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xe4 0xe8 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xff 0xff 0xff 0xff 0xe4 0xe8 0xe4 0xe8 
0xe4 0xe8 0xe4 0xe8 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
0xff 0xff 0xff 0xff 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 
0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 0xff 0xff 
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xe4 0xe8 
0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 0xe4 0xe8 
0xe4 0xe8 0xe4 0xe8 0xff 0xff 0xff 0xff 0xff 0xff

The hex values that are stored on the flash:

00 00 00 00 00 00 00 00 00 00
40 00 00 00 28 00 00 00 0C 00
00 00 08 00 00 00 01 00 00 00
03 00 00 00 20 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 E0 00 00 E0 00
00 00 1F 00 00 00 E4 E8 E4 E8
E4 E4 E8 64 6F 6F 6F 6F 6F 6F
6F 6F 6F 6F 6F 6F 6F 6F 6F 6F
64 68 64 68 6F 6F 6F 6F 6F 6F
6F 6F 6F 6F 6F 6F 6F 6F 6F 6F
6F 6F 6F 6F 64 68 64 68 64 68
6F 6F 6F 6F 6F 6F 6F 6F 64 68
6F 6F 6F 6F 6F 6F 6F 6F 64 68
64 68 64 68 64 68 6F 6F 6F 6F
6F 6F 6F 6F 6F 6F 6F 6F 6F 6F
6F 6F 64 68 64 68 64 68 64 68
6F 6F 6F 6F 6F 6F 6F 6F 6F 6F
6F 6F 6F 6F 6F 6F 64 68 64 68
64 68 64 68 64 68 6F 6F 6F 6F
6F 6F 6F 6F 6F 6F 6F 6F 6F 6F
64 68 64 68 64 68 64 68 64 68
64 68 64 68 6F 6F 6F 6F 6F 6F
6F 6F 6F 6F 64 68 64 68 64 68
64 68 64 68 64 68 64 68 64 68

I can see for an example that it is storing the correct values from 0x1F and onward to 0xE8 but then it goes crazy again.

 

Baud rate for both is set to 115200.

 

I have not verified the speed with an oscilloscope but I have verified it with a blinking LED.

This topic has a solution.

1010001010111101110111

Last Edited: Fri. Jun 18, 2021 - 11:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure that your Python is correctly sending these binary values ... ?

 

Mithrandir_ wrote:

else if(!strcmp("fsh_page", (char*)usart_buffer)){

 

As a Standard C Library function, strcmp() requires that its arguments are NUL-terminated strings - so are you sure that usart_buffer will always be a NUL-terminated string ?

 

In other words, strcmp() isn't going to work for arbitrary binary data - which is what you seems to be trying to send ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

Are you sure that your Python is correctly sending these binary values ... ?

 

When I print out the values that it is sending they seem correct. I copy pasted the hex values that python prints out on the terminal as "the values that I am trying to send" above.

 

awneil wrote:

As a Standard C Library function, strcmp() requires that its arguments are NUL-terminated strings - so are you sure that usart_buffer will always be a NUL-terminated string ?

 

In other words, strcmp() isn't going to work for arbitrary binary data - which is what you seems to be trying to send ?

 

Yes - that part of the code works flawlessly. I have several statements that use strcmp() in my infinite loop that are used for various things e.g.

main()
  do stuff
    while(1) //infinite loop
      read_usart_buffer
      if strcmp(blala) : do stuff
      if strmcomp(yadayada): do something else

That part works fine.

 

 

I switched the memory location that I was writing to and it seems to work better, which is really perplexing to me. This is a SST26VF016B flash and it is supposed to have 100k write cycles - I have written to it less than 50 times. At any rate, I added a delay between sending the "write" command from python and sending the page data as follows:

 

#send full pages
for i in range(fullPages):
    page_data = [b'\x00'] * 260 #reset page
    for j in range(256):
        page_data[j+4] = data[(256*i)+j]
    ser.write("fsh_page")
    time.sleep(0.001)
    ser.write(page_data)
#send leftover bytes
page_data = [b'\x00'] * 260 #reset page
for j in range(leftoverBytes):
    page_data[j+4] = data[(256*fullPages)+j]
ser.write("fsh_page")
time.sleep(0.001)
ser.write(page_data)

ser.close()

and I am getting much closer to the actual values, however it's still not QUITE there, for an example on the first row I am getting 40 4C 60 instead of 42 4D 62

 

It definitely seems like the timing is off by a little, but what is surprising is that the same UART never fails to receive the loop commands. Really strange.

40 4C 60 00 00 00 00 00 00 00
42 00 00 00 28 00 00 00 0C 00
00 00 0C 00 00 00 01 00 00 00
03 00 00 00 20 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 68 00 00 60 07
00 00 0F 00 00 00 64 68 6F 6F
6F 6F 6F 6F 6F 6F 6F 6F 6F 6F
6F 6F 6F 6F 6F 6F 6F 6F 6F 6F
64 68 64 68 6F 6F 6F 6F 6F FF
FF FF FF FF FF FF FF FF FF FF
FF FF FF FF E4 E8 E4 E8 E4 E8
FF FF FF FF FF FF FF FF E4 E8
FF FF FF FF FF FF FF FF E4 E8
E4 E8 E4 E8 E4 E8 FF FF FF FF
FF FF FF FF FF FF FF FF FF FF
FF FF E4 E8 E4 E8 E4 E8 E4 E8
FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF E4 E8 E4 E8
E4 E8 E4 E8 E4 E8 FF FF FF FF
FF FF FF FF FF FF FF FF FF FF
E4 E8 E4 E8 E4 E8 E4 E8 E4 E8
E4 E8 E4 E8 FF FF FF FF FF FF
FF FF FF FF E4 E8 E4 E8 E4 E8
E4 E8 E4 E8 E4 E8 E4 E8 E4 E8
FF FF FF FF FF FF E8 E4 E8 FF
FF FF FF E4 E8 E4 E8 E4 E8 E4
E8 E4 E8 E4 E8 E4 E8 E4 E8 E4
E8 E4 E8 E4 E8 FF FF E4 E8 E4
E8 E4 E8 E4 E8 E4 E8 E4 E8 E4
E8 E4 E8 E4 E8 E4 E8 E4 E8 E4
E8

 

1010001010111101110111

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay I actually printed out the values prior to storing them on the flash and loading them from there - the problem is not in the UART at all - it is sending the correct values. There's some issue with the flash. I will make another post and mark this one as solved.

1010001010111101110111

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mithrandir_ wrote:
the problem is not in the UART at all ... There's some issue with the flash

No issue with the flash - it was in the handling of the UART: https://community.atmel.com/comm...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...