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:
- 6:f1c3ea8bc850
- Parent:
- 5:65d4e94735b6
- Child:
- 7:b9270a37345b
File content as of revision 6:f1c3ea8bc850:
/* 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;
		// Disable interrupt
		ok = gpio1.write8(
			MCP23017::GPINTENB,
			0b00000000
		);
		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
		);
		// Enable interrupt
		ok = gpio1.write8(
			MCP23017::GPINTENB,
			0b11111111
		);
		// Clear interrupt
		gpio1.read8(MCP23017::GPIOB, ok);
		// TODO gpio2
	}
};
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;
void buttonIntCallback() {
	printf("pinChanged!!!\r\n");
	uint8_t (&keysCurr)[COLS] = state ? keysA : keysB;
	uint8_t (&keysPrev)[COLS] = state ? keysB : keysA;
	printf("scanKeyboard\r\n");
	keyboardMatrixController.scanKeyboard(keysCurr);
	for (int col = 0; col < COLS; col++) {
		uint8_t changed = keysPrev[col] ^ keysCurr[col];
		if (changed) printf("changed: %x\r\n", changed);
		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;
}
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) {
		HIDController::process();
	}
}