Skip to content

Commit

Permalink
WIP: ble: add next gen profile
Browse files Browse the repository at this point in the history
  • Loading branch information
kienvo committed Jan 7, 2025
1 parent 5c4e5b1 commit ec5e29f
Show file tree
Hide file tree
Showing 18 changed files with 649 additions and 101 deletions.
25 changes: 0 additions & 25 deletions CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,28 +369,3 @@ void mDelaymS(uint16_t t)
}
}

#ifdef DEBUG
int _write(int fd, char *buf, int size)
{
int i;
for(i = 0; i < size; i++)
{
#if DEBUG == Debug_UART0
while(R8_UART0_TFC == UART_FIFO_SIZE); /* 等待数据发送 */
R8_UART0_THR = *buf++; /* 发送数据 */
#elif DEBUG == Debug_UART1
while(R8_UART1_TFC == UART_FIFO_SIZE); /* 等待数据发送 */
R8_UART1_THR = *buf++; /* 发送数据 */
#elif DEBUG == Debug_UART2
while(R8_UART2_TFC == UART_FIFO_SIZE); /* 等待数据发送 */
R8_UART2_THR = *buf++; /* 发送数据 */
#elif DEBUG == Debug_UART3
while(R8_UART3_TFC == UART_FIFO_SIZE); /* 等待数据发送 */
R8_UART3_THR = *buf++; /* 发送数据 */
#endif
}
return size;
}

#endif

6 changes: 0 additions & 6 deletions CH5xx_ble_firmware_library/StdPeriphDriver/inc/CH583SFR.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,6 @@ typedef volatile unsigned long long *PUINT64V;
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif

#ifdef DEBUG
#define PRINT(X...) printf(X)
#else
#define PRINT(X...)
#endif

/* Calculate the byte offset of a field in a structure of type */
#define FIELD_OFFSET(Type, Field) ((UINT16)&(((Type *)0)->Field))

Expand Down
9 changes: 0 additions & 9 deletions CH5xx_ble_firmware_library/StdPeriphDriver/inc/CH58x_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,6 @@
#endif
#endif

#define Debug_UART0 0
#define Debug_UART1 1
#define Debug_UART2 2
#define Debug_UART3 3

#ifdef DEBUG
#include <stdio.h>
#endif

/**
* @brief 系统主频时钟(Hz)
*/
Expand Down
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,25 @@ CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_clk.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_uart0.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_timer1.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_pwm.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_usbhostClass.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_adc.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_usbhostBase.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_timer3.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_timer0.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_usb2hostClass.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_flash.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_uart1.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_usb2dev.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_usb2hostBase.c \
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_spi1.c \
CH5xx_ble_firmware_library/RVMSIS/core_riscv.c \
src/main.c \
src/debug.c \
src/leddrv.c \
src/button.c \
src/bmlist.c \
src/ble/profile/legacy.c \
src/ble/profile/batt.c \
src/ble/profile/devinfo.c \
src/ble/profile/ng.c \
src/config.c \
src/ngctrl.c \
src/ble/setup.c \
src/ble/peripheral.c \
src/data.c \
Expand Down Expand Up @@ -129,6 +129,7 @@ C_INCLUDES = \
ASFLAGS = $(MCU) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

CFLAGS = $(MCU) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS += -Werror=implicit-function-declaration

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2 -DDEBUG=$(DEBUG)
Expand Down
73 changes: 44 additions & 29 deletions src/ble/peripheral.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "CH58xBLE_LIB.h"
#include "setup.h"
#include "../config.h"

#define ADV_UUID (0xFEE0)

Expand All @@ -24,29 +25,6 @@ typedef struct

#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[] = {
Expand Down Expand Up @@ -210,21 +188,58 @@ void ble_disable_advertise()
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &e);
}

// len should not exceed 20 chars excluding null-terminate char. Otherwise it
// will be trimmed off and return -1
static int setup_scan_rsp(char *name, uint8_t len)
{
int ret = 0;
// GAP - SCAN RSP data (max size = 31 bytes)
uint8_t scanRspData[31] = {
// 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

len + 1,
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
};

if (len < (31 - 11)) {
tmos_memcpy(&scanRspData[11], name, len);
ret = -1;
} else {
tmos_memcpy(&scanRspData[11], name, 20);
}
int total_len = 11 + len;
tmos_memset(&scanRspData[total_len], 0, 31 - total_len);
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, total_len, scanRspData);
return ret;
}

static void gap_init()
{
GAPRole_PeripheralInit();

static uint16 desired_min_interval = 6;
static uint16 desired_max_interval = 500;
uint16_t min_interval = 6;
uint16_t max_interval = 500;

// Set the GAP Role Parameters
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
setup_scan_rsp(badge_cfg.ble.devname.ptr, badge_cfg.ble.devname.len);
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);
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16), &min_interval);
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16), &max_interval);

// Set the GAP Characteristics
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, devName);
GGS_SetParameter(GGS_DEVICE_NAME_ATT, badge_cfg.ble.devname.len,
badge_cfg.ble.devname.ptr);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, MIN_ADV_INTERVAL);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, MAX_ADV_INTERVAL);

Expand Down
3 changes: 3 additions & 0 deletions src/ble/profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
int legacy_registerService();
int devInfo_registerService();
int batt_registerService();
int ng_registerService();

bStatus_t ng_notify(uint8_t *pValue, uint8_t len);

#endif /* __BLE_UART_SERVICE_H__ */
160 changes: 160 additions & 0 deletions src/ble/profile/ng.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#include "utils.h"

#include "CH583SFR.h"

#include "../../power.h"
#include "../../ngctrl.h"
#include "../../debug.h"

static const uint16_t ServiceUUID = 0xF055;
static const gattAttrType_t service = {2, (uint8_t *)&ServiceUUID};

static const uint16_t TxCharUUID = 0xF056;
static uint8_t TxCharProps = GATT_PROP_READ | GATT_PROP_NOTIFY;
static uint8_t TxCharVal[256];
static uint16_t TxLen;

static const uint16_t RxCharUUID = 0xF057;
static uint8_t RxCharProps = GATT_PROP_WRITE;
#define RxCharVal TxCharVal
static gattCharCfg_t TxCCCD[1];

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),

CHAR_DECLAR(&TxCharProps),
CHAR_VAL_DECLAR(&TxCharUUID, 2, GATT_PERMIT_READ, TxCharVal),
ATTR_DECLAR(clientCharCfgUUID, 2, GATT_PERMIT_READ | GATT_PERMIT_WRITE, TxCCCD),
};

#define notiAttr attr_table[4]


static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint16 len, uint16 offset, uint8 method)
{
PRINT("ble: write_handler(): connHandle: %04X\n", connHandle);

if (!gattPermitWrite(pAttr->permissions)) {
return ATT_ERR_WRITE_NOT_PERMITTED;
}

uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
if(uuid == GATT_CLIENT_CHAR_CFG_UUID) {
bStatus_t ret = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY);
PRINT("ble: CCCD changed: %02X\n", TxCCCD->value);
return ret;
}

if (uuid == RxCharUUID) {
return ng_parse(pValue, len);
}

return ATT_ERR_ATTR_NOT_FOUND;
}

static bStatus_t read_handler(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset,
uint16_t maxLen, uint8_t method)
{
if (!gattPermitRead(pAttr->permissions)) {
return ATT_ERR_READ_NOT_PERMITTED;
}

uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
if(uuid == GATT_CLIENT_CHAR_CFG_UUID) {
*pLen = 2;
tmos_memcpy(pValue, pAttr->pValue, *pLen);
return SUCCESS;
}

if (uuid == TxCharUUID) {
*pLen = MIN(TxLen-offset, maxLen);
tmos_memcpy(pValue, &pAttr->pValue[offset], *pLen);
return SUCCESS;
}

return ATT_ERR_ATTR_NOT_FOUND;
}

static gattServiceCBs_t service_handlers = {
read_handler,
write_handler,
NULL
};

static void connStatus_handler(uint16 connHandle, uint8 changeType)
{
if(connHandle == LOOPBACK_CONNHANDLE)
return;

// Reset ClientCharConfig if connection has dropped
if((changeType == LINKDB_STATUS_UPDATE_REMOVED)
|| ((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS)
&& (!linkDB_Up(connHandle)))) {
GATTServApp_InitCharCfg(connHandle, TxCCCD);
}
}

int ng_registerService()
{
uint8 status = SUCCESS;
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, TxCCCD);
linkDB_Register(connStatus_handler);

status = GATTServApp_RegisterService(attr_table,
GATT_NUM_ATTRS(attr_table),
GATT_MAX_ENCRYPT_KEY_SIZE,
&service_handlers);
return (status);
}

static uint8 isNotifyEnabled(uint16 connHandle)
{
uint16_t val = GATTServApp_ReadCharCfg(connHandle, TxCCCD);
return val & GATT_CLIENT_CFG_NOTIFY;
}
/**
* @brief Send notify to client. Currently support one client connection
* only.
*
* @param val Value to be sent
* @param len length of val. This should not be larger than MTU.
* @return bStatus_t
*/
bStatus_t ng_notify(uint8_t *val, uint8_t len)
{
if(!isNotifyEnabled(TxCCCD->connHandle)) {
PRINT("ble: ng_notify() notify is not enabled\n");
return bleIncorrectMode;
}
if(len > ATT_GetMTU(TxCCCD->connHandle)) {
return bleInvalidRange;
}

attHandleValueNoti_t noti = {
.handle = notiAttr.handle,
.len = len
};
noti.pValue = GATT_bm_alloc(TxCCCD->connHandle, ATT_HANDLE_VALUE_NOTI,
len, NULL, 0);
if (noti.pValue == NULL) {
return bleMemAllocError;
}

tmos_memcpy(noti.pValue, val, len);

bStatus_t ret = GATT_Notification(TxCCCD->connHandle, &noti, FALSE);
GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
if (ret != SUCCESS) {
PRINT("ble: noti sending failed\n");
return ret;
}

PRINT("ble: noti sent\n");
return SUCCESS;
}
Loading

0 comments on commit ec5e29f

Please sign in to comment.