hi all,
how to use Atomic FIFO Lib on ble stack ?
Called nrf_atfifo_get_free() always get NRF_ERROR_NOT_FOUND when ble_peripheral connect to central .
In ble_app_uart project use nrf_libuarte_async lib , Atomic FIFO(app_fifo lib that seem race condition) and Schedule handling library.
NRF_ATFIFO_DEF(my_fifo, uint8_t, 256);
//define uarte scheduler event handler
typedef struct uarte_ele {
uint8_t uarte_data[255];
uint32_t uarte_len;
}Suarte_ele;
// Scheduler settings
#define SCHED_MAX_EVENT_DATA_SIZE sizeof(Suarte_ele)
#define SCHED_QUEUE_SIZE 3
void uarte_scheduler_event_handler(void *p_event_data, uint16_t event_size);
//libuarte_async handle
void uart_event_handler(nrf_libuarte_async_evt_t *p_evt) {
Suarte_ele ele;
ret_code_t ret;
switch (p_evt->type) {
case NRF_LIBUARTE_ASYNC_EVT_ERROR:
printf("\r\nNRF_LIBUARTE_ASYNC_EVT_ERROR.\r\n");
break;
case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
//copy uarte rx data and scheduler to ble
ele.uarte_len = p_evt->data.rxtx.length;
memcpy(ele.uarte_data,p_evt->data.rxtx.p_data,p_evt->data.rxtx.length);
nrf_libuarte_async_rx_free(p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
//
app_sched_event_put(&ele, sizeof(ele), uarte_scheduler_event_handler);
//
break;
case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
break;
default:
break;
}
}
//
void uarte_scheduler_event_handler(void *p_event_data, uint16_t event_size) {
uint32_t ret;
uint8_t *pData = (*(Suarte_ele*)p_event_data).uarte_data;
ret = nrf_atfifo_alloc_put(my_fifo,pData,((Suarte_ele*)p_event_data)->uarte_len,NULL);
APP_ERROR_CHECK(ret);
send_string_to_nus();//send to ble
}
uint32_t fill_nus_packet() {
uint32_t err_code;
err_code = nrf_atfifo_get_free(my_fifo,data_array,20,NULL);
APP_ERROR_CHECK(err_code);//get error when connect
return NRF_SUCCESS;
}
//Attempts to send nus packet
//If NRF_SUCCESS is returned, the packet was successfully stored for transmission in a softdevice buffer.
uint32_t send_nus_packet(void) {
uint32_t err_code;
err_code = ble_nus_data_send(&m_nus, data_array, &index, m_conn_handle);
if (err_code == NRF_SUCCESS) {
index = 0; //Data has been buffered in softdevice for transmission so we can write data_array with new data.
} else if (err_code == NRF_ERROR_INVALID_STATE ||
err_code == NRF_ERROR_RESOURCES ||
err_code == NRF_ERROR_BUSY ||
err_code == NRF_ERROR_NOT_FOUND) {
//Do nothing. data_array still contains data for subsequent transmission.
//data_array content will be transmitted on another UART RX interrupt, TX_COMPLETE event or BLE services enabled event.
} else {
APP_ERROR_CHECK(err_code);
}
return err_code;
}
//Sends packet to NUS service if there are 20 bytes or more in collection packet
//If there is pending packet ready, transmit that instead.
void send_string_to_nus(void) {
uint32_t err_code;
if (pending_nus_packet) {
err_code = send_nus_packet();
if (err_code == NRF_SUCCESS)
pending_nus_packet = false;
}
//If no packet is ready for transmission, extract data from UART RX fifo until packet is filled up with data.
if (!pending_nus_packet) {
err_code = NRF_SUCCESS;
//Send nus packets while there is data to send and while softdevice buffer space is available
while (err_code == NRF_SUCCESS) {
err_code = fill_nus_packet(); //fill data packet
if (err_code == NRF_SUCCESS || index !=0) {
err_code = send_nus_packet(); //only send if packet is filled up
if (err_code != NRF_SUCCESS)
pending_nus_packet = true; //sending nus packet failed. Set the packet as pending.
}
}
}
}
hw:
nrf52832 DK (pca10040
sdk:
nRF5_SDK_15.1.0_a8c0c4d
ide:
SEGGER Embedded Studio for ARM
Release 3.50 Build 2018081000.36713
os:
macOS x64