source: avrstuff/starkadroid/code/main.c@ 5649b6c

main
Last change on this file since 5649b6c was 5649b6c, checked in by Adrien Destugues <pulkomandy@…>, 14 years ago
  • Report everything as buttons.
  • Don't periodically send reports. Only send one when there is an actual change of button state
  • Set the period to 20ms, as that's enough.
  • Some code cleanup.

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

  • Property mode set to 100644
File size: 3.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[6];
20static uint8_t idleRate;
21
22void main() {
23 bool which = false;
24 uint8_t idleCounter = 0;
25
26 wdt_enable(WDTO_2S);
27
28 // USB
29 usbInit();
30 sei();
31 bool doReport;
32
33 DDROUT = 0; // Keyboard matrix out
34 PORTOUT = 255; // Enable pull up
35 // We put all pins as input then output a 0 in only one at a time.
36 // All the other pins are high-Z to avoid short circuits when many buttons are pressed.
37 DDRIN = 0; // Keyboard matrix in
38 PORTIN = 255; // Enable pull up
39
40 // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz
41 TCCR0 = 4; // timer 0 prescaler: 256
42
43 while(1) {
44 wdt_reset();
45 usbPoll();
46
47 doReport = false;
48 for(char i = 0; i != 6; i++) {
49 DDROUT = 1<<i;
50 PORTOUT = ~(1<<i);
51 if (reportBuffer[i] != ((~PININ)&0x3F))
52 doReport = true;
53 reportBuffer[i] = (~PININ)&0x3F;
54 }
55 DDROUT = 0;
56 PORTOUT = 255;
57
58 if (doReport && usbInterruptIsReady()) {
59 usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
60 doReport = false;
61 }
62 }
63}
64
65
66static uint8_t protocolVer = 1;
67uint8_t expectReport = 0;
68
69
70char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
71 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
72 0x09, 0x05, // USAGE (Game Pad)
73 0xa1, 0x01, // COLLECTION (Application)
74 0xa1, 0x00, // COLLECTION (Physical)
75 0x05, 0x09, // USAGE_PAGE (Button)
76 0x19, 0x01, // USAGE_MINIMUM (Button 1)
77 0x29, 0x30, // USAGE_MAXIMUM (Button 40)
78 0x15, 0x00, // LOGICAL_MINIMUM (0)
79 0x25, 0x01, // LOGICAL_MAXIMUM (1)
80 0x95, 0x30, // REPORT_COUNT (40)
81 0x75, 0x01, // REPORT_SIZE (1)
82 0x81, 0x02, // INPUT (Data,Var,Abs)
83 0xc0, // END_COLLECTION
84 0xc0 // END_COLLECTION
85};
86
87
88uint8_t usbFunctionSetup(uint8_t data[8]) {
89 usbRequest_t *rq = (void *)data;
90 usbMsgPtr = reportBuffer;
91 if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
92 // class request type
93 if (rq->bRequest == USBRQ_HID_GET_REPORT) {
94 // wValue: ReportType (highbyte), ReportID (lowbyte)
95 // we only have one report type, so don't look at wValue
96 return sizeof(reportBuffer);
97 } else if (rq->bRequest == USBRQ_HID_SET_REPORT) {
98 if (rq->wLength.word == 1) {
99 // We expect one byte reports
100 expectReport = 1;
101 return 0xff; // Call usbFunctionWrite with data
102 }
103 } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
104 usbMsgPtr = &idleRate;
105 return 1;
106 } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
107 idleRate = rq->wValue.bytes[1];
108 } else if (rq->bRequest == USBRQ_HID_GET_PROTOCOL) {
109 if (rq->wValue.bytes[1] < 1) {
110 protocolVer = rq->wValue.bytes[1];
111 }
112 } else if(rq->bRequest == USBRQ_HID_SET_PROTOCOL) {
113 usbMsgPtr = &protocolVer;
114 return 1;
115 }
116 } else {
117 // no vendor specific requests implemented
118 }
119 return 0;
120}
121
122uint8_t usbFunctionWrite(uchar *data, uchar len) {
123 expectReport = 0;
124 return 0x01;
125}
126
Note: See TracBrowser for help on using the repository browser.