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
Diff: main.cpp
- Revision:
- 4:54cb552e50c4
- Parent:
- 3:266dfa9f8709
- Child:
- 5:65d4e94735b6
--- a/main.cpp Tue Jul 19 01:06:00 2016 +0900
+++ b/main.cpp Wed Jul 20 02:05:45 2016 +0900
@@ -19,6 +19,7 @@
#include "KeyboardService.h"
#include "BatteryService.h"
#include "DeviceInformationService.h"
+#include "mcp23017.h"
static const char MODEL_NAME[] = "keyboard";
static const char SERIAL_NUMBER[] = "X00000";
@@ -33,8 +34,6 @@
static const bool REQUIRE_MITM = true;
static const uint8_t PASSKEY[6] = {'1','2','3','4','5','6'}; // must be 6-digits number
-InterruptIn button1(D2);
-
static const uint16_t uuid16_list[] = {
GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
GattService::UUID_DEVICE_INFORMATION_SERVICE,
@@ -45,19 +44,45 @@
BatteryService* batteryService;
DeviceInformationService* deviceInformationService;
-// I2C i2c(D2, D3);
-AnalogIn batteryInput(A4);
+I2C i2c(I2C_SDA0, I2C_SCL0);
+MCP23017 gpio1(i2c, 0b0100000);
+InterruptIn buttonInt(P0_5);
void updateBatteryLevel() {
if (!batteryService) return;
static const float BATTERY_MAX = 2.4;
+ static const float REFERNECE = 1.2;
+ static const float PRESCALE = 3;
- float batteryVoltage = batteryInput.read() * 1.2 * 3;
+ NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
+
+ // Use internal 1.2V reference for batteryInput
+ // 1/3 pre-scaled input and 1.2V internal band gap reference
+ // ref. mbed-src/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/analogin_api.c
+ NRF_ADC->CONFIG =
+ (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+ // Use VDD 1/3 for input
+ (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ // Use internal band gap for reference
+ (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+ (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+
+ // Start ADC
+ NRF_ADC->TASKS_START = 1;
+ while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {
+ // busy loop
+ }
+
+ // Read ADC result
+ uint16_t raw10bit = static_cast<uint16_t>(NRF_ADC->RESULT);
+ float ratio = raw10bit / static_cast<float>(1<<10);
+
+ float batteryVoltage = ratio * (REFERNECE * PRESCALE);
float percentage = (batteryVoltage / BATTERY_MAX) * 100;
if (percentage > 100) {
percentage = 100;
}
- printf("updateBatteryLevel %d\r\n",static_cast<uint8_t>(percentage));
+ printf("updateBatteryLevel %f V : %d/100\r\n", batteryVoltage, static_cast<uint8_t>(percentage));
batteryService->updateBatteryLevel(static_cast<uint8_t>(percentage));
}
@@ -177,32 +202,157 @@
return;
}
-void send_string(const char * c) {
- if (!keyboardService) return;
+class MyKeyboardService : public HIDServiceBase {
+ union {
+ uint8_t raw[8];
+ struct {
+ uint8_t modifier;
+ uint8_t padding;
+ uint8_t keycode[6];
+ } data;
+ } inputReportData;
+
+ union {
+ uint8_t raw[1];
+ } outputReportData;
+public:
+ MyKeyboardService(BLE& _ble) :
+ HIDServiceBase(
+ _ble,
+ KEYBOARD_REPORT_MAP,
+ sizeof(KEYBOARD_REPORT_MAP),
+ inputReport = inputReportData.raw,
+ outputReport = outputReportData.raw,
+ featureReport = NULL,
+ inputReportLength = sizeof(inputReportData),
+ outputReportLength = sizeof(outputReportData),
+ featureReportLength = 0,
+ reportTickerDelay = 24
+ )
+ {
+ }
+
+ void appendReportData(uint8_t keycode) {
+ for (int i = 0; i < 6; i++) {
+ if (inputReportData.data.keycode[i] == 0) {
+ inputReportData.data.keycode[i] = keycode;
+ startReportTicker();
+ return;
+ }
+ }
- if (!keyboardService->isConnected()) {
- printf("we haven't connected yet...");
- } else {
- int len = strlen(c);
- keyboardService->printf(c);
- printf("sending %d chars\r\n", len);
+ // TODO: report data is full
+ }
+
+ void deleteReportData(uint8_t keycode) {
+ for (int i = 0; i < 6; i++) {
+ if (inputReportData.data.keycode[i] == keycode) {
+ inputReportData.data.keycode[i] = 0;
+ startReportTicker();
+ return;
+ }
+ }
}
-}
+
+ bool isKeyPressed() {
+ for (int i = 0; i < 8; i++) {
+ if (inputReportData.raw[i]) {
+ return 1;
+ }
+ }
+ return 0;
+ }
-void send_stuff() {
- send_string("hello world!\n");
+ virtual void sendCallback(void) {
+ ble_error_t error = HIDServiceBase::send(inputReportData.raw);
+ if (error == BLE_STACK_BUSY) {
+ // retry after
+ return;
+ }
+
+ if (!isKeyPressed()) {
+ stopReportTicker();
+ }
+ }
+};
+
+void buttonIntCallback() {
+ int ok;
+ printf("buttonInt!!\r\n");
+ uint8_t read = gpio1.read8(MCP23017::GPIOA, ok);
+ printf("read %x\r\n", read);
}
int main(void) {
- // Use internal 1.2V reference for batteryInput
- // 1/3 pre-scaled input and 1.2V internal band gap reference
- // (mbed uses vdd for reference but i want use band gap)
- // ref. mbed-src/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/analogin_api.c
- NRF_ADC->CONFIG =
- (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
- (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
- (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
- (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+ // 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;
+
+ buttonInt.mode(PullUp);
+ buttonInt.fall(buttonIntCallback);
+
+ int ok;
+
+ // 100kHz
+ i2c.frequency(100000);
+
+ ok = gpio1.write8(
+ MCP23017::IOCON,
+ 0<<MCP23017::BANK |
+ 1<<MCP23017::MIRROR |
+ 1<<MCP23017::SEQOP |
+ 0<<MCP23017::DISSLW |
+ 1<<MCP23017::ODR
+ );
+
+ // IODIR
+ // 1: input
+ // 0: output
+ ok = gpio1.write16(
+ MCP23017::IODIRA,
+ 0b1111111100000000
+ );
+
+ // INPUT POLARITY
+ ok = gpio1.write8(
+ MCP23017::IPOLA,
+ 0b00000000
+ );
+ // INTERRUPT-ON-CHANGE Enable
+ ok = gpio1.write8(
+ MCP23017::GPINTENA,
+ 0b11111111
+ );
+ // INTERRUPT-ON-CHANGE Control
+ // 1: compared with DEFVAL
+ // 0: compared to previous value
+ ok = gpio1.write8(
+ MCP23017::INTCONA,
+ 0b00000000
+ );
+ // PULL-UP (for input pin)
+ // 1: pull-up enabled
+ // 0: pull-up disabled
+ ok = gpio1.write8(
+ MCP23017::GPPUA,
+ 0b11111111
+ );
+
+ if (!ok) {
+ printf("failed to write to i2c bus\r\n");
+ } else {
+ printf("wrote to i2c bus\r\n");
+ }
+
+ uint8_t read = gpio1.read8(MCP23017::GPIOA, ok);
+ printf("read %x\r\n", read);
+
+ while (1) {}
+
+ return;
// https://github.com/jpbrucker/BLE_HID/blob/master/examples/examples_common.cpp
@@ -210,8 +360,6 @@
BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
ble.init(bleInitComplete);
- button1.rise(send_stuff);
-
while (!ble.hasInitialized()) { }
printf("ble.hasIntialized\r\n");