Changeset bf42f57 in avrstuff for starkadroid/code/main.c


Ignore:
Timestamp:
Oct 17, 2010, 9:49:32 PM (14 years ago)
Author:
Adrien Destugues <pulkomandy@…>
Branches:
main
Children:
1dc9759
Parents:
be9ba97
Message:
  • Ajout de pins "extra" sur le PCB. On sait jamais ça peut toujours servir...
  • Gros nettoyage du code qui est maintenant fonctionnel.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • starkadroid/code/main.c

    rbe9ba97 rbf42f57  
    88#include <stdbool.h>
    99
    10 #include "amiga_keyboard/amiga_keyboard.h"
    1110#include "usbdrv/usbdrv.h"
    12 #include "keycodes.h"
    1311
    14 #define LEDSWAP PORTD ^= (1<<PD6)
    15 #define LEDON PORTD |= 1<<PD6
    16 #define LEDOFF PORTD &= ~(1<<PD6)
     12static uint8_t reportBuffer[5];
     13static uint8_t idleRate;
    1714
    18 static uint8_t pressingCaps = 0;
    19 
    20 const uint8_t PROGMEM keymatrix[0x70] = {
    21 // 0         1            2            3            4          5          6                 7            8            9              A             B             C             D             E              F
    22 KEY_grave,   KEY_1,       KEY_2,       KEY_3,       KEY_4,     KEY_5,     KEY_6,            KEY_7,       KEY_8,       KEY_9,         KEY_0,        KEY_minus,    KEY_equals,   KEY_F11,       KEY_Reserved,  KEY_KP0,      //0
    23 KEY_Q,       KEY_W,       KEY_E,       KEY_R,       KEY_T,     KEY_Y,     KEY_U,            KEY_I,       KEY_O,       KEY_P,         KEY_lbracket, KEY_rbracket, KEY_Reserved, KEY_KP1,       KEY_KP2,       KEY_KP3,      //1
    24 KEY_A,       KEY_S,       KEY_D,       KEY_F,       KEY_G,     KEY_H,     KEY_J,            KEY_K,       KEY_L,       KEY_semicolon, KEY_apostroph,KEY_hash,     KEY_Reserved, KEY_KP4,       KEY_KP5,       KEY_KP6,      //2
    25 KEY_Euro,    KEY_Z,       KEY_X,       KEY_C,       KEY_V,     KEY_B,     KEY_N,            KEY_M,       KEY_comma,   KEY_dot,       KEY_slash,    KEY_Reserved, KEY_KPcomma,  KEY_KP7,       KEY_KP8,       KEY_KP9,      //3
    26 KEY_Spacebar,KEY_DELETE,  KEY_Tab,     KEY_KPenter, KEY_Return,KEY_ESCAPE,KEY_DeleteForward,KEY_Reserved,KEY_Reserved,KEY_Reserved,  KEY_KPminus,  KEY_Reserved, KEY_UpArrow,  KEY_DownArrow, KEY_RightArrow,KEY_LeftArrow,//4
    27 KEY_F1,      KEY_F2,      KEY_F3,      KEY_F4,      KEY_F5,    KEY_F6,    KEY_F7,           KEY_F8,      KEY_F9,      KEY_F10,       KEY_KPLParen, KEY_KPRParen, KEY_KPslash,  KEY_KPasterisk,KEY_KPplus,    KEY_Help,     //5
    28 KEY_Reserved,KEY_Reserved,KEY_capslock,KEY_Reserved,KEY_Reserved,KEY_Reserved,KEY_Reserved, KEY_Reserved,KEY_Reserved,KEY_Reserved,  KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved,  KEY_Reserved,  KEY_Reserved, //6
    29 };
    30 
    31 /**
    32  * The modmatrix-array contains positions of the modifier-keys in the matrix.
    33  * It is built in the same way as the keymatrix-array.
    34  * \sa keymatrix
    35  */
    36 const uint8_t PROGMEM modmatrix[8] = { // contains positions of modifiers in the matrix
    37   // 0             1               2                 3         4         5         6                  7
    38 MOD_SHIFT_LEFT,MOD_SHIFT_RIGHT,MOD_NONE,MOD_CONTROL_LEFT,MOD_ALT_LEFT,MOD_ALT_RIGHT, MOD_GUI_LEFT, MOD_GUI_RIGHT,
    39 };
    40 
    41 static uint8_t idleRate;
    42 static uint8_t reportIndex = 2;
    43 static uint8_t reportBuffer[8];
    44 
    45 void fillReportBuffer(uint8_t key_code) {
    46         uint8_t key, modifier;
    47         key = pgm_read_byte(&keymatrix[key_code]);
    48         if (key_code >= 0x60 && key_code < 0x68)
    49                 modifier = pgm_read_byte(&modmatrix[key_code - 0x60]);
    50         else
    51                 modifier = MOD_NONE;
    52 
    53         if (key != KEY_Reserved && reportIndex < 8) {
    54                 reportBuffer[reportIndex] = key; // set next available entry
    55                 reportIndex++;
    56                 if (key == KEY_capslock)
    57                         pressingCaps = 1;
    58         }
    59         reportBuffer[0] |= modifier;
    60 }
    61 
    62 
    63 void emptyReportBuffer(uint8_t key_code) {
    64        
    65         uint8_t key, modifier;
    66         uint8_t i;
    67         key = pgm_read_byte(&keymatrix[key_code]);
    68         if (key_code >= 0x60 && key_code < 0x68)
    69                 modifier = pgm_read_byte(&modmatrix[key_code - 0x60]);
    70         else
    71                 modifier = MOD_NONE;
    72 
    73         if (key == KEY_capslock) {
    74                 if (reportIndex < 8) {
    75                         reportBuffer[reportIndex] = key; // set next available entry
    76                         reportIndex++;
    77                         pressingCaps = 1;
    78                 }
    79         } else if (key != KEY_Reserved) {
    80                 for (i = 2; i < reportIndex; i++) {
    81                         if (reportBuffer[i] == key) {
    82                                 for (; i < 7; i++)
    83                                         reportBuffer[i] = reportBuffer[i+1];
    84                                 reportBuffer[7] = 0;
    85                                 reportIndex--;
    86                         }
    87                 }
    88         }
    89         reportBuffer[0] &= ~modifier;
    90 }
    91 
    92 
    93 /*
    94 void usbSendReport(uint8_t mode, uint8_t key) {
    95     // buffer for HID reports. we use a private one, so nobody gets disturbed
    96     uint8_t repBuffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
    97     repBuffer[0] = mode;
    98     repBuffer[2] = key;
    99     while (!usbInterruptIsReady()); // wait
    100     usbSetInterrupt(repBuffer, sizeof(repBuffer)); // send
    101 }
    102 */
    103 
    104 int main() {
     15void main() {
    10516        uint8_t idleCounter = 0;
    106     uint8_t updateNeeded = 0;
    107         int capsDelay = 16;
    10817
    10918        wdt_enable(WDTO_2S);
    110     // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz
    111     TCCR0 = 4;          // timer 0 prescaler: 256
    112 
    113         //debug LED - output
    114         DDRD |= (1<<PD6);
    115 
    116         // Keyboard
    117         uint8_t key_code = 255;
    118         memset(reportBuffer, 0, sizeof(reportBuffer)); // clear report buffer
    11919
    12020        // USB
    12121        usbInit();
    122         ak_init_keyboard();
    12322        sei();
    124         bool doReport = false;
    125         bool doRelease = false;
     23        bool doReport;
    12624
     25        DDRB = 0; // Keyboard matrix out
     26        PORTB = 255; // Enable pull up
     27                // We put all pins as input then output a 0 in only one at a time.
     28                // All the other pins are high-Z to avoid short circuits when many buttons are pressed.
     29        DDRC = 0; // Keyboard matrix in
     30        PORTC = 255; // Enable pull up
     31
     32    // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz
     33    TCCR0 = 4;          // timer 0 prescaler: 256
     34       
    12735        while(1) {
    12836                wdt_reset();
    12937                usbPoll();
    13038
    131                 updateNeeded = char_waiting;
    132 
    133                 if (char_waiting) {
    134                         key_code = ak_read_scancode();
    135                         // if an update is needed, send the report
    136                         if ((key_code & 1) == 0) {
    137                                 fillReportBuffer(key_code>>1);
    138                                 LEDON;
    139                                 doReport = true;
    140                         } else {
    141                                 emptyReportBuffer(key_code>>1);
    142                                 doRelease = true;
    143                         }
     39                doReport = false;
     40                for(int i=0; i < 5; i++) {
     41                        DDRB = ~(1<<i);
     42                        PORTB = ~(1<<i);
     43                        reportBuffer[i] = (~PINC)&0x3F;
    14444                }
    14545
    146                 if (doReport && usbInterruptIsReady()) {
     46                DDRB = ~(1<<5);
     47                PORTB = ~(1<<5);
     48                reportBuffer[0] |= (~PINC)<<6 & 0xC0;
     49                reportBuffer[1] |= (~PINC)<<4 & 0xC0;
     50                reportBuffer[2] |= (~PINC)<<2 & 0xC0;
     51                // reportBuffer[3] |= (~PINC)<<0 & 0xC0; // These are not existing pins...
     52
     53                DDRB = 255;
     54                PORTB = 255;
     55
     56                if (usbInterruptIsReady()) {
    14757                        usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
    148                         LEDOFF;
     58//                      LEDOFF;
    14959                        doReport = false;
    15060                }
    15161
    152 
    153                 // check timer if we need periodic reports
    15462                if (TIFR & (1 << TOV0)) {
    15563                        TIFR = (1 << TOV0); // reset flag
    15664
    157                         if (pressingCaps) {
    158                                 if (--capsDelay == 0) {
    159                                         capsDelay = 16;
    160                                         pressingCaps = 0;
    161 
    162                                         int i;
    163                                         for (i = 2; i < reportIndex; i++) {
    164                                                 if (reportBuffer[i] == KEY_capslock) {
    165                                                         for (; i < 7; i++)
    166                                                                 reportBuffer[i] = reportBuffer[i+1];
    167                                                         reportBuffer[7] = 0;
    168                                                         reportIndex--;
    169                                                 }
    170                                         }                               
    171                                 }
    172                         }
    173 
    174                         ++idleCounter;
    175                         if(idleCounter > 4){ // yes, but not yet
     65                        if(++idleCounter > 4){ // yes, but not yet
    17666                                idleCounter -= 5; // 22ms in units of 4ms
    17767                        } else { // yes, it is time now
    17868                                idleCounter = idleRate;
    179                                 /*
    180                                 if (pressingCaps) {
    181                                         emptyReportBuffer(0x62);
    182                                         pressingCaps = 0;
    183                                 }
    184                                 */
    185                                 if (doRelease && usbInterruptIsReady()) {
     69                                if (usbInterruptIsReady()) {
    18670                                        usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
    187                                         doRelease = false;
    18871                                }
    18972                        }
    19073                }
    19174        }
     75}
    19276
    193         return 0;
    194 }
    19577
    19678static uint8_t protocolVer = 1;
    19779uint8_t expectReport = 0;
    19880
    199 #define LED_NUM     0x01  ///< num LED on a boot-protocol keyboard
    200 #define LED_CAPS    0x02  ///< caps LED on a boot-protocol keyboard
    201 #define LED_SCROLL  0x04  ///< scroll LED on a boot-protocol keyboard
    202 #define LED_COMPOSE 0x08  ///< compose LED on a boot-protocol keyboard
    203 #define LED_KANA    0x10  ///< kana LED on a boot-protocol keyboard
    204 uint8_t LEDstate = 0;     ///< current state of the LEDs
    205 
    20681
    20782char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
    208         0x05, 0x01,   // USAGE_PAGE (Generic Desktop)
    209         0x09, 0x06,   // USAGE (Keyboard)
    210         0xa1, 0x01,   // COLLECTION (Application)
    211         0x05, 0x07,   //   USAGE_PAGE (Keyboard)
    212         0x19, 0xe0,   //   USAGE_MINIMUM (Keyboard LeftControl)
    213         0x29, 0xe7,   //   USAGE_MAXIMUM (Keyboard Right GUI)
    214         0x15, 0x00,   //   LOGICAL_MINIMUM (0)
    215         0x25, 0x01,   //   LOGICAL_MAXIMUM (1)
    216         0x75, 0x01,   //   REPORT_SIZE (1)
    217         0x95, 0x08,   //   REPORT_COUNT (8)
    218         0x81, 0x02,   //   INPUT (Data,Var,Abs)
    219         0x95, 0x01,   //   REPORT_COUNT (1)
    220         0x75, 0x08,   //   REPORT_SIZE (8)
    221         0x81, 0x03,   //   INPUT (Cnst,Var,Abs)
    222         0x95, 0x05,   //   REPORT_COUNT (5)
    223         0x75, 0x01,   //   REPORT_SIZE (1)
    224         0x05, 0x08,   //   USAGE_PAGE (LEDs)
    225         0x19, 0x01,   //   USAGE_MINIMUM (Num Lock)
    226         0x29, 0x05,   //   USAGE_MAXIMUM (Kana)
    227         0x91, 0x02,   //   OUTPUT (Data,Var,Abs)
    228         0x95, 0x01,   //   REPORT_COUNT (1)
    229         0x75, 0x03,   //   REPORT_SIZE (3)
    230         0x91, 0x03,   //   OUTPUT (Cnst,Var,Abs)
    231         0x95, 0x06,   //   REPORT_COUNT (6)
    232         0x75, 0x08,   //   REPORT_SIZE (8)
    233         0x15, 0x00,   //   LOGICAL_MINIMUM (0)
    234         0x25, 0x65,   //   LOGICAL_MAXIMUM (101)
    235         0x05, 0x07,   //   USAGE_PAGE (Keyboard)
    236         0x19, 0x00,   //   USAGE_MINIMUM (Reserved (no event indicated))
    237         0x29, 0x65,   //   USAGE_MAXIMUM (Keyboard Application)
    238         0x81, 0x00,   //   INPUT (Data,Ary,Abs)
    239         0xc0          // END_COLLECTION
     83    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
     84    0x09, 0x05,                    // USAGE (Game Pad)
     85    0xa1, 0x01,                    // COLLECTION (Application)
     86    0x09, 0x01,                    //   USAGE (Pointer)
     87    0xa1, 0x00,                    //   COLLECTION (Physical)
     88    0x09, 0x30,                    //     USAGE (X)
     89    0x09, 0x31,                    //     USAGE (Y)
     90    0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
     91    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
     92    0x75, 0x02,                    //     REPORT_SIZE (2)
     93    0x95, 0x02,                    //     REPORT_COUNT (2)
     94    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
     95    0xc0,                          //   END_COLLECTION
     96    0x05, 0x09,                    //   USAGE_PAGE (Button)
     97    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
     98    0x29, 0x24,                    //   USAGE_MAXIMUM (Button 36)
     99    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
     100    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
     101    0x75, 0x01,                    //   REPORT_SIZE (1)
     102    0x95, 0x24,                    //   REPORT_COUNT (36)
     103    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
     104    0xc0                           // END_COLLECTION
    240105};
    241 
    242 
    243106
    244107
     
    277140}
    278141
    279 /**
    280  * The write function is called when LEDs should be set. Normally, we get only
    281  * one byte that contains info about the LED states.
    282  * \param data pointer to received data
    283  * \param len number ob bytes received
    284  * \return 0x01
    285  */
    286142uint8_t usbFunctionWrite(uchar *data, uchar len) {
    287     if (expectReport && (len == 1)) {
    288         LEDstate = data[0]; // Get the state of all 5 LEDs
    289                 /* TODO
    290         if (LEDstate & LED_NUM) { // light up caps lock
    291             PORTLEDS &= ~(1 << LEDNUM);
    292         } else {
    293             PORTLEDS |= (1 << LEDNUM);
    294         }
    295         if (LEDstate & LED_CAPS) { // light up caps lock
    296             PORTLEDS &= ~(1 << LEDCAPS);
    297         } else {
    298             PORTLEDS |= (1 << LEDCAPS);
    299         }
    300         if (LEDstate & LED_SCROLL) { // light up caps lock
    301             PORTLEDS &= ~(1 << LEDSCROLL);
    302         } else {
    303             PORTLEDS |= (1 << LEDSCROLL);
    304         }
    305                 */
    306     }
    307143    expectReport = 0;
    308144    return 0x01;
Note: See TracChangeset for help on using the changeset viewer.