#include "ble.h" #include "ble_pub.h" #include "ble_api.h" #include "common_bt.h" #include "comm_task.h" #include "comm.h" #include "gattc.h" #include "gattc_task.h" #include "prf.h" #include "application.h" #include "generic.h" #include #include "include.h" #include "driver_pub.h" #include "func_pub.h" #include "app.h" #include "start_type_pub.h" #include "mcu_ps_pub.h" #define ATT_DB_LENGTH 6 #define BK_ATT_DECL_PRIMARY_SERVICE_128 {0x00,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0} #define BK_ATT_DECL_CHARACTERISTIC_128 {0x03,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0} #define BK_ATT_DESC_CLIENT_CHAR_CFG_128 {0x02,0x29,0,0,0,0,0,0,0,0,0,0,0,0,0,0} #define WRITE_REQ_CHARACTERISTIC {0xD0,0x07,0x9B,0x5F,0x80,0x00, 0x01,0x80, 0x01,0x10, 0,0, 0x01,0,0,0} #define NOTIFY_CHARACTERISTIC {0xD0,0x07,0x9B,0x5F,0x80,0x00, 0x01,0x80, 0x01,0x10, 0,0, 0x02,0,0,0} typedef struct ble_cfg_st { struct bd_addr mac; char name[APP_DEVICE_NAME_LENGTH_MAX]; } BLE_CFG_ST, *BLE_CFG_PTR; uint32_t app_stack_size = 4096; uint32_t ext_init_stack_size = 2048; char canary[2] = { 'N', '\0' }; extern uint32_t _bootloader_world_flag; volatile uint32_t *bootloader_world_flag = &_bootloader_world_flag; extern BLE_CFG_ST ble_cfg; extern struct bd_addr common_default_bdaddr; static void update_thread (void *arg); extern struct prf_env_tag prf_env; extern uint8_t bk_ble_get_prf_by_task (kernel_task_id_t task, struct prf_task_env **env); static void notify_val (void); static void *pull_stubs (void); bk_attm_desc_t btl_att_db[ATT_DB_LENGTH] = { [0] = {BK_ATT_DECL_PRIMARY_SERVICE_128, BK_PERM_SET (RD, ENABLE), 0, 0}, [1] = {BK_ATT_DECL_CHARACTERISTIC_128, BK_PERM_SET (RD, ENABLE), 0, 0}, [2] = {WRITE_REQ_CHARACTERISTIC, BK_PERM_SET (WRITE_REQ, ENABLE) | BK_PERM_SET (WRITE_COMMAND, ENABLE), BK_PERM_SET (RI, ENABLE) | BK_PERM_SET (UUID_LEN, UUID_128), 256}, [3] = {BK_ATT_DECL_CHARACTERISTIC_128, BK_PERM_SET (RD, ENABLE), 0, 0}, [4] = {NOTIFY_CHARACTERISTIC, BK_PERM_SET (NTF, ENABLE), BK_PERM_SET (RI, ENABLE) | BK_PERM_SET (UUID_LEN, UUID_128), 256}, [5] = {BK_ATT_DESC_CLIENT_CHAR_CFG_128, BK_PERM_SET (RD, ENABLE) | BK_PERM_SET (WRITE_REQ, ENABLE), 0, 0}, }; beken_semaphore_t app_sema = NULL; beken_semaphore_t ext_init_sema = NULL; static void ble_event_callback (ble_event_t event, void *param) { switch (event) { case BLE_STACK_OK: bk_printf ("STACK INIT OK\r\n"); { struct bk_ble_db_cfg ble_db_cfg; ble_db_cfg.att_db = btl_att_db; ble_db_cfg.att_db_nb = ATT_DB_LENGTH; ble_db_cfg.prf_task_id = 0; ble_db_cfg.start_hdl = 0; ble_db_cfg.svc_perm = BK_PERM_SET (SVC_UUID_LEN, UUID_16); #if 0 memcpy (&(ble_db_cfg.uuid[0]), &custom_uuid[0], 16); #endif bk_ble_create_db (&ble_db_cfg); } break; case BLE_CREATE_DB_OK: bk_printf ("CREATE DB SUCCESS\r\n"); appm_start_advertising (); break; case BLE_CONNECT: bk_printf ("BLE CONNECT\r\n"); if (((struct gapc_connection_req_ind *) param)->sup_to < 200) { struct gapc_conn_param conn_param; conn_param.intv_max = ((struct gapc_connection_req_ind *) param)->con_interval; conn_param.intv_min = ((struct gapc_connection_req_ind *) param)->con_interval; conn_param.latency = ((struct gapc_connection_req_ind *) param)->con_latency; conn_param.time_out = 600; appm_update_param (&conn_param); } rtos_create_thread (NULL, THD_APPLICATION_PRIORITY, "update thread", (beken_thread_function_t) update_thread, ext_init_stack_size, (beken_thread_arg_t) 0); mcu_prevent_set (MCU_PS_BLE_FROBID); break; case BLE_MTU_CHANGE: bk_printf ("BLE_MTU_CHANGE:%d\r\n", *(unsigned short *) param); break; case BLE_DISCONNECT: bk_printf ("BLE DISCONNECTed\r\n"); break; case BLE_CFG_NOTIFY: bk_printf ("BLE_CFG_NOTIFY:%d\r\n", *(unsigned short *) param); break; case BLE_CFG_INDICATE: bk_printf ("BLE_CFG_INDICATE:%d\r\n", *(unsigned short *) param); break; case BLE_TX_DONE: bk_printf ("BLE_TX_DONE\r\n"); break; case BLE_GEN_DH_KEY: bk_printf ("BLE_GEN_DH_KEY\r\n"); break; case BLE_GET_KEY: bk_printf ("BLE_GET_KEY\r\n"); break; case BLE_STACK_FAIL: bk_printf ("STACK INIT FAIL\r\n"); break; case BLE_HW_ERROR: bk_printf ("BLE_HW_ERROR\r\n"); break; default: bk_printf ("UNKNOWN EVENT:%d\r\n", event); break; } } static void ble_write_callback (write_req_t * write_req) { bk_printf ("write req"); #if 0 tuya_ble_data_buf_t data; if (write_req->att_idx == 5) { ntf_enable = (write_req->value[0]) | (write_req->value[1] << 8); } else { data.data = write_req->value; data.len = write_req->len; if (ty_bt_msg_cb != NULL) { ty_bt_msg_cb (0, TY_BT_EVENT_RX_DATA, &data); } } #endif } static unsigned char ble_read_callback (read_req_t * read_req) { bk_printf ("read req"); #if 0 if (read_req->att_idx == 5) { memcpy (read_req->value, &ntf_enable, sizeof (ntf_enable)); } #endif return 2; } static void ble_recv_adv_callback (recv_adv_t * recv_adv) { } static void init_ble_thread (void *arg) { ble_set_event_cb (ble_event_callback); ble_set_write_cb (ble_write_callback); ble_set_read_cb (ble_read_callback); ble_set_recv_adv_cb (ble_recv_adv_callback); ble_clk_power_up (); ble_switch_rf_to_ble (); ble_init (); ble_activate ("TESTER"); uint8_t *mac = (uint8_t *) & ble_cfg.mac; bk_printf ("ble name:%s, %02x:%02x:%02x:%02x:%02x:%02x\r\n", &ble_cfg.name, mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]); rtos_delete_thread (NULL); } static void update_thread (void *arg) { while (1) { #if 0 notify_val (); #else bk_ble_send_ntf_value (5, (uint8_t *) "\x27\x18\x28\x18\x28", 0, 4); bk_printf ("BLE control[8]: 0x%x\n", *((volatile uint16_t *) 0x0081436e)); bk_printf ("Hop control[8]: 0x%x\n", *((volatile uint16_t *) 0x00814380)); bk_printf ("SYNCWL[8]: 0x%x\n", *((volatile uint16_t *) 0x814376)); #endif rtos_delay_milliseconds (3000); } } static void notify_val (void) { bk_printf ("."); struct gattc_send_evt_cmd *ntf_value = KERNEL_MSG_ALLOC_DYN (GATTC_SEND_EVT_CMD, KERNEL_BUILD_ID (TASK_GATTC, 0), prf_src_task_get (&(prf_env_t) { TASK_APP, TASK_ID_COMMON }, 0), gattc_send_evt_cmd, 5); ntf_value->operation = GATTC_NOTIFY; struct bk_ble_env_tag *ble_env = NULL; #if 0 struct prf_task_env *prf_env = NULL; bk_ble_get_prf_by_task (TASK_GAPC + 1, &prf_env); ble_env = (struct bk_ble_env_tag *) (prf_env->env); #else ble_env = (struct bk_ble_env_tag *) prf_env_get (TASK_ID_COMMON); #endif ntf_value->handle = ble_env->start_hdl + 4; ntf_value->length = 5; ntf_value->seq_num = 4; memcpy (&ntf_value->value[0], (uint8_t *) "\x31\x41\x59\x26\x53", 5); kernel_msg_send (ntf_value); } static void ext_init_task_handler (void *arg) { OSStatus ret; func_init_extended (); ret = rtos_set_semaphore (&ext_init_sema); ASSERT (kNoErr == ret); rtos_delete_thread (NULL); } void app_set_sema (void) { OSStatus ret; ret = rtos_set_semaphore (&app_sema); (void) ret; } __attribute__((noinline)) static void *pull_stubs (void) { int a = 0; extern uint32_t _vector_start; uint32_t *vecs = &_vector_start; extern uint8_t wifi_read_efuse (uint8_t addr); uint8_t ef = 0; ef = wifi_read_efuse (31); bk_printf ("start: %x, ef: %x, a: %d\n", *vecs, ef, a); #if 0 extern void rwble_hl_init_re (void); extern void rwble_reset_re (void); void *func_list[] = { rwble_hl_init_re, rwble_reset_re }; return func_list[!!ef]; #endif return NULL; } void entry_main (void) { OSStatus ret; canary[0] = 'm'; *bootloader_world_flag = 1; bk_misc_init_start_type (); driver_init (); bk_misc_check_start_type (); func_init_basic (); pull_stubs (); uint32_t my_stack = 0; __asm__ __volatile__ ("mov %0, sp":"=r" (my_stack)::); bk_printf ("current stack top: 0x%x\n", my_stack); int a = 0x7FFFFFFF; int b[3] = { 1, 2, 3 }; if (a + 2[b] >= 0) { bk_printf ("condition (%d >= 0) is true\n", a + 2[b]); } union u_t { uint32_t a; struct s_t { uint16_t b; uint16_t c; } d; } u; u.d = (struct s_t) { 0, 1 }; bk_printf ("value: 0x%x, system is %s endian\n", u.a, u.a == 1 ? "big" : "little"); #define IS_ARM() do{ \ uint32_t is_arm = 0; \ __asm__ __volatile__( \ "mov %0, pc\n" \ "mov r1, pc\n" \ "sub %0, r1, %0\n" \ "sub %0, #2\n" \ : "=r" (is_arm) :: "r1"); \ bk_printf("current state is %s\n", is_arm ? "ARM" : "Thumb"); \ } while(0) extern uint32_t is_arm (void); bk_printf ("is_arm() runs in %s state\n", is_arm ()? "ARM" : "Thumb"); IS_ARM (); ret = rtos_create_thread (NULL, THD_INIT_PRIORITY, "main", (beken_thread_function_t) init_ble_thread, app_stack_size, (beken_thread_arg_t) 0); ASSERT (kNoErr == ret); rtos_init_semaphore (&ext_init_sema, 1); ret = rtos_create_thread (NULL, THD_EXTENDED_APP_PRIORITY, "ext_init", (beken_thread_function_t) ext_init_task_handler, ext_init_stack_size, (beken_thread_arg_t) 0); ASSERT (kNoErr == ret); vTaskStartScheduler (); }