I moved from Arduino to AVR, and the whole USB business has left me spinning with information overload and far too many new doors to cope with.
Still, I am hoping that if I can get a simple example up and running, it'll be a good basis to start some proper learning.
Here's where I am at....
I started with this article for v-usb : http://codeandlife.com/2012/01/22/avr-a ... al-part-1/
and was doing well setting up an ATTiny45.
Included in the code I programmed it with is :
Code: Select all
USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) {
usbRequest_t *rq = (void *)data; // cast data to correct type
switch(rq->bRequest) { // custom command is in the bRequest field
case USB_LED_ON:
PORTB |= (1<<3); // turn LED on (ATTiny45 PB3)
return 0;
case USB_LED_OFF:
PORTB &= ~(1<<3); // turn LED off (ATTiny45 PB3)
return 0;
}
return 0; // should not get here
}
My problems start when it comes to the host-side coding.
The example on codeandlife works with C, and I am not too familar with that.
Hence after some googling, I found libusbdotnet, and thought I'd be more comofrtable working in c# which I have a 'little' experience of.
I've installed the libusbdotnet downloads and examples.
What I cannot understand, is how/when the above function (usbFunctionSetup) gets triggered by my c# code.
(my LED is not lighting up)
I can see that in the AVR code, usbFunctionSetup is called by usbProcessRx, when certain conditions are met ... but I really dont' understand all the code as yet.
I thought the LED would light even just on the Show.Info example, but I have tried a few other examples as well.
Like I said, I am now rather lost, dazed and confused as to what is happening on the host & AVR side sof things and how they all tie together!
I could give up and admit I am in too deep .... but I have to get USB working in my ATTiny's.
Hope someone will take pity and maybe point me in the right direction ?
Eternal thanks to that person !
Code: Select all
static inline void usbProcessRx(uchar *data, uchar len)
{
usbRequest_t *rq = (void *)data;
/* usbRxToken can be:
* 0x2d 00101101 (USBPID_SETUP for setup data)
* 0xe1 11100001 (USBPID_OUT: data phase of setup transfer)
* 0...0x0f for OUT on endpoint X
*/
DBG2(0x10 + (usbRxToken & 0xf), data, len + 2); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */
USB_RX_USER_HOOK(data, len)
#if USB_CFG_IMPLEMENT_FN_WRITEOUT
if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */
usbFunctionWriteOut(data, len);
return;
}
#endif
if(usbRxToken == (uchar)USBPID_SETUP){
if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */
return;
usbMsgLen_t replyLen;
usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */
usbTxLen = USBPID_NAK; /* abort pending transmit */
usbMsgFlags = 0;
uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */
replyLen = usbFunctionSetup(data);
}else{
replyLen = usbDriverSetup(rq);
}