Skip to content

Commit

Permalink
WIP: iton_bt placeholder commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gxcreator committed Nov 4, 2024
1 parent 55325f7 commit 228e330
Show file tree
Hide file tree
Showing 7 changed files with 418 additions and 3 deletions.
7 changes: 6 additions & 1 deletion builddefs/common_features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ ifeq ($(strip $(USBPD_ENABLE)), yes)
endif

BLUETOOTH_ENABLE ?= no
VALID_BLUETOOTH_DRIVER_TYPES := bluefruit_le custom rn42
VALID_BLUETOOTH_DRIVER_TYPES := bluefruit_le custom rn42 iton_bt
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
ifeq ($(filter $(strip $(BLUETOOTH_DRIVER)),$(VALID_BLUETOOTH_DRIVER_TYPES)),)
$(call CATASTROPHIC_ERROR,Invalid BLUETOOTH_DRIVER,BLUETOOTH_DRIVER="$(BLUETOOTH_DRIVER)" is not a valid Bluetooth driver type)
Expand All @@ -902,6 +902,11 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
SRC += $(DRIVER_PATH)/bluetooth/rn42.c
endif

ifeq ($(strip $(BLUETOOTH_DRIVER)), iton_bt)
SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
SRC += $(DRIVER_PATH)/bluetooth/iton_bt.c
endif
endif

ENCODER_ENABLE ?= no
Expand Down
2 changes: 1 addition & 1 deletion data/schemas/keyboard.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
"properties": {
"driver": {
"type": "string",
"enum": ["bluefruit_le", "custom", "rn42"]
"enum": ["bluefruit_le", "custom", "rn42", "iton_bt"]
}
}
},
Expand Down
8 changes: 8 additions & 0 deletions drivers/bluetooth/bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@
# include "bluefruit_le.h"
#elif defined(BLUETOOTH_RN42)
# include "rn42.h"
#elif defined(BLUETOOTH_ITON_BT)
# include "iton_bt.h"
#endif

void bluetooth_init(void) {
#if defined(BLUETOOTH_BLUEFRUIT_LE)
bluefruit_le_init();
#elif defined(BLUETOOTH_RN42)
rn42_init();
#elif defined(BLUETOOTH_ITON_BT)
iton_bt_init();
#endif
}

Expand All @@ -42,6 +46,8 @@ void bluetooth_send_keyboard(report_keyboard_t *report) {
bluefruit_le_send_keyboard(report);
#elif defined(BLUETOOTH_RN42)
rn42_send_keyboard(report);
#elif defined(BLUETOOTH_ITON_BT)
iton_bt_send_keyboard(report);
#endif
}

Expand All @@ -58,5 +64,7 @@ void bluetooth_send_consumer(uint16_t usage) {
bluefruit_le_send_consumer(usage);
#elif defined(BLUETOOTH_RN42)
rn42_send_consumer(usage);
#elif defined(BLUETOOTH_ITON_BT)
iton_bt_send_consumer(usage);
#endif
}
245 changes: 245 additions & 0 deletions drivers/bluetooth/iton_bt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
// Copyright 2023 1Conan (@1Conan)
// SPDX-License-Identifier: GPL-2.0-or-later

#include <string.h>
#include <hal.h>
#include "gpio.h"
#include "config.h"
#include "iton_bt.h"

#ifndef ITON_BT_SPI_PORT
# define ITON_BT_SPI_PORT SPID0
#endif

#ifndef ITON_BT_IRQ_LINE
# define ITON_BT_IRQ_LINE A0
#endif

#ifndef ITON_BT_INT_LINE
# define ITON_BT_INT_LINE A1
#endif

#ifndef ITON_BT_BUFFER_LEN
# define ITON_BT_BUFFER_LEN 16
#endif

/**
* Driver Macros
*/
#define HIGH_BITS(x) ((uint8_t)(x >> 8))
#define LOW_BITS(x) ((uint8_t)(x & 0x00FF))

/**
* Function definitions
*/
void iton_bt_data_cb(SPIDriver *spip);

/**
* Callbacks
*/
__attribute__((weak)) void iton_bt_battery_voltage_low(void) {}
__attribute__((weak)) void iton_bt_battery_exit_low_battery_mode(void) {}
__attribute__((weak)) void iton_bt_battery_low_power_shutdown(void) {}
__attribute__((weak)) void iton_bt_battery_level(uint8_t level) {}

__attribute__((weak)) void iton_bt_connection_successful(void) {}
__attribute__((weak)) void iton_bt_entered_pairing(void) {}
__attribute__((weak)) void iton_bt_disconnected(void) {}
__attribute__((weak)) void iton_bt_enters_connection_state(void) {}

/**
* Driver variables
*/
bool iton_bt_is_connected = false;
uint8_t iton_bt_led_state = 0x00;

static uint8_t iton_bt_buffer[ITON_BT_BUFFER_LEN];
uint8_t iton_bt_send_kb_last_key = 0x00;

const SPIConfig iton_bt_spicfg = {
.slave = true,
.data_cb = iton_bt_data_cb,
#if defined(SN32)
.ctrl0 = SPI_DATA_LENGTH(8),
#endif
};

