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 #ifndef IAR_SECTION
00026 #define IAR_SECTION(arg)
00027 #define __no_init
00028 #endif
00029
00030
00031
00032
00033
00034
00035
00036
00037 __no_init uchar usbRxBuf[2][USB_BUFSIZE] __attribute__ ((section (USB_BUFFER_SECTION))) IAR_SECTION(USB_BUFFER_SECTION);
00038 uchar usbDeviceAddr;
00039 uchar usbNewDeviceAddr;
00040 uchar usbConfiguration;
00041 uchar usbInputBuf;
00042 uchar usbAppBuf;
00043 volatile schar usbRxLen;
00044 uchar usbCurrentTok;
00045 uchar usbRxToken;
00046 uchar usbMsgLen = 0xff;
00047 volatile schar usbTxLen = -1;
00048 uchar usbTxBuf[USB_BUFSIZE];
00049 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00050
00051 volatile schar usbTxLen1 = -1;
00052 uchar usbTxBuf1[USB_BUFSIZE];
00053 #endif
00054 uchar usbAckBuf[1] = {USBPID_ACK};
00055 uchar usbNakBuf[1] = {USBPID_NAK};
00056
00057
00058 uchar *usbMsgPtr;
00059 static uchar usbMsgFlags;
00060 static uchar usbIsReset;
00061
00062 #define USB_FLG_TX_PACKET (1<<0)
00063
00064 #define USB_FLG_MSGPTR_IS_ROM (1<<6)
00065 #define USB_FLG_USE_DEFAULT_RW (1<<7)
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 static PROGMEM char usbDescrDevice[] = {
00078 18,
00079 USBDESCR_DEVICE,
00080 0x01, 0x01,
00081 USB_CFG_DEVICE_CLASS,
00082 USB_CFG_DEVICE_SUBCLASS,
00083 0,
00084 8,
00085 USB_CFG_VENDOR_ID,
00086 USB_CFG_DEVICE_ID,
00087 USB_CFG_DEVICE_VERSION,
00088 #if USB_CFG_VENDOR_NAME_LEN
00089 1,
00090 #else
00091 0,
00092 #endif
00093 #if USB_CFG_DEVICE_NAME_LEN
00094 2,
00095 #else
00096 0,
00097 #endif
00098 #if USB_CFG_SERIAL_NUMBER_LENGTH
00099 3,
00100 #else
00101 0,
00102 #endif
00103 1,
00104 };
00105
00106 static PROGMEM char usbDescrConfig[] = {
00107 9,
00108 USBDESCR_CONFIG,
00109 (18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT
00110 #if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
00111 + 9
00112 #endif
00113 ), 0,
00114 1,
00115 1,
00116 0,
00117 #if USB_CFG_IS_SELF_POWERED
00118 USBATTR_SELFPOWER,
00119 #else
00120 USBATTR_BUSPOWER,
00121 #endif
00122 USB_CFG_MAX_BUS_POWER/2,
00123
00124 9,
00125 USBDESCR_INTERFACE,
00126 0,
00127 0,
00128 USB_CFG_HAVE_INTRIN_ENDPOINT,
00129 USB_CFG_INTERFACE_CLASS,
00130 USB_CFG_INTERFACE_SUBCLASS,
00131 USB_CFG_INTERFACE_PROTOCOL,
00132 0,
00133 #if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
00134 9,
00135 USBDESCR_HID,
00136 0x01, 0x01,
00137 0x00,
00138 0x01,
00139 0x22,
00140 USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0,
00141 #endif
00142 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00143 7,
00144 USBDESCR_ENDPOINT,
00145 0x81,
00146 0x03,
00147 8, 0,
00148 USB_CFG_INTR_POLL_INTERVAL,
00149 #endif
00150 };
00151
00152 static PROGMEM char usbDescrString0[] = {
00153 4,
00154 3,
00155 0x09, 0x04,
00156 };
00157
00158 #if USB_CFG_VENDOR_NAME_LEN
00159 static PROGMEM int usbDescrString1[] = {
00160 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
00161 USB_CFG_VENDOR_NAME
00162 };
00163 #endif
00164 #if USB_CFG_DEVICE_NAME_LEN
00165 static PROGMEM int usbDescrString2[] = {
00166 USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
00167 USB_CFG_DEVICE_NAME
00168 };
00169 #endif
00170
00171
00172
00173
00174 #ifndef PRG_RDB
00175 #define PRG_RDB(addr) pgm_read_byte(addr)
00176 #endif
00177
00178 typedef union{
00179 unsigned word;
00180 uchar *ptr;
00181 uchar bytes[2];
00182 }converter_t;
00183
00184
00185
00186
00187
00188
00189
00190 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00191 static uchar usbTxPacketCnt1;
00192 #if USB_CFG_IMPLEMENT_HALT
00193 static uchar usbHalted1;
00194 #endif
00195
00196 void usbSetInterrupt(uchar *data, uchar len)
00197 {
00198 uchar *p, i;
00199
00200 #if USB_CFG_IMPLEMENT_HALT
00201 if(usbHalted1)
00202 return;
00203 #endif
00204 if(len > 8)
00205 len = 8;
00206 i = USBPID_DATA1;
00207 if(usbTxPacketCnt1 & 1)
00208 i = USBPID_DATA0;
00209 if(usbTxLen1 < 0){
00210 usbTxPacketCnt1++;
00211 }else{
00212 usbTxLen1 = -1;
00213 }
00214 p = usbTxBuf1;
00215 *p++ = i;
00216 for(i=len;i--;)
00217 *p++ = *data++;
00218 usbCrc16Append(&usbTxBuf1[1], len);
00219 usbTxLen1 = len + 4;
00220 #if DEBUG_LEVEL > 1
00221 DBG2(0x21, usbTxBuf1, usbTxLen1-1);
00222 #else
00223 DBG1(0x21, usbTxBuf1 + 1, 2);
00224 #endif
00225 }
00226 #endif
00227
00228
00229 static uchar usbRead(uchar *data, uchar len)
00230 {
00231 #if USB_CFG_IMPLEMENT_FN_READ
00232 if(usbMsgFlags & USB_FLG_USE_DEFAULT_RW){
00233 #endif
00234 uchar i = len, *r = usbMsgPtr;
00235 if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){
00236 while(i--){
00237 uchar c = PRG_RDB(r);
00238 *data++ = c;
00239 r++;
00240 }
00241 }else{
00242 while(i--)
00243 *data++ = *r++;
00244 }
00245 usbMsgPtr = r;
00246 return len;
00247 #if USB_CFG_IMPLEMENT_FN_READ
00248 }else{
00249 if(len != 0)
00250 return usbFunctionRead(data, len);
00251 return 0;
00252 }
00253 #endif
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263 static void usbProcessRx(uchar *data, uchar len)
00264 {
00265 usbRequest_t *rq = (void *)data;
00266 uchar replyLen = 0, flags = USB_FLG_USE_DEFAULT_RW;
00267
00268
00269
00270 #if DEBUG_LEVEL > 1
00271 DBG2(0x10 + (usbRxToken == (uchar)USBPID_SETUP), data, len);
00272 #else
00273 DBG1(0x10 + (usbRxToken == (uchar)USBPID_SETUP), data, 2);
00274 #endif
00275 if(usbRxToken == (uchar)USBPID_SETUP){
00276 if(len == 8){
00277 uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
00278 if(type == USBRQ_TYPE_STANDARD){
00279 uchar *replyData = usbTxBuf + 9;
00280 replyData[0] = 0;
00281 if(rq->bRequest == USBRQ_GET_STATUS){
00282 uchar __attribute__((__unused__)) recipient = rq->bmRequestType & USBRQ_RCPT_MASK;
00283 #if USB_CFG_IS_SELF_POWERED
00284 if(recipient == USBRQ_RCPT_DEVICE)
00285 replyData[0] = USB_CFG_IS_SELF_POWERED;
00286 #endif
00287 #if USB_CFG_HAVE_INTRIN_ENDPOINT && USB_CFG_IMPLEMENT_HALT
00288 if(usbHalted1 && recipient == USBRQ_RCPT_ENDPOINT && rq->wIndex.bytes[0] == 0x81)
00289 replyData[0] = 1;
00290 #endif
00291 replyData[1] = 0;
00292 replyLen = 2;
00293 }else if(rq->bRequest == USBRQ_SET_ADDRESS){
00294 usbNewDeviceAddr = rq->wValue.bytes[0];
00295 }else if(rq->bRequest == USBRQ_GET_DESCRIPTOR){
00296 flags = USB_FLG_MSGPTR_IS_ROM | USB_FLG_USE_DEFAULT_RW;
00297 if(rq->wValue.bytes[1] == 1){
00298 replyLen = sizeof(usbDescrDevice);
00299 replyData = (uchar *)usbDescrDevice;
00300 }else if(rq->wValue.bytes[1] == 2){
00301 replyLen = sizeof(usbDescrConfig);
00302 replyData = (uchar *)usbDescrConfig;
00303 }else if(rq->wValue.bytes[1] == 3){
00304 if(rq->wValue.bytes[0] == 0){
00305 replyLen = sizeof(usbDescrString0);
00306 replyData = (uchar *)usbDescrString0;
00307 #if USB_CFG_VENDOR_NAME_LEN
00308 }else if(rq->wValue.bytes[0] == 1){
00309 replyLen = sizeof(usbDescrString1);
00310 replyData = (uchar *)usbDescrString1;
00311 #endif
00312 #if USB_CFG_DEVICE_NAME_LEN
00313 }else if(rq->wValue.bytes[0] == 2){
00314 replyLen = sizeof(usbDescrString2);
00315 replyData = (uchar *)usbDescrString2;
00316 #endif
00317 #if USB_CFG_SERIAL_NUMBER_LENGTH
00318 }else if(rq->wValue.bytes[0] == 3){
00319 replyLen = 2 * USB_CFG_SERIAL_NUMBER_LENGTH + 2;
00320 replyData = (uchar *)usbCfgSerialNumberStringDescriptor;
00321 #endif
00322 }
00323 }
00324 #if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
00325 else if(rq->wValue.bytes[1] == USBDESCR_HID){
00326 replyLen = 9;
00327 replyData = (uchar *)usbDescrConfig + 18;
00328 }else if(rq->wValue.bytes[1] == USBDESCR_HID_REPORT){
00329 replyLen = USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH;
00330 replyData = (uchar *)usbHidReportDescriptor;
00331 }
00332 #endif
00333 }else if(rq->bRequest == USBRQ_GET_CONFIGURATION){
00334 replyLen = 1;
00335 replyData = &usbConfiguration;
00336 }else if(rq->bRequest == USBRQ_SET_CONFIGURATION){
00337 usbConfiguration = rq->wValue.bytes[0];
00338 #if USB_CFG_IMPLEMENT_HALT
00339 usbHalted1 = 0;
00340 #endif
00341 }else if(rq->bRequest == USBRQ_GET_INTERFACE){
00342 replyLen = 1;
00343 #if USB_CFG_HAVE_INTRIN_ENDPOINT
00344 #if USB_CFG_IMPLEMENT_HALT
00345 }else if(rq->bRequest == USBRQ_CLEAR_FEATURE || rq->bRequest == USBRQ_SET_FEATURE){
00346 if(rq->wValue.bytes[0] == 0 && rq->wIndex.bytes[0] == 0x81){
00347 usbHalted1 = rq->bRequest - 1;
00348 if(usbHalted1){
00349 usbTxBuf1[0] = USBPID_STALL;
00350 usbTxLen1 = 2;
00351 }
00352 usbTxPacketCnt1 = 0;
00353 }
00354 #endif
00355 }else if(rq->bRequest == USBRQ_SET_INTERFACE){
00356 usbTxPacketCnt1 = 0;
00357 #if USB_CFG_IMPLEMENT_HALT
00358 usbHalted1 = 0;
00359 #endif
00360 #endif
00361 }else{
00362
00363
00364
00365 }
00366 usbMsgPtr = replyData;
00367 if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0])
00368 replyLen = rq->wLength.bytes[0];
00369 }else{
00370 replyLen = usbFunctionSetup(data);
00371 #if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE
00372 if(replyLen == 0xff){
00373 if((rq->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_DEVICE_TO_HOST){
00374 replyLen = rq->wLength.bytes[0];
00375 }
00376 flags = 0;
00377 }
00378 #endif
00379 }
00380 }
00381
00382 }else{
00383 #if USB_CFG_IMPLEMENT_FN_WRITE
00384 if(!(usbMsgFlags & USB_FLG_USE_DEFAULT_RW)){
00385 uchar rval = usbFunctionWrite(data, len);
00386 replyLen = 0xff;
00387 if(rval == 0xff){
00388
00389 usbTxBuf[0] = USBPID_STALL;
00390 usbTxLen = 2;
00391 }else if(rval != 0){
00392 replyLen = 0;
00393 }
00394 flags = 0;
00395 }
00396 #else
00397 replyLen = 0;
00398 #endif
00399 }
00400 usbMsgFlags = flags;
00401 usbMsgLen = replyLen;
00402 }
00403
00404
00405
00406 static void usbBuildTxBlock(void)
00407 {
00408 uchar wantLen, len, txLen, token;
00409
00410 wantLen = usbMsgLen;
00411 if(wantLen > 8)
00412 wantLen = 8;
00413 usbMsgLen -= wantLen;
00414 token = USBPID_DATA1;
00415 if(usbMsgFlags & USB_FLG_TX_PACKET)
00416 token = USBPID_DATA0;
00417 usbMsgFlags++;
00418 len = usbRead(usbTxBuf + 1, wantLen);
00419 if(len <= 8){
00420 usbCrc16Append(usbTxBuf + 1, len);
00421 txLen = len + 4;
00422 if(len < 8)
00423 usbMsgLen = 0xff;
00424 }else{
00425 token = USBPID_STALL;
00426 txLen = 2;
00427 usbMsgLen = 0xff;
00428 }
00429 usbTxBuf[0] = token;
00430 usbTxLen = txLen;
00431 #if DEBUG_LEVEL > 1
00432 DBG2(0x20, usbTxBuf, txLen-1);
00433 #else
00434 DBG1(0x20, usbTxBuf + 1, 2);
00435 #endif
00436 }
00437
00438 static inline uchar isNotSE0(void)
00439 {
00440 uchar rval;
00441
00442
00443
00444
00445
00446 rval = USBIN & USBMASK;
00447 return rval;
00448 }
00449
00450
00451
00452 void usbPoll(void)
00453 {
00454 uchar len;
00455
00456 if((len = usbRxLen) > 0){
00457
00458
00459
00460
00461
00462
00463 len -= 3;
00464 if(len < 128){
00465 converter_t appBuf;
00466 appBuf.ptr = (uchar *)usbRxBuf;
00467 appBuf.bytes[0] = usbAppBuf;
00468 appBuf.bytes[0]++;
00469 usbProcessRx(appBuf.ptr, len);
00470 }
00471 usbRxLen = 0;
00472 }
00473 if(usbMsgLen != 0xff){
00474 if(usbTxLen < 0)
00475 usbBuildTxBlock();
00476 }
00477 if(isNotSE0()){
00478 usbIsReset = 0;
00479 }else{
00480
00481 if(!usbIsReset){
00482 uchar i;
00483 for(i=100;i;i--){
00484 if(isNotSE0())
00485 goto notUsbReset;
00486 }
00487 usbIsReset = 1;
00488 usbNewDeviceAddr = 0;
00489 usbDeviceAddr = 0;
00490 #if USB_CFG_IMPLEMENT_HALT
00491 usbHalted1 = 0;
00492 #endif
00493 DBG1(0xff, 0, 0);
00494 notUsbReset:;
00495 }
00496 }
00497 }
00498
00499
00500
00501 void usbInit(void)
00502 {
00503 usbInputBuf = (uchar)usbRxBuf[0];
00504 usbAppBuf = (uchar)usbRxBuf[1];
00505 #if USB_INTR_CFG_SET != 0
00506 USB_INTR_CFG |= USB_INTR_CFG_SET;
00507 #endif
00508 #if USB_INTR_CFG_CLR != 0
00509 USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
00510 #endif
00511 USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
00512 }
00513
00514