Changeset 4af90bf in avrstuff
- Timestamp:
- Jan 14, 2012, 9:11:20 PM (12 years ago)
- Branches:
- main
- Children:
- e07597b
- Parents:
- 1fabcce
- Location:
- V-USB_Dev/firmwares/CrO2
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
V-USB_Dev/firmwares/CrO2/main.c
r1fabcce r4af90bf 10 10 #include "usbdrv/usbdrv.h" 11 11 12 #define DDRIN DDRB 13 #define PORTIN PORTB 14 #define PININ PINB 12 static uint8_t ioblock[275]; // Max. Size of an MO5 standard block including sync header 13 static uint8_t status; // status bits 14 static uint16_t writePos; 15 static uint16_t blksz; 15 16 16 #define DDROUT DDRC 17 #define PORTOUT PORTC 17 static uint16_t readPos; 18 static uint8_t bitpos; 19 static uint8_t bit; // Currently generated bit 18 20 19 static uint8_t reportBuffer[5]; 20 static uint8_t buttons[6]; 21 static uint8_t idleRate; 21 int main() { 22 // Init 23 status = 0; 24 writePos = 0; 25 blksz = 0; 22 26 23 void main() {24 27 wdt_enable(WDTO_2S); 25 28 … … 27 30 usbInit(); 28 31 sei(); 29 bool doReport;30 32 31 DDROUT = 0; // Keyboard matrix out 32 PORTOUT = 255; // Enable pull up 33 // We put all pins as input then output a 0 in only one at a time. 34 // All the other pins are high-Z to avoid short circuits when many 35 // buttons are pressed. 36 DDRIN = 0; // Keyboard matrix in 37 PORTIN = 255; // Enable pull up 33 bit = 1; 34 bitpos = 0; 35 readPos = 0; 38 36 39 // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz 40 TCCR0 = 4; // timer 0 prescaler: 256 37 // Setup TIMER 1 for MFM pulses generation 38 TCCR1A = (1<<COM1A0); // Enable OC1A output 39 // CTC mode with OCR1A as MAXregister 40 TCCR1B = (1<<WGM12) | (1<<CS10); 41 OCR1A = 12800; // 800us bit clock 42 OCR1B = 6400; // Half-clock for 1 bits 43 TIMSK = (1 << OCIE1B) | (1 << OCIE1A); // interrupts on both timer matches. 41 44 42 reportBuffer[0] = 0; 43 doReport = false; 45 // TODO only start the timer when actually needed (start of block) 46 // and stop it when done. 47 DDRB |= 2; // OC1A/PB1 as output 48 44 49 45 50 while(1) { … … 47 52 usbPoll(); 48 53 49 for(int i = 0; i != 6; i++) { 50 DDROUT = 1<<i; 51 PORTOUT = ~(1<<i); 52 _delay_us(63); 53 if (buttons[i] != ((~PININ)&0x3F)) 54 { 55 doReport = true; 56 buttons[i] = (~PININ)&0x3F; 57 } 58 } 59 DDROUT = 0; 60 PORTOUT = 255; 61 62 // Copy lines 1 to 3 to the same lines in the report 63 for(int i=1; i != 4; i++) { 64 reportBuffer[i] = buttons[i]; 65 } 66 67 // Dispatch line 0 to report 1,2,3 (2 buttons each) 68 reportBuffer[1] |= (buttons[0] << 4)&0xC0; 69 reportBuffer[2] |= (buttons[0] << 2)&0xC0; 70 reportBuffer[3] |= (buttons[0])&0xC0; 71 72 // Copy part line 6 73 reportBuffer[4] = buttons[5]; // 2 btns left here 74 //reportBuffer[0] = buttons[4]; // this line is unused anyway, report as 75 // axis 76 77 if (doReport && usbInterruptIsReady()) { 78 usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 79 doReport = false; 80 } 54 // TODO send data to tape ! 81 55 } 82 56 } 83 57 84 58 85 static uint8_t protocolVer = 1; 86 uint8_t expectReport = 0;59 uint8_t usbFunctionSetup(uint8_t data[8]) { 60 usbRequest_t *rq = (void *)data; 87 61 88 89 char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { 90 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 91 0x09, 0x04, // USAGE (Joystick) 92 0xa1, 0x01, // COLLECTION (Application) 93 0xa1, 0x02, // COLLECTION (Logical) 94 95 0x75, 0x04, // REPORT_SIZE (8) 96 0x95, 0x02, // REPORT_COUNT (2) 97 0x15, 0x00, // LOGICAL_MINIMUM (0) 98 0x25, 0x0F, // LOGICAL_MAXIMUM (15) 99 0x35, 0x00, // PHYS_MINIMUM (0) 100 0x45, 0x0F, // PHYS_MAXIMUM (15) 101 0x09, 0x30, // USAGE (X) 102 0x09, 0x31, // USAGE (Y) 103 0x81, 0x02, // INPUT (Data,Var,Abs) 104 105 0x75, 0x01, // REPORT_SIZE (1) 106 0x95, 0x20, // REPORT_COUNT (32) 107 0x25, 0x01, // LOGICAL_MAXIMUM (1) 108 0x45, 0x01, // PHYSMAX (1) 109 0x05, 0x09, // USAGE_PAGE (Button) 110 0x19, 0x01, // USAGE_MINIMUM (Button 1) 111 0x29, 0x20, // USAGE_MAXIMUM (Button 32) 112 0x81, 0x02, // INPUT (Data,Var,Abs) 113 0xc0, // END_COLLECTION 114 0xc0 // END_COLLECTION 115 }; 116 117 118 uint8_t usbFunctionSetup(uint8_t data[8]) { 119 usbRequest_t *rq = (void *)data; 120 usbMsgPtr = reportBuffer; 121 if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) { 122 // class request type 123 if (rq->bRequest == USBRQ_HID_GET_REPORT) { 124 // wValue: ReportType (highbyte), ReportID (lowbyte) 125 // we only have one report type, so don't look at wValue 126 return sizeof(reportBuffer); 127 } else if (rq->bRequest == USBRQ_HID_SET_REPORT) { 128 if (rq->wLength.word == 1) { 129 // We expect one byte reports 130 expectReport = 1; 131 return 0xff; // Call usbFunctionWrite with data 132 } 133 } else if (rq->bRequest == USBRQ_HID_GET_IDLE) { 134 usbMsgPtr = &idleRate; 135 return 1; 136 } else if (rq->bRequest == USBRQ_HID_SET_IDLE) { 137 idleRate = rq->wValue.bytes[1]; 138 } else if (rq->bRequest == USBRQ_HID_GET_PROTOCOL) { 139 if (rq->wValue.bytes[1] < 1) { 140 protocolVer = rq->wValue.bytes[1]; 141 } 142 } else if(rq->bRequest == USBRQ_HID_SET_PROTOCOL) { 143 usbMsgPtr = &protocolVer; 144 return 1; 145 } 146 } else { 147 // no vendor specific requests implemented 148 } 149 return 0; 62 usbMsgPtr = ioblock; 63 switch(rq->bRequest) 64 { 65 case 0: 66 { /* CONFIGURE */ 67 status = rq->wValue.bytes[0]; 68 return 0; 69 } 70 case 1: 71 { /* RECEIVE/POLL DATA (TAPE > USB) */ 72 return 254; 73 } 74 case 2: 75 { 76 /* SEND DATA (USB > TAPE) */ 77 /* Get ready, actual data will come in usbFunctionWrite */ 78 // TODO store type of MO5 block + size in ioblock 79 writePos = 0; 80 blksz = rq->wLength.word; 81 return USB_NO_MSG; // Call usbFunctionWrite to send the data 82 } 83 } 84 return 0; 150 85 } 151 86 152 uint8_t usbFunctionWrite(uchar *data, uchar len) { 153 expectReport = 0; 154 return 0x01; 87 uint8_t usbFunctionWrite(uint8_t* data, uint8_t len) 88 { 89 // The data for a single request will be sent as slices of up to 8 bytes. 90 for (int i = 0; i < len; i++) 91 { 92 // TODO leave place for sync header and block type+size 93 ioblock[writePos++] = data[i]; 94 } 95 96 // TODO compute checksum as we go 97 98 return writePos>= blksz ? 1:0; 99 // returns 0: "needs more data" 100 // returns 1: "done" 101 // returns FF: "error" 155 102 } 156 103 104 ISR (TIMER1_COMPA_vect) 105 { 106 // generate next bit 107 bit = (ioblock[readPos] >> bitpos) & 1; 108 bitpos++; 109 if (bitpos > 7) 110 { 111 bitpos = 0; 112 readPos++; 113 if (readPos > 270) 114 readPos = 0; // TODO stop timer 115 } 116 } 117 118 ISR (TIMER1_COMPB_vect) 119 { 120 TCCR1A |= (bit << FOC1A); // Force toggle of A on B compare when generating a 1 bit 121 } -
V-USB_Dev/firmwares/CrO2/usbconfig.h
r1fabcce r4af90bf 52 52 * default control endpoint 0 and an interrupt-in endpoint 1. 53 53 */ 54 #define USB_CFG_HAVE_INTRIN_ENDPOINT 154 #define USB_CFG_HAVE_INTRIN_ENDPOINT 0 55 55 /** Define this to 1 if you want to compile a version with three endpoints: The 56 56 * default control endpoint 0, an interrupt-in endpoint 1 and an interrupt-in … … 72 72 * device is powered from the USB bus. 73 73 */ 74 #define USB_CFG_IS_SELF_POWERED 074 #define USB_CFG_IS_SELF_POWERED 1 75 75 /** Set this variable to the maximum USB bus power consumption of your device. 76 76 * The value is in milliamperes. [It will be divided by two since USB 77 77 * communicates power requirements in units of 2 mA.] 78 78 */ 79 #define USB_CFG_MAX_BUS_POWER 10079 #define USB_CFG_MAX_BUS_POWER 20 80 80 /** Set this to 1 if you want usbFunctionWrite() to be called for control-out 81 81 * transfers. Set it to 0 if you don't need it and want to save a couple of 82 82 * bytes. 83 83 */ 84 #define USB_CFG_IMPLEMENT_FN_WRITE 084 #define USB_CFG_IMPLEMENT_FN_WRITE 1 85 85 /** Set this to 1 if you need to send control replies which are generated 86 86 * "on the fly" when usbFunctionRead() is called. If you only want to send … … 102 102 /* -------------------------- Device Description --------------------------- */ 103 103 104 /** We cannot use Obdev's free shared VID/PID pair because this is a HID. 105 * We use John Hyde's VID (author of the book "USB Design By Example") for 106 * this example instead. John has offered this VID for use by students for 107 * non-commercial devices. Well... This example is for demonstration and 108 * education only... DO NOT LET DEVICES WITH THIS VID ESCAPE YOUR LAB! 109 * The Product-ID is a random number. 110 * 104 /* 111 105 * USB vendor ID for the device, low byte first. If you have registered your 112 106 * own Vendor ID, define it here. Otherwise you use obdev's free shared 113 107 * VID/PID pair. Be sure to read USBID-License.txt for rules! 114 108 */ 115 #define USB_CFG_VENDOR_ID 0x 42, 0x42109 #define USB_CFG_VENDOR_ID 0xC0, 0x16 116 110 /** This is the ID of the product, low byte first. It is interpreted in the 117 111 * scope of the vendor ID. If you have registered your own VID with usb.org … … 120 114 * USBID-License.txt! 121 115 */ 122 #define USB_CFG_DEVICE_ID 0x 31, 0x17116 #define USB_CFG_DEVICE_ID 0xDC, 0x05 123 117 /** Version number of the device: Minor number first, then major number. 124 118 */ … … 139 133 * the macros. See the file USBID-License.txt before you assign a name. 140 134 */ 141 #define USB_CFG_DEVICE_NAME ' S','t','a','r','k','a','d','r','o','i','d'135 #define USB_CFG_DEVICE_NAME 'C','r','O','2' 142 136 /** Length of USB_CFG_DEVICE_NAME 143 137 */ 144 #define USB_CFG_DEVICE_NAME_LEN 11138 #define USB_CFG_DEVICE_NAME_LEN 4 145 139 /** See USB specification if you want to conform to an existing device class. 146 140 * This setting means to specify the class at the interface level. 147 141 */ 148 #define USB_CFG_DEVICE_CLASS 0 142 #define USB_CFG_DEVICE_CLASS 0xFF 149 143 /** See USB specification if you want to conform to an existing device subclass. 150 144 */ … … 153 147 * protocol. This is HID class. 154 148 */ 155 #define USB_CFG_INTERFACE_CLASS 0x0 3149 #define USB_CFG_INTERFACE_CLASS 0x0 156 150 /** See USB specification if you want to conform to an existing device class or 157 151 * protocol. This is not a boot device. … … 165 159 * an HID device. Otherwise don't define it or define it to 0. 166 160 */ 167 #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 44161 #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0 168 162 169 163 /* ------------------- Fine Control over USB Descriptors ------------------- */
Note:
See TracChangeset
for help on using the changeset viewer.