Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed-dev nRF51822
main.cpp
- Committer:
- cho45
- Date:
- 2016-07-21
- Revision:
- 10:1aed2481a743
- Parent:
- 9:d1daefbf1fbd
- Child:
- 13:b0ffdf2012b9
File content as of revision 10:1aed2481a743:
/* mbed Microcontroller Library
* Copyright (c) 2015 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h"
#include "HIDController_BLE.h"
#include "mcp23017.h"
#include "keymap.h"
class KeyboardMatrixController {
I2C& i2c;
MCP23017 gpio1;
MCP23017 gpio2;
static const uint8_t GPIO1_SLAVE_ADDRESS = 0b0100000;
static const uint8_t GPIO2_SLAVE_ADDRESS = 0b0100001;
/**
* COL=GPIOA (output normaly positive)
* ROW=GPIOB (input pulled-up)
*/
int setupGpio(MCP23017& gpio) {
int ok;
ok = gpio.write8(
MCP23017::IOCON,
0<<MCP23017::BANK |
1<<MCP23017::MIRROR |
1<<MCP23017::SEQOP |
0<<MCP23017::DISSLW |
1<<MCP23017::ODR // int pin is open drain
);
// IODIR
// 1: input
// 0: output
ok = gpio.write16(
MCP23017::IODIRA,
0b0000000011111111
);
// INPUT POLARITY
// 1: inverse polarity
// 0: raw
ok = gpio.write8(
MCP23017::IPOLB,
0b11111111
);
// INTERRUPT-ON-CHANGE Enable
ok = gpio.write8(
MCP23017::GPINTENB,
0b11111111
);
// INTERRUPT-ON-CHANGE Control
// 1: compared with DEFVAL
// 0: compared to previous value
ok = gpio.write8(
MCP23017::INTCONB,
0b00000000
);
// PULL-UP (for input pin)
// 1: pull-up enabled
// 0: pull-up disabled
ok = gpio.write8(
MCP23017::GPPUB,
0b11111111
);
ok = gpio1.write8(
MCP23017::GPIOA,
0b00000000
);
return ok;
}
public:
KeyboardMatrixController(I2C& _i2c) :
i2c(_i2c),
gpio1(i2c, GPIO1_SLAVE_ADDRESS),
gpio2(i2c, GPIO2_SLAVE_ADDRESS)
{
}
void init() {
setupGpio(gpio1);
// setupGpio(gpio2);
}
void scanKeyboard(uint8_t* keys) {
int ok;
for (int i = 0; i < 8; i++) {
ok = gpio1.write8(
MCP23017::GPIOA,
~(1<<i)
);
keys[i] = gpio1.read8(MCP23017::GPIOB, ok);
}
// set all output to negative for interrupt
ok = gpio1.write8(
MCP23017::GPIOA,
0b00000000
);
// TODO gpio2
}
void disableInterrupt() {
int ok;
// Disable interrupt
ok = gpio1.write8(
MCP23017::GPINTENB,
0b00000000
);
}
void enableInterrupt() {
int ok;
// Enable interrupt
ok = gpio1.write8(
MCP23017::GPINTENB,
0b11111111
);
// Clear interrupt
gpio1.read8(MCP23017::GPIOB, ok);
}
};
I2C i2c(I2C_SDA0, I2C_SCL0);
KeyboardMatrixController keyboardMatrixController(i2c);
Keymap keymap;
InterruptIn buttonInt(P0_5);
DigitalIn buttonIntIn(P0_5);
// ROWS=8
// COLS=16
// 列ごとに1バイトにパックしてキーの状態を保持する
static uint8_t keysA[COLS];
static uint8_t keysB[COLS];
static bool state = 0;
// delay for interrupt
static int8_t pollCount = 0;
void buttonIntCallback() {
// just for wakeup
pollCount = 100;
}
int main(void) {
printf("init\r\n");
// mbed's Serial of TARGET_RBLAB_BLENANO sucks
// DO NOT CONNECT RTS/CTS AUTOMATICALY!
NRF_UART0->PSELRTS = 0xFFFFFFFFUL;
NRF_UART0->PSELCTS = 0xFFFFFFFFUL;
// 100kHz
i2c.frequency(100000);
buttonInt.mode(PullUp);
buttonInt.fall(buttonIntCallback);
keyboardMatrixController.init();
buttonIntCallback();
HIDController::init();
while (1) {
if (pollCount-- > 0) {
uint8_t (&keysCurr)[COLS] = state ? keysA : keysB;
uint8_t (&keysPrev)[COLS] = state ? keysB : keysA;
keyboardMatrixController.scanKeyboard(keysCurr);
bool queue = false;
for (int col = 0; col < COLS; col++) {
uint8_t changed = keysPrev[col] ^ keysCurr[col];
if (changed) queue = true;
for (int row = 0; row < ROWS; row++) {
if (changed & (1<<row)) {
bool pressed = keysCurr[col] & (1<<row);
// printf("changed: col=%d, row=%d / pressed=%d\r\n", col, row, pressed);
keymap.execute(col, row, pressed);
}
}
}
state = !state;
if (queue) HIDController::queueCurrentReportData();
wait_ms(5);
} else {
HIDController::waitForEvent();
}
}
}