Interrupt based UART while running VUSB on ATmega8

Thread Starter

AkashG

Joined Apr 14, 2016
2
I've built a wireless mouse that sends data through UART over RF to base station which is just an ATmega8 with VUSB Ckt and RF reciever connected.



things that i've tried :



1. Running UART on interrupt mode. This didnt work because VUSB already uses an interrupt and there was clashes between VUSb n UART .. so the device would disconnect from the computer or simply be not recognized.



2. Then i've used while loops to capture data from Rf but the micro controller gets stuck on the while loop because the transmitter is not on and information is not received and hence the flag never gets set.



What is a better solution for this .. my device acts as a HID compliant mouse ..
 

shteii01

Joined Feb 19, 2010
4,644
2. Then i've used while loops to capture data from Rf but the micro controller gets stuck on the while loop because the transmitter is not on and information is not received and hence the flag never gets set.



What is a better solution for this .. my device acts as a HID compliant mouse ..
Set your own "flag" variable. You can either use the size of received data as a flag or you can use time as a flag. Check if you received X bytes, if you did receive X bytes, then the "flag" variable is set, program exits while loop, executes whatever you want it to execute, resets the "flat" variable, goes back into while loop. Check the time, check if 100 milliseconds have passed, if it did, set the "flag" variable, exit while loop, do whatever you want to do, reset the "flag" variable, go back into while loop.
 

Thread Starter

AkashG

Joined Apr 14, 2016
2
I didnt get what u meant .. but here is the code ...
C:
#define  F_CPU 16000000UL
#define  NULL 0

#define  false 0
#define  true 1

#include "usbdrv/usbdrv.h"
#include "IMU.h"
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/io.h>

volatile uint8_t x=0,y=0;
volatile uint8_t prev_x=0,prev_y=0;

volatile uchar xRecieved = false, yRecieved = false;

int resolution = 256;

#pragma region usb

PROGMEM const char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x02,                    // USAGE (Mouse)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xA1, 0x00,                    //   COLLECTION (Physical)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM
    0x29, 0x03,                    //     USAGE_MAXIMUM
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x03,                    //     REPORT_COUNT (3)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x95, 0x01,                    //     REPORT_COUNT (1)
    0x75, 0x05,                    //     REPORT_SIZE (5)
    0x81, 0x03,                    //     INPUT (Const,Var,Abs)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x09, 0x38,                    //     USAGE (Wheel)
    0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
    0x25, 0x7F,                    //     LOGICAL_MAXIMUM (127)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x03,                    //     REPORT_COUNT (3)
    0x81, 0x06,                    //     INPUT (Data,Var,Rel)
    0xC0,                          //   END_COLLECTION
    0xC0,                          // END COLLECTION
};

typedef struct{
    uchar   buttonMask;
    char    dx;
    char    dy;
    char    dWheel;
}report_t;


static report_t reportBuffer;
static uchar    idleRate;
#pragma endregion usb
#pragma region usbFunction
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
    usbRequest_t    *rq = (void *)data;

    /* The following requests are never used. But since they are required by
    * the specification, we implement them in this example.
    */
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS)
    {    /* class request type */
        if(rq->bRequest == USBRQ_HID_GET_REPORT)
        {  /* wValue: ReportType (highbyte), ReportID (lowbyte) */
            /* we only have one report type, so don't look at wValue */
            usbMsgPtr = (void *)&reportBuffer;
            return sizeof(reportBuffer);
        }
        else if(rq->bRequest == USBRQ_HID_GET_IDLE){
            usbMsgPtr = &idleRate;
            return 1;
        }
        else if(rq->bRequest == USBRQ_HID_SET_IDLE){
            idleRate = rq->wValue.bytes[1];
        }
    }
    else{
        /* no vendor specific requests implemented */
    }
    return 0;   /* default for not implemented requests: return no data back to host */
}
#pragma endregion usb



unsigned char Receive( void )
{
    /* Wait for data to be received */
    while ( !(UCSRA & (1<<RXC)) );
    /* Get and return received data from buffer */
    return UDR;
}

void USART_Init( unsigned int baud)
{
    unsigned int ubrr = ( F_CPU /  ( 16 * baud ) ) - 1;

    /* Set baud rate */
    UBRRH = (ubrr>>8);
    UBRRL = ubrr;

    /* Enable receiver*/
    UCSRB |= (1<<RXEN);

    /*Enable the Interrupt mode*/
    UCSRB |= (1<<RXCIE);

    /* Set frame format: 8data, 2stop bit */
    UCSRC |= (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}


int main(void)
{

    DDRC=0xff;

    uchar i;

    wdt_enable(WDTO_1S);

    usbInit();
    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */

    i = 0;

    while(--i){             /* fake USB disconnect for > 250 ms */
        wdt_reset();
        _delay_ms(1);
    }

    usbDeviceConnect();

    sei();

    USART_Init(36482);


    while(1)
    {
        wdt_reset();

        if( !(UCSRA & (1<<RXC)) )
    x=UDR;
    if( !(UCSRA & (1<<RXC)) )
    y=UDR;



        reportBuffer.dx = x;
        reportBuffer.dy = y;

        usbPoll();

        if(usbInterruptIsReady()){
            /* called after every poll of the interrupt endpoint */
            usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
        }

    }
    return 0;
}
Moderators note: Changed code tags.
 
Top