201 lines
5.6 KiB
C
201 lines
5.6 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "CH58x_common.h"
|
|
#include "CH58x_sys.h"
|
|
#include "CH58xBLE_LIB.h"
|
|
#include "led.h"
|
|
#include "wang.h"
|
|
|
|
int ble_on = 0;
|
|
int ble_connected = 0;
|
|
void ble_toggle(void) {
|
|
uint8_t ble_mode = ble_on ? FALSE : TRUE;
|
|
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(ble_mode), &ble_mode);
|
|
ble_on = !ble_on;
|
|
}
|
|
|
|
// We use TMOS only for BLE things and wrap the rest.
|
|
static __attribute__((aligned(4), section(".noinit")))
|
|
uint8_t BLE_BUF[1024 * 6];
|
|
|
|
static void ble_calib_cb(void) {
|
|
Calibration_LSI(Level_128);
|
|
}
|
|
|
|
static uint8_t periph_task = INVALID_TASK_ID;
|
|
|
|
static uint16_t peripheral_task(uint8_t task_id, uint16_t events) {
|
|
if (events & SYS_EVENT_MSG) {
|
|
uint8_t *pMsg = tmos_msg_receive(periph_task);
|
|
if (pMsg) {
|
|
// process the message. noop.
|
|
tmos_msg_deallocate(pMsg);
|
|
}
|
|
|
|
return events ^ SYS_EVENT_MSG;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void gap_onParamUpdate(uint16_t a, uint16_t b, uint16_t c, uint16_t d) {
|
|
}
|
|
static void gap_onStateChange(gapRole_States_t a, gapRoleEvent_t *b) {
|
|
}
|
|
|
|
uint8_t advertData[] = {
|
|
0x02,
|
|
GAP_ADTYPE_FLAGS,
|
|
GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
|
|
|
|
0x03,
|
|
GAP_ADTYPE_16BIT_MORE,
|
|
LO_UINT16(0xFEE0),
|
|
HI_UINT16(0xFEE0),
|
|
};
|
|
|
|
uint8_t scanRspData[31] = {
|
|
0x05,
|
|
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
|
|
LO_UINT16(100),
|
|
HI_UINT16(100),
|
|
LO_UINT16(200),
|
|
HI_UINT16(200),
|
|
|
|
0x02,
|
|
GAP_ADTYPE_POWER_LEVEL,
|
|
6,
|
|
|
|
19,
|
|
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
|
'L', 'S', 'L', 'E', 'D', ' ', 'B', 'a', 'd', 'g', 'e', ' ', 'W', 'i', 't', 'c', 'h', 0,
|
|
|
|
0, 0,
|
|
};
|
|
|
|
static gapRolesBroadcasterCBs_t broadcast_handlers = {
|
|
0,
|
|
0,
|
|
};
|
|
static gapRolesCBs_t gap_handlers = {
|
|
gap_onStateChange,
|
|
0,
|
|
gap_onParamUpdate,
|
|
};
|
|
|
|
static gapBondCBs_t bond_managers = {
|
|
0,
|
|
0,
|
|
};
|
|
|
|
static const uint8_t service_uuid[2] = {LO_UINT16(0xFEE0), HI_UINT16(0xFEE0)};
|
|
static const gattAttrType_t service = {2, service_uuid};
|
|
|
|
static const uint8_t rx_char_uuid[2] = {LO_UINT16(0xFEE1), HI_UINT16(0xFEE1)};
|
|
static uint8_t rx_char_props = GATT_PROP_WRITE;
|
|
static uint8_t rx_char_val[16];
|
|
|
|
static gattAttribute_t attr_table[] = {
|
|
{{2, primaryServiceUUID}, GATT_PERMIT_READ, 0, (uint8_t *)&service},
|
|
{{2, characterUUID}, GATT_PERMIT_READ, 0, &rx_char_props},
|
|
{{2, rx_char_uuid}, GATT_PERMIT_WRITE, 0, (uint8_t *)&rx_char_val},
|
|
};
|
|
|
|
uint16_t blefb[44] = {0};
|
|
|
|
static bStatus_t write_handler(uint16_t conn_handle, gattAttribute_t *pAttr, uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method) {
|
|
if (gattPermitAuthorWrite(pAttr->permissions)) return ATT_ERR_INSUFFICIENT_AUTHOR;
|
|
|
|
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
|
if (uuid != 0xFEE1) return ATT_ERR_ATTR_NOT_FOUND;
|
|
|
|
wang_rx(pValue, len);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static gattServiceCBs_t service_handlers = {
|
|
0,
|
|
write_handler,
|
|
0,
|
|
};
|
|
|
|
void ble_init(void) {
|
|
bleConfig_t cfg = {0};
|
|
|
|
// BLE heap
|
|
cfg.MEMAddr = (uint32_t) BLE_BUF;
|
|
cfg.MEMLen = (uint32_t) sizeof(BLE_BUF);
|
|
|
|
// not using the bonding information, as we do not support _bonding_.
|
|
// This should be changed. but. you know.
|
|
|
|
// TODO: magic numbers
|
|
// amount of buffered packets
|
|
cfg.BufNumber = (512 / 23);
|
|
// maximum data length of each packet
|
|
cfg.BufMaxLen = (64 + 4);
|
|
|
|
cfg.TxNumEvent = 1;
|
|
cfg.TxPower = LL_TX_POWEER_6_DBM;
|
|
cfg.ConnectNumber = (1 & 3) | (1 << 2);
|
|
cfg.SelRTCClock = 1 << 7;
|
|
cfg.rcCB = ble_calib_cb;
|
|
|
|
uint8_t m[6];
|
|
GetMACAddress(m);
|
|
memcpy(cfg.MacAddr, m, 6);
|
|
|
|
BLE_LibInit(&cfg);
|
|
|
|
sys_safe_access_enable();
|
|
R8_CK32K_CONFIG &= ~(RB_CLK_OSC32K_XT | RB_CLK_XT32K_PON);
|
|
sys_safe_access_enable();
|
|
R8_CK32K_CONFIG |= RB_CLK_INT32K_PON;
|
|
sys_safe_access_disable();
|
|
|
|
Calibration_LSI(Level_128);
|
|
RTC_InitTime(2020, 1, 1, 0, 0, 0);
|
|
TMOS_TimerInit(0);
|
|
|
|
|
|
periph_task = TMOS_ProcessEventRegister(peripheral_task);
|
|
|
|
GAPRole_PeripheralInit();
|
|
|
|
// the GAP parameters all kinda suck to set. sooo
|
|
#define SET_PARAM(a, b, c, d) do { static c val = d; a(b, sizeof(val), &val); } while(0)
|
|
SET_PARAM(GAPRole_SetParameter, GAPROLE_ADVERT_ENABLED, uint8_t, FALSE);
|
|
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, 31, scanRspData);
|
|
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
|
|
SET_PARAM(GAPRole_SetParameter, GAPROLE_MIN_CONN_INTERVAL, uint16_t, 6);
|
|
SET_PARAM(GAPRole_SetParameter, GAPROLE_MAX_CONN_INTERVAL, uint16_t, 500);
|
|
|
|
GGS_SetParameter(GGS_DEVICE_NAME_ATT, 20, "LED Badge Witch\0\0\0\0\0\0\0");
|
|
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, 100);
|
|
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, 200);
|
|
|
|
SET_PARAM(GAPBondMgr_SetParameter, GAPBOND_PERI_DEFAULT_PASSCODE, uint32_t, 0);
|
|
SET_PARAM(GAPBondMgr_SetParameter, GAPBOND_PERI_PAIRING_MODE, uint8_t, GAPBOND_PAIRING_MODE_NO_PAIRING);
|
|
SET_PARAM(GAPBondMgr_SetParameter, GAPBOND_PERI_MITM_PROTECTION, uint8_t, FALSE);
|
|
SET_PARAM(GAPBondMgr_SetParameter, GAPBOND_PERI_IO_CAPABILITIES, uint8_t, GAPBOND_IO_CAP_DISPLAY_ONLY);
|
|
SET_PARAM(GAPBondMgr_SetParameter, GAPBOND_PERI_BONDING_ENABLED, uint8_t, FALSE);
|
|
|
|
GAPRole_BroadcasterSetCB(&broadcast_handlers);
|
|
|
|
GGS_AddService(GATT_ALL_SERVICES);
|
|
GATTServApp_AddService(GATT_ALL_SERVICES);
|
|
|
|
GAPRole_PeripheralStartDevice(periph_task, &bond_managers, &gap_handlers);
|
|
|
|
GATTServApp_RegisterService(attr_table, GATT_NUM_ATTRS(attr_table), GATT_MAX_ENCRYPT_KEY_SIZE, &service_handlers);
|
|
}
|
|
|
|
struct connection_data {
|
|
uint16_t handle;
|
|
uint16_t interval;
|
|
uint16_t slave_latency;
|
|
uint16_t timeout;
|
|
};
|