#include #include #include #include #include #include #include #include "usbdrv/usbdrv.h" static uint8_t ioblock[275]; // Max. Size of an MO5 standard block including sync header static uint8_t status; // status bits static uint16_t writePos; static uint16_t blksz; static uint16_t readPos; static uint8_t bitpos; static uint8_t bit; // Currently generated bit int main() { // Init status = 0; writePos = 0; blksz = 0; wdt_enable(WDTO_2S); // USB usbInit(); sei(); bit = 1; bitpos = 7; readPos = 0; // Generate sync header (this never changes) int i; for (i = 0; i< 16; i++) { ioblock[i] = 1; } ioblock[i++] = 0x3C; ioblock[i++] = 0x5A; // HEAD block ioblock[i++] = 0x0; ioblock[i++] = 0x10; int j = i; ioblock[i++] = 'C'; ioblock[i++] = 'r'; ioblock[i++] = 'O'; ioblock[i++] = '2'; ioblock[i++] = ' '; ioblock[i++] = ' '; ioblock[i++] = ' '; ioblock[i++] = ' '; ioblock[i++] = 'B'; ioblock[i++] = 'A'; ioblock[i++] = 'S'; ioblock[i++] = 0; ioblock[i++] = 0; ioblock[i++] = 0; uint8_t s = 0; for (;jbRequest) { case 0: { /* CONFIGURE */ status = rq->wValue.bytes[0]; return 0; } case 1: { /* RECEIVE/POLL DATA (TAPE > USB) */ return 254; } case 2: { /* SEND DATA (USB > TAPE) */ /* Get ready, actual data will come in usbFunctionWrite */ // TODO store type of MO5 block + size in ioblock writePos = 0; blksz = rq->wLength.word; return USB_NO_MSG; // Call usbFunctionWrite to send the data } } return 0; } uint8_t usbFunctionWrite(uint8_t* data, uint8_t len) { // The data for a single request will be sent as slices of up to 8 bytes. for (int i = 0; i < len; i++) { // TODO leave place for sync header and block type+size // ioblock[writePos] = data[i]; writePos++; } // TODO compute checksum as we go if (writePos >= blksz) { // start generating TCCR1A &= ~(1<> bitpos) & 1; bitpos--; if (bitpos > 7) // overflow ? { bitpos = 7; readPos++; if (readPos > blksz) { // Make sure output is high TCCR1A |= (1<