feat: add initial Bluetooth LE module
This commit is contained in:
parent
2383bf65e5
commit
8274cab154
4594
CH5xx_ble_firmware_library/BLE/CH58xBLE_LIB.h
Normal file
4594
CH5xx_ble_firmware_library/BLE/CH58xBLE_LIB.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
CH5xx_ble_firmware_library/BLE/LIBCH58xBLE.a
Normal file
BIN
CH5xx_ble_firmware_library/BLE/LIBCH58xBLE.a
Normal file
Binary file not shown.
11
Makefile
11
Makefile
@ -53,6 +53,10 @@ src/main.c \
|
||||
src/leddrv.c \
|
||||
src/button.c \
|
||||
src/fb.c \
|
||||
src/ble/profile/legacy.c \
|
||||
src/ble/profile/devinfo.c \
|
||||
src/ble/setup.c \
|
||||
src/ble/peripheral.c \
|
||||
|
||||
|
||||
# ASM sources
|
||||
@ -95,7 +99,7 @@ C_INCLUDES = \
|
||||
-ICH5xx_ble_firmware_library/StdPeriphDriver/inc \
|
||||
-ICH5xx_ble_firmware_library/RVMSIS \
|
||||
-ICH5xx_ble_firmware_library/Core \
|
||||
-IUser
|
||||
-ICH5xx_ble_firmware_library/BLE \
|
||||
|
||||
# compile gcc flags
|
||||
ASFLAGS = $(MCU) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
|
||||
@ -118,7 +122,10 @@ CFLAGS += -MMD -MP
|
||||
LDSCRIPT = CH5xx_ble_firmware_library/Ld/Link.ld
|
||||
|
||||
# libraries
|
||||
LIBS = -lc -lm -lnosys ./CH5xx_ble_firmware_library/StdPeriphDriver/libISP583.a
|
||||
LIBS = -lc -lm -lnosys \
|
||||
./CH5xx_ble_firmware_library/StdPeriphDriver/libISP583.a \
|
||||
./CH5xx_ble_firmware_library/BLE/LIBCH58xBLE.a \
|
||||
|
||||
LIBDIR =
|
||||
LDFLAGS = $(MCU) -mno-save-restore -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wunused -Wuninitialized -T $(LDSCRIPT) -nostartfiles -Xlinker --gc-sections -Wl,-Map=$(BUILD_DIR)/$(TARGET).map --specs=nano.specs $(LIBS)
|
||||
|
||||
|
||||
23
src/ble/common.h
Normal file
23
src/ble/common.h
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* This file contain high-level data structures for differents BLE chip.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __BLE_H__
|
||||
#define __BLE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t *bytes;
|
||||
int size;
|
||||
} byte_t;
|
||||
|
||||
typedef struct {
|
||||
byte_t val; // Values
|
||||
uint8_t props; // Properties //TODO: add enum
|
||||
byte_t uuid;
|
||||
} ble_char_t;
|
||||
|
||||
#endif /* __BLE_H__ */
|
||||
246
src/ble/peripheral.c
Normal file
246
src/ble/peripheral.c
Normal file
@ -0,0 +1,246 @@
|
||||
#include "CH58xBLE_LIB.h"
|
||||
#include "setup.h"
|
||||
|
||||
#define ADV_UUID (0xFEE0)
|
||||
|
||||
static uint8 taskid = INVALID_TASK_ID;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 connHandle; // Connection handle of current connection
|
||||
uint16 connInterval;
|
||||
uint16 connSlaveLatency;
|
||||
uint16 connTimeout;
|
||||
} peripheralConnItem_t;
|
||||
|
||||
#define SBP_PARAM_UPDATE_DELAY 1600 // Parameter update delay (unit of 0.625ms)
|
||||
#define SLAVE_LATENCY 0
|
||||
|
||||
#define MIN_ADV_INTERVAL 100 // Advertising interval (units of 0.625ms)
|
||||
#define MAX_ADV_INTERVAL 200 // Advertising interval (units of 0.625ms)
|
||||
|
||||
#define MIN_CONN_INTERVAL 20 // Connection interval (units of 1.25ms)
|
||||
#define MAX_CONN_INTERVAL 100 // Connection interval (units of 1.25ms)
|
||||
|
||||
#define CONN_TIMEOUT 100 // Supervision timeout (units of 10ms)
|
||||
|
||||
// GAP - SCAN RSP data (max size = 31 bytes)
|
||||
static uint8 scanRspData[] = {
|
||||
// complete name
|
||||
16, // length of this section
|
||||
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
||||
'L', 'E','D', ' ',
|
||||
'B', 'a','d', 'g', 'e', ' ',
|
||||
'M', 'a','g', 'i', 'c',
|
||||
|
||||
// connection interval range
|
||||
0x05, // length of this section
|
||||
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
|
||||
LO_UINT16(MIN_CONN_INTERVAL),
|
||||
HI_UINT16(MIN_CONN_INTERVAL),
|
||||
LO_UINT16(MAX_CONN_INTERVAL),
|
||||
HI_UINT16(MAX_CONN_INTERVAL),
|
||||
|
||||
// Tx power level
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_POWER_LEVEL,
|
||||
9 // 9dBm
|
||||
};
|
||||
|
||||
// GAP - Advertisement data (max size = 31 bytes)
|
||||
// keep short, save energy, save the planet
|
||||
static uint8 advertData[] = {
|
||||
0x02, // section length
|
||||
GAP_ADTYPE_FLAGS,
|
||||
GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
|
||||
|
||||
// advertise UUID
|
||||
0x03, // section length
|
||||
GAP_ADTYPE_16BIT_MORE,
|
||||
LO_UINT16(ADV_UUID),
|
||||
HI_UINT16(ADV_UUID)
|
||||
};
|
||||
|
||||
// GAP GATT Attributes
|
||||
static uint8 devName[GAP_DEVICE_NAME_LEN] = "LED Badge Magic";
|
||||
|
||||
// Connection item list
|
||||
static peripheralConnItem_t conn_list;
|
||||
|
||||
static void initConn(peripheralConnItem_t *conn)
|
||||
{
|
||||
conn->connHandle = GAP_CONNHANDLE_INIT;
|
||||
conn->connInterval = 0;
|
||||
conn->connSlaveLatency = 0;
|
||||
conn->connTimeout = 0;
|
||||
}
|
||||
|
||||
static void processTMOSMsg(tmos_event_hdr_t *pMsg)
|
||||
{
|
||||
switch(pMsg->event) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_advertising(uint8_t enable)
|
||||
{
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &enable);
|
||||
}
|
||||
|
||||
static void link_onEstablished(gapRoleEvent_t *pe)
|
||||
{
|
||||
gapEstLinkReqEvent_t *e = (gapEstLinkReqEvent_t *)pe;
|
||||
|
||||
// If already connected
|
||||
if(conn_list.connHandle != GAP_CONNHANDLE_INIT) {
|
||||
// Only allow 1 connection, so the new connection will be dropped:
|
||||
GAPRole_TerminateLink(e->connectionHandle);
|
||||
GAPRole_PeripheralConnParamUpdateReq(e->connectionHandle,
|
||||
MIN_CONN_INTERVAL,
|
||||
MAX_CONN_INTERVAL,
|
||||
SLAVE_LATENCY,
|
||||
CONN_TIMEOUT,
|
||||
taskid);
|
||||
return;
|
||||
}
|
||||
conn_list.connHandle = e->connectionHandle;
|
||||
conn_list.connInterval = e->connInterval;
|
||||
conn_list.connSlaveLatency = e->connLatency;
|
||||
conn_list.connTimeout = e->connTimeout;
|
||||
enable_advertising(FALSE);
|
||||
}
|
||||
|
||||
static void link_onTerminated(gapRoleEvent_t *pe)
|
||||
{
|
||||
gapTerminateLinkEvent_t *event = (gapTerminateLinkEvent_t *)pe;
|
||||
GAPRole_TerminateLink(pe->linkCmpl.connectionHandle);
|
||||
enable_advertising(TRUE);
|
||||
|
||||
if(event->connectionHandle == conn_list.connHandle) {
|
||||
conn_list.connHandle = GAP_CONNHANDLE_INIT;
|
||||
conn_list.connInterval = 0;
|
||||
conn_list.connSlaveLatency = 0;
|
||||
conn_list.connTimeout = 0;
|
||||
} else {
|
||||
// Requested connection is not existed in connection list
|
||||
}
|
||||
}
|
||||
|
||||
static void gap_onParamUpdate(uint16 connHandle, uint16 connInterval,
|
||||
uint16 connSlaveLatency, uint16 connTimeout)
|
||||
{
|
||||
conn_list.connHandle = connHandle;
|
||||
conn_list.connInterval = connInterval;
|
||||
conn_list.connSlaveLatency = connSlaveLatency;
|
||||
conn_list.connTimeout = connTimeout;
|
||||
}
|
||||
|
||||
static void gap_onStateChange(gapRole_States_t newState, gapRoleEvent_t *pEvent)
|
||||
{
|
||||
switch(newState & GAPROLE_STATE_ADV_MASK) {
|
||||
case GAPROLE_ADVERTISING:
|
||||
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT) {
|
||||
link_onTerminated(pEvent);
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED:
|
||||
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT) {
|
||||
link_onEstablished(pEvent);
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_WAITING:
|
||||
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT) {
|
||||
link_onTerminated(pEvent);
|
||||
} else {
|
||||
// refer to pEvent->gap.opcode
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// GAP Role Callbacks
|
||||
static gapRolesCBs_t gap_handlers = {
|
||||
gap_onStateChange,
|
||||
NULL,
|
||||
gap_onParamUpdate
|
||||
};
|
||||
|
||||
// Broadcast Callbacks
|
||||
static gapRolesBroadcasterCBs_t broadcast_handlers = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
// GAP Bond Manager Callbacks
|
||||
static gapBondCBs_t bond_managers = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static uint16 peripheral_task(uint8 task_id, uint16 events)
|
||||
{
|
||||
if(events & SYS_EVENT_MSG) { // Handle BLE stack message
|
||||
uint8 *pMsg = tmos_msg_receive(taskid);
|
||||
if(pMsg) {
|
||||
processTMOSMsg((tmos_event_hdr_t *)pMsg);
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gap_init()
|
||||
{
|
||||
GAPRole_PeripheralInit();
|
||||
|
||||
static uint8 initial_advertising_enable = TRUE;
|
||||
static uint16 desired_min_interval = 6;
|
||||
static uint16 desired_max_interval = 500;
|
||||
|
||||
// Set the GAP Role Parameters
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &initial_advertising_enable);
|
||||
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
|
||||
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16), &desired_min_interval);
|
||||
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16), &desired_max_interval);
|
||||
|
||||
// Set the GAP Characteristics
|
||||
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, devName);
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, MIN_ADV_INTERVAL);
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, MAX_ADV_INTERVAL);
|
||||
|
||||
static uint32 passkey = 0; // passkey "000000"
|
||||
static uint8 pairMode = GAPBOND_PAIRING_MODE_NO_PAIRING;
|
||||
static uint8 mitm = FALSE;
|
||||
static uint8 bonding = FALSE;
|
||||
static uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32), &passkey);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8), &pairMode);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8), &mitm);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8), &ioCap);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8), &bonding);
|
||||
|
||||
GAPRole_BroadcasterSetCB(&broadcast_handlers);
|
||||
|
||||
GGS_AddService(GATT_ALL_SERVICES);
|
||||
GATTServApp_AddService(GATT_ALL_SERVICES);
|
||||
}
|
||||
|
||||
void peripheral_init()
|
||||
{
|
||||
taskid = TMOS_ProcessEventRegister(peripheral_task);
|
||||
|
||||
initConn(&conn_list);
|
||||
gap_init();
|
||||
|
||||
GAPRole_PeripheralStartDevice(taskid, &bond_managers, &gap_handlers);
|
||||
}
|
||||
7
src/ble/profile.h
Normal file
7
src/ble/profile.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __BLE_UART_SERVICE_H__
|
||||
#define __BLE_UART_SERVICE_H__
|
||||
|
||||
int legacy_registerService();
|
||||
int devInfo_registerService();
|
||||
|
||||
#endif /* __BLE_UART_SERVICE_H__ */
|
||||
120
src/ble/profile/devinfo.c
Normal file
120
src/ble/profile/devinfo.c
Normal file
@ -0,0 +1,120 @@
|
||||
#include "../common.h"
|
||||
#include "utils.h"
|
||||
|
||||
// TODO: Automatic assign these on build
|
||||
static const uint8_t systemId_val[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static const uint16_t systemId_UUID = SYSTEM_ID_UUID;
|
||||
|
||||
static const uint8_t modelNumber_val[] = "B1144";
|
||||
static const uint16_t modelNumber_UUID = MODEL_NUMBER_UUID;
|
||||
|
||||
const uint16_t serialNumber_UUID = SERIAL_NUMBER_UUID;
|
||||
static const uint8_t serialNumber_val[] = "N/A";
|
||||
|
||||
const uint16_t firmwareRev_UUID = FIRMWARE_REV_UUID;
|
||||
static const uint8_t firmwareRev_val[] = "v0.0.1";
|
||||
|
||||
const uint16_t hardwareRev_UUID = HARDWARE_REV_UUID;
|
||||
static const uint8_t hardwareRev_val[] = "221028";
|
||||
|
||||
const uint16_t softwareRev_UUID = SOFTWARE_REV_UUID;
|
||||
static const uint8_t softwareRev_val[] = "N/A";
|
||||
|
||||
uint16_t mfr_name_UUID = MANUFACTURER_NAME_UUID;
|
||||
static const uint8_t mfr_name_val[] = "FOSSASIA";
|
||||
|
||||
static const ble_char_t dev_info[7] = {
|
||||
{
|
||||
{systemId_val, sizeof(systemId_val)},
|
||||
GATT_PROP_READ, { (uint8_t*)&systemId_UUID, 2}
|
||||
}, {
|
||||
{modelNumber_val, sizeof(modelNumber_val) - 1},
|
||||
GATT_PROP_READ, { (uint8_t*)&modelNumber_UUID, 2}
|
||||
}, {
|
||||
{serialNumber_val, sizeof(serialNumber_val) - 1},
|
||||
GATT_PROP_READ, { (uint8_t*)&serialNumber_UUID, 2}
|
||||
}, {
|
||||
{firmwareRev_val, sizeof(firmwareRev_val) - 1},
|
||||
GATT_PROP_READ, { (uint8_t*)&firmwareRev_UUID, 2}
|
||||
}, {
|
||||
{hardwareRev_val, sizeof(hardwareRev_val) - 1},
|
||||
GATT_PROP_READ, { (uint8_t*)&hardwareRev_UUID, 2}
|
||||
}, {
|
||||
{softwareRev_val, sizeof(softwareRev_val) - 1},
|
||||
GATT_PROP_READ, { (uint8_t*)&softwareRev_UUID, 2}
|
||||
}, {
|
||||
{mfr_name_val, sizeof(mfr_name_val) - 1},
|
||||
GATT_PROP_READ,
|
||||
{ (uint8_t*)&mfr_name_UUID, 2},
|
||||
}
|
||||
};
|
||||
|
||||
const uint16_t service_UUID = DEVINFO_SERV_UUID;
|
||||
static const gattAttrType_t service = {ATT_BT_UUID_SIZE, (uint8_t *)&service_UUID};
|
||||
|
||||
static bStatus_t read_handler(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *p_value, uint16_t *pLen, uint16_t offset,
|
||||
uint16_t maxLen, uint8_t method)
|
||||
{
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
|
||||
if (uuid < SYSTEM_ID_UUID || uuid > MANUFACTURER_NAME_UUID ) {
|
||||
*pLen = 0;
|
||||
return ATT_ERR_ATTR_NOT_FOUND;
|
||||
}
|
||||
|
||||
uint16_t i = uuid - SYSTEM_ID_UUID;
|
||||
if(offset >= dev_info[i].val.size) {
|
||||
return ATT_ERR_INVALID_OFFSET;
|
||||
} else {
|
||||
*pLen = MIN(maxLen, (dev_info[i].val.size - offset));
|
||||
tmos_memcpy(p_value, &dev_info[i].val.bytes[offset], *pLen);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
gattServiceCBs_t devInfoCBs = {
|
||||
read_handler,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int devInfo_registerService()
|
||||
{
|
||||
static gattAttribute_t attr_table[] = {
|
||||
ATTR_DECLAR(primaryServiceUUID, 2, GATT_PERMIT_READ, &service),
|
||||
|
||||
CHAR_DECLAR(&dev_info[0].props),
|
||||
CHAR_VAL_DECLAR(dev_info[0].uuid.bytes, dev_info[0].uuid.size, \
|
||||
GATT_PERMIT_READ, dev_info[0].val.bytes),
|
||||
|
||||
CHAR_DECLAR(&dev_info[1].props),
|
||||
CHAR_VAL_DECLAR(dev_info[1].uuid.bytes, dev_info[1].uuid.size, \
|
||||
GATT_PERMIT_READ, dev_info[1].val.bytes),
|
||||
|
||||
CHAR_DECLAR(&dev_info[2].props),
|
||||
CHAR_VAL_DECLAR(dev_info[2].uuid.bytes, dev_info[2].uuid.size, \
|
||||
GATT_PERMIT_READ, dev_info[2].val.bytes),
|
||||
|
||||
CHAR_DECLAR(&dev_info[3].props),
|
||||
CHAR_VAL_DECLAR(dev_info[3].uuid.bytes, dev_info[3].uuid.size, \
|
||||
GATT_PERMIT_READ, dev_info[3].val.bytes),
|
||||
|
||||
CHAR_DECLAR(&dev_info[4].props),
|
||||
CHAR_VAL_DECLAR(dev_info[4].uuid.bytes, dev_info[4].uuid.size, \
|
||||
GATT_PERMIT_READ, dev_info[4].val.bytes),
|
||||
|
||||
CHAR_DECLAR(&dev_info[5].props),
|
||||
CHAR_VAL_DECLAR(dev_info[5].uuid.bytes, dev_info[5].uuid.size, \
|
||||
GATT_PERMIT_READ, dev_info[5].val.bytes),
|
||||
|
||||
CHAR_DECLAR(&dev_info[6].props),
|
||||
CHAR_VAL_DECLAR(dev_info[6].uuid.bytes, dev_info[6].uuid.size, \
|
||||
GATT_PERMIT_READ, dev_info[6].val.bytes),
|
||||
};
|
||||
|
||||
return GATTServApp_RegisterService(attr_table,
|
||||
GATT_NUM_ATTRS(attr_table),
|
||||
GATT_MAX_ENCRYPT_KEY_SIZE,
|
||||
&devInfoCBs);
|
||||
}
|
||||
51
src/ble/profile/legacy.c
Normal file
51
src/ble/profile/legacy.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include "utils.h"
|
||||
|
||||
static const uint16_t ServiceUUID = 0xFEE0;
|
||||
static const gattAttrType_t service = {2, (uint8_t *)&ServiceUUID};
|
||||
|
||||
static const uint16_t RxCharUUID = 0xFEE1;
|
||||
static uint8 RxCharProps = GATT_PROP_WRITE;
|
||||
static uint8 RxCharVal[16];
|
||||
|
||||
static gattAttribute_t attr_table[] = {
|
||||
ATTR_DECLAR(primaryServiceUUID, 2, GATT_PERMIT_READ, &service),
|
||||
|
||||
CHAR_DECLAR(&RxCharProps),
|
||||
CHAR_VAL_DECLAR(&RxCharUUID, 2, GATT_PERMIT_WRITE, RxCharVal),
|
||||
};
|
||||
|
||||
static bStatus_t receive(uint8_t *val, uint16_t len)
|
||||
{
|
||||
/* TODO: implement data receiving here*/
|
||||
}
|
||||
|
||||
static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr,
|
||||
uint8 *pValue, uint16 len, uint16 offset, uint8 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 == RxCharUUID) {
|
||||
return receive(pValue, len);
|
||||
}
|
||||
return ATT_ERR_ATTR_NOT_FOUND;
|
||||
}
|
||||
|
||||
gattServiceCBs_t service_handlers = {
|
||||
NULL,
|
||||
write_handler,
|
||||
NULL
|
||||
};
|
||||
|
||||
int legacy_registerService()
|
||||
{
|
||||
uint8 status = SUCCESS;
|
||||
|
||||
status = GATTServApp_RegisterService(attr_table,
|
||||
GATT_NUM_ATTRS(attr_table),
|
||||
GATT_MAX_ENCRYPT_KEY_SIZE,
|
||||
&service_handlers);
|
||||
return (status);
|
||||
}
|
||||
22
src/ble/profile/utils.h
Normal file
22
src/ble/profile/utils.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __UTILS_H__
|
||||
#define __UTILS_H__
|
||||
|
||||
#include "CH58xBLE_LIB.h"
|
||||
|
||||
#define ATTR_DECLAR(uuid, uuid_size, permissions, val) \
|
||||
{ \
|
||||
{(uuid_size), (uint8_t *)(uuid)}, \
|
||||
(permissions), \
|
||||
0, \
|
||||
(uint8_t *)(val) \
|
||||
}
|
||||
|
||||
// Characteristic Declaration
|
||||
#define CHAR_DECLAR(properties) \
|
||||
ATTR_DECLAR(characterUUID, 2, GATT_PERMIT_READ, properties)
|
||||
|
||||
// Characteristic Value Declaration
|
||||
#define CHAR_VAL_DECLAR(uuid, uuid_size, permissions, val) \
|
||||
ATTR_DECLAR(uuid, uuid_size, permissions, val)
|
||||
|
||||
#endif /* __UTILS_H__ */
|
||||
72
src/ble/setup.c
Normal file
72
src/ble/setup.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "setup.h"
|
||||
#include "CH58xBLE_LIB.h"
|
||||
#include "CH58x_common.h"
|
||||
|
||||
#ifndef BLE_BUFF_LEN
|
||||
#define BLE_BUFF_LEN 27
|
||||
#endif
|
||||
#ifndef BLE_BUFF_NUM
|
||||
#define BLE_BUFF_NUM 5
|
||||
#endif
|
||||
#ifndef BLE_TX_NUM_EVENT
|
||||
#define BLE_TX_NUM_EVENT 1
|
||||
#endif
|
||||
#ifndef BLE_TX_POWER
|
||||
#define BLE_TX_POWER LL_TX_POWEER_6_DBM
|
||||
#endif
|
||||
#ifndef BLE_MEMHEAP_SIZE
|
||||
#define BLE_MEMHEAP_SIZE (1024*6)
|
||||
#endif
|
||||
#ifndef CENTRAL_MAX_CONNECTION
|
||||
#define CENTRAL_MAX_CONNECTION 3
|
||||
#endif
|
||||
#ifndef PERIPHERAL_MAX_CONNECTION
|
||||
#define PERIPHERAL_MAX_CONNECTION 1
|
||||
#endif
|
||||
|
||||
static __attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
|
||||
static void lsi_calib(void)
|
||||
{
|
||||
Calibration_LSI(Level_128);
|
||||
}
|
||||
|
||||
void tmos_clockInit(void)
|
||||
{
|
||||
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();
|
||||
lsi_calib();
|
||||
|
||||
RTC_InitTime(2020, 1, 1, 0, 0, 0);
|
||||
TMOS_TimerInit(0);
|
||||
}
|
||||
|
||||
void ble_hardwareInit(void)
|
||||
{
|
||||
bleConfig_t cfg;
|
||||
memset(&cfg, 0, sizeof(bleConfig_t));
|
||||
|
||||
cfg.MEMAddr = (uint32_t)MEM_BUF;
|
||||
cfg.MEMLen = (uint32_t)BLE_MEMHEAP_SIZE;
|
||||
cfg.BufMaxLen = (uint32_t)BLE_BUFF_LEN;
|
||||
cfg.BufNumber = (uint32_t)BLE_BUFF_NUM;
|
||||
cfg.TxNumEvent = (uint32_t)BLE_TX_NUM_EVENT;
|
||||
cfg.TxPower = (uint32_t)BLE_TX_POWER;
|
||||
cfg.ConnectNumber = (PERIPHERAL_MAX_CONNECTION & 3) | (CENTRAL_MAX_CONNECTION << 2);
|
||||
|
||||
cfg.SelRTCClock = 1 << 7;
|
||||
|
||||
cfg.rcCB = lsi_calib;
|
||||
|
||||
uint8_t m[6];
|
||||
GetMACAddress(m);
|
||||
memcpy(cfg.MacAddr, m, 6);
|
||||
|
||||
BLE_LibInit(&cfg);
|
||||
}
|
||||
8
src/ble/setup.h
Normal file
8
src/ble/setup.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __HAL_H__
|
||||
#define __HAL_H__
|
||||
|
||||
void tmos_clockInit(void);
|
||||
void ble_hardwareInit(void);
|
||||
void peripheral_init(void);
|
||||
|
||||
#endif /* __HAL_H__ */
|
||||
16
src/main.c
16
src/main.c
@ -5,6 +5,9 @@
|
||||
#include "button.h"
|
||||
#include "fb.h"
|
||||
|
||||
#include "ble/setup.h"
|
||||
#include "ble/profile.h"
|
||||
|
||||
#define FB_WIDTH (LED_COLS * 4)
|
||||
#define SCROLL_IRATIO (16)
|
||||
#define SCAN_F (2000)
|
||||
@ -103,6 +106,16 @@ void poweroff()
|
||||
LowPower_Shutdown(0);
|
||||
}
|
||||
|
||||
void ble_start()
|
||||
{
|
||||
ble_hardwareInit();
|
||||
tmos_clockInit();
|
||||
|
||||
peripheral_init();
|
||||
devInfo_registerService();
|
||||
legacy_registerService();
|
||||
}
|
||||
|
||||
void handle_mode_transition()
|
||||
{
|
||||
static int prev_mode;
|
||||
@ -116,8 +129,9 @@ void handle_mode_transition()
|
||||
|
||||
// Take control of the current fb to display
|
||||
// the Bluetooth animation
|
||||
ble_start();
|
||||
while (mode == DOWNLOAD) {
|
||||
/* Animation and Bluetooth will be placed here */
|
||||
TMOS_SystemProcess();
|
||||
}
|
||||
// If not being flashed, pressing KEY1 again will
|
||||
// make the badge goes off:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user