00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "iarcompat.h"
00012 #ifndef __IAR_SYSTEMS_ICC__
00013 # include <avr/io.h>
00014 # include <avr/pgmspace.h>
00015 #endif
00016 #include "usbdrv.h"
00017 #include "oddebug.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 uchar usbRxBuf[2*USB_BUFSIZE];
00029 uchar usbInputBufOffset;
00030 uchar usbDeviceAddr;
00031 uchar usbNewDeviceAddr;
00032 uchar usbConfiguration;
00033 volatile schar usbRxLen;
00034 uchar usbCurrentTok;
00035 uchar usbRxToken;
00036 uchar usbMsgLen = 0xff;
00037 volatile uchar usbTxLen = USBPID_NAK;
00038 uchar usbTxBuf[USB_BUFSIZE];
00039 #if USB_COUNT_SOF
00040 volatile uchar usbSofCount;
00041 #endif
00042 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00043 volatile uchar usbTxLen1 = USBPID_NAK;
00044 uchar usbTxBuf1[USB_BUFSIZE];
00045 # if USB_CFG_HAVE_INTRIN_ENDPOINT3
00046 volatile uchar usbTxLen3 = USBPID_NAK;
00047 uchar usbTxBuf3[USB_BUFSIZE];
00048 # endif
00049 #endif
00050
00051
00052 uchar *usbMsgPtr;
00053 static uchar usbMsgFlags;
00054
00055 #define USB_FLG_TX_PACKET (1<<0)
00056
00057 #define USB_FLG_MSGPTR_IS_ROM (1<<6)
00058 #define USB_FLG_USE_DEFAULT_RW (1<<7)
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #if USB_CFG_DESCR_PROPS_STRINGS == 0
00071
00072 #if USB_CFG_DESCR_PROPS_STRING_0 == 0
00073 #undef USB_CFG_DESCR_PROPS_STRING_0
00074 #define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0)
00075 PROGMEM char usbDescriptorString0[] = {
00076 4,
00077 3,
00078 0x09, 0x04,
00079 };
00080 #endif
00081
00082 #if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
00083 #undef USB_CFG_DESCR_PROPS_STRING_VENDOR
00084 #define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor)
00085 PROGMEM int usbDescriptorStringVendor[] = {
00086 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
00087 USB_CFG_VENDOR_NAME
00088 };
00089 #endif
00090
00091 #if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
00092 #undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
00093 #define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice)
00094 PROGMEM int usbDescriptorStringDevice[] = {
00095 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
00096 USB_CFG_DEVICE_NAME
00097 };
00098 #endif
00099
00100 #if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && defined(USB_CFG_SERIAL_NUMBER_LEN)
00101 #undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
00102 #define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber)
00103 PROGMEM int usbDescriptorStringSerialNumber[] = {
00104 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN),
00105 USB_CFG_SERIAL_NUMBER
00106 };
00107 #endif
00108
00109 #endif
00110
00111 #if USB_CFG_DESCR_PROPS_DEVICE == 0
00112 #undef USB_CFG_DESCR_PROPS_DEVICE
00113 #define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
00114 PROGMEM char usbDescriptorDevice[] = {
00115 18,
00116 USBDESCR_DEVICE,
00117 0x10, 0x01,
00118 USB_CFG_DEVICE_CLASS,
00119 USB_CFG_DEVICE_SUBCLASS,
00120 0,
00121 8,
00122
00123
00124
00125 (char)USB_CFG_VENDOR_ID,
00126 (char)USB_CFG_DEVICE_ID,
00127 USB_CFG_DEVICE_VERSION,
00128 USB_CFG_DESCR_PROPS_STRING_VENDOR != 0 ? 1 : 0,
00129 USB_CFG_DESCR_PROPS_STRING_PRODUCT != 0 ? 2 : 0,
00130 USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER != 0 ? 3 : 0,
00131 1,
00132 };
00133 #endif
00134
00135 #if USB_CFG_DESCR_PROPS_HID_REPORT != 0 && USB_CFG_DESCR_PROPS_HID == 0
00136 #undef USB_CFG_DESCR_PROPS_HID
00137 #define USB_CFG_DESCR_PROPS_HID 9
00138 #endif
00139
00140 #if USB_CFG_DESCR_PROPS_CONFIGURATION == 0
00141 #undef USB_CFG_DESCR_PROPS_CONFIGURATION
00142 #define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration)
00143 PROGMEM char usbDescriptorConfiguration[] = {
00144 9,
00145 USBDESCR_CONFIG,
00146 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + (USB_CFG_DESCR_PROPS_HID & 0xff), 0,
00147
00148 1,
00149 1,
00150 0,
00151 #if USB_CFG_IS_SELF_POWERED
00152 USBATTR_SELFPOWER,
00153 #else
00154 (char)USBATTR_BUSPOWER,
00155 #endif
00156 USB_CFG_MAX_BUS_POWER/2,
00157
00158 9,
00159 USBDESCR_INTERFACE,
00160 0,
00161 0,
00162 USB_CFG_HAVE_INTRIN_ENDPOINT,
00163 USB_CFG_INTERFACE_CLASS,
00164 USB_CFG_INTERFACE_SUBCLASS,
00165 USB_CFG_INTERFACE_PROTOCOL,
00166 0,
00167 #if (USB_CFG_DESCR_PROPS_HID & 0xff)
00168 9,
00169 USBDESCR_HID,
00170 0x01, 0x01,
00171 0x00,
00172 0x01,
00173 0x22,
00174 USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0,
00175 #endif
00176 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00177 7,
00178 USBDESCR_ENDPOINT,
00179 (char)0x81,
00180 0x03,
00181 8, 0,
00182 USB_CFG_INTR_POLL_INTERVAL,
00183 #endif
00184 };
00185 #endif
00186
00187
00188
00189
00190 #ifndef PRG_RDB
00191 #define PRG_RDB(addr) pgm_read_byte(addr)
00192 #endif
00193
00194 typedef union{
00195 unsigned word;
00196 uchar *ptr;
00197 uchar bytes[2];
00198 }converter_t;
00199
00200
00201
00202
00203
00204
00205
00206 static inline void usbResetDataToggling(void)
00207 {
00208 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00209 USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN);
00210 # if USB_CFG_HAVE_INTRIN_ENDPOINT3
00211 USB_SET_DATATOKEN3(USB_INITIAL_DATATOKEN);
00212 # endif
00213 #endif
00214 }
00215
00216 static inline void usbResetStall(void)
00217 {
00218 #if USB_CFG_IMPLEMENT_HALT && USB_CFG_HAVE_INTRIN_ENDPOINT
00219 usbTxLen1 = USBPID_NAK;
00220 #if USB_CFG_HAVE_INTRIN_ENDPOINT3
00221 usbTxLen3 = USBPID_NAK;
00222 #endif
00223 #endif
00224 }
00225
00226
00227
00228 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00229 USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len)
00230 {
00231 uchar *p, i;
00232
00233 #if USB_CFG_IMPLEMENT_HALT
00234 if(usbTxLen1 == USBPID_STALL)
00235 return;
00236 #endif
00237 #if 0
00238 if(len > 8)
00239 len = 8;
00240 #endif
00241 if(usbTxLen1 & 0x10){
00242 usbTxBuf1[0] ^= USBPID_DATA0 ^ USBPID_DATA1;
00243 }else{
00244 usbTxLen1 = USBPID_NAK;
00245 }
00246 p = usbTxBuf1 + 1;
00247 for(i=len;i--;)
00248 *p++ = *data++;
00249 usbCrc16Append(&usbTxBuf1[1], len);
00250 usbTxLen1 = len + 4;
00251 DBG2(0x21, usbTxBuf1, len + 3);
00252 }
00253 #endif
00254
00255 #if USB_CFG_HAVE_INTRIN_ENDPOINT3
00256 USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len)
00257 {
00258 uchar *p, i;
00259
00260 if(usbTxLen3 & 0x10){
00261 usbTxBuf3[0] ^= USBPID_DATA0 ^ USBPID_DATA1;
00262 }else{
00263 usbTxLen3 = USBPID_NAK;
00264 }
00265 p = usbTxBuf3 + 1;
00266 for(i=len;i--;)
00267 *p++ = *data++;
00268 usbCrc16Append(&usbTxBuf3[1], len);
00269 usbTxLen3 = len + 4;
00270 DBG2(0x23, usbTxBuf3, len + 3);
00271 }
00272 #endif
00273
00274
00275 static uchar usbRead(uchar *data, uchar len)
00276 {
00277 #if USB_CFG_IMPLEMENT_FN_READ
00278 if(usbMsgFlags & USB_FLG_USE_DEFAULT_RW){
00279 #endif
00280 uchar i = len, *r = usbMsgPtr;
00281 if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){
00282 while(i--){
00283 uchar c = PRG_RDB(r);
00284 *data++ = c;
00285 r++;
00286 }
00287 }else{
00288 while(i--)
00289 *data++ = *r++;
00290 }
00291 usbMsgPtr = r;
00292 return len;
00293 #if USB_CFG_IMPLEMENT_FN_READ
00294 }else{
00295 if(len != 0)
00296 return usbFunctionRead(data, len);
00297 return 0;
00298 }
00299 #endif
00300 }
00301
00302
00303 #define GET_DESCRIPTOR(cfgProp, staticName) \
00304 if(cfgProp){ \
00305 if((cfgProp) & USB_PROP_IS_RAM) \
00306 flags &= ~USB_FLG_MSGPTR_IS_ROM; \
00307 if((cfgProp) & USB_PROP_IS_DYNAMIC){ \
00308 replyLen = usbFunctionDescriptor(rq); \
00309 }else{ \
00310 replyData = (uchar *)(staticName); \
00311 SET_REPLY_LEN((cfgProp) & 0xff); \
00312 } \
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 static void usbProcessRx(uchar *data, uchar len)
00327 {
00328 usbRequest_t *rq = (void *)data;
00329 uchar replyLen = 0, flags = USB_FLG_USE_DEFAULT_RW;
00330
00331
00332
00333
00334
00335
00336
00337
00338 DBG2(0x10 + ((usbRxToken >> 1) & 3), data, len);
00339 #ifdef USB_RX_USER_HOOK
00340 USB_RX_USER_HOOK(data, len)
00341 #endif
00342 #if USB_CFG_IMPLEMENT_FN_WRITEOUT
00343 if(usbRxToken < 0x10){
00344 usbFunctionWriteOut(data, len);
00345 return;
00346 }
00347 #endif
00348 if(usbRxToken == (uchar)USBPID_SETUP){
00349 usbTxLen = USBPID_NAK;
00350 if(len == 8){
00351 uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
00352 if(type == USBRQ_TYPE_STANDARD){
00353 #define SET_REPLY_LEN(len) replyLen = (len); usbMsgPtr = replyData
00354
00355
00356 uchar *replyData = usbTxBuf + 9;
00357 replyData[0] = 0;
00358 if(rq->bRequest == USBRQ_GET_STATUS){
00359 uchar __attribute__((__unused__)) recipient = rq->bmRequestType & USBRQ_RCPT_MASK;
00360 #if USB_CFG_IS_SELF_POWERED
00361 if(recipient == USBRQ_RCPT_DEVICE)
00362 replyData[0] = USB_CFG_IS_SELF_POWERED;
00363 #endif
00364 #if USB_CFG_HAVE_INTRIN_ENDPOINT && USB_CFG_IMPLEMENT_HALT
00365 if(recipient == USBRQ_RCPT_ENDPOINT && rq->wIndex.bytes[0] == 0x81)
00366 replyData[0] = usbTxLen1 == USBPID_STALL;
00367 #endif
00368 replyData[1] = 0;
00369 SET_REPLY_LEN(2);
00370 }else if(rq->bRequest == USBRQ_SET_ADDRESS){
00371 usbNewDeviceAddr = rq->wValue.bytes[0];
00372 #ifdef USB_SET_ADDRESS_HOOK
00373 USB_SET_ADDRESS_HOOK();
00374 #endif
00375 }else if(rq->bRequest == USBRQ_GET_DESCRIPTOR){
00376 flags = USB_FLG_MSGPTR_IS_ROM | USB_FLG_USE_DEFAULT_RW;
00377 if(rq->wValue.bytes[1] == USBDESCR_DEVICE){
00378 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice)
00379 }else if(rq->wValue.bytes[1] == USBDESCR_CONFIG){
00380 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration)
00381 }else if(rq->wValue.bytes[1] == USBDESCR_STRING){
00382 #if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC
00383 if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM)
00384 flags &= ~USB_FLG_MSGPTR_IS_ROM;
00385 replyLen = usbFunctionDescriptor(rq);
00386 #else
00387 if(rq->wValue.bytes[0] == 0){
00388 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0)
00389 }else if(rq->wValue.bytes[0] == 1){
00390 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor)
00391 }else if(rq->wValue.bytes[0] == 2){
00392 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice)
00393 }else if(rq->wValue.bytes[0] == 3){
00394 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber)
00395 }else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
00396 replyLen = usbFunctionDescriptor(rq);
00397 }
00398 #endif
00399 #if USB_CFG_DESCR_PROPS_HID_REPORT
00400 }else if(rq->wValue.bytes[1] == USBDESCR_HID){
00401 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18)
00402 }else if(rq->wValue.bytes[1] == USBDESCR_HID_REPORT){
00403 GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport)
00404 #endif
00405 }else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
00406 replyLen = usbFunctionDescriptor(rq);
00407 }
00408 }else if(rq->bRequest == USBRQ_GET_CONFIGURATION){
00409 replyData = &usbConfiguration;
00410 SET_REPLY_LEN(1);
00411 }else if(rq->bRequest == USBRQ_SET_CONFIGURATION){
00412 usbConfiguration = rq->wValue.bytes[0];
00413 usbResetStall();
00414 }else if(rq->bRequest == USBRQ_GET_INTERFACE){
00415 SET_REPLY_LEN(1);
00416 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00417 }else if(rq->bRequest == USBRQ_SET_INTERFACE){
00418 usbResetDataToggling();
00419 usbResetStall();
00420 # if USB_CFG_IMPLEMENT_HALT
00421 }else if(rq->bRequest == USBRQ_CLEAR_FEATURE || rq->bRequest == USBRQ_SET_FEATURE){
00422 if(rq->wValue.bytes[0] == 0 && rq->wIndex.bytes[0] == 0x81){
00423 usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL;
00424 usbResetDataToggling();
00425 }
00426 # endif
00427 #endif
00428 }else{
00429
00430
00431
00432 }
00433 #undef SET_REPLY_LEN
00434 }else{
00435 replyLen = usbFunctionSetup(data);
00436 }
00437 #if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE
00438 if(replyLen == 0xff){
00439 if((rq->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_DEVICE_TO_HOST){
00440 replyLen = rq->wLength.bytes[0];
00441 }
00442 flags &= ~USB_FLG_USE_DEFAULT_RW;
00443 }else
00444 #endif
00445 if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0])
00446 replyLen = rq->wLength.bytes[0];
00447 }
00448
00449 }else{
00450 #if USB_CFG_IMPLEMENT_FN_WRITE
00451 if(!(usbMsgFlags & USB_FLG_USE_DEFAULT_RW)){
00452 uchar rval = usbFunctionWrite(data, len);
00453 replyLen = 0xff;
00454 if(rval == 0xff){
00455 usbMsgLen = 0xff;
00456 usbTxLen = USBPID_STALL;
00457 }else if(rval != 0){
00458 replyLen = 0;
00459 }
00460 flags = 0;
00461 }
00462 #endif
00463 }
00464 usbMsgFlags = flags;
00465 usbMsgLen = replyLen;
00466 }
00467
00468
00469
00470 static void usbBuildTxBlock(void)
00471 {
00472 uchar wantLen, len, txLen, token;
00473
00474 wantLen = usbMsgLen;
00475 if(wantLen > 8)
00476 wantLen = 8;
00477 usbMsgLen -= wantLen;
00478 token = USBPID_DATA1;
00479 if(usbMsgFlags & USB_FLG_TX_PACKET)
00480 token = USBPID_DATA0;
00481 usbMsgFlags++;
00482 len = usbRead(usbTxBuf + 1, wantLen);
00483 if(len <= 8){
00484 usbCrc16Append(&usbTxBuf[1], len);
00485 txLen = len + 4;
00486 if(len < 8)
00487 usbMsgLen = 0xff;
00488 }else{
00489 txLen = USBPID_STALL;
00490 usbMsgLen = 0xff;
00491 }
00492 usbTxBuf[0] = token;
00493 usbTxLen = txLen;
00494 DBG2(0x20, usbTxBuf, txLen-1);
00495 }
00496
00497
00498
00499 static inline uchar isNotSE0(void)
00500 {
00501 uchar rval;
00502
00503
00504
00505
00506
00507 rval = USBIN & USBMASK;
00508 return rval;
00509 }
00510
00511 static inline void usbHandleResetHook(uchar notResetState)
00512 {
00513 #ifdef USB_RESET_HOOK
00514 static uchar wasReset;
00515 uchar isReset = !notResetState;
00516
00517 if(wasReset != isReset){
00518 USB_RESET_HOOK(isReset);
00519 wasReset = isReset;
00520 }
00521 #endif
00522 }
00523
00524
00525
00526 USB_PUBLIC void usbPoll(void)
00527 {
00528 schar len;
00529 uchar i;
00530
00531 if((len = usbRxLen) > 0){
00532
00533
00534
00535
00536
00537
00538 usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len - 3);
00539 #if USB_CFG_HAVE_FLOWCONTROL
00540 if(usbRxLen > 0)
00541 usbRxLen = 0;
00542 #else
00543 usbRxLen = 0;
00544 #endif
00545 }
00546 if(usbTxLen & 0x10){
00547 if(usbMsgLen != 0xff){
00548 usbBuildTxBlock();
00549 }
00550 }
00551 for(i = 10; i > 0; i--){
00552 if(isNotSE0())
00553 break;
00554 }
00555 if(i == 0){
00556 usbNewDeviceAddr = 0;
00557 usbDeviceAddr = 0;
00558 usbResetStall();
00559 DBG1(0xff, 0, 0);
00560 }
00561 usbHandleResetHook(i);
00562 }
00563
00564
00565
00566 USB_PUBLIC void usbInit(void)
00567 {
00568 #if USB_INTR_CFG_SET != 0
00569 USB_INTR_CFG |= USB_INTR_CFG_SET;
00570 #endif
00571 #if USB_INTR_CFG_CLR != 0
00572 USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
00573 #endif
00574 USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
00575 usbResetDataToggling();
00576 }
00577
00578