-
Notifications
You must be signed in to change notification settings - Fork 24
/
UartBleDemo.cpp
executable file
·413 lines (340 loc) · 13.7 KB
/
UartBleDemo.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
/**-------------------------------------------------------------------------
@example UartBleDemo.cpp
@brief Uart BLE demo
This application demo shows UART Rx/Tx over BLE custom service using EHAL library.
For evaluating power consumption of the UART, the button 1 is used to enable/disable it.
This example also demonstrates passkey paring mode.
@author Hoang Nguyen Hoan
@date Feb. 4, 2017
@license
Copyright (c) 2017, I-SYST inc., all rights reserved
Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies, and none of the
names : I-SYST or its contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.
For info or contributing contact : hnhoan at i-syst dot com
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------*/
#include "app_util_platform.h"
#include "app_scheduler.h"
#include "istddef.h"
#include "ble_app.h"
#include "ble_service.h"
#include "bluetooth/blueio_blesrvc.h"
#include "blueio_board.h"
#include "coredev/uart.h"
#include "custom_board.h"
#include "coredev/iopincfg.h"
#include "iopinctrl.h"
#include "board.h"
//#define HM_10
#define DEVICE_NAME "UARTDemo" /**< Name of device. Will be included in the advertising data. */
#define PACKET_SIZE 20
#define MANUFACTURER_NAME "I-SYST inc." /**< Manufacturer. Will be passed to Device Information Service. */
#ifdef NRF52
#define MODEL_NAME "IMM-NRF52x" /**< Model number. Will be passed to Device Information Service. */
#else
#define MODEL_NAME "IMM-NRF51x" /**< Model number. Will be passed to Device Information Service. */
#endif
#define MANUFACTURER_ID ISYST_BLUETOOTH_ID /**< Manufacturer ID, part of System ID. Will be passed to Device Information Service. */
#define ORG_UNIQUE_ID ISYST_BLUETOOTH_ID /**< Organizational Unique ID, part of System ID. Will be passed to Device Information Service. */
#define APP_ADV_INTERVAL MSEC_TO_UNITS(64, UNIT_0_625_MS) /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#if (NRF_SD_BLE_API_VERSION < 6)
#define APP_ADV_TIMEOUT 180 /**< The advertising timeout (in units of seconds). */
#else
#define APP_ADV_TIMEOUT MSEC_TO_UNITS(180000, UNIT_10_MS) /**< The advertising timeout (in units of 10ms seconds). */
#endif
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(10, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(40, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#ifdef NORDIC_NUS_SERVICE
#define BLE_UART_UUID_BASE NUS_BASE_UUID
#define BLE_UART_UUID_SERVICE BLE_UUID_NUS_SERVICE /**< The UUID of the Nordic UART Service. */
#define BLE_UART_UUID_TX_CHAR BLE_UUID_NUS_RX_CHARACTERISTIC /**< The UUID of the TX Characteristic. */
#define BLE_UART_UUID_RX_CHAR BLE_UUID_NUS_TX_CHARACTERISTIC /**< The UUID of the RX Characteristic. */
#elif defined(HM_10)
// 0000FFE0-0000-1000-8000-00805F9B34FB
#define BLE_UART_UUID_BASE { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, \
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
#define BLE_UART_UUID_SERVICE 0xFFE0 //!< HM-10 custom service
#define BLE_UART_UUID_RX_CHAR 0xFFE1 //!< HM-10 custom characteristic
#else
#define BLE_UART_UUID_BASE BLUEIO_UUID_BASE
#define BLE_UART_UUID_SERVICE BLUEIO_UUID_UART_SERVICE //!< BlueIO default service
#define BLE_UART_UUID_TX_CHAR BLUEIO_UUID_UART_TX_CHAR //!< Data characteristic
#define BLE_UART_UUID_RX_CHAR BLUEIO_UUID_UART_RX_CHAR //!< Command control characteristic
#endif
void UartTxSrvcCallback(BLESRVC *pBlueIOSvc, uint8_t *pData, int Offset, int Len);
static const ble_uuid_t s_AdvUuids[] = {
{BLE_UART_UUID_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN}
};
static const char s_RxCharDescString[] = {
"UART Rx characteristic",
};
static const char s_TxCharDescString[] = {
"UART Tx characteristic",
};
uint8_t g_ManData[8];
/// Characteristic definitions
BLESRVC_CHAR g_UartChars[] = {
{
// Read characteristic
.Uuid = BLE_UART_UUID_RX_CHAR,
.MaxDataLen = PACKET_SIZE,
.Property =
#ifdef HM_10
BLESVC_CHAR_PROP_WRITE |
#endif
BLESVC_CHAR_PROP_READ | BLESVC_CHAR_PROP_NOTIFY | BLESVC_CHAR_PROP_VARLEN,
.pDesc = s_RxCharDescString, // char UTF-8 description string
#ifdef HM_10
.WrCB = UartTxSrvcCallback,
#else
.WrCB = NULL, // Callback for write char, set to NULL for read char
#endif
.SetNotifCB = NULL, // Callback on set notification
.TxCompleteCB = NULL, // Tx completed callback
.pDefValue = NULL, // pointer to char default values
.ValueLen = 0, // Default value length in bytes
},
#ifndef HM_10
{
// Write characteristic
.Uuid = BLE_UART_UUID_TX_CHAR, // char UUID
.MaxDataLen = PACKET_SIZE, // char max data length
.Property = BLESVC_CHAR_PROP_WRITEWORESP,// char properties define by BLUEIOSVC_CHAR_PROP_...
.pDesc = s_TxCharDescString, // char UTF-8 description string
.WrCB = UartTxSrvcCallback, // Callback for write char, set to NULL for read char
.SetNotifCB = NULL, // Callback on set notification
.TxCompleteCB = NULL, // Tx completed callback
.pDefValue = NULL, // pointer to char default values
.ValueLen = 0 // Default value length in bytes
},
#endif
};
static const int s_BleUartNbChar = sizeof(g_UartChars) / sizeof(BLESRVC_CHAR);
uint8_t g_LWrBuffer[512];
/// Service definition
const BLESRVC_CFG s_UartSrvcCfg = {
.SecType = BLESRVC_SECTYPE_NONE, // Secure or Open service/char
.UuidBase = {BLE_UART_UUID_BASE,}, // Base UUID
1,
.UuidSvc = BLE_UART_UUID_SERVICE, // Service UUID
.NbChar = s_BleUartNbChar, // Total number of characteristics for the service
.pCharArray = g_UartChars, // Pointer a an array of characteristic
.pLongWrBuff = g_LWrBuffer, // pointer to user long write buffer
.LongWrBuffSize = sizeof(g_LWrBuffer), // long write buffer size
};
BLESRVC g_UartBleSrvc;
const BLEAPP_DEVDESC s_UartBleDevDesc = {
MODEL_NAME, // Model name
MANUFACTURER_NAME, // Manufacturer name
"123", // Serial number string
"0.0", // Firmware version string
"0.0", // Hardware version string
};
const BLEAPP_CFG s_BleAppCfg = {
#ifdef IMM_NRF51822
.ClkCfg = { NRF_CLOCK_LF_SRC_RC, 1, 1, 0},
#else
.ClkCfg = { NRF_CLOCK_LF_SRC_XTAL, 0, 0, NRF_CLOCK_LF_ACCURACY_20_PPM},
#endif
.CentLinkCount = 0, // Number of central link
.PeriLinkCount = 1, // Number of peripheral link
.AppMode = BLEAPP_MODE_APPSCHED, // Use scheduler
.pDevName = DEVICE_NAME, // Device name
.VendorID = ISYST_BLUETOOTH_ID, // PnP Bluetooth/USB vendor id
.ProductId = 1, // PnP Product ID
.ProductVer = 0, // Pnp prod version
.bEnDevInfoService = true, // Enable device information service (DIS)
.pDevDesc = &s_UartBleDevDesc,
.pAdvManData = g_ManData, // Manufacture specific data to advertise
.AdvManDataLen = sizeof(g_ManData), // Length of manufacture specific data
.pSrManData = NULL,
.SrManDataLen = 0,
.SecType = BLEAPP_SECTYPE_NONE,//BLEAPP_SECTYPE_STATICKEY_MITM,//BLEAPP_SECTYPE_NONE, // Secure connection type
.SecExchg = BLEAPP_SECEXCHG_NONE, // Security key exchange
.pAdvUuids = NULL, // Service uuids to advertise
.NbAdvUuid = 0, // Total number of uuids
.AdvInterval = APP_ADV_INTERVAL, // Advertising interval in msec
.AdvTimeout = APP_ADV_TIMEOUT, // Advertising timeout in sec
.AdvSlowInterval = 0, // Slow advertising interval, if > 0, fallback to
// slow interval on adv timeout and advertise until connected
.ConnIntervalMin = MIN_CONN_INTERVAL,
.ConnIntervalMax = MAX_CONN_INTERVAL,
.ConnLedPort = BLUEIO_CONNECT_LED_PORT,// Led port nuber
.ConnLedPin = BLUEIO_CONNECT_LED_PIN,// Led pin number
.TxPower = 0, // Tx power
.SDEvtHandler = NULL // RTOS Softdevice handler
};
int nRFUartEvthandler(UARTDEV *pDev, UART_EVT EvtId, uint8_t *pBuffer, int BufferLen);
#define UARTFIFOSIZE CFIFO_MEMSIZE(256)
static uint8_t s_UartRxFifo[UARTFIFOSIZE];
static uint8_t s_UartTxFifo[UARTFIFOSIZE];
/// UART pins definitions
static IOPINCFG s_UartPins[] = {
{UART_RX_PORT, UART_RX_PIN, UART_RX_PINOP, IOPINDIR_INPUT, IOPINRES_NONE, IOPINTYPE_NORMAL}, // RX
{UART_TX_PORT, UART_TX_PIN, UART_TX_PINOP, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL}, // TX
{UART_CTS_PORT, UART_CTS_PIN, UART_CTS_PINOP, IOPINDIR_INPUT, IOPINRES_NONE, IOPINTYPE_NORMAL}, // CTS
{UART_RTS_PORT, UART_RTS_PIN, UART_RTS_PINOP, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL}, // RTS
};
/// UART configuration
const UARTCFG g_UartCfg = {
.DevNo = 0, // Device number zero based
.pIOPinMap = s_UartPins, // UART assigned pins
.NbIOPins = sizeof(s_UartPins) / sizeof(IOPINCFG), // Total number of UART pins used
.Rate = 115200, // Baudrate
.DataBits = 8, // Data bits
.Parity = UART_PARITY_NONE, // Parity
.StopBits = 1, // Stop bit
.FlowControl = UART_FLWCTRL_NONE, // Flow control
.bIntMode = true, // Interrupt mode
.IntPrio = APP_IRQ_PRIORITY_LOW, // Interrupt priority
.EvtCallback = nRFUartEvthandler, // UART event handler
.bFifoBlocking = true, // Blocking FIFO
.RxMemSize = UARTFIFOSIZE,
.pRxMem = s_UartRxFifo,
.TxMemSize = UARTFIFOSIZE,
.pTxMem = s_UartTxFifo,
};
/// UART object instance
UART g_Uart;
static const IOPINCFG s_LedPins[] = {
{BLUEIO_LED_BLUE_PORT, BLUEIO_LED_BLUE_PIN, BLUEIO_LED_BLUE_PINOP, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL}, // LED1 (Blue)
{BLUEIO_LED_GREEN_PORT, BLUEIO_LED_GREEN_PIN, BLUEIO_LED_GREEN_PINOP, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},// LED2 (Green)
{BLUEIO_LED_RED_PORT, BLUEIO_LED_RED_PIN, BLUEIO_LED_RED_PINOP, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL}, // LED3 (Red)
};
static int s_NbLedPins = sizeof(s_LedPins) / sizeof(IOPINCFG);
static const IOPINCFG s_ButPins[] = {
{BUTTON1_PORT, BUTTON1_PIN, 0, IOPINDIR_INPUT, IOPINRES_PULLUP, IOPINTYPE_NORMAL},// Button 1
{BUTTON2_PORT, BUTTON2_PIN, 0, IOPINDIR_INPUT, IOPINRES_PULLUP, IOPINTYPE_NORMAL},// Button 2
};
static int s_NbButPins = sizeof(s_ButPins) / sizeof(IOPINCFG);
int g_DelayCnt = 0;
volatile bool g_bUartState = false;
void UartTxSrvcCallback(BLESRVC *pBlueIOSvc, uint8_t *pData, int Offset, int Len)
{
g_Uart.Tx(pData, Len);
}
void BlePeriphEvtUserHandler(ble_evt_t * p_ble_evt)
{
BleSrvcEvtHandler(&g_UartBleSrvc, p_ble_evt);
}
void BleAppInitUserServices()
{
uint32_t err_code;
err_code = BleSrvcInit(&g_UartBleSrvc, &s_UartSrvcCfg);
APP_ERROR_CHECK(err_code);
}
void ButEvent(int IntNo)
{
if (IntNo == 0)
{
if (g_bUartState == false)
{
g_Uart.Enable();
g_bUartState = true;
}
else
{
g_Uart.Disable();
g_bUartState = false;
}
}
}
void HardwareInit()
{
g_Uart.Init(g_UartCfg);
IOPinCfg(s_LedPins, s_NbLedPins);
IOPinSet(BLUEIO_LED_BLUE_PORT, BLUEIO_LED_BLUE_PIN);
IOPinSet(BLUEIO_LED_GREEN_PORT, BLUEIO_LED_GREEN_PIN);
IOPinSet(BLUEIO_LED_RED_PORT, BLUEIO_LED_RED_PIN);
IOPinCfg(s_ButPins, s_NbButPins);
IOPinEnableInterrupt(0, APP_IRQ_PRIORITY_LOW, s_ButPins[0].PortNo, s_ButPins[0].PinNo, IOPINSENSE_LOW_TRANSITION, ButEvent);
}
void BleAppInitUserData()
{
// Add passkey pairing
ble_opt_t opt;
opt.gap_opt.passkey.p_passkey = (uint8_t*)"123456";
uint32_t err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opt);
APP_ERROR_CHECK(err_code);
}
void UartRxChedHandler(void * p_event_data, uint16_t event_size)
{
static uint8_t buff[PACKET_SIZE];
static int bufflen = 0;
bool flush = false;
int l = g_Uart.Rx(&buff[bufflen], PACKET_SIZE - bufflen);
if (l > 0)
{
bufflen += l;
if (bufflen >= PACKET_SIZE)
{
flush = true;
}
}
else
{
if (bufflen > 0)
{
flush = true;
}
}
if (flush)
{
if (BleSrvcCharNotify(&g_UartBleSrvc, 0, buff, bufflen) == 0)
{
bufflen = 0;
}
app_sched_event_put(NULL, 0, UartRxChedHandler);
}
}
int nRFUartEvthandler(UARTDEV *pDev, UART_EVT EvtId, uint8_t *pBuffer, int BufferLen)
{
int cnt = 0;
uint8_t buff[20];
switch (EvtId)
{
case UART_EVT_RXTIMEOUT:
case UART_EVT_RXDATA:
app_sched_event_put(NULL, 0, UartRxChedHandler);
break;
case UART_EVT_TXREADY:
break;
case UART_EVT_LINESTATE:
break;
}
return cnt;
}
//
// Print a greeting message on standard output and exit.
//
// On embedded platforms this might require semi-hosting or similar.
//
// For example, for toolchains derived from GNU Tools for Embedded,
// to enable semi-hosting, the following was added to the linker:
//
// --specs=rdimon.specs -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group
//
// Adjust it for other toolchains.
//
int main()
{
HardwareInit();
g_Uart.printf("UART over BLE Demo\r\n");
//g_Uart.Disable();
BleAppInit((const BLEAPP_CFG *)&s_BleAppCfg, true);
BleAppRun();
return 0;
}