source: avrstuff/V-USB_Dev/firmwares/starkadroid/main.c@ b0c194d

main
Last change on this file since b0c194d was b0c194d, checked in by Adrien Destugues <pulkomandy@…>, 12 years ago

Copy Starkadroid firmware.

git-svn-id: svn://pulkomandy.tk/avrstuff@45 c6672c3c-f6b6-47f9-9001-1fd6b12fecbe

  • Property mode set to 100644
File size: 4.7 KB
Line 
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <avr/wdt.h>
4#include <avr/pgmspace.h>
5#include <util/delay.h>
6
7#include <string.h>
8#include <stdbool.h>
9
10#include "usbdrv/usbdrv.h"
11
12#define DDRIN DDRB
13#define PORTIN PORTB
14#define PININ PINB
15
16#define DDROUT DDRC
17#define PORTOUT PORTC
18
19static uint8_t reportBuffer[5];
20static uint8_t buttons[6];
21static uint8_t idleRate;
22
23void main() {
24 wdt_enable(WDTO_2S);
25
26 // USB
27 usbInit();
28 sei();
29 bool doReport;
30
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
38
39 // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz
40 TCCR0 = 4; // timer 0 prescaler: 256
41
42 reportBuffer[0] = 0;
43 doReport = false;
44
45 while(1) {
46 wdt_reset();
47 usbPoll();
48
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 }
81 }
82}
83
84
85static uint8_t protocolVer = 1;
86uint8_t expectReport = 0;
87
88
89char 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
118uint8_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;
150}
151
152uint8_t usbFunctionWrite(uchar *data, uchar len) {
153 expectReport = 0;
154 return 0x01;
155}
156
Note: See TracBrowser for help on using the repository browser.