AVR USB device and UART Polling

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

AVR USB device and UART Polling

Post by Ankur » Sun Jul 15, 2007 9:34 pm

Hi ,
Is it not possible to receive 12 bytes of data at Buad Rate of 9600
with the AVR polling the usb in the main loop .
i am doing like this

Code: Select all

    //main loop
    for ( ; ; ) {
    wdt_reset();
    usbPoll();
   for ( i = 0 ; i < 12 ; i++ )
    receiveBuffer[i]=rxChar_poll();
   }
   


and i am pointing usbMsgPtr = receiveBuffer in the usbFunctionSetup()
function and returning 12 . When does these 12 bytes get transferred
through the USB port to the host pc .
I am always receiving 0 0 0 0 0 0 0 0 0 0 0 0 as the 12 bytes at the
host , whatever the transmission may be .

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Mon Jul 16, 2007 3:57 pm

With this code, you'll not only run into troubles with AVR-USB, you will also get hit by the watchdog. I don't know what your rxChar_poll() routine looks like, but I suspect that it busy-waits for a character to arrive on the UART.

Since it may take a long time until 12 bytes are received, your main loop will not iterate with the required frequency.

Please see the RemoteSensor example (receiver firmware) how to receive data in the background from an interrupt routine. If you don't want to use interrupts and have a low bit rate, you could also so something like this:

Code: Select all

for(;;){
    wdt_reset();
    usbPoll();
    while(data available on UART){
        receiveBuffer[i++] = rxChar_poll();
        if(i >= 12){
            do_whatever_you_like_with_buffer();
            i = 0;
        }
    }
}

Ankur

UART polling

Post by Ankur » Mon Jul 16, 2007 5:29 pm

Hi christian ,
My rxChar_poll() is this

Code: Select all

char rxChar_poll ( void )
{
        while ( ! ( UCSRA & ( 1 << RXC ) ) ) ;
        return UDR ;

}

Well i got your point , but i didnt get one thing out of what you wrote

Code: Select all

 while ( data available on UART ) 
how do i check whether data is available
on the UART , is it checking for the RXC flag ?

By the way what is the watchdog timer doing here ?

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Mon Jul 16, 2007 5:35 pm

Yes, checking for data available on the UART is done via the RXC flag. The while statement should therefore be:

Code: Select all

    while(UCSRA & ( 1 << RXC )){
        ....
    }


The watchdog timer is a hardware unit which resets your device when the firmware has crashed. Your firmware must call wdt_reset() in regular intervals to prove that it has not crashed (yet).

The watchdog timer is turned on and configured for a maximum interval somewhere close to the beginning of main().

Ankur

USB polling time

Post by Ankur » Mon Jul 16, 2007 8:46 pm

Hi christian
One more doubt i had in my mind . How much maximum delay is
allowed between two successive calls to usbPoll() ? if the delay is
more than the time it takes to receive the 12 bytes over the UART
at a baud rate of 9600 by the AVR clocked at 12Mhz , then that
shouldn't matter . Should it ? I have seen in the odDebug.h , it is
written that it takes .5ms per byte to receive the data on the UART
at 19200bps through polling, but my baud rate is 9600 so is it .25ms per
byte ? then it should be .25ms / byte x 12 bytes = 3ms .
Am i correct ?

Ankur

Wrong File Name

Post by Ankur » Mon Jul 16, 2007 8:51 pm

sry , the file name was usbdrv.h not obDebug.h

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Mon Jul 16, 2007 11:20 pm

Since the suggested code goes into rxChar_poll() only when data is available, there's no delay, at least no delay related to the bit rate. The maximum delay between calls to usbPoll() is documented in usbdrv.h, I think it's 50 ms.

One byte sent through asynchronous serial transmission consists of 10 bits. This means that one byte at 9600 bps takes 10 / 9600 = 1.04 ms. But that's not relevant in your case.

Post Reply