/**
* Callbacks
*/
#if defined(PAL_USE_CALLBACKS) || defined(PAL_USE_WAIT)
static inline void iton_bt_rx_battery_notif(uint8_t data) {
switch (data) {
case batt_voltage_low:
iton_bt_battery_voltage_low();
break;
case batt_exit_low_battery_mode:
iton_bt_battery_exit_low_battery_mode();
break;
case batt_low_power_shutdown:
iton_bt_battery_low_power_shutdown();
break;
case batt_above_70:
case batt_between_30_70:
case batt_below_30:
iton_bt_battery_level(data);
break;
case batt_wake_mcu:
#ifdef ITON_BT_ENABLE_ACK
iton_bt_send_ack(control_bt, wake_ack);
#endif
break;
case batt_unknown:
#ifdef ITON_BT_ENABLE_ACK
iton_bt_send_ack(control_bt, unknown_ack);
#endif
break;
case query_working_mode:
break;
case query_bt_name:
break;
}
}

static inline void iton_bt_rx_bluetooth_notif(uint8_t data) {
switch (iton_bt_buffer[2]) {
case bt_connection_success:
iton_bt_is_connected = true;

#ifdef ITON_BT_ENABLE_ACK
iton_bt_send_ack(control_bt, connect_ack);
#endif

iton_bt_connection_successful();
break;
case bt_entered_pairing:
iton_bt_entered_pairing();
break;
case bt_disconected:
iton_bt_is_connected = false;

#ifdef ITON_BT_ENABLE_ACK
iton_bt_send_ack(control_bt, disconnect_ack);
#endif

iton_bt_disconnected();
break;
case bt_enters_connection:
iton_bt_enters_connection_state();
break;
}
}

static void iton_bt_rx_cb(void *arg) {
if (readPin(ITON_BT_INT_LINE)) {
chSysLockFromISR();
spiStartReceiveI(&ITON_BT_SPI_PORT, ITON_BT_BUFFER_LEN, &iton_bt_buffer[0]);
chSysUnlockFromISR();
} else {
chSysLockFromISR();
spiStopTransferI(&ITON_BT_SPI_PORT, NULL);
chSysUnlockFromISR();

#ifdef ITON_BT_ENABLE_ACK
// hack to make sure irq is low since acks messes with stuff
writePinLow(ITON_BT_IRQ_LINE);
#endif

switch (iton_bt_buffer[0]) {
case led_state:
iton_bt_led_state = iton_bt_buffer[1];
break;
case notification:
switch (iton_bt_buffer[1]) {
case notif_battery:
iton_bt_rx_battery_notif(iton_bt_buffer[2]);
break;
case notif_bluetooth:
iton_bt_rx_bluetooth_notif(iton_bt_buffer[2]);
break;
}
break;
}
}
}
#endif


void iton_bt_data_cb(SPIDriver *spip) {
writePinLow(ITON_BT_IRQ_LINE);
}

/**
* Driver Functions
*/
void iton_bt_init(void) {
setPinOutput(ITON_BT_IRQ_LINE);
setPinInput(ITON_BT_INT_LINE);

writePinLow(ITON_BT_IRQ_LINE);

#if defined(PAL_USE_CALLBACKS) || defined(PAL_USE_WAIT)
palSetLineCallback(ITON_BT_INT_LINE, iton_bt_rx_cb, NULL);
palEnableLineEvent(ITON_BT_INT_LINE, PAL_EVENT_MODE_BOTH_EDGES);
#endif

spiStart(&ITON_BT_SPI_PORT, &iton_bt_spicfg);
}

void iton_bt_send(uint8_t cmd, uint8_t *data, uint8_t len) {
while (readPin(ITON_BT_IRQ_LINE));

writePinHigh(ITON_BT_IRQ_LINE);
iton_bt_buffer[0] = cmd;
memcpy(&iton_bt_buffer[1], data, len);
spiStartSend(&ITON_BT_SPI_PORT, len + 1, &iton_bt_buffer[0]);
}

void iton_bt_send2(uint8_t cmd, uint8_t b1, uint8_t b2) {
while (readPin(ITON_BT_IRQ_LINE));

writePinHigh(ITON_BT_IRQ_LINE);
iton_bt_buffer[0] = cmd;
iton_bt_buffer[1] = b1;
iton_bt_buffer[2] = b2;

spiStartSend(&ITON_BT_SPI_PORT, 3, &iton_bt_buffer[0]);
}

inline void iton_bt_send_ack(uint8_t b1, uint8_t b2) {
writePinHigh(ITON_BT_IRQ_LINE);
iton_bt_buffer[0] = control;
iton_bt_buffer[1] = b1;
iton_bt_buffer[2] = b2;
chSysLockFromISR();
spiStartSendI(&ITON_BT_SPI_PORT, 3, &iton_bt_buffer[0]);
chSysUnlockFromISR();
}

void iton_bt_send_fn(bool pressed) {
uint8_t data = pressed ? 0xA3 : 0x00;

iton_bt_send(report_fn, &data, 1);
}

void iton_bt_send_system(uint16_t data) {
iton_bt_send(report_system, (uint8_t *)&data, 1);
}

void iton_bt_send_consumer(uint16_t data) {
iton_bt_send2(report_consumer, HIGH_BITS(data), LOW_BITS(data));
}

void iton_bt_send_keyboard(report_keyboard_t *report) {
// iton module only reads 5 of the keys in the hid report
// so we send the last key as an nkro report.
if (report->keys[5] != iton_bt_send_kb_last_key) {
uint8_t nkro_report[15] = {0};
nkro_report[report->keys[5] >> 3] |= (1 << (report->keys[5] & 7));
iton_bt_send_kb_last_key = report->keys[5];

return iton_bt_send(report_nkro, &nkro_report[0], 15);
}

iton_bt_send(report_hid, &report->mods, 8);
}
Loading

0 comments on commit 228e330

Please sign in to comment.