uchar usbFunctionSetup(uchar data[8])
{
static uchar replyBuf[3];
usbRequest_t *rq = (void *)data;
usbMsgPtr = replyBuf;
DBG1(0x49, &rq->bmRequestType, 1); /* debug output: print our request */
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
if(rq->wValue.bytes[0] == 1){ /* ReportID 1 */
replyBuf[0] = rq->wValue.bytes[0];
replyBuf[1] = LOWBYTE(ledWord);
replyBuf[2] = HIGHBYTE(ledWord);
return 3;
}else if(rq->wValue.bytes[0] == 2){ /* ReportID 2 */
replyBuf[0] = rq->wValue.bytes[0];
replyBuf[1] = PINC;
return 2;
}
}else if(rq->bRequest == USBRQ_HID_SET_REPORT){
if(rq->wValue.bytes[0] == 1){ /* ReportID "SET ADDRESS" */
usbWriteLen = 0xff; /* indicates "address" */
return 0xff; /* use usbFunctionWrite() */
}else if(rq->wValue.bytes[0] == 2){ /* ReportID "SET 128 bytes block" */
usbWriteLen = 129;
return 0xff; /* use usbFunctionWrite() */
}
}
}else{
if(data[1] == 0){ /* ECHO, for testing */
replyBuf[0] = data[2];
replyBuf[1] = data[3];
return 2;
}
}
return 0;
}
/* Writing to the EEPROM may take 7 * 8.5ms = 59.9ms which is slightly more
* than the allowable <50ms. We usually get away with that.
*/
uchar usbFunctionWrite(uchar *data, uchar len)
{
if(usbWriteLen == 0)
return 1;
if(usbWriteLen == 0xff){ /* expecting address */
usbWriteLen = 0;
if(len < 3)
return 0xff; /* stall */
LOWBYTE(ledWord) = data[1];
HIGHBYTE(ledWord) = data[2];
return 1;
}
if(usbWriteLen == 129){ /* first byte is report ID */
data++;
len--;
usbWriteLen--;
}
if(len > usbWriteLen)
len = usbWriteLen;
eeprom_write_block(data, (uchar *)0 + usbAddress, len);
if(usbAddress < 2){
codeEepromSize = eeprom_read_word(0); /* refresh
RAM copy of code size */
if(codeEepromSize > sizeof(code.data))
codeEepromSize = 0;
}
usbAddress += len;
usbWriteLen -= len;
return usbWriteLen == 0;
}