Changeset 5b8020c in avrstuff


Ignore:
Timestamp:
Sep 8, 2019, 2:20:20 PM (5 years ago)
Author:
Adrien Destugues <pulkomandy@…>
Branches:
main
Children:
5b8c7e2
Parents:
c956fd4
Message:

grip2hid: make it work with 2 pads

The CPU on the AT90USBKEY is apparently too slow to manage two pads in
parallel, so scan them one at a time instead.

Location:
grip2hid
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • grip2hid/Makefile

    rc956fd4 r5b8020c  
    11#Set vars
     2PROJECT=grip2hid
     3FCPU=1000000
     4BAUD=9600
     5
     6PROG=flip1 -u
    27MCU=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# -----------------------------------------------------------------------------
     14COMPILE = avr-g++ -Wall -Wextra -Werror -O3 -mmcu=$(MCU) -DF_CPU=$(FCPU) -DBAUD=$(BAUD)
    515
    616#Rules
     
    818        avr-objcopy -j .text -j .data -O ihex $^ $@
    919
    10 $(PROJECT).bin: main.o
     20$(PROJECT).bin: main.o usart.o
    1121        $(COMPILE) $^ -o $@
    1222
     
    1828        $(COMPILE) -c $< -o $@
    1929
     30usart.o: ../libs/usart/usart.c
     31        $(COMPILE) -c $< -o $@
     32
    2033flash: $(PROJECT).hex
    21         avrdude -u -c flip1 -p $(MCU) -Uflash:w:$^
     34        avrdude -u -c $(PROG) -p $(MCU) -Uflash:w:$^
    2235
    2336clean:
  • grip2hid/main.cpp

    rc956fd4 r5b8020c  
    77#include <string.h>
    88#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)
    919
    1020class GrIP
     
    1828        }
    1929
    20         void PushBit(uint32_t bit)
     30        bool PushBit(uint32_t bit)
    2131        {
    2232                word = (word << 1) | (bit & 1);
     
    2535                switch (state) {
    2636                        case 0:
    27                                 if ((word & 0x3F) != 0x1F) return;
     37                                if ((word & 0x3F) != 0x1F) return false;
    2838                                count = 6;
    2939                                state = 1;
    3040                                break;
    3141                        case 1:
    32                                 if (count == 11 || count == 16 || count == 21 || count == 24) {
    33                                         PORTD = word << 4;
    34                                 }
    3542                                if (count == 24) {
    3643                                        state = 0;
    3744                                        count = 0;
     45                                        return true;
    3846                                }
    3947                                break;
    4048                }
     49
     50                return false;
     51        }
     52
     53        void Dump() {
     54                USARTWriteHex(word >> 16);
     55                USARTWriteHex(word >> 8);
     56                USARTWriteHex(word);
    4157        }
    4258
    4359private:
    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;
    4763};
    4864
     65
    4966int main() {
     67        GrIP pad[2];
     68
    5069        wdt_enable(WDTO_2S);
    5170
    5271        // debug LEDs - output
    53         DDRD |= 0xF0;
     72        DDRD |= 0x7C;
    5473        PORTD = 0;
    5574
    5675        // 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;
    5979
    60         GrIP pad;
     80        USARTInit();
     81        USARTWriteChar('h');
     82        USARTWriteChar('\r');
     83        USARTWriteChar('\n');
     84
    6185
    6286        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.
    6498
    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();
    66105
    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                                }
    72119                        }
     120                        oldv = newv;
    73121                }
    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');
    75144        }
    76145
Note: See TracChangeset for help on using the changeset viewer.