Changeset 5b8020c in avrstuff
- Timestamp:
- Sep 8, 2019, 2:20:20 PM (5 years ago)
- Branches:
- main
- Children:
- 5b8c7e2
- Parents:
- c956fd4
- Location:
- grip2hid
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
grip2hid/Makefile
rc956fd4 r5b8020c 1 1 #Set vars 2 PROJECT=grip2hid 3 FCPU=1000000 4 BAUD=9600 5 6 PROG=flip1 -u 2 7 MCU=at90usb1287 3 COMPILE = avr-gcc -Wall -Wextra -Werror -Os -Iusbdrv -I. -mmcu=$(MCU) -DF_CPU=16000000 4 PROJECT=grip2hid 8 9 #MCU=atmega8 10 #PROG=avr109 -P /dev/ports/usb0 -b $(BAUD) -u 11 12 # You should not need to change anything below 13 # ----------------------------------------------------------------------------- 14 COMPILE = avr-g++ -Wall -Wextra -Werror -O3 -mmcu=$(MCU) -DF_CPU=$(FCPU) -DBAUD=$(BAUD) 5 15 6 16 #Rules … … 8 18 avr-objcopy -j .text -j .data -O ihex $^ $@ 9 19 10 $(PROJECT).bin: main.o 20 $(PROJECT).bin: main.o usart.o 11 21 $(COMPILE) $^ -o $@ 12 22 … … 18 28 $(COMPILE) -c $< -o $@ 19 29 30 usart.o: ../libs/usart/usart.c 31 $(COMPILE) -c $< -o $@ 32 20 33 flash: $(PROJECT).hex 21 avrdude -u -c flip1-p $(MCU) -Uflash:w:$^34 avrdude -u -c $(PROG) -p $(MCU) -Uflash:w:$^ 22 35 23 36 clean: -
grip2hid/main.cpp
rc956fd4 r5b8020c 7 7 #include <string.h> 8 8 #include <stdbool.h> 9 10 #include "../libs/usart/usart.h" 11 12 #define GRIP_PORT PORTB 13 #define GRIP_DDR DDRB 14 #define GRIP_PIN PINB 15 #define GRIP_DAT_A (1 << 0) 16 #define GRIP_CLK_A (1 << 1) 17 #define GRIP_DAT_B (1 << 3) 18 #define GRIP_CLK_B (1 << 2) 9 19 10 20 class GrIP … … 18 28 } 19 29 20 voidPushBit(uint32_t bit)30 bool PushBit(uint32_t bit) 21 31 { 22 32 word = (word << 1) | (bit & 1); … … 25 35 switch (state) { 26 36 case 0: 27 if ((word & 0x3F) != 0x1F) return ;37 if ((word & 0x3F) != 0x1F) return false; 28 38 count = 6; 29 39 state = 1; 30 40 break; 31 41 case 1: 32 if (count == 11 || count == 16 || count == 21 || count == 24) {33 PORTD = word << 4;34 }35 42 if (count == 24) { 36 43 state = 0; 37 44 count = 0; 45 return true; 38 46 } 39 47 break; 40 48 } 49 50 return false; 51 } 52 53 void Dump() { 54 USARTWriteHex(word >> 16); 55 USARTWriteHex(word >> 8); 56 USARTWriteHex(word); 41 57 } 42 58 43 59 private: 44 uint32_t word = 0;45 uint8_t count = 0;46 uint8_t state = 0;60 uint32_t word; 61 uint8_t count; 62 uint8_t state; 47 63 }; 48 64 65 49 66 int main() { 67 GrIP pad[2]; 68 50 69 wdt_enable(WDTO_2S); 51 70 52 71 // debug LEDs - output 53 DDRD |= 0x F0;72 DDRD |= 0x7C; 54 73 PORTD = 0; 55 74 56 75 // GrIP input 57 DDRB = 0; 58 uint8_t oldv = PINB; 76 GRIP_PORT = 0; // Disable pull-ups 77 GRIP_DDR = 0; // Port as input 78 uint8_t oldv = GRIP_PIN; 59 79 60 GrIP pad; 80 USARTInit(); 81 USARTWriteChar('h'); 82 USARTWriteChar('\r'); 83 USARTWriteChar('\n'); 84 61 85 62 86 for (;;) { 63 wdt_reset(); 87 // Because the CPU is too slow, if we try to scan all pads at once we 88 // don't manage to decode them (missed transitions). So we scan them 89 // one at a time. 90 // To scan all 4 gamepads this will take about 4 milliseconds, which 91 // is not the best we could do, but is okay. When we have the real 92 // hardware (with the CPU running at full 16MHz speed instead of crappy 93 // 1MHz here), we can try to interleave them again (one just has to put 94 // them all into a single for loop instead of separate loops for each). 95 // Then we get to 1ms to scan all 4 pads in parallel, cool! And it 96 // also fixes the problem mentionned below that when less pads are 97 // connected, it will not slowdown waiting for one of them to timeout. 64 98 65 uint8_t newv = PINB; 99 // FIXME the loop to 255 here to wait for a bit isn't too nice. We 100 // should rather use a timer with a known period? 101 // Process pad1 102 uint8_t i; 103 for (i = 0; i < 255; i++) { 104 wdt_reset(); 66 105 67 if (!(newv & 2)) { // clock is down 68 if (oldv & 2) { // and it was up at previous read 69 // Read bit 70 uint32_t bit = (newv & 1) != 0; 71 pad.PushBit(bit); 106 uint8_t newv = GRIP_PIN; 107 108 if (!(newv & GRIP_CLK_A)) { // clock is down 109 if (oldv & GRIP_CLK_A) { // and it was up at previous read 110 // Read bit 111 uint32_t bit = (newv & GRIP_DAT_A) != 0; 112 i = 0; 113 if (pad[0].PushBit(bit)) { 114 pad[0].Dump(); 115 USARTWriteChar(' '); 116 break; 117 } 118 } 72 119 } 120 oldv = newv; 73 121 } 74 oldv = newv; 122 123 // Process pad 2 124 for (i = 0; i < 255; i++) { 125 wdt_reset(); 126 127 uint8_t newv = GRIP_PIN; 128 if (!(newv & GRIP_CLK_B)) { // clock is down 129 if (oldv & GRIP_CLK_B) { // and it was up at previous read 130 // Read bit 131 uint32_t bit = (newv & GRIP_DAT_B) != 0; 132 i = 0; 133 if (pad[1].PushBit(bit)) { 134 pad[1].Dump(); 135 USARTWriteChar(' '); 136 break; 137 } 138 } 139 } 140 oldv = newv; 141 } 142 USARTWriteChar('\r'); 143 USARTWriteChar('\n'); 75 144 } 76 145
Note:
See TracChangeset
for help on using the changeset viewer.