#include "include.h" #include "ble_init.h" #include "ble_service.h" #include "wireless_service.h" #include "wireless_cmd.h" #include "utils_ring_buffer.h" #if FUNC_WIRELESS_EN #define TRACE_EN 1 #if TRACE_EN #define TRACE(...) my_printf("[WIRELESS] ");\ my_printf(__VA_ARGS__) #define TRACE_R(...) my_print_r(__VA_ARGS__); #else #define TRACE(...) #define TRACE_R(...) #endif // TRACE_EN /* Format: Header(1B) + [HID(n)] + [AUDIO(n)] + [CMD(n)] */ #define WIRELESS_SINGLE_PACKET_SIZE (1 + WIRELESS_DATA_LENGTH_HID + WIRELESS_DATA_LENGTH_AUDIO + CTRL_CMD_PACKET_SIZE) static struct { uint16_t con_handle; wireless_addr_info_typedef addr_info; uint8_t transmit_done; uint8_t single_packet[WIRELESS_SINGLE_PACKET_SIZE]; uint32_t data_len; } wireless_cb AT(.ble_buf.wireless.sta); AT(.com_text.wireless.transmit) void wireless_packet_process(uint8_t *buf, uint32_t size) { u8 head = buf[WIRELESS_HEAD_POS]; u8 pos = WIRELESS_PAYLOAD_POS; u8 *cmd_data = NULL, cmd_len = 0; /* Unpack data */ if (head & WIRELESS_HEADER_CTRL_BIT) { cmd_data = &buf[pos]; cmd_len = cmd_data[WIRELESS_CMD_DATA_LENGTH_POS]; pos += 2 + cmd_len; } /* Check length valid */ if (pos != size) { TRACE("data length err: %d %d\n", pos, size); return; } /* Process */ if (cmd_data) { TRACE("receive cmd - type:0x%02x data[%d]:\n", cmd_data[WIRELESS_CMD_DATA_TYPE_POS], cmd_len); TRACE_R(&cmd_data[WIRELESS_CMD_DATA_VALUE_POS], cmd_len); wireless_user_event_handle(cmd_data, cmd_len); } } static void wireless_event_packet_handler(uint8_t event_type, uint8_t *packet, uint8_t size) { switch (event_type) { case WIRELESS_EVENT_CONNECTED: TRACE("connected - con_handle: 0x%04x\n", GET_LE16(&packet[0])); wireless_cb.con_handle = GET_LE16(&packet[0]); memcpy((u8 *)&wireless_cb.addr_info, &packet[2], 7); bsp_wireless_link_info_write(&wireless_cb.addr_info); wireless_cb.transmit_done = 1; wireless_latency_applied(wireless_cb.con_handle, false); break; case WIRELESS_EVENT_DISCONNECTED: TRACE("disconnected - con_handle: 0x%04x reason: 0x%02x\n", GET_LE16(&packet[0]), packet[2]); wireless_cb.con_handle = 0; /* Update adv info and start when disc */ wireless_adv_init(true); /* Reset HW state */ sys_cb.peer_usb_is_active = 0; break; default: break; } } AT(.com_text.wireless.transmit) static void wireless_receive_handler(uint16_t con_handle, uint8_t *packet, uint8_t size) { if (con_handle == wireless_cb.con_handle) { wireless_packet_process(packet, size); } wireless_rxbuf_release(packet); lowpwr_pwroff_delay_reset(); lowpwr_sleep_delay_reset(); } void wireless_enter_sleep_hook(void) { if (wireless_cb.con_handle) { wireless_latency_applied(wireless_cb.con_handle, true); } } void wireless_exit_sleep_hook(void) { if (wireless_cb.con_handle) { wireless_latency_applied(wireless_cb.con_handle, false); } } void wireless_service_init(void) { TRACE("slave init\n"); memset(&wireless_cb, 0x00, sizeof(wireless_cb)); wireless_event_handler_register(wireless_event_packet_handler); wireless_receive_handler_register(wireless_receive_handler); wireless_cmd_init(); } AT(.text.app.proc.ble) void wireless_service_proc(void) { u8 *ptr = &wireless_cb.single_packet[WIRELESS_PAYLOAD_POS]; u32 len = 0; u8 found = 0; u8 head = 0; if (wireless_cb.con_handle) { if (wireless_cb.transmit_done) { len = wireless_cmd_get_buf(ptr); if (len) { ptr += len; head |= WIRELESS_HEADER_CTRL_BIT; found = 1; } wireless_cb.single_packet[WIRELESS_HEAD_POS] = head; wireless_cb.data_len = ptr - wireless_cb.single_packet; } if (found || !wireless_cb.transmit_done) { found = wireless_send_for_con(wireless_cb.con_handle, wireless_cb.single_packet, wireless_cb.data_len); wireless_cb.transmit_done = (found == 0)? 1: 0; lowpwr_pwroff_delay_reset(); lowpwr_sleep_delay_reset(); } } } #endif