cancel
Showing results for 
Search instead for 
Did you mean: 

uart + xmodem1k. Get incorrect char in the beginning of data

carlogulliani
Associate III
Posted on December 07, 2015 at 18:07

The original post was too long to process during our migration. Please click on the attachment to read the original post.
12 REPLIES 12
Posted on December 07, 2015 at 19:39

Do you have an adequate stack to accommodate this data?

Is f_puts() appropriate? It's NOT a string, and you're NOT terminating it. Use f_write() and write the block of bytes in place.

With these protocols you are going to have to own the synchronization/resych tasks, you can't assume everything is going to work perfectly.

Looks to be sending the SAME block again. Have you tried different Terminal programs to see if it's the specific one you are using that's stuffing the extra NUL

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
carlogulliani
Associate III
Posted on December 07, 2015 at 20:21

Yes, I have stack to store received data. I'm not sure it is an extra NUL, it's the last char of sending data.

Here is the code for transmitting

byte

[] bb =

new
byte

[1030];
bb[0] = STX;
bb[1] = blocknumber;
bb[2] = (

byte

)(255 - blocknumber);
for

(

byte

b: sector)
{
bb[3+k] = b;
}
bb[SECSIZE+3] = (

byte

)(crc16 >> 8);
bb[SECSIZE+4] = (

byte

)(crc16 & 0xff);
bb[SECSIZE+5] = 0x00; // this char moves to the 0 position of buffer, if I change it to 0x1A or something else, I see new value...
putChar(bb,

''Block ''

+blocknumber);

And if I have a wrong data, sum sends NAK and my transmitting program sends this block again. But there is no good result, because I send the same block 10 times while I get ACK I used f_puts just to try to write something to file
Posted on December 07, 2015 at 21:38

This is not part of the protocol
 bb[SECSIZE+5] = 0x00;

You are supposed to be sending 1024+5 (1029) bytes, not as a string
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
carlogulliani
Associate III
Posted on December 07, 2015 at 22:13

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6dL&d=%2Fa%2F0X0000000bs9%2FuaoDQYYP7Hl5wVmbPjS7CKPgd57YdZ9_rWbBvriZS1M&asPdf=false
carlogulliani
Associate III
Posted on December 07, 2015 at 22:22

And here is my sender

