using usbPoll and usbSetInterrupt

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

using usbPoll and usbSetInterrupt

Post by AkashG » Tue Apr 19, 2016 8:16 pm

I'm pretty new to the VUSB library and the USB.. making a Wireless HID mouse

I'm .unable to program the RX ATmega8 properly .. which has the USB Connection

i'm reieving data on UART of ATMega8 through Polling and sending the data into report buffer .. but nothing is happening ..
Some times it gets disconnected too...

Can anyone suggest a better way of using the library's usbPoll() and setInterrupt() functions ..

CODE:

/*
* HID VUSB WIRELESS MOUSE.c
*
* Created: 4/16/2016 3:52:10 PM
* Author : Akash
*/

//////////////////////////////////////////////////////////////////////////
//Defines
//////////////////////////////////////////////////////////////////////////
#define F_CPU 16000000UL
#define true 0x01
#define false 0x00
#define uchar unsigned char
#define uint unsigned int

#define START_SYNC_BYTE 0b10101010
#define END_SYNC_BYTE 0b01010101

#define RECIEVE_BUFF_MAX 4
//////////////////////////////////////////////////////////////////////////

#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <util/delay.h>

#include "uart/UART.h"
#include "usbdrv/usbdrv.h"

//////////////////////////////////////////////////////////////////////////
//GLOBAL VARIABLES
//////////////////////////////////////////////////////////////////////////
uint recieveBuffer[RECIEVE_BUFF_MAX];
bool TransmissionComplete = false;
uchar i=0;
//////////////////////////////////////////////////////////////////////////



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;

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 */
}



int main(void)
{
wdt_enable(WDTO_1S);

DDRC=0xff;

//Initializing to Reciever at 9600 bps
UART_Init(9600 , false , true , true);

for(i=0;i<RECIEVE_BUFF_MAX;i++){
recieveBuffer[i]= 0;}

usbInit();

usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
while(--i)
{ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();


sei();

while(1)
{
wdt_reset();

usbPoll();

RecieveUARTdata();

if(TransmissionComplete && usbInterruptIsReady()){
usbSetInterrupt( recieveBuffer , sizeof(reportBuffer) );
}
}
return 0;
}

void ResetValues(){
recieveBuffer[0] = 0;
recieveBuffer[1] = 0;
recieveBuffer[2] = 0;
recieveBuffer[3] = 0;
}

void SetHIDReport( uint *recieveBuffer )
{
reportBuffer.dx = recieveBuffer[0];
reportBuffer.dy = recieveBuffer[1];
reportBuffer.buttonMask = recieveBuffer[2];
reportBuffer.dWheel = recieveBuffer[3];
}

void ClearHIDReport( )
{
reportBuffer.dx = 0;
reportBuffer.dy = 0;
reportBuffer.buttonMask = 0;
reportBuffer.dWheel = 0;
}

void RecieveUARTdata(){
//Get the data if available by checking the RXC in UCSRA
if ( UCSRA & (1<<RXC) )
{
//Get the data
uchar data = UDR;
if (data==START_SYNC_BYTE)
{
i=0;
}
else
{
if (data != END_SYNC_BYTE )
{
recieveBuffer[i] = data;
i++;
if(i==RECIEVE_BUFF_MAX ){
PORTC ^= 0xff;
TransmissionComplete = true;
i=0;
}
}
else i=0;
}

}
}

Here is another question:
so USbPOll() must be called every 5ms?
how do i do that .. can i use a Timer ? if so how to make sure the Timer interrupt and the USB interrupt dont coincide..

Post Reply