Hiroh Satoh / keyboard Featured

Dependencies:   BLE_API mbed-dev nRF51822

Committer:
cho45
Date:
Sun Aug 28 14:32:28 2016 +0000
Revision:
45:f4be69c936f6
Parent:
43:4de3870b39cb
Child:
47:5bf2ae8cc710
??????????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cho45 42:2c3be8694896 1 /* BLE Keyboard Implementation for mbed
cho45 42:2c3be8694896 2 * Copyright (c) 2016 cho45 <cho45@lowreal.net>
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 30:f9ebc769118d 17 #include <cmath>
cho45 0:be89b5fdea09 18 #include "mbed.h"
cho45 6:f1c3ea8bc850 19
cho45 6:f1c3ea8bc850 20 #include "HIDController_BLE.h"
cho45 42:2c3be8694896 21 #include "KeyboardMatrixController.h"
cho45 42:2c3be8694896 22 #include "BatteryLevel.h"
cho45 42:2c3be8694896 23 #include "WatchDog.h"
cho45 4:54cb552e50c4 24
cho45 42:2c3be8694896 25 #include "keymap.h"
cho45 42:2c3be8694896 26 #include "config.h"
cho45 5:65d4e94735b6 27
cho45 42:2c3be8694896 28 RawSerial serial(USBTX, USBRX);
cho45 5:65d4e94735b6 29 I2C i2c(I2C_SDA0, I2C_SCL0);
cho45 5:65d4e94735b6 30 KeyboardMatrixController keyboardMatrixController(i2c);
cho45 6:f1c3ea8bc850 31 Keymap keymap;
cho45 15:70bf079d3ee1 32
cho45 15:70bf079d3ee1 33 // Interrupt from MCP23017
cho45 15:70bf079d3ee1 34 // (pulled-up and two MCP23017 is configured with open drain INT)
cho45 43:4de3870b39cb 35 InterruptIn keyboardInterruptIn(P0_5);
cho45 5:65d4e94735b6 36
cho45 37:4ce71fa47fc3 37 #define PIN_STATUS_LED P0_4
cho45 37:4ce71fa47fc3 38 DigitalOut statusLed(PIN_STATUS_LED, 0);
cho45 25:094df0d9e95b 39
cho45 43:4de3870b39cb 40 // timeout for status led and wakeup from sleep
cho45 35:6a7fddfa14cf 41 Timeout timeout;
cho45 35:6a7fddfa14cf 42
cho45 5:65d4e94735b6 43 // ROWS=8
cho45 5:65d4e94735b6 44 // COLS=16
cho45 5:65d4e94735b6 45 // 列ごとに1バイトにパックしてキーの状態を保持する
cho45 5:65d4e94735b6 46 static uint8_t keysA[COLS];
cho45 5:65d4e94735b6 47 static uint8_t keysB[COLS];
cho45 5:65d4e94735b6 48 static bool state = 0;
cho45 28:1f843a3daab0 49 #define is_pressed(keys, row, col) (!!(keys[col] & (1<<row)))
cho45 28:1f843a3daab0 50
cho45 9:d1daefbf1fbd 51 // delay for interrupt
cho45 23:b31957ce64e9 52 static volatile int8_t pollCount = 50;
cho45 5:65d4e94735b6 53
cho45 43:4de3870b39cb 54 void keyboardInterrupt() {
cho45 8:d684faf04c9a 55 // just for wakeup
cho45 33:6a2301a89e92 56 pollCount = 25;
cho45 2:c2e3f240640c 57 }
cho45 2:c2e3f240640c 58
cho45 23:b31957ce64e9 59 void powerOff() {
cho45 42:2c3be8694896 60 DEBUG_PRINTF("power off\r\n");
cho45 23:b31957ce64e9 61 NRF_POWER->SYSTEMOFF = 1;
cho45 23:b31957ce64e9 62 }
cho45 23:b31957ce64e9 63
cho45 26:78ee13f69ec3 64 void tickerStatus() {
cho45 43:4de3870b39cb 65 statusLed = !statusLed;
cho45 26:78ee13f69ec3 66 }
cho45 26:78ee13f69ec3 67
cho45 35:6a7fddfa14cf 68 static bool updateStatudLedEnabled = false;
cho45 35:6a7fddfa14cf 69 void updateStatusLed() {
cho45 35:6a7fddfa14cf 70 switch (HIDController::status()) {
cho45 35:6a7fddfa14cf 71 case TIMEOUT:
cho45 38:115875b8cb6c 72 case DISCONNECTED:
cho45 38:115875b8cb6c 73 case CONNECTED:
cho45 38:115875b8cb6c 74 statusLed = 0;
cho45 38:115875b8cb6c 75 updateStatudLedEnabled = false;
cho45 38:115875b8cb6c 76 return;
cho45 35:6a7fddfa14cf 77 case ADVERTISING:
cho45 38:115875b8cb6c 78 case CONNECTING:
cho45 38:115875b8cb6c 79 statusLed = !statusLed;
cho45 38:115875b8cb6c 80 updateStatudLedEnabled = true;
cho45 38:115875b8cb6c 81 timeout.attach(updateStatusLed, statusLed ? 0.5 : 0.1);
cho45 38:115875b8cb6c 82 break;
cho45 35:6a7fddfa14cf 83 }
cho45 35:6a7fddfa14cf 84 }
cho45 35:6a7fddfa14cf 85
cho45 36:78c211da4eb0 86 static volatile bool keyIntervalInterrupt = false;
cho45 36:78c211da4eb0 87 void wakeupKeyIntervalSleep() {
cho45 36:78c211da4eb0 88 keyIntervalInterrupt = true;
cho45 30:f9ebc769118d 89 }
cho45 30:f9ebc769118d 90
cho45 38:115875b8cb6c 91 #define is_pressed(keys, row, col) (!!(keys[col] & (1<<row)))
cho45 35:6a7fddfa14cf 92
cho45 0:be89b5fdea09 93 int main(void) {
cho45 33:6a2301a89e92 94 {
cho45 33:6a2301a89e92 95 uint32_t reason = NRF_POWER->RESETREAS;
cho45 33:6a2301a89e92 96 NRF_POWER->RESETREAS = 0xffffffff; // clear reason
cho45 43:4de3870b39cb 97 // reset cause should be shown everytime
cho45 42:2c3be8694896 98 serial.printf("init [%x]\r\n", reason);
cho45 33:6a2301a89e92 99 }
cho45 43:4de3870b39cb 100
cho45 42:2c3be8694896 101 float battery = BatteryLevel::readBatteryVoltage();
cho45 42:2c3be8694896 102 if (battery < BatteryLevel::BATTERY_LOW) {
cho45 37:4ce71fa47fc3 103 powerOff();
cho45 37:4ce71fa47fc3 104 }
cho45 43:4de3870b39cb 105
cho45 30:f9ebc769118d 106 // Enable Pin-reset on DEBUG mode
cho45 30:f9ebc769118d 107 // This makes possiable booting without normal mode easily.
cho45 30:f9ebc769118d 108 NRF_POWER->RESET = 1;
cho45 30:f9ebc769118d 109 // Disable Internal DC/DC step down converter surely
cho45 29:ec548c473d50 110 NRF_POWER->DCDCEN = 0;
cho45 30:f9ebc769118d 111 // Enable 2.1V brown out detection for avoiding over discharge of NiMH
cho45 29:ec548c473d50 112 NRF_POWER->POFCON =
cho45 29:ec548c473d50 113 POWER_POFCON_POF_Enabled << POWER_POFCON_POF_Pos |
cho45 29:ec548c473d50 114 POWER_POFCON_THRESHOLD_V21 << POWER_POFCON_THRESHOLD_Pos;
cho45 43:4de3870b39cb 115
cho45 4:54cb552e50c4 116 // mbed's Serial of TARGET_RBLAB_BLENANO sucks
cho45 30:f9ebc769118d 117 // DO NOT CONNECT RTS/CTS WITHOUT PRIOR CONSENT!
cho45 4:54cb552e50c4 118 NRF_UART0->PSELRTS = 0xFFFFFFFFUL;
cho45 4:54cb552e50c4 119 NRF_UART0->PSELCTS = 0xFFFFFFFFUL;
cho45 43:4de3870b39cb 120
cho45 37:4ce71fa47fc3 121 // Set LED Pin as HIGH Current mode
cho45 37:4ce71fa47fc3 122 NRF_GPIO->PIN_CNF[PIN_STATUS_LED] =
cho45 41:2b034f22b98f 123 (NRF_GPIO->PIN_CNF[PIN_STATUS_LED] & ~GPIO_PIN_CNF_DRIVE_Msk) |
cho45 41:2b034f22b98f 124 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos);
cho45 16:345eebc4f259 125
cho45 42:2c3be8694896 126 // Unsed pins.
cho45 42:2c3be8694896 127 // Set as PullUp for power consumption
cho45 42:2c3be8694896 128 // Use GPIO registers directly for saving ram
cho45 42:2c3be8694896 129 // Pad pinouts
cho45 42:2c3be8694896 130 /*
cho45 42:2c3be8694896 131 DigitalIn unused_p0_7(P0_7, PullUp);
cho45 42:2c3be8694896 132 DigitalIn unused_p0_6(P0_6, PullUp);
cho45 42:2c3be8694896 133 DigitalIn unused_p0_15(P0_15, PullUp);
cho45 42:2c3be8694896 134 DigitalIn unused_p0_29(P0_29, PullUp);
cho45 42:2c3be8694896 135 DigitalIn unused_p0_28(P0_28, PullUp);
cho45 42:2c3be8694896 136 */
cho45 42:2c3be8694896 137 NRF_GPIO->PIN_CNF[P0_7] =
cho45 42:2c3be8694896 138 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
cho45 42:2c3be8694896 139 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
cho45 42:2c3be8694896 140 (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
cho45 42:2c3be8694896 141 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
cho45 42:2c3be8694896 142 (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
cho45 42:2c3be8694896 143 NRF_GPIO->PIN_CNF[P0_6] =
cho45 42:2c3be8694896 144 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
cho45 42:2c3be8694896 145 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
cho45 42:2c3be8694896 146 (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
cho45 42:2c3be8694896 147 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
cho45 42:2c3be8694896 148 (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
cho45 42:2c3be8694896 149 NRF_GPIO->PIN_CNF[P0_15] =
cho45 42:2c3be8694896 150 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
cho45 42:2c3be8694896 151 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
cho45 42:2c3be8694896 152 (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
cho45 42:2c3be8694896 153 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
cho45 42:2c3be8694896 154 (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
cho45 42:2c3be8694896 155 NRF_GPIO->PIN_CNF[P0_29] =
cho45 42:2c3be8694896 156 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
cho45 42:2c3be8694896 157 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
cho45 42:2c3be8694896 158 (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
cho45 42:2c3be8694896 159 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
cho45 42:2c3be8694896 160 (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
cho45 42:2c3be8694896 161 NRF_GPIO->PIN_CNF[P0_28] =
cho45 42:2c3be8694896 162 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
cho45 42:2c3be8694896 163 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
cho45 42:2c3be8694896 164 (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
cho45 42:2c3be8694896 165 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
cho45 42:2c3be8694896 166 (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
cho45 42:2c3be8694896 167 /*
cho45 42:2c3be8694896 168 DigitalIn unused_p0_19(P0_19, PullUp); // This is on board LED which connected to VDD
cho45 42:2c3be8694896 169 DigitalIn unused_p0_11(P0_11, PullUp); // RXD
cho45 42:2c3be8694896 170 */
cho45 42:2c3be8694896 171 NRF_GPIO->PIN_CNF[P0_19] = // This is on board LED which connected to VDD
cho45 42:2c3be8694896 172 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
cho45 42:2c3be8694896 173 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
cho45 42:2c3be8694896 174 (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
cho45 42:2c3be8694896 175 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
cho45 42:2c3be8694896 176 (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
cho45 42:2c3be8694896 177 NRF_GPIO->PIN_CNF[P0_11] = // RXD
cho45 42:2c3be8694896 178 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
cho45 42:2c3be8694896 179 (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
cho45 42:2c3be8694896 180 (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
cho45 42:2c3be8694896 181 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
cho45 42:2c3be8694896 182 (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
cho45 42:2c3be8694896 183
cho45 32:6c0f43fda460 184 WatchDog::init();
cho45 42:2c3be8694896 185
cho45 42:2c3be8694896 186 // only 100kHz/250khz/400khz
cho45 36:78c211da4eb0 187 i2c.frequency(250000);
cho45 4:54cb552e50c4 188
cho45 43:4de3870b39cb 189 keyboardInterruptIn.mode(PullUp);
cho45 43:4de3870b39cb 190 keyboardInterruptIn.fall(keyboardInterrupt);
cho45 4:54cb552e50c4 191
cho45 5:65d4e94735b6 192 keyboardMatrixController.init();
cho45 33:6a2301a89e92 193 pollCount = 10;
cho45 4:54cb552e50c4 194
cho45 6:f1c3ea8bc850 195 HIDController::init();
cho45 43:4de3870b39cb 196
cho45 16:345eebc4f259 197 // STOP UART RX for power consumption
cho45 21:d801c32231b0 198 NRF_UART0->TASKS_STOPRX = 1;
cho45 43:4de3870b39cb 199
cho45 30:f9ebc769118d 200 // Disable TWI by default.
cho45 16:345eebc4f259 201 NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
cho45 43:4de3870b39cb 202
cho45 32:6c0f43fda460 203 while (1) {
cho45 32:6c0f43fda460 204 WatchDog::reload();
cho45 43:4de3870b39cb 205
cho45 23:b31957ce64e9 206 if (pollCount > 0) {
cho45 42:2c3be8694896 207 DEBUG_PRINTF("scan keys\r\n");
cho45 43:4de3870b39cb 208
cho45 33:6a2301a89e92 209 while (pollCount-- > 0) {
cho45 33:6a2301a89e92 210 WatchDog::reload();
cho45 43:4de3870b39cb 211
cho45 23:b31957ce64e9 212 uint8_t (&keysCurr)[COLS] = state ? keysA : keysB;
cho45 23:b31957ce64e9 213 uint8_t (&keysPrev)[COLS] = state ? keysB : keysA;
cho45 43:4de3870b39cb 214
cho45 23:b31957ce64e9 215 NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
cho45 23:b31957ce64e9 216 keyboardMatrixController.scanKeyboard(keysCurr);
cho45 23:b31957ce64e9 217 NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
cho45 43:4de3870b39cb 218
cho45 23:b31957ce64e9 219 bool queue = false;
cho45 43:4de3870b39cb 220
cho45 23:b31957ce64e9 221 for (int col = 0; col < COLS; col++) {
cho45 23:b31957ce64e9 222 uint8_t changed = keysPrev[col] ^ keysCurr[col];
cho45 23:b31957ce64e9 223 if (changed) queue = true;
cho45 23:b31957ce64e9 224 for (int row = 0; row < ROWS; row++) {
cho45 23:b31957ce64e9 225 if (changed & (1<<row)) {
cho45 23:b31957ce64e9 226 bool pressed = keysCurr[col] & (1<<row);
cho45 42:2c3be8694896 227 // DEBUG_KEYEVENT("changed: col=%d, row=%d / pressed=%d\r\n", col, row, pressed);
cho45 23:b31957ce64e9 228 keymap.execute(col, row, pressed);
cho45 23:b31957ce64e9 229 }
cho45 7:b9270a37345b 230 }
cho45 7:b9270a37345b 231 }
cho45 23:b31957ce64e9 232 state = !state;
cho45 43:4de3870b39cb 233
cho45 38:115875b8cb6c 234 if (HIDController::status() == DISCONNECTED ||
cho45 38:115875b8cb6c 235 HIDController::status() == TIMEOUT) {
cho45 43:4de3870b39cb 236
cho45 43:4de3870b39cb 237 if (
cho45 43:4de3870b39cb 238 is_pressed(keysCurr, 0, 0) && // left top 1
cho45 43:4de3870b39cb 239 is_pressed(keysCurr, 1, 0) && // left top 2
cho45 43:4de3870b39cb 240 is_pressed(keysCurr, 0, 15) // right top
cho45 43:4de3870b39cb 241 ) {
cho45 43:4de3870b39cb 242 DEBUG_PRINTF("re-init connection\r\n");
cho45 43:4de3870b39cb 243 HIDController::initializeConnection(true);
cho45 43:4de3870b39cb 244 } else {
cho45 43:4de3870b39cb 245 if (HIDController::status() == TIMEOUT) {
cho45 43:4de3870b39cb 246 DEBUG_PRINTF("wakeup\r\n");
cho45 43:4de3870b39cb 247 HIDController::initializeConnection(false);
cho45 43:4de3870b39cb 248 }
cho45 43:4de3870b39cb 249 }
cho45 38:115875b8cb6c 250 }
cho45 43:4de3870b39cb 251
cho45 23:b31957ce64e9 252 if (queue) HIDController::queueCurrentReportData();
cho45 43:4de3870b39cb 253
cho45 31:010a44d53627 254 // wait_ms(5); is busy loop
cho45 31:010a44d53627 255 // use timer1 to use wait 5ms
cho45 36:78c211da4eb0 256 timeout.attach_us(wakeupKeyIntervalSleep, 5000);
cho45 36:78c211da4eb0 257 keyIntervalInterrupt = false;
cho45 45:f4be69c936f6 258 while (!keyIntervalInterrupt) HIDController::waitForEvent();
cho45 7:b9270a37345b 259 }
cho45 8:d684faf04c9a 260 } else {
cho45 35:6a7fddfa14cf 261 if (!updateStatudLedEnabled) updateStatusLed();
cho45 43:4de3870b39cb 262
cho45 42:2c3be8694896 263 float batteryVoltage = BatteryLevel::readBatteryVoltage();
cho45 42:2c3be8694896 264 uint8_t batteryPercentage = BatteryLevel::readBatteryPercentage(batteryVoltage);
cho45 42:2c3be8694896 265 bool isLowBattery = batteryVoltage < BatteryLevel::BATTERY_LOW;
cho45 37:4ce71fa47fc3 266
cho45 42:2c3be8694896 267 DEBUG_PRINTF("%d%% [%d:%s] %s\r\n",
cho45 37:4ce71fa47fc3 268 batteryPercentage,
cho45 37:4ce71fa47fc3 269 HIDController::status(),
cho45 37:4ce71fa47fc3 270 HIDController::statusString(),
cho45 39:b7889285c9ef 271 isLowBattery ? "LOWBAT" : "WFE"
cho45 37:4ce71fa47fc3 272 );
cho45 43:4de3870b39cb 273
cho45 37:4ce71fa47fc3 274 HIDController::updateBatteryLevel(batteryPercentage);
cho45 43:4de3870b39cb 275
cho45 37:4ce71fa47fc3 276 if (isLowBattery) {
cho45 37:4ce71fa47fc3 277 powerOff();
cho45 37:4ce71fa47fc3 278 }
cho45 45:f4be69c936f6 279
cho45 45:f4be69c936f6 280 if (HIDController::status() == DISCONNECTED) {
cho45 45:f4be69c936f6 281 HIDController::initializeConnection(false);
cho45 45:f4be69c936f6 282 }
cho45 43:4de3870b39cb 283
cho45 42:2c3be8694896 284 if (DEBUG_BLE_INTERRUPT) {
cho45 42:2c3be8694896 285 HIDController::waitForEvent();
cho45 42:2c3be8694896 286 } else {
cho45 42:2c3be8694896 287 // disable internal HFCLK RC Clock surely. It consume 1mA constantly
cho45 42:2c3be8694896 288 // TWI / SPI / UART must be disabled and boot without debug mode
cho45 42:2c3be8694896 289 while (NRF_UART0->EVENTS_TXDRDY != 1);
cho45 43:4de3870b39cb 290
cho45 42:2c3be8694896 291 uint32_t tx = NRF_UART0->PSELTXD;
cho45 43:4de3870b39cb 292
cho45 42:2c3be8694896 293 NRF_UART0->TASKS_STOPTX = 1;
cho45 42:2c3be8694896 294 NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos);
cho45 43:4de3870b39cb 295
cho45 42:2c3be8694896 296 HIDController::waitForEvent();
cho45 43:4de3870b39cb 297
cho45 42:2c3be8694896 298 NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
cho45 42:2c3be8694896 299 NRF_UART0->TASKS_STARTTX = 1;
cho45 42:2c3be8694896 300 // dummy send to wakeup...
cho45 42:2c3be8694896 301 NRF_UART0->PSELTXD = 0xFFFFFFFF;
cho45 43:4de3870b39cb 302 NRF_UART0->EVENTS_TXDRDY = 0;
cho45 43:4de3870b39cb 303 NRF_UART0->TXD = 0;
cho45 43:4de3870b39cb 304 while (NRF_UART0->EVENTS_TXDRDY != 1);
cho45 42:2c3be8694896 305 NRF_UART0->PSELTXD = tx;
cho45 42:2c3be8694896 306 }
cho45 7:b9270a37345b 307 }
cho45 2:c2e3f240640c 308 }
cho45 43:4de3870b39cb 309 }