public
boolean send(String tfile) throws IOException
{
fileName = tfile;
char
errorcount;
byte
blocknumber, character;
byte
[] sector = 
new
byte
[SECSIZE];
int
nbytes;
DataInputStream dis;
File f = 
new
File(tfile);
dis = 
new
DataInputStream(
new
FileInputStream(tfile));
errStream.println(
''file open, ready to send''
);
System.
out
.println(
''file open, ready to send''
);
errorcount = 0;
blocknumber = 0x01;
int
count = 0;
gotChar = 
false
;
do
{
character = getChar();
System.
out
.println(
''Initial character, obtained: ''
+ (
int
)character);
if
(character == NAK || character == CRC) 
break
;
gotChar = 
true
;
if
(character != NAK || character != 
'C'
)
{
++errorcount;
}
} 
while
(character != NAK || character != 
'C'
);
System.
out
.println(
''Start Transmitting''
);
while
((nbytes = dis.read(sector))!=0)
{
int
p = (
int
)(count*SECSIZE*100/f.length());
_progressBar.setValue(p);
count++;
if
(nbytes <= -1)
{
break
;
}
if
(nbytes < SECSIZE)
{
sector[nbytes]=CTRLZ;
}
errorcount = 0;
while
(errorcount < MAXERRORS)
{
errStream.println(
''{''
+ blocknumber + 
''}''
);
System.
out
.println(
''{''
+ (
int
)blocknumber + 
''}''
);
char
crc16 = crc16(sector);
byte
[] bb = 
new
byte
[SECSIZE+6];
bb[0] = (SECSIZE == 128) ? SOH : STX;
bb[1] = blocknumber;
bb[2] = (
byte
)(255 - blocknumber);
for
(
byte
b: sector)
{
bb[3+k] = b;
}
bb[SECSIZE+3] = (
byte
)(crc16 >> 8);
bb[SECSIZE+4] = (
byte
)(crc16 & 0xff);
//bb[SECSIZE+5] = 0x00;
putChar(bb, 
''Block ''
+blocknumber);
if
(getChar() != ACK)
{
++errorcount;
}
else
break
;
}
blocknumber = (
byte
)((++blocknumber) % 256);
}
boolean isAck = 
false
;
while
(!isAck)
{
putChar(EOT, 
''EOT''
);
isAck = getChar() == ACK;
}
errStream.println(
''Transmission complete.''
);
return
true
;
}
protected
byte
getChar() throws IOException
{
byte
something = (
byte
)inStream.read();
return
something;
}
protected
void
putChar(
byte
[] b, String debug) throws IOException
{
System.
out
.println(debug + 
'', ''
+ b.length);
byte
[] b2 = 
new
byte
[b.length+1];
int
i = 0;
for
(
byte
b1 : b)
{
b2[i++] = b1;
System.
out
.print((b1 & 0xFF)+
'' ''
); 
// showing all my buffer by byte
}
System.
out
.println(
''''
);
System.
out
.println(i);
outStream.write(b); 
}
protected
char
crc16(
byte
[] bytes)
{
char
crc = 0x0000;
for
(
byte
b: bytes)
{
crc = (
char
) ((crc << 8) ^ crctable[((crc >> 8) ^ b) & 0x00ff]);
}
return
(
char
) (crc);
}

Posted on December 07, 2015 at 23:45

Ok

#define MAXCLISTRING SIZE+5 // NOT SIZE+6

            if (checkCRC16(&rxString[3], SIZE) == 1)

            {

                led_toggle(GPIO_PIN_15);

                xbuf[0] = ACK;

 

                UINT* bw;

                f_write(&fil, &rxString[3], SIZE, (UINT*)&bw); // write in-place

                if (bw > 0) led_toggle(ORANGE);

            }

Your receiver doesn't need to clear the buffer, only reset the index. However you probably want it to attempt to resync if the first character in the buffer is wrong, rather than keep filling it with 1000+ bytes that will be thrown away.

Your sender needs to wait for the response, don't let it time out.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
carlogulliani
Associate III
Posted on December 08, 2015 at 11:25

I found that I receive mixed bytes, I can see the order which was sent and I see mixed bytes in my buffer. My sender waits response and there is not problem.

I commented part of code and use just receiver of data (also I send only data without headers and CRC). I send an image and I got the image, which has the same count of Kb which I sent, but when I open this image I see that the picture's pixels moved in different position then original pic.

How can I control the order of received bytes, maybe I have to set some setting for usart or dma handler?

dthedens
Associate II
Posted on December 08, 2015 at 21:53

Perhaps it is an endian issue.  RGB on an ARM might not be RGB on an Intel PC

carlogulliani
Associate III
Posted on December 08, 2015 at 23:31

No sure. I tried other formats, not only images... The same problem.

I made a test, I have an error counter in my sender code, when I'm sending NAK from stm32, I'm increasing this counter and when it has 10 I increase block number. So, now I increased the limit of this counter, also I put breakpoint on my stm32, where I compare current index and buffer size, so I have a button, which sends NAK, when I check break point every 4th data is correct.

In the other words, I check break point and see wrong bytes order, I press resume, the next data which comes is correct, I pressed resume again, and I got incorrect data again and so 4th times, then is correct again. But after 4th checked break point my program is freezing and I must press button with NAK, after that I got the first packet is correct.

If I remove break point, I don't receive the correct data anymore, only the 1st data of packet 1.

The model with breakpoint:

-> sender sends packet 1

. receiver got all data and stop for break point and press resume

<- ACK ... all data is correct

-> sender sends packet 2

. receiver got all data and stop for break point and press resume

<- NAK ... data is incorrect // #1

-> sender sends packet 2

. receiver got all data and stop for break point and press resume

<- NAK ... data is incorrect // #2

-> sender sends packet 2

. receiver got all data and stop for break point and press resume

<- NAK ... data is incorrect // #3

. HERE IS THE PROGRAM IS FREEZING AND I NEED TO PRESS BUTTON TO SEND NAK. PRESS IT

-> sender sends packet 2

. receiver got all data and stop for break point and press resume

<- ACK ... all data is correct

-> sender sends packet 3

. receiver got all data and stop for break point and press resume

<- NAK ... data is incorrect // #1

and so on

Without breakpoint:

First packet is ok, send the 2nd one and I always see incorrect data, even the very 4th packet has incorrect data