1 /*****************************************************************************
2 * Copyright (c) 2019, Nations Technologies Inc.
3 *
4 * All rights reserved.
5 * ****************************************************************************
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the disclaimer below.
12 *
13 * Nations' name may not be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
19 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * ****************************************************************************/
27
28 /**
29 * @file Interface.c
30 * @author Nations
31 * @version v1.0.2
32 *
33 * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
34 */
35
36 #include <stdint.h>
37 #include "Interface.h"
38 #include "rwip.h"
39 #include "Ramcode.h"
40 #include "gapm_task.h"
41 #include "app.h"
42 #include "stdlib.h"
43 #include "string.h"
44 #include "stdlib.h"
45 #include "app_user.h"
46 #include "Eif_uart.h"
47 #include "ke_event.h"
48 #include "Eif_flash.h"
49 #include "Eif_timer.h"
50 #include "Eif_spi.h"
51 #include "Eif_iom.h"
52 #include "log.h"
53
54 #ifdef N32WB452_BT_API
55 #include "n32wb452_data_fifo.h"
56 #include "n32wb452_ble_api.h"
57 #include "n32wb452_log_level.h"
58
59
60 extern uint32_t g_bt_start_finished_flag;
61 extern bt_attr_param * g_bt_init;
62
63 #endif
64
65 #define RAMCODE_CMD 0xBB
66 #define PATCH_CMD 0xCC
67 #define NVDS_CMD 0xDD
68 #define SINGLE_CMD_SIZE 0xFA
69
70 uint8_t read_state_flag = READ_STATE_RX_START;
data_read_state_handle(uint8_t read_state_value)71 void data_read_state_handle(uint8_t read_state_value)
72 {
73 read_state_flag = read_state_value;
74 }
75
76
77 const struct rwip_eif_api spi_eif_api =
78 {
79 eif_spi_read,
80 eif_spi_write,
81 eif_spi_flow_on,
82 eif_spi_flow_off,
83 };
84
85
rwip_eif_get(uint8_t type)86 const struct rwip_eif_api *rwip_eif_get(uint8_t type)
87 {
88 /*harry would add */
89 const struct rwip_eif_api *ret = NULL;
90 switch (type)
91 {
92 case RWIP_EIF_AHI:
93 //ret = &uart_eif_api;
94 break;
95 case RWIP_EIF_HCIH:
96 ret = &spi_eif_api;
97 break;
98
99 default:
100 ASSERT_INFO(0, type, 0);
101 break;
102 }
103 return ret;
104 }
105
106
wait_for_status_enable(void)107 bool wait_for_status_enable(void)
108 {
109 #if 0
110 while (!eif_get_status_io_value());
111 eif_delay_us(500); //根据时钟频率设置为延时100us
112 while (!eif_get_status_io_value());
113 return 1;
114 #else
115 uint16_t cnt = 25000;
116 while (cnt--)
117 {
118 if (eif_get_status_io_value() == 1)
119 {
120 return 1;
121 }
122 eif_delay_us(50);
123 }
124
125 return 0;
126 #endif
127 }
128
eif_delay_us(uint32_t Cnt)129 void eif_delay_us(uint32_t Cnt)
130 {
131 while (Cnt--)
132 for(uint16_t m = 0; m < 28; m++);
133 }
134
eif_delay_ms(uint32_t Cnt)135 void eif_delay_ms(uint32_t Cnt)
136 {
137 while (Cnt--)
138 {
139 eif_delay_us(999);
140 }
141 }
142
143 #ifdef N32WB452_BT_API
IsAscii(uint8_t ch)144 int32_t IsAscii(uint8_t ch)
145 {
146 if ((ch >= 0x20) && (ch <= 0x7E)) /*ASCII*/
147 {
148 return E_OK;
149 }
150 else
151 {
152 return E_PAR;
153 }
154 }
155 #endif
156
157
158 extern struct app_env_tag app_env;
bt_features_init(void)159 void bt_features_init(void)
160 {
161 #ifdef N32WB452_BT_API
162 uint32_t size;
163 uint32_t name_len = 0;
164 uint32_t i;
165 uint8_t addr[BD_ADDR_LEN], ch1, ch2;
166 uint8_t device_name[32] = {0};
167 uint8_t *ptmp = "12:34:56:AB:CD:EF";
168 #endif
169
170 app_env.adv_para.adv_type = GAPM_ADV_UNDIRECT; // GAP OPCODE direct ,no connect undirect
171 app_env.adv_para.channel_map = 0x7; // BTstack_data.user_config.adv_para.channel_map;//
172 app_env.adv_para.adv_int_min = 0x320; //广播间隔时间最小值:0.5S = 0x320*0.625 ms
173 app_env.adv_para.adv_int_max = 0x320; //广播间隔时间最大值:0.5S = 0x320*0.625 ms
174 app_env.adv_para.discover_mode = GAP_GEN_DISCOVERABLE;
175
176 #ifdef N32WB452_BT_API
177 if (g_bt_init) {
178 size = sizeof(g_bt_init->device_name);
179 for (i = 0; i < size; i++) {
180 if (E_OK == IsAscii(g_bt_init->device_name[i])) {
181 device_name[name_len] = g_bt_init->device_name[i];
182 name_len++;
183 }
184 }
185 if (name_len >= 3) {//必须2个字符以上
186 //fill name in addr data
187 app_env.adv_data_buf[app_env.adv_data_len++] = name_len + 1; // length
188 app_env.adv_data_buf[app_env.adv_data_len++] = 0x08; // device name tag
189 memcpy( &app_env.adv_data_buf[app_env.adv_data_len], device_name, name_len);
190 app_env.adv_data_len += name_len;
191 memcpy(app_env.dev_name, device_name, name_len);
192 ble_log(BLE_DEBUG,"device_name:%0s.\r\n", device_name);
193 } else {
194 uint8_t dev_name[31] = {'N','Z','_','B','L','E'};
195 uint8_t dev_name_len = 6;
196 //fill name in addr data
197 app_env.adv_data_buf[app_env.adv_data_len++] = dev_name_len + 1; // length
198 app_env.adv_data_buf[app_env.adv_data_len++] = 0x08; // device name tag
199 memcpy( &app_env.adv_data_buf[app_env.adv_data_len], dev_name, dev_name_len);
200 app_env.adv_data_len += dev_name_len;
201 memcpy(app_env.dev_name, device_name, name_len);
202 }
203 } else {
204 uint8_t dev_name[31] = {'N','Z','_','B','L','E'};
205 uint8_t dev_name_len = 6;
206 //fill name in addr data
207 app_env.adv_data_buf[app_env.adv_data_len++] = dev_name_len + 1; // length
208 app_env.adv_data_buf[app_env.adv_data_len++] = 0x08; // device name tag
209 memcpy( &app_env.adv_data_buf[app_env.adv_data_len], dev_name, dev_name_len);
210 app_env.adv_data_len += dev_name_len;
211 memcpy(app_env.dev_name, device_name, name_len);
212 }
213 #else
214 uint8_t dev_name[31] = {'N','S','_','B','L','E'};
215 uint8_t dev_name_len = 6;
216 //fill name in addr data
217 app_env.adv_data_buf[app_env.adv_data_len++] = dev_name_len + 1; // length
218 app_env.adv_data_buf[app_env.adv_data_len++] = 0x08; // device name tag
219 memcpy( &app_env.adv_data_buf[app_env.adv_data_len], dev_name, dev_name_len);
220 app_env.adv_data_len += dev_name_len;
221 memcpy(app_env.dev_name, device_name, name_len);
222 #endif
223
224 #ifdef N32WB452_BT_API
225 if (g_bt_init) {
226 memcpy(app_env.scan_rsp_data_buf, g_bt_init->scan_rsp_data, g_bt_init->scan_rsp_data_len);
227 app_env.scan_rsp_data_buf[g_bt_init->scan_rsp_data_len] = 0x00;//最后一个设置为0
228 app_env.scan_rsp_data_len = g_bt_init->scan_rsp_data_len;
229 } else {
230 uint8_t scan_rsp_data[31] = "\x09\xFF\x60\x52\x57\x2D\x42\x4C\x45\0x00";
231 memcpy(app_env.scan_rsp_data_buf, scan_rsp_data, 10);
232 app_env.scan_rsp_data_len = 10;
233 }
234 #endif
235 app_env.pairing_mode = GAPM_PAIRING_DISABLE/*GAPM_PAIRING_LEGACY*/;
236 app_env.iocap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
237
238 #ifdef N32WB452_BT_API
239 if (g_bt_init) {
240 //地址为十六进制如12:34:56:AB:CD:EF
241 size = MIN(strlen((const char *)ptmp), sizeof(g_bt_init->device_addr));
242 for (i = 0; i < size;) {
243 if ((g_bt_init->device_addr[i + 0] && (g_bt_init->device_addr[i + 0] >= '0') && (g_bt_init->device_addr[i + 0] <= '9'))) {
244 ch1 = g_bt_init->device_addr[i + 0] - '0';
245 } else if ((g_bt_init->device_addr[i + 0] && (g_bt_init->device_addr[i + 0] >= 'a') && (g_bt_init->device_addr[i + 0] <= 'f'))) {
246 ch1 = g_bt_init->device_addr[i + 0] - 'a' + 10;
247 } else if ((g_bt_init->device_addr[i + 0] && (g_bt_init->device_addr[i + 0] >= 'A') && (g_bt_init->device_addr[i + 0] <= 'F'))) {
248 ch1 = g_bt_init->device_addr[i + 0] - 'A' + 10;
249 } else {
250 ble_log(BLE_DEBUG,"***err1,addr[%d] = %c.\r\n", i + 0, g_bt_init->device_addr[i + 0]);
251 break;
252 }
253
254 if ((g_bt_init->device_addr[i + 1] && (g_bt_init->device_addr[i + 1] >= '0') && (g_bt_init->device_addr[i + 1] <= '9'))) {
255 ch2 = g_bt_init->device_addr[i + 1] - '0';
256 } else if ((g_bt_init->device_addr[i + 1] && (g_bt_init->device_addr[i + 1] >= 'a') && (g_bt_init->device_addr[i + 1] <= 'f'))) {
257 ch2 = g_bt_init->device_addr[i + 1] - 'a' + 10;
258 } else if ((g_bt_init->device_addr[i + 1] && (g_bt_init->device_addr[i + 1] >= 'A') && (g_bt_init->device_addr[i + 1] <= 'F'))) {
259 ch2 = g_bt_init->device_addr[i + 1] - 'A' + 10;
260 } else {
261 ble_log(BLE_DEBUG,"***err2,addr[%d] = %c.\r\n", i + 1, g_bt_init->device_addr[i + 1]);
262 break;
263 }
264
265 if ((i + 2) < strlen((const char *)ptmp)) {
266 if ((g_bt_init->device_addr[i + 2]) && (g_bt_init->device_addr[i + 2] == ':')) {
267 //nothint to do
268 } else {
269 ble_log(BLE_DEBUG,"***err3,addr[%d] = %c.\r\n", i + 2, g_bt_init->device_addr[i + 2]);
270 break;
271 }
272 }
273
274 addr[i / 3] = ch1 * 16 + ch2;
275 ble_log(BLE_DEBUG,"addr[%d]:%0x.\r\n", i / 3, addr[i / 3]);
276 i += 3;
277 }
278 if (i >= size) {
279 app_env.bdaddr.addr[0] = addr[5];
280 app_env.bdaddr.addr[1] = addr[4];
281 app_env.bdaddr.addr[2] = addr[3];
282 app_env.bdaddr.addr[3] = addr[2];
283 app_env.bdaddr.addr[4] = addr[1];
284 app_env.bdaddr.addr[5] = addr[0];
285
286 ble_log(BLE_DEBUG,"addr set ok\r\n");
287 } else {
288 uint8_t bd_addr[6] = "\x21\x22\x22\x22\x22\x12";
289 memcpy(app_env.bdaddr.addr, bd_addr, 6);
290 }
291 } else {
292 uint8_t bd_addr[6] = "\x21\x22\x22\x22\x22\x12";
293 memcpy(app_env.bdaddr.addr, bd_addr, 6);
294 }
295 #else
296 uint8_t bd_addr[6] = "\x21\x22\x22\x22\x22\x12";
297 memcpy(app_env.bdaddr.addr, bd_addr, 6);
298 #endif
299
300 #ifdef BLE_OTA_WRITE_CHAR_EN
301 //在广播中增加manufacture数据
302 app_env.adv_data_buf[app_env.adv_data_len++] = 3+sizeof(app_env.bdaddr.addr); // device name tag
303 app_env.adv_data_buf[app_env.adv_data_len++] = 0xff; // device name tag
304 app_env.adv_data_buf[app_env.adv_data_len++] = 0x56; // device name tag
305 app_env.adv_data_buf[app_env.adv_data_len++] = 0x00; // device name tag
306 memcpy(&app_env.adv_data_buf[app_env.adv_data_len], app_env.bdaddr.addr, sizeof(app_env.bdaddr.addr));
307 app_env.adv_data_len += sizeof(app_env.bdaddr.addr);
308
309 //在广播中增加服务ID数据
310 uint8_t service_uuid_len = sizeof(g_bt_init->service[0].svc_uuid);
311 app_env.adv_data_buf[app_env.adv_data_len++] = service_uuid_len + 1; // length
312 app_env.adv_data_buf[app_env.adv_data_len++] = 0x03; // service uuid tag
313 memcpy(&app_env.adv_data_buf[app_env.adv_data_len], (uint8_t *)&g_bt_init->service[0].svc_uuid, service_uuid_len);
314 app_env.adv_data_len += service_uuid_len;
315 #endif
316
317 app_env.bdaddr_type = 0;
318
319 app_env.batt_lvl = 100; // device battery level
320
321 #ifdef N32WB452_BT_API
322 g_bt_start_finished_flag = 1;
323 #endif
324 }
325
send_vendor_array(uint8_t cmd_type,const uint8_t * byte_array,uint16_t size,uint16_t crc)326 int32_t send_vendor_array(uint8_t cmd_type, const uint8_t * byte_array, uint16_t size, uint16_t crc)
327 {
328 uint8_t recv_event[5];
329 uint8_t length_cmd[6] = { 0x01, 0xBB, 0xF1, 0x02, 0x00, 0x00 };
330 length_cmd[1] = cmd_type;
331 length_cmd[4] = size % 0x100;
332 length_cmd[5] = size / 0x100;
333 int32_t ret;
334 //增加SPI发送和接收
335 // eif_uart_send_bytes(length_cmd, 6);
336 // eif_uart_recv_bytes(recv_event,5);
337 eif_spi_send_bytes(length_cmd, 6);
338
339 ret = eif_spi_recv_bytes(recv_event,5);
340 if (ret == E_WAIT) {
341 ble_log(BLE_DEBUG,"send_vendor_array-wait1.\r\n");
342 return ret;
343 }
344 else if ((recv_event[0] !=0x04) || (recv_event[4] !=0x00))
345 {
346 ASSERT_ERR(0);
347 ble_log(BLE_DEBUG,"send_vendor_array-errdata1.\r\n");
348 return E_ERRDATA;
349 }
350
351 uint16_t left_data_length = 0;
352 uint8_t data_cmd[256] = { 0x01, 0xBB, 0xF2 };
353 data_cmd[1] = cmd_type;
354 for(int i = 0; i*SINGLE_CMD_SIZE < size; i++ )
355 {
356 left_data_length = size - SINGLE_CMD_SIZE*i;
357 if (left_data_length >= SINGLE_CMD_SIZE)
358 {
359 data_cmd[3] = SINGLE_CMD_SIZE;
360 memcpy(&data_cmd[4], &byte_array[SINGLE_CMD_SIZE*i], SINGLE_CMD_SIZE);
361 //eif_uart_send_bytes(data_cmd, SINGLE_CMD_SIZE+4);
362 eif_spi_send_bytes(data_cmd, SINGLE_CMD_SIZE+4);
363 }
364 else
365 {
366 data_cmd[3] = left_data_length;
367 memcpy(&data_cmd[4], &byte_array[size - left_data_length], left_data_length);
368 // eif_uart_send_bytes(data_cmd, left_data_length+4);
369 eif_spi_send_bytes(data_cmd, left_data_length+4);
370 }
371 // eif_uart_recv_bytes(recv_event, 5);
372 ret = eif_spi_recv_bytes(recv_event, 5);
373 if (ret == E_WAIT) {
374 ble_log(BLE_DEBUG,"send_vendor_array-wait2.\r\n");
375 return ret;
376 }
377 else if ((recv_event[0] !=0x04) || (recv_event[4] !=0x00))
378 {
379 ASSERT_ERR(0);
380 ble_log(BLE_DEBUG,"send_vendor_array-errdata2.\r\n");
381 return E_ERRDATA;
382 }
383 }
384
385 uint8_t crc_cmd[6] = { 0x01, 0xBB, 0xF3, 0x02, 0x00, 0x00 };
386 crc_cmd[1] = cmd_type;
387 crc_cmd[4] = crc % 0x100;
388 crc_cmd[5] = crc / 0x100;
389
390 // eif_uart_send_bytes(crc_cmd, 6);
391 // eif_uart_recv_bytes(recv_event, 5);
392 eif_spi_send_bytes(crc_cmd, 6);
393 ret = eif_spi_recv_bytes(recv_event, 5);
394 if (ret == E_WAIT) {
395 ble_log(BLE_DEBUG,"send_vendor_array-wait3.\r\n");
396 return ret;
397 }
398 else if (recv_event[0] !=0x04 || recv_event[4] !=0x00)
399 {
400 ASSERT_ERR(0);
401 ble_log(BLE_DEBUG,"send_vendor_array-errdata3.\r\n");
402 return E_ERRDATA;
403 }
404
405 return E_OK;
406 }
407
408
409
send_vendor_bypass_command()410 int32_t send_vendor_bypass_command()
411 {
412 int32_t ret;
413 uint8_t passby[6] = { 0x01, 0xEE, 0xf1, 0x02, 0x00, 0x00 };
414 //eif_uart_send_bytes(passby, 6);
415 eif_spi_send_bytes(passby, 6);
416
417 uint8_t recv_event[5];
418 // eif_uart_recv_bytes(recv_event, 5);
419 ret = eif_spi_recv_bytes(recv_event,5);
420 if (ret == E_WAIT) {
421 ble_log(BLE_DEBUG,"send_vendor_bypass_command-wait1.\r\n");
422 return ret;
423 }
424 else if (recv_event[0] !=0x04 || recv_event[4] !=0x00)
425 {
426 ASSERT_ERR(0);
427 ble_log(BLE_DEBUG,"send_vendor_bypass_command-errdata1.\r\n");
428 return E_ERRDATA;
429 }
430
431 return E_OK;
432 }
433
434
435
436
eif_reset_ble_core(void)437 void eif_reset_ble_core(void)
438 {
439 eif_delay_ms(20);
440 eif_pull_down_reset_io();
441 //eif_delay_ms(20);
442 eif_delay_ms(50);
443 eif_pull_up_reset_io();
444 //eif_delay_ms(10);
445 eif_delay_ms(50);
446 }
447
448
449 ///Z32HUB system init and timer driver
450 static const struct interface_sys_tag interface_sys_api =
451 {
452 //timer handle
453 eif_set_timeout,
454 eif_get_time,
455 eif_enable_timer,
456
457 //flash handle
458 eif_flash_init,
459 eif_flash_erase,
460 eif_flash_write,
461 eif_flash_read,
462
463 //init bt feature
464 bt_features_init,
465 };
466
467 struct interface_sys_tag interface_sys;
468
469
ble_interface_init(void)470 int32_t ble_interface_init(void)
471 {
472 interface_sys = interface_sys_api;
473
474 return E_OK;
475 }
476
477 extern void eif_spi_init(void);
ble_hardware_init(void)478 int32_t ble_hardware_init(void)
479 {
480 eif_spi_recv_irq_enable(0);
481 eif_gpio_init(); //io init
482 eif_timer_init();
483 eif_spi_init();
484 eif_reset_ble_core();
485 return E_OK;
486 }
487
ble_hardware_reinit(void)488 int32_t ble_hardware_reinit(void)
489 {
490 ble_interface_init();
491 eif_gpio_ReInit();
492 eif_spi_init();
493 eif_timer_init();
494 return E_OK;
495 }
496
497
ble_init_check(void)498 int32_t ble_init_check(void)
499 {
500 uint8_t length_cmd[6] = { 0x01, 0xBB, 0xF1, 0x02, 0x00, 0x00 };
501 length_cmd[1] = RAMCODE_CMD;
502 length_cmd[4] = CopyArrayLength % 0x100;
503 length_cmd[5] = CopyArrayLength / 0x100;
504 volatile uint32_t i;
505 uint32_t tmp;
506
507 while (1) {
508 //delay
509 eif_delay_ms(100);
510
511 eif_spi_send_bytes(length_cmd, 6);
512
513 for (i = 0; i < 30000; i++) {
514 if (eif_spi_ack_event_check() == E_OK) {
515 break;
516 }
517
518 if ((i > 0) && ((i % 10000) == 0)) {
519 tmp = 100 + i / 10;
520 ble_log(BLE_DEBUG,"reset continue[%d],dly-time[%d].\r\n", i, tmp);
521 eif_reset_ble_core();
522 eif_delay_ms(tmp);
523 eif_spi_send_bytes(length_cmd, 6);
524 }
525 }
526
527 if (i < 10000) {
528 ble_log(BLE_DEBUG,"ble_init_check-ok[%d].\r\n", i);
529 break;
530 } else {
531 ble_log(BLE_DEBUG,"eif_reset_ble_core-again.\r\n");
532 eif_reset_ble_core();
533 }
534 }
535
536 return E_OK;
537 }
538
539
ble_initdata_down(void)540 int32_t ble_initdata_down(void)
541 {
542 send_vendor_array(RAMCODE_CMD, CopyArray, CopyArrayLength, CopyCrcValue);
543 send_vendor_bypass_command();
544 send_vendor_array(RAMCODE_CMD, RamcodeArray, RamcodeArrayLength, RamcodeCrcValue);
545 send_vendor_array(PATCH_CMD, PatchArray, PatchArrayLength, PatchCrcValue);
546 send_vendor_array(NVDS_CMD, NvdsArray, NvdsArrayLength, NvdsCrcValue);
547 send_vendor_bypass_command();
548 return E_OK;
549 }
550
551
ble_host_init(void)552 int32_t ble_host_init(void)
553 {
554 //eif_uart_init(500000);
555 //eif_uart_recv_irq_enable(1);
556 eif_spi_recv_irq_enable(1);
557 BT_init();
558 appm_init();
559
560 return E_OK;
561 }
562
ble_system_Init(void)563 void ble_system_Init(void)
564 {
565 ble_interface_init();
566 ble_hardware_init();
567 ble_initdata_down();
568 ble_host_init();
569 }
570
571
572