#include "ble.h" #include "ble_api.h" #include "ble_pub.h" #include "comm.h" #include "comm_task.h" #include "common_bt.h" #include "gattc.h" #include "gattc_task.h" #include "prf.h" #include "application.h" #include "generic.h" #include #include "app.h" #include "driver_pub.h" #include "func_pub.h" #include "include.h" #include "mcu_ps_pub.h" #include "start_type_pub.h" #include "space_light.h" #define ATT_DB_LENGTH 5 #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} 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; 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 *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] = {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); 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); } 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; } } #define CMD_RGBCW 0x1 static void ble_write_callback(write_req_t *write_req) { struct RGBCW rgbcw = { write_req->value[1], write_req->value[2], write_req->value[3], write_req->value[4], write_req->value[5], }; setRGBCW(&rgbcw); } static unsigned char ble_read_callback(read_req_t *read_req) { // TODO: implement error codes for commands 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("SPACELIGHT"); 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 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); 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); ret = rtos_create_thread(NULL, THD_INIT_PRIORITY, "main", (beken_thread_function_t)init_led_thread, app_stack_size, (beken_thread_arg_t)0); ASSERT(kNoErr == ret); vTaskStartScheduler(); }