Page 1 of 1

ATMEGA 32, LibUSB Win32 and Delphi - Access Denied

Posted: Thu Jan 29, 2009 8:14 pm
by mschumann
Using an ATMEGA32 at 16MHz I implemented (g)LCD, DCF77 and RC5 for an HTPC Controller. Everything works quite well but the Host USB side gets stuck after transferring some or more remote control codes. LibUSB then delivers -5 (access denied as far as I found out). I use LibUSB for Windows 32 and Libusb.pas (delphi 7). I suspect the rc5 code from http://www.roboternetz.de/wissen/index. ... BCr_ATMega to interfer with the usbdrv. Of course rc5 uses a different hardware interrupt.

The effect is reproducable if the remote control goes into repeating a key thats held down but sometimes it works quite a while. I tried using the Jedi VCL components for HID devices to avoid LibUSB but they just wouldnt receive anything although they perfectly connect to the device.

These are the key routines, any help is very appreciated since I am relatively new to usb. Thanks in advance!

// USB globale Variablen
static uchar usbrec[128];
static int8_t usbcmd[4] = {0,0,0,0};
static uchar bytesRemaining, currentPosition;


usbMsgLen_t usbFunctionSetup(uchar data[8]) {

usbRequest_t *rq = (void *)data;

// HID-Class Request
if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {

if (rq->bRequest == USBRQ_HID_GET_REPORT) {

if (usbcmd[3]!=0) {
usbMsgPtr = usbcmd;
usbcmd[3]=0; // Gesendet markieren
return sizeof(usbcmd);
} else {
// Da libsub Probleme hat mit 0 Byte Reports
usbcmd[0]=0;
usbMsgPtr = usbcmd;
return sizeof(usbcmd);
}

} else if(rq->bRequest == USBRQ_HID_SET_REPORT) {

// Empfangen geht über usbFunctionWrite()
currentPosition = 0;
// Puffer leeren
for (uchar i=0; i<sizeof(usbrec); i++)
usbrec[i] = 0;
bytesRemaining = rq->wLength.word;
// Länge begrenzen
if(bytesRemaining > sizeof(usbrec))
bytesRemaining = sizeof(usbrec);
// Empfangen macht usbFunctionWrite()
return USB_NO_MSG;
}
}
return 0;
}


// Daten vom Host empfangen und im Puffer übertragen
uchar usbFunctionWrite(uchar *data, uchar len)
{
if(len > bytesRemaining)
len = bytesRemaining;
bytesRemaining -= len;
for(uchar i = 0; i < len; i++)
usbrec[currentPosition++] = data[i];
if (bytesRemaining == 0) {
// todo
return 1;
} else
return 0;
}

and this is the device descriptor (stolen from the hiddata example):

PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x20, // REPORT_SIZE (8)
0x95, 0x80, // REPORT_COUNT (128)
0x09, 0x00, // USAGE (Undefined)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
0xc0 // END_COLLECTION
};