This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

how to use Atomic FIFO Lib on softdevice

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
Parents Reply Children
No Data
Related