Hiroh Satoh / keyboard Featured

Dependencies:   BLE_API mbed-dev nRF51822

Committer:
cho45
Date:
Thu Jul 21 01:25:31 2016 +0900
Revision:
6:f1c3ea8bc850
Parent:
5:65d4e94735b6
Child:
7:b9270a37345b
act as keyboard

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cho45 0:be89b5fdea09 1 /* mbed Microcontroller Library
cho45 0:be89b5fdea09 2 * Copyright (c) 2015 ARM Limited
cho45 0:be89b5fdea09 3 *
cho45 0:be89b5fdea09 4 * Licensed under the Apache License, Version 2.0 (the "License");
cho45 0:be89b5fdea09 5 * you may not use this file except in compliance with the License.
cho45 0:be89b5fdea09 6 * You may obtain a copy of the License at
cho45 0:be89b5fdea09 7 *
cho45 0:be89b5fdea09 8 * http://www.apache.org/licenses/LICENSE-2.0
cho45 0:be89b5fdea09 9 *
cho45 0:be89b5fdea09 10 * Unless required by applicable law or agreed to in writing, software
cho45 0:be89b5fdea09 11 * distributed under the License is distributed on an "AS IS" BASIS,
cho45 0:be89b5fdea09 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
cho45 0:be89b5fdea09 13 * See the License for the specific language governing permissions and
cho45 0:be89b5fdea09 14 * limitations under the License.
cho45 0:be89b5fdea09 15 */
cho45 0:be89b5fdea09 16
cho45 0:be89b5fdea09 17 #include "mbed.h"
cho45 6:f1c3ea8bc850 18
cho45 6:f1c3ea8bc850 19 #include "HIDController_BLE.h"
cho45 6:f1c3ea8bc850 20
cho45 4:54cb552e50c4 21 #include "mcp23017.h"
cho45 5:65d4e94735b6 22 #include "keymap.h"
cho45 0:be89b5fdea09 23
cho45 0:be89b5fdea09 24
cho45 5:65d4e94735b6 25 class KeyboardMatrixController {
cho45 5:65d4e94735b6 26 I2C& i2c;
cho45 5:65d4e94735b6 27 MCP23017 gpio1;
cho45 5:65d4e94735b6 28 MCP23017 gpio2;
cho45 5:65d4e94735b6 29
cho45 5:65d4e94735b6 30 static const uint8_t GPIO1_SLAVE_ADDRESS = 0b0100000;
cho45 5:65d4e94735b6 31 static const uint8_t GPIO2_SLAVE_ADDRESS = 0b0100001;
cho45 5:65d4e94735b6 32
cho45 5:65d4e94735b6 33 /**
cho45 5:65d4e94735b6 34 * COL=GPIOA (output normaly positive)
cho45 5:65d4e94735b6 35 * ROW=GPIOB (input pulled-up)
cho45 5:65d4e94735b6 36 */
cho45 5:65d4e94735b6 37
cho45 5:65d4e94735b6 38 int setupGpio(MCP23017& gpio) {
cho45 5:65d4e94735b6 39 int ok;
cho45 5:65d4e94735b6 40 ok = gpio.write8(
cho45 5:65d4e94735b6 41 MCP23017::IOCON,
cho45 5:65d4e94735b6 42 0<<MCP23017::BANK |
cho45 5:65d4e94735b6 43 1<<MCP23017::MIRROR |
cho45 5:65d4e94735b6 44 1<<MCP23017::SEQOP |
cho45 5:65d4e94735b6 45 0<<MCP23017::DISSLW |
cho45 5:65d4e94735b6 46 1<<MCP23017::ODR // int pin is open drain
cho45 5:65d4e94735b6 47 );
cho45 5:65d4e94735b6 48
cho45 5:65d4e94735b6 49 // IODIR
cho45 5:65d4e94735b6 50 // 1: input
cho45 5:65d4e94735b6 51 // 0: output
cho45 5:65d4e94735b6 52 ok = gpio.write16(
cho45 5:65d4e94735b6 53 MCP23017::IODIRA,
cho45 5:65d4e94735b6 54 0b0000000011111111
cho45 5:65d4e94735b6 55 );
cho45 4:54cb552e50c4 56
cho45 5:65d4e94735b6 57 // INPUT POLARITY
cho45 5:65d4e94735b6 58 // 1: inverse polarity
cho45 5:65d4e94735b6 59 // 0: raw
cho45 5:65d4e94735b6 60 ok = gpio.write8(
cho45 5:65d4e94735b6 61 MCP23017::IPOLB,
cho45 5:65d4e94735b6 62 0b11111111
cho45 5:65d4e94735b6 63 );
cho45 5:65d4e94735b6 64
cho45 5:65d4e94735b6 65 // INTERRUPT-ON-CHANGE Enable
cho45 5:65d4e94735b6 66 ok = gpio.write8(
cho45 5:65d4e94735b6 67 MCP23017::GPINTENB,
cho45 5:65d4e94735b6 68 0b11111111
cho45 5:65d4e94735b6 69 );
cho45 5:65d4e94735b6 70 // INTERRUPT-ON-CHANGE Control
cho45 5:65d4e94735b6 71 // 1: compared with DEFVAL
cho45 5:65d4e94735b6 72 // 0: compared to previous value
cho45 5:65d4e94735b6 73 ok = gpio.write8(
cho45 5:65d4e94735b6 74 MCP23017::INTCONB,
cho45 5:65d4e94735b6 75 0b00000000
cho45 5:65d4e94735b6 76 );
cho45 5:65d4e94735b6 77 // PULL-UP (for input pin)
cho45 5:65d4e94735b6 78 // 1: pull-up enabled
cho45 5:65d4e94735b6 79 // 0: pull-up disabled
cho45 5:65d4e94735b6 80 ok = gpio.write8(
cho45 5:65d4e94735b6 81 MCP23017::GPPUB,
cho45 5:65d4e94735b6 82 0b11111111
cho45 5:65d4e94735b6 83 );
cho45 5:65d4e94735b6 84
cho45 5:65d4e94735b6 85 ok = gpio1.write8(
cho45 5:65d4e94735b6 86 MCP23017::GPIOA,
cho45 5:65d4e94735b6 87 0b00000000
cho45 5:65d4e94735b6 88 );
cho45 5:65d4e94735b6 89
cho45 5:65d4e94735b6 90 return ok;
cho45 5:65d4e94735b6 91 }
cho45 5:65d4e94735b6 92
cho45 4:54cb552e50c4 93 public:
cho45 5:65d4e94735b6 94 KeyboardMatrixController(I2C& _i2c) :
cho45 5:65d4e94735b6 95 i2c(_i2c),
cho45 5:65d4e94735b6 96 gpio1(i2c, GPIO1_SLAVE_ADDRESS),
cho45 5:65d4e94735b6 97 gpio2(i2c, GPIO2_SLAVE_ADDRESS)
cho45 4:54cb552e50c4 98 {
cho45 4:54cb552e50c4 99 }
cho45 4:54cb552e50c4 100
cho45 5:65d4e94735b6 101 void init() {
cho45 5:65d4e94735b6 102 setupGpio(gpio1);
cho45 5:65d4e94735b6 103 // setupGpio(gpio2);
cho45 5:65d4e94735b6 104 }
cho45 5:65d4e94735b6 105
cho45 5:65d4e94735b6 106 void scanKeyboard(uint8_t* keys) {
cho45 5:65d4e94735b6 107 int ok;
cho45 5:65d4e94735b6 108
cho45 5:65d4e94735b6 109 // Disable interrupt
cho45 5:65d4e94735b6 110 ok = gpio1.write8(
cho45 5:65d4e94735b6 111 MCP23017::GPINTENB,
cho45 5:65d4e94735b6 112 0b00000000
cho45 5:65d4e94735b6 113 );
cho45 5:65d4e94735b6 114
cho45 5:65d4e94735b6 115 for (int i = 0; i < 8; i++) {
cho45 5:65d4e94735b6 116 ok = gpio1.write8(
cho45 5:65d4e94735b6 117 MCP23017::GPIOA,
cho45 5:65d4e94735b6 118 ~(1<<i)
cho45 5:65d4e94735b6 119 );
cho45 5:65d4e94735b6 120 keys[i] = gpio1.read8(MCP23017::GPIOB, ok);
cho45 4:54cb552e50c4 121 }
cho45 2:c2e3f240640c 122
cho45 5:65d4e94735b6 123 // set all output to negative for interrupt
cho45 5:65d4e94735b6 124 ok = gpio1.write8(
cho45 5:65d4e94735b6 125 MCP23017::GPIOA,
cho45 5:65d4e94735b6 126 0b00000000
cho45 5:65d4e94735b6 127 );
cho45 5:65d4e94735b6 128
cho45 5:65d4e94735b6 129 // Enable interrupt
cho45 5:65d4e94735b6 130 ok = gpio1.write8(
cho45 5:65d4e94735b6 131 MCP23017::GPINTENB,
cho45 5:65d4e94735b6 132 0b11111111
cho45 5:65d4e94735b6 133 );
cho45 5:65d4e94735b6 134
cho45 5:65d4e94735b6 135 // Clear interrupt
cho45 5:65d4e94735b6 136 gpio1.read8(MCP23017::GPIOB, ok);
cho45 5:65d4e94735b6 137
cho45 5:65d4e94735b6 138 // TODO gpio2
cho45 4:54cb552e50c4 139 }
cho45 5:65d4e94735b6 140 };
cho45 4:54cb552e50c4 141
cho45 5:65d4e94735b6 142 I2C i2c(I2C_SDA0, I2C_SCL0);
cho45 5:65d4e94735b6 143 KeyboardMatrixController keyboardMatrixController(i2c);
cho45 6:f1c3ea8bc850 144 Keymap keymap;
cho45 5:65d4e94735b6 145 InterruptIn buttonInt(P0_5);
cho45 5:65d4e94735b6 146 DigitalIn buttonIntIn(P0_5);
cho45 5:65d4e94735b6 147
cho45 5:65d4e94735b6 148 // ROWS=8
cho45 5:65d4e94735b6 149 // COLS=16
cho45 5:65d4e94735b6 150 // 列ごとに1バイトにパックしてキーの状態を保持する
cho45 5:65d4e94735b6 151 static uint8_t keysA[COLS];
cho45 5:65d4e94735b6 152 static uint8_t keysB[COLS];
cho45 5:65d4e94735b6 153 static bool state = 0;
cho45 5:65d4e94735b6 154
cho45 5:65d4e94735b6 155 void buttonIntCallback() {
cho45 5:65d4e94735b6 156 printf("pinChanged!!!\r\n");
cho45 5:65d4e94735b6 157 uint8_t (&keysCurr)[COLS] = state ? keysA : keysB;
cho45 5:65d4e94735b6 158 uint8_t (&keysPrev)[COLS] = state ? keysB : keysA;
cho45 5:65d4e94735b6 159
cho45 5:65d4e94735b6 160 printf("scanKeyboard\r\n");
cho45 5:65d4e94735b6 161 keyboardMatrixController.scanKeyboard(keysCurr);
cho45 5:65d4e94735b6 162
cho45 5:65d4e94735b6 163 for (int col = 0; col < COLS; col++) {
cho45 5:65d4e94735b6 164 uint8_t changed = keysPrev[col] ^ keysCurr[col];
cho45 5:65d4e94735b6 165 if (changed) printf("changed: %x\r\n", changed);
cho45 5:65d4e94735b6 166 for (int row = 0; row < ROWS; row++) {
cho45 5:65d4e94735b6 167 if (changed & (1<<row)) {
cho45 5:65d4e94735b6 168 bool pressed = keysCurr[col] & (1<<row);
cho45 5:65d4e94735b6 169 printf("changed: col=%d, row=%d / pressed=%d\r\n", col, row, pressed);
cho45 6:f1c3ea8bc850 170 keymap.execute(col, row, pressed);
cho45 4:54cb552e50c4 171 }
cho45 4:54cb552e50c4 172 }
cho45 2:c2e3f240640c 173 }
cho45 5:65d4e94735b6 174 state = !state;
cho45 2:c2e3f240640c 175 }
cho45 2:c2e3f240640c 176
cho45 0:be89b5fdea09 177 int main(void) {
cho45 5:65d4e94735b6 178 printf("init\r\n");
cho45 4:54cb552e50c4 179
cho45 4:54cb552e50c4 180 // mbed's Serial of TARGET_RBLAB_BLENANO sucks
cho45 4:54cb552e50c4 181 // DO NOT CONNECT RTS/CTS AUTOMATICALY!
cho45 4:54cb552e50c4 182 NRF_UART0->PSELRTS = 0xFFFFFFFFUL;
cho45 4:54cb552e50c4 183 NRF_UART0->PSELCTS = 0xFFFFFFFFUL;
cho45 4:54cb552e50c4 184
cho45 4:54cb552e50c4 185 // 100kHz
cho45 4:54cb552e50c4 186 i2c.frequency(100000);
cho45 4:54cb552e50c4 187
cho45 5:65d4e94735b6 188 buttonInt.mode(PullUp);
cho45 5:65d4e94735b6 189 buttonInt.fall(buttonIntCallback);
cho45 4:54cb552e50c4 190
cho45 5:65d4e94735b6 191 keyboardMatrixController.init();
cho45 5:65d4e94735b6 192 buttonIntCallback();
cho45 4:54cb552e50c4 193
cho45 6:f1c3ea8bc850 194 HIDController::init();
cho45 5:65d4e94735b6 195 while (1) {
cho45 6:f1c3ea8bc850 196 HIDController::process();
cho45 2:c2e3f240640c 197 }
cho45 2:c2e3f240640c 198 }