/** * #brief Ble notify data function. * * #called by ref@uart_rec_process() - #Condition Complete Packet; * ref@uart_rec_process() - #Condition Incomplete Packet; * ref@on_ble_evt() - #Case BLE_EVT_TX_COMPLETE. */ static void ble_data_notify_handler(void * p_context) { if (is_device_connect() == false) { return; } uint32_t err_code = ble_nus_string_send(&m_nus, m_temp_array.data, (uint16_t *)&m_temp_array.size); if (err_code == NRF_SUCCESS) { //! 成功通知一次数据,拉低一次表示对方可发送 nrf_gpio_pin_clear(FIFO_FULL_PIN); NRF_LOG_WARNING("noty ok [%d]###\r\n", m_temp_array.size); //! 数据填入协议栈buffer成功, 清除静态数组内容. memset(&m_temp_array, 0, sizeof(m_temp_array)); //! 上次数据填入协议栈buffer失败, 本次成功后尝试再次检索uart fifo, 查看时候有多余数据. if (m_uart_rec_states == UART_REC_DATA_PASS_WAIT /**#Condition.*/) { m_uart_rec_states /**#StatesChange.*/ = UART_REC_DATA_PASS; APP_ERROR_CHECK(app_sched_event_put((void *)0, 0, uart_rec_process)); } } else if (err_code == NRF_ERROR_RESOURCES) { NRF_LOG_WARNING("buf exce\r\n"); m_uart_rec_states /**#StatesChange.*/ = UART_REC_DATA_PASS_WAIT; return; } else if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING || err_code == NRF_ERROR_INVALID_STATE) { NRF_LOG_WARNING("ignor error\r\n"); //! 忽略这些由蓝牙连接带来的错误. } else { NRF_LOG_WARNING("error check\r\n"); APP_ERROR_CHECK(err_code); } } /** * #brief UART rec process function. * * #called by ref@uart_event_handle() - #Case - APP_UART_DATA_READY; * #called by ref@ble_data_notify_handler() - #Condition - NRF_SUCCESS, #Scheduled. */ static void uart_rec_process(void * p_context, uint16_t data_length) { static uint8_t fifo_buffer[32]; if (is_device_connect() == true /**< 在连接状态下,所有数据都将被视为透传数据 */) { // if ( 1 ) { m_uart_rec_states = (m_uart_rec_states == UART_REC_IDLE)? UART_REC_DATA_PASS : m_uart_rec_states; APP_ERROR_CHECK(app_simple_timer_stop()); uint8_t tmp_mid_data = 0; while (app_fifo_get(&m_uart_rec_fifo, &tmp_mid_data) == NRF_SUCCESS) { m_temp_array.data[m_temp_array.size++] = tmp_mid_data; //! 当数据达到最大长度即尝试将数组内容全部发送出去. if (m_temp_array.size >= m_ble_nus_max_data_len) { // NRF_LOG_WARNING("size : %d \r\n",m_temp_array.size); ble_data_notify_handler(NULL); if (m_uart_rec_states == UART_REC_DATA_PASS_WAIT /**#Condition.*/) { NRF_LOG_WARNING("uart wait\r\n"); //! DPASS WAIT 0 return; } } } if (m_temp_array.size > 0 && /**< 数据凑不满一整包字节的情况, 延时判断后发送. */ m_temp_array.size < m_ble_nus_max_data_len) { APP_ERROR_CHECK(app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT, ble_data_notify_handler, APP_TIMER_TICKS(600), NULL)); } } else { /**< 在非连接状态下,所有数据都将被视为命令数据. */ while (app_fifo_get(&m_uart_rec_fifo, fifo_buffer + m_temp_array.size) == NRF_SUCCESS) { APP_ERROR_CHECK(app_timer_stop(uart_clear_id)); APP_ERROR_CHECK(app_timer_start(uart_clear_id, APP_TIMER_TICKS(200), NULL)); if (m_temp_array.size >= 9 && m_temp_array.size <= (COMMAND_MAX_LEN-1)) { if (memcmp(fifo_buffer + (m_temp_array.size -1), (uint8_t *)COMMAND_END_STR, 2) == 0) { APP_ERROR_CHECK(app_timer_stop(uart_clear_id)); APP_ERROR_CHECK(app_simple_timer_stop()); memcpy(m_temp_array.data, fifo_buffer, m_temp_array.size + 1); APP_ERROR_CHECK(app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT, uart_cmd_process_handler, APP_TIMER_TICKS(UART_REC_WAIT_INTERVAL), NULL)); } } m_temp_array.size ++; } /* 出口发送的配置命令大于指定长度*/ if (m_temp_array.size > COMMAND_MAX_LEN) { NRF_LOG_RAW_INFO(">COMMAND_MAX_LEN stop timer\r\n"); APP_ERROR_CHECK(app_simple_timer_stop()); m_temp_array.size = 0; uart_rec_process_clr(); } /* 清楚发送不足命令长度.*/ APP_ERROR_CHECK(app_timer_stop(uart_clear_id)); APP_ERROR_CHECK(app_timer_start(uart_clear_id, APP_TIMER_TICKS(200), NULL)); } m_uart_rec_states /**#StatesChange.*/ = UART_REC_IDLE; } /** * #简介 查询串口接收处理模块当前是否繁忙. * * #返回 true 串口接收处理模块当前繁忙. * #返回 false 串口接收处理模块当前空闲. */ static inline bool is_uart_rec_in_process(void) { return (m_uart_rec_states == UART_REC_IDLE)? false : true; } /** * #brief Function for handling app_uart events. */ void uart_event_handle(app_uart_evt_t * p_event) { switch (p_event->evt_type) { /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */ case APP_UART_DATA_READY: { uint8_t tmp_rec_data = 0; UNUSED_VARIABLE(app_uart_get(&tmp_rec_data)); if (app_fifo_put(&m_uart_rec_fifo, tmp_rec_data) == NRF_SUCCESS) { if (is_uart_rec_in_process() == false) { uart_rec_process((void *)0, 0); } else { NRF_LOG_WARNING("uart buzy\r\n"); m_uart_rec_states == UART_REC_IDLE; //! Busy return; } } else { //! Rec fifo is full NRF_LOG_WARNING("@#$@##@%$#@^@#$%#@$%@#$%fifo full@#!$!#$@!#%#$@%@$##$@%#@$^%$#&@$#%#$%@\r\n"); nrf_gpio_pin_set(FIFO_FULL_PIN); return; } break; } /**< An communication error has occured during reception. */ case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER(p_event->data.error_communication); break; /**< An error in the FIFO module used by the app_uart module has occured. */ case APP_UART_FIFO_ERROR: APP_ERROR_HANDLER(p_event->data.error_code); break; case APP_UART_TX_EMPTY: NRF_LOG_INFO("UART SEND COMPELETE\r\n"); // APP_ERROR_CHECK(app_uart_flush()); uart_rec_process_clr(); break; /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */ // case APP_UART_TX_EMPTY: // //! TX_EMPTY // break; default: break; } } /** * #brief Function for initializing the UART module. */ static void uart_init(void) { uint32_t err_code; uint32_t tmp_uart_baud_list[] = UART_BAUDRATE_LIST; const app_uart_comm_params_t comm_params = { .rx_pin_no = RX_PIN_NUMBER, .tx_pin_no = TX_PIN_NUMBER, .rts_pin_no = RTS_PIN_NUMBER, .cts_pin_no = CTS_PIN_NUMBER, .flow_control = APP_UART_FLOW_CONTROL_DISABLED, .use_parity = false, .baud_rate = tmp_uart_baud_list[m_cmd_collection.uart_baudrate] }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_event_handle, APP_IRQ_PRIORITY_LOWEST, err_code); APP_ERROR_CHECK(err_code); } /** * @brief Function for initializing the GATT library. */ void gatt_init(void) { APP_ERROR_CHECK(nrf_ble_gatt_init(&m_gatt, gatt_evt_handler)); NRF_LOG_DEBUG("nrf_ble_gatt_init\r\n"); APP_ERROR_CHECK(nrf_ble_gatt_att_mtu_periph_set(&m_gatt,43)); NRF_LOG_DEBUG("nrf_ble_gatt_att_mtu_periph_set\r\n"); } * #param[in] length Length of the data. */ static void nus_data_handler(ble_nus_evt_t * p_evt) { uint32_t err_code; switch (p_evt->type) { case BLE_NUS_EVT_RX_DATA: NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART."); NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length); for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++) { do { err_code = app_uart_put(p_evt->params.rx_data.p_data[i]); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) { NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code); APP_ERROR_CHECK(err_code); } } while (err_code == NRF_ERROR_BUSY); } if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length-1] == '\r') { while (app_uart_put('\n') == NRF_ERROR_BUSY); } break; case BLE_NUS_EVT_TX_RDY: if (m_uart_rec_states == UART_REC_DATA_PASS_WAIT) { NRF_LOG_WARNING("uart reboot\r\n"); ble_data_notify_handler(NULL); } break; default : break; } }