aboutsummaryrefslogtreecommitdiffstats
path: root/nrf52/nrf52.ino
blob: 1b4ac3c5abfda8044479b1ec7d04880d3f80a341 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// -*- mode: c++ -*-
#include "i2c_message.h"
#include "i2c_ring_buffer.h"
#include "log.h"
#include "state_machine.h"

#include <bluefruit.h>
#include <Wire.h>

BLEDis bledis;
BLEHidAdafruit blehid;

I2CRingBuffer rb;
StateMachine fsm(&blehid);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  pinMode(PIN_WIRE_SDA, INPUT_PULLUP);
  pinMode(PIN_WIRE_SCL, INPUT_PULLUP);

  Serial.begin(115200);
  Serial.println("usb2btle booting.");

  Wire.begin(BTLE_WIREADDR);
  Wire.onReceive(wireDataReceived);

  Bluefruit.begin();
  Bluefruit.setTxPower(4);
  Bluefruit.setName("usb2btle");

  // Configure and Start Device Information Service
  bledis.setManufacturer("Kublai Khansulting");
  bledis.setModel("devel-nrf52832-trinketm0");
  bledis.begin();

  /* Start BLE HID
   * Note: Apple requires BLE device must have min connection interval >= 20m
   * ( The smaller the connection interval the faster we could send data).
   * However for HID and MIDI device, Apple could accept min connection interval
   * up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
   * connection interval to 11.25  ms and 15 ms respectively for best performance.
   */
  blehid.begin();
  blehid.setKeyboardLedCallback(setKeyboardLED);

  startAdv();

  digitalWrite(LED_BUILTIN, LOW);
}

void startAdv(void)
{
  Serial.println("Advertising HID.");

  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD);
  Bluefruit.Advertising.addService(blehid);
  Bluefruit.Advertising.addName();
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);
  Bluefruit.Advertising.setFastTimeout(30);
  Bluefruit.Advertising.start(0);
}

void loop() {
  waitForEvent();

  uint8_t v;
  while (rb.read(&v)) {
    dbgPrintf("got byte on rb: %02x\r\n", v);
    fsm.byteReceived(v);
  }
}

void wireDataReceived(int numBytes) {
  dbgPrintf("wireDataReceived: %u\r\n", numBytes);
  for (int i = 0; i < numBytes; i++) {
    rb.write(Wire.read());
  }
}

void setKeyboardLED(uint16_t conn_handle, uint8_t led_bitmap) {
  (void) conn_handle;

  // light up Red Led if any bits is set
  if (led_bitmap) {
    ledOn(LED_RED);
  } else {
    ledOff(LED_RED);
  }
}