Skip to content

Commit a6c6229

Browse files
authored
Merge pull request #30 from kienvo/ble-init
feat: Bluetooth LE initial setup
2 parents 69b530c + 8274cab commit a6c6229

File tree

12 files changed

+5167
-3
lines changed

12 files changed

+5167
-3
lines changed

CH5xx_ble_firmware_library/BLE/CH58xBLE_LIB.h

+4,594
Large diffs are not rendered by default.
1.06 MB
Binary file not shown.

Makefile

+9-2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ src/main.c \
5353
src/leddrv.c \
5454
src/button.c \
5555
src/fb.c \
56+
src/ble/profile/legacy.c \
57+
src/ble/profile/devinfo.c \
58+
src/ble/setup.c \
59+
src/ble/peripheral.c \
5660

5761

5862
# ASM sources
@@ -95,7 +99,7 @@ C_INCLUDES = \
9599
-ICH5xx_ble_firmware_library/StdPeriphDriver/inc \
96100
-ICH5xx_ble_firmware_library/RVMSIS \
97101
-ICH5xx_ble_firmware_library/Core \
98-
-IUser
102+
-ICH5xx_ble_firmware_library/BLE \
99103

100104
# compile gcc flags
101105
ASFLAGS = $(MCU) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
@@ -118,7 +122,10 @@ CFLAGS += -MMD -MP
118122
LDSCRIPT = CH5xx_ble_firmware_library/Ld/Link.ld
119123

120124
# libraries
121-
LIBS = -lc -lm -lnosys ./CH5xx_ble_firmware_library/StdPeriphDriver/libISP583.a
125+
LIBS = -lc -lm -lnosys \
126+
./CH5xx_ble_firmware_library/StdPeriphDriver/libISP583.a \
127+
./CH5xx_ble_firmware_library/BLE/LIBCH58xBLE.a \
128+
122129
LIBDIR =
123130
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)
124131

src/ble/common.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* This file contain high-level data structures for differents BLE chip.
3+
*
4+
*/
5+
6+
#ifndef __BLE_H__
7+
#define __BLE_H__
8+
9+
#include <stdint.h>
10+
#include <stddef.h>
11+
12+
typedef struct {
13+
uint8_t *bytes;
14+
int size;
15+
} byte_t;
16+
17+
typedef struct {
18+
byte_t val; // Values
19+
uint8_t props; // Properties //TODO: add enum
20+
byte_t uuid;
21+
} ble_char_t;
22+
23+
#endif /* __BLE_H__ */

src/ble/peripheral.c

+246
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
#include "CH58xBLE_LIB.h"
2+
#include "setup.h"
3+
4+
#define ADV_UUID (0xFEE0)
5+
6+
static uint8 taskid = INVALID_TASK_ID;
7+
8+
typedef struct
9+
{
10+
uint16 connHandle; // Connection handle of current connection
11+
uint16 connInterval;
12+
uint16 connSlaveLatency;
13+
uint16 connTimeout;
14+
} peripheralConnItem_t;
15+
16+
#define SBP_PARAM_UPDATE_DELAY 1600 // Parameter update delay (unit of 0.625ms)
17+
#define SLAVE_LATENCY 0
18+
19+
#define MIN_ADV_INTERVAL 100 // Advertising interval (units of 0.625ms)
20+
#define MAX_ADV_INTERVAL 200 // Advertising interval (units of 0.625ms)
21+
22+
#define MIN_CONN_INTERVAL 20 // Connection interval (units of 1.25ms)
23+
#define MAX_CONN_INTERVAL 100 // Connection interval (units of 1.25ms)
24+
25+
#define CONN_TIMEOUT 100 // Supervision timeout (units of 10ms)
26+
27+
// GAP - SCAN RSP data (max size = 31 bytes)
28+
static uint8 scanRspData[] = {
29+
// complete name
30+
16, // length of this section
31+
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
32+
'L', 'E','D', ' ',
33+
'B', 'a','d', 'g', 'e', ' ',
34+
'M', 'a','g', 'i', 'c',
35+
36+
// connection interval range
37+
0x05, // length of this section
38+
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
39+
LO_UINT16(MIN_CONN_INTERVAL),
40+
HI_UINT16(MIN_CONN_INTERVAL),
41+
LO_UINT16(MAX_CONN_INTERVAL),
42+
HI_UINT16(MAX_CONN_INTERVAL),
43+
44+
// Tx power level
45+
0x02, // length of this data
46+
GAP_ADTYPE_POWER_LEVEL,
47+
9 // 9dBm
48+
};
49+
50+
// GAP - Advertisement data (max size = 31 bytes)
51+
// keep short, save energy, save the planet
52+
static uint8 advertData[] = {
53+
0x02, // section length
54+
GAP_ADTYPE_FLAGS,
55+
GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
56+
57+
// advertise UUID
58+
0x03, // section length
59+
GAP_ADTYPE_16BIT_MORE,
60+
LO_UINT16(ADV_UUID),
61+
HI_UINT16(ADV_UUID)
62+
};
63+
64+
// GAP GATT Attributes
65+
static uint8 devName[GAP_DEVICE_NAME_LEN] = "LED Badge Magic";
66+
67+
// Connection item list
68+
static peripheralConnItem_t conn_list;
69+
70+
static void initConn(peripheralConnItem_t *conn)
71+
{
72+
conn->connHandle = GAP_CONNHANDLE_INIT;
73+
conn->connInterval = 0;
74+
conn->connSlaveLatency = 0;
75+
conn->connTimeout = 0;
76+
}
77+
78+
static void processTMOSMsg(tmos_event_hdr_t *pMsg)
79+
{
80+
switch(pMsg->event) {
81+
default:
82+
break;
83+
}
84+
}
85+
86+
static void enable_advertising(uint8_t enable)
87+
{
88+
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &enable);
89+
}
90+
91+
static void link_onEstablished(gapRoleEvent_t *pe)
92+
{
93+
gapEstLinkReqEvent_t *e = (gapEstLinkReqEvent_t *)pe;
94+
95+
// If already connected
96+
if(conn_list.connHandle != GAP_CONNHANDLE_INIT) {
97+
// Only allow 1 connection, so the new connection will be dropped:
98+
GAPRole_TerminateLink(e->connectionHandle);
99+
GAPRole_PeripheralConnParamUpdateReq(e->connectionHandle,
100+
MIN_CONN_INTERVAL,
101+
MAX_CONN_INTERVAL,
102+
SLAVE_LATENCY,
103+
CONN_TIMEOUT,
104+
taskid);
105+
return;
106+
}
107+
conn_list.connHandle = e->connectionHandle;
108+
conn_list.connInterval = e->connInterval;
109+
conn_list.connSlaveLatency = e->connLatency;
110+
conn_list.connTimeout = e->connTimeout;
111+
enable_advertising(FALSE);
112+
}
113+
114+
static void link_onTerminated(gapRoleEvent_t *pe)
115+
{
116+
gapTerminateLinkEvent_t *event = (gapTerminateLinkEvent_t *)pe;
117+
GAPRole_TerminateLink(pe->linkCmpl.connectionHandle);
118+
enable_advertising(TRUE);
119+
120+
if(event->connectionHandle == conn_list.connHandle) {
121+
conn_list.connHandle = GAP_CONNHANDLE_INIT;
122+
conn_list.connInterval = 0;
123+
conn_list.connSlaveLatency = 0;
124+
conn_list.connTimeout = 0;
125+
} else {
126+
// Requested connection is not existed in connection list
127+
}
128+
}
129+
130+
static void gap_onParamUpdate(uint16 connHandle, uint16 connInterval,
131+
uint16 connSlaveLatency, uint16 connTimeout)
132+
{
133+
conn_list.connHandle = connHandle;
134+
conn_list.connInterval = connInterval;
135+
conn_list.connSlaveLatency = connSlaveLatency;
136+
conn_list.connTimeout = connTimeout;
137+
}
138+
139+
static void gap_onStateChange(gapRole_States_t newState, gapRoleEvent_t *pEvent)
140+
{
141+
switch(newState & GAPROLE_STATE_ADV_MASK) {
142+
case GAPROLE_ADVERTISING:
143+
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT) {
144+
link_onTerminated(pEvent);
145+
}
146+
break;
147+
148+
case GAPROLE_CONNECTED:
149+
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT) {
150+
link_onEstablished(pEvent);
151+
}
152+
break;
153+
154+
case GAPROLE_WAITING:
155+
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT) {
156+
link_onTerminated(pEvent);
157+
} else {
158+
// refer to pEvent->gap.opcode
159+
}
160+
break;
161+
162+
default:
163+
break;
164+
}
165+
}
166+
167+
// GAP Role Callbacks
168+
static gapRolesCBs_t gap_handlers = {
169+
gap_onStateChange,
170+
NULL,
171+
gap_onParamUpdate
172+
};
173+
174+
// Broadcast Callbacks
175+
static gapRolesBroadcasterCBs_t broadcast_handlers = {
176+
NULL,
177+
NULL
178+
};
179+
180+
// GAP Bond Manager Callbacks
181+
static gapBondCBs_t bond_managers = {
182+
NULL,
183+
NULL
184+
};
185+
186+
187+
static uint16 peripheral_task(uint8 task_id, uint16 events)
188+
{
189+
if(events & SYS_EVENT_MSG) { // Handle BLE stack message
190+
uint8 *pMsg = tmos_msg_receive(taskid);
191+
if(pMsg) {
192+
processTMOSMsg((tmos_event_hdr_t *)pMsg);
193+
tmos_msg_deallocate(pMsg);
194+
}
195+
return (events ^ SYS_EVENT_MSG);
196+
}
197+
198+
return 0;
199+
}
200+
201+
static void gap_init()
202+
{
203+
GAPRole_PeripheralInit();
204+
205+
static uint8 initial_advertising_enable = TRUE;
206+
static uint16 desired_min_interval = 6;
207+
static uint16 desired_max_interval = 500;
208+
209+
// Set the GAP Role Parameters
210+
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &initial_advertising_enable);
211+
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
212+
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
213+
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16), &desired_min_interval);
214+
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16), &desired_max_interval);
215+
216+
// Set the GAP Characteristics
217+
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, devName);
218+
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, MIN_ADV_INTERVAL);
219+
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, MAX_ADV_INTERVAL);
220+
221+
static uint32 passkey = 0; // passkey "000000"
222+
static uint8 pairMode = GAPBOND_PAIRING_MODE_NO_PAIRING;
223+
static uint8 mitm = FALSE;
224+
static uint8 bonding = FALSE;
225+
static uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
226+
GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32), &passkey);
227+
GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8), &pairMode);
228+
GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8), &mitm);
229+
GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8), &ioCap);
230+
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8), &bonding);
231+
232+
GAPRole_BroadcasterSetCB(&broadcast_handlers);
233+
234+
GGS_AddService(GATT_ALL_SERVICES);
235+
GATTServApp_AddService(GATT_ALL_SERVICES);
236+
}
237+
238+
void peripheral_init()
239+
{
240+
taskid = TMOS_ProcessEventRegister(peripheral_task);
241+
242+
initConn(&conn_list);
243+
gap_init();
244+
245+
GAPRole_PeripheralStartDevice(taskid, &bond_managers, &gap_handlers);
246+
}

src/ble/profile.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef __BLE_UART_SERVICE_H__
2+
#define __BLE_UART_SERVICE_H__
3+
4+
int legacy_registerService();
5+
int devInfo_registerService();
6+
7+
#endif /* __BLE_UART_SERVICE_H__ */

0 commit comments

Comments
 (0)