working nicely on my laptop, but fail on my PC?

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers

working nicely on my laptop, but fail on my PC?

Postby SimonQian » Fri Apr 11, 2008 1:12 am

recognized by both, but sometimes fails on PC.
Using Bulk.
any possible reason?
or any thing else I can check?
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby SimonQian » Fri Apr 11, 2008 12:37 pm

It's really hard to debug cause I have no USB proto analyzer, but I still tried to fight out.
There are 2 kinds of errors.
1.is solved
2 is that Bulk package error, for example, the package format is:
//dat[idx] para(value) --Description
//dat[0] Command
//dat[1] NumBytes(MSB) --Total number of bytes to program(MSB)
//dat[2] NumBytes(LSB) --Total number of bytes to program(LSB)
//dat[3] mode --Mode byte
//dat[4] delay --Delay used for different types of programming termination,according to mode byte
//dat[5] cmd1 --Comamnd byte for Load Page
//dat[6] cmd2 --Command byte for Write Memory
//dat[7] cmd3 --Command byte for Read Memory
//dat[8] poll1
//dat[9] poll2
//data[10] Data --Data to program
........// other data, length of which is define in NumBytes section.

when OK, package length is NumBytes + 10, but when fails, it's larger.
If Data section is read by "dat[10 + i ]" for example, it will fail when package size is error, but succeed if read data by "dat[len - NumBytes + i]", in which "len" is the size of the whole package received, even if package size is error.
Last edited by SimonQian on Sat Apr 12, 2008 3:00 pm, edited 1 time in total.
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby SimonQian » Fri Apr 11, 2008 3:30 pm

To find what's wrong, I add these code:
if((10 + NumBytes) < len) {
for(i = 0;i < len;i++)
EEPROM_Write(0x10+i,dat[i]);
}

And found that if error occurs, the first or second 8 bytes is received twice, so the real package size is 18 + NumBytes, and data can be obtained if count from bottom.

I tried 100 times to retrieve data from bottom, and even if the package size is wrong, data retrieved is OK. Another 100 times, I retrieve data from dat[10 + i], and got 9 errors in all.
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby christian » Sat Apr 12, 2008 9:06 pm

This probably means that Sharity was not fast enough sending an ACK so that the host did a USB retry after some time.

What clock frequency do you use? Can you reproduce this? If yes, do you have a digital storage scope to analyze it? Would be really interesting to find out why this happens since bulk endpoints cause problems on some computers.
christian
Objective Development
Objective Development
 
Posts: 1330
Joined: Thu Nov 09, 2006 11:46 am

Postby SimonQian » Sun Apr 13, 2008 7:39 am

christian wrote:This probably means that Sharity was not fast enough sending an ACK so that the host did a USB retry after some time.

What clock frequency do you use? Can you reproduce this? If yes, do you have a digital storage scope to analyze it? Would be really interesting to find out why this happens since bulk endpoints cause problems on some computers.


It's running on 12MHz.
I CAN reproduce it.
My scope can't store so many data(maybe 1 error among hundreds of packages). I think a USB proto analyzer will do, but I don't have one.
If using a older version, it's not that bad. But still will error occasionally.

Anything else I can do to find the reason?
Try a faster oscillator, and see whether it fails again?
-- tried and failed for same error with 16MHz oscillator.
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby christian » Sun Apr 13, 2008 12:27 pm

The 16 MHz version meets the specs reliably when you use bulk endpoints, the 12 MHz version is very close to the limit.

Since one 8 byte chunk is duplicated, it's almost certain that this is a retry from the host. In principle, it's possible to filter out retries by checking data toggling. But I'd rather try to find out why there is a retry at all.

How much memory do you have in your scope? If you generate a trigger when you receive the duplicate package, would the memory suffice?
christian
Objective Development
Objective Development
 
Posts: 1330
Joined: Thu Nov 09, 2006 11:46 am

Postby SimonQian » Sun Apr 13, 2008 2:15 pm

I'll try sometime next week.

BTW:
I tried to check the data toggle by this:
in usbdrvasm.S add(myTok is define uchar in main.c):
extern myTok
in asmcommon.S function handleData insert first:
sts myTok,token; this will store token(DATA0 or DATA1) to myTok

This will add 2 cycle delay.
But if I check the data toggle in usbFunctionWriteOut function,
some other package will fails.
I will chech it later if I have time next week.
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby christian » Sun Apr 13, 2008 3:27 pm

You must reset data toggling after each new connection. Do you lose the first chunk or one in the middle?

When you generate a trigger in usbFunctionWriteOut() if data toggling is wrong, you should see many DATA packets which are answered with a NAK between the two with the same token. The main loop code should be as fast as possible to limit this number.
christian
Objective Development
Objective Development
 
Posts: 1330
Joined: Thu Nov 09, 2006 11:46 am

Postby SimonQian » Wed Apr 16, 2008 3:57 pm

too busssssssssy these days.
Is there any list to show which PC or chipset is more likely to fail with Bulk Transfer?
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby christian » Wed Apr 16, 2008 4:02 pm

I think Osamu has some statistics included with his AVR-CDC project.
christian
Objective Development
Objective Development
 
Posts: 1330
Joined: Thu Nov 09, 2006 11:46 am

Postby SimonQian » Thu Apr 17, 2008 11:46 am

I add code to check data toggle like this(AVRUSB run at 16M):
Code: Select all
/// Token recorded when receive DATA package
uchar lastTok;

///
/// @brief   AVRUSB will call this function when DATA package is received
/// @param   data   received data to process
/// @param   len      received data length
///
void usbFunctionWriteOut(uchar *data, uchar len)
{
#if 1
   static uchar preTok;

   // not first package, same tok as last package, then ignore
   if(CMD_Len_tmp && (preTok == lastTok))
   {
      uint8 i;
      EEPROM_Write(0x01,preTok);
      EEPROM_Write(0x02,lastTok);
      for(i = 0;i < CMD_Len_tmp;i++)
         EEPROM_Write(0x10 + i,AVR_Device_DataBuff[i]);
      for(i = 0;i < len;i++)
         EEPROM_Write(0x80 + i,data[i]);

      return;
   }
   preTok = lastTok;
#endif
......
}


On my Lenovo T60, it works fine under windows and linux.
On my IBM i Series, it works fine also under windows(have no linux installed)
On my PC(SL-K8AV-R), fials frequently under windows(in fact, never succeed), OK under Linux.
Checking the EEPROM, data token and some data are error.
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby christian » Thu Apr 17, 2008 12:30 pm

Can you please post (or mail me) the EEPROM content (previous and current package) and add a note where see an error?

Another question: Do you use other interrupts than the USB interrupt or do you disable interrupts in your main code?
christian
Objective Development
Objective Development
 
Posts: 1330
Joined: Thu Nov 09, 2006 11:46 am

Postby SimonQian » Fri Apr 18, 2008 2:10 pm

Code for usbFunctionWriteOut:
Code: Select all
/// Token recorded when receive DATA package
uchar lastTok;

///
/// @brief   AVRUSB will call this function when DATA package is received
/// @param   data   received data to process
/// @param   len      received data length
///
void usbFunctionWriteOut(uchar *data, uchar len)
{
#if 1
   static uchar preTok;

   // not first package, same tok as last package, then ignore
   if(CMD_Len_tmp && (preTok == lastTok))
   {
      uint8 i;
      EEPROM_Write(0x01,preTok);
      EEPROM_Write(0x02,lastTok);
      EEPROM_Write(0x03,CMD_Len_tmp);
      EEPROM_Write(0x04,len);
      for(i = 0;i < CMD_Len_tmp;i++)
         EEPROM_Write(0x10 + i,AVR_Device_DataBuff[i]);
      for(i = 0;i < len;i++)
         EEPROM_Write(0x80 + i,data[i]);

      LED_On(LED_Green);
      while(1);

      return;
   }
   preTok = lastTok;
#endif

   memcpy(AVR_Device_DataBuff + CMD_Len_tmp,data,len);
   CMD_Len_tmp += len;

......
}


PC should send(12 bytes in Hex): 10 C8 64 19 20 00 53 03 AC 53 00 00
EEPROM content(in Hex) On error(addr:data):
1.
0x01:C3
0x02:C3
0c03:08
0c04:04
0x10:10 C8 64 19 20 00 53 03
0x80:AC 53 00 00
Error: same DATA PID
2.
0x01:4B
0x02:4B
0c03:08
0c04:04
0x10:10 C8 64 19 20 00 53 03
0x80:AC 53 00 00
Error:same DATA PID

Tried 50 times,
Running on my PC under Linux, the green LED is never on.
Running on my PC under Windows, can't pass even once.

Bad driver for Windows? But it drives my USB mice and keyboard well.
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Postby christian » Fri Apr 18, 2008 3:27 pm

Where exactly do you store lastTok in the assembler code? Do you store it even if the request is answered with NAK? This would explain it: Data is only stored if we answer with ACK, but lastTok may change if a packet has been rejected meanwhile.
christian
Objective Development
Objective Development
 
Posts: 1330
Joined: Thu Nov 09, 2006 11:46 am

Postby SimonQian » Sat Apr 19, 2008 7:45 am

It's OK after I only store the DATA token when ACK is sent:
Code: Select all
handleData:
mov x3, token
    lds     token, usbCurrentTok;[18]
    tst     token               ;[20]
    breq    doReturn            ;[21]
    lds     x2, usbRxLen        ;[22]
    tst     x2                  ;[24]
    brne    sendNakAndReti      ;[25]
; 2006-03-11: The following two lines fix a problem where the device was not
; recognized if usbPoll() was called less frequently than once every 4 ms.
    cpi     cnt, 4              ;[26] zero sized data packets are status phase only -- ignore and ack
    brmi    sendAckAndReti      ;[27] keep rx buffer clean -- we must not NAK next SETUP
sts lastTok, x3
    sts     usbRxLen, cnt       ;[28] store received data, swap buffers
    sts     usbRxToken, token   ;[30]
    lds     x2, usbInputBufOffset;[32] swap buffers
    ldi     cnt, USB_BUFSIZE    ;[34]
    sub     cnt, x2             ;[35]
    sts     usbInputBufOffset, cnt;[36] buffers now swapped
    rjmp    sendAckAndReti      ;[38] 40 + 17 = 57 until SOP


Checking the EEPROM, some package is really sent twice, and even there is a data error among them.
Just ignore the resent package, it's running well. Tested many times, never fails.
SimonQian
 
Posts: 19
Joined: Fri Nov 30, 2007 6:42 am

Next

Return to V-USB

Who is online

Users browsing this forum: No registered users and 3 guests