Hi,
I use nrf51822 + S130 platform, in my application I used ADC,UART and APP TIMER, I mens only these can cause interruptions,all these interrupt priority is 3(APP_IRQ_PRIORITY_LOWEST), The related code is as follows:
ADC init function in main.c:
/**
* @brief ADC initialization.
*/
static void adc_init(void)
{
ret_code_t ret_code;
nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;
ret_code = nrf_drv_adc_init(&config, adc_event_handler);
APP_ERROR_CHECK(ret_code);
m_accelerator_channel_config.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
m_break_channel_config.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
m_accelerator_channel_child_config.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
m_break_channel_child_config.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
m_power_channel_config.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
nrf_drv_adc_channel_enable(&m_accelerator_channel_config);
nrf_drv_adc_channel_enable(&m_break_channel_config);
nrf_drv_adc_channel_enable(&m_accelerator_channel_child_config);
nrf_drv_adc_channel_enable(&m_break_channel_child_config);
nrf_drv_adc_channel_enable(&m_power_channel_config);
adc_start();
}
ADC event hadler in main.c:
/**
* @brief ADC interrupt handler.
*/
static void adc_event_handler(nrf_drv_adc_evt_t const * p_event)
{
if (p_event->type == NRF_DRV_ADC_EVT_DONE)
{
adc_start();
}
}
ADC interrupt priority define in sdk_config.h:
#ifndef ADC_ENABLED
#define ADC_ENABLED 1
#endif
#if ADC_ENABLED
// <o> ADC_CONFIG_IRQ_PRIORITY - Interrupt priority
// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
#ifndef ADC_CONFIG_IRQ_PRIORITY
#define ADC_CONFIG_IRQ_PRIORITY 3
#endif
UART init function in main.c:
/**@brief Function for initializing the UART.
*/
static void uart_init(void)
{
uint32_t err_code;
app_fifo_init(&s_tUARTRxFIFO, s_ucUARTRxFIFOBuf, 128);
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 = UART_BAUDRATE_BAUDRATE_Baud115200
};
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);
}
UART event handler in main.c:
void uart_event_handle(app_uart_evt_t * p_event)
{
uint8_t data;
switch (p_event->evt_type)
{
/**@snippet [Handling data from UART] */
case APP_UART_DATA_READY:
app_uart_get(&data);
app_fifo_put(&s_tUARTRxFIFO, data);
break;
default:
break;
}
}
APP Timer init in main.c:
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);
app_timer_create(&system_timer_id, APP_TIMER_MODE_REPEATED, system_timer_handler);
app_timer_start(system_timer_id, 32, NULL);
APP Timer event handler in main.c:
/** @brief system_timer_handler.
*/
void system_timer_handler(void * p_context)
{
static uint8_t div_cnt = 0;
uint32_t i;
//parse data from COM and BLE every 5ms
if (div_cnt++ == 5)
{
div_cnt = 0;
MiniResponeDataParse();
BLEPeripheralDataParse();
}
//process beep keep
if (g_ulBeepKeepTime)
{
g_ulBeepKeepTime--;
if (!g_ulBeepKeepTime)
{
nrf_gpio_pin_write(BEEP_PIN, BEEP_ACTIVE_STATE ? 0 : 1);
}
}
//process counters
for (i = 0; i < 16; i++)
{
if (g_tMainLoopInterface.pCounter[i])
{
if (*g_tMainLoopInterface.pCounter[i])
{
(*g_tMainLoopInterface.pCounter[i])--;
}
}
}
}
APP Timer related interrupt priority define in app_timer.c:
#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */
#define SWI_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the SWI interrupt (used for updating the timer list). */
APP_IRQ_PRIORITY_LOWEST define in app_util_platform.h:
#if __CORTEX_M == (0x00U)
#define _PRIO_SD_HIGH 0
#define _PRIO_APP_HIGH 1
#define _PRIO_APP_MID 1
#define _PRIO_SD_LOW 2
#define _PRIO_APP_LOW 3
#define _PRIO_APP_LOWEST 3
#define _PRIO_THREAD 4
#elif __CORTEX_M == (0x04U)
#define _PRIO_SD_HIGH 0
#define _PRIO_SD_MID 1
#define _PRIO_APP_HIGH 2
#define _PRIO_APP_MID 3
#define _PRIO_SD_LOW 4
#define _PRIO_SD_LOWEST 5
#define _PRIO_APP_LOW 6
#define _PRIO_APP_LOWEST 7
#define _PRIO_THREAD 15
#else
#error "No platform defined"
#endif
//lint -save -e113 -e452
/**@brief The interrupt priorities available to the application while the SoftDevice is active. */
typedef enum
{
#ifndef SOFTDEVICE_PRESENT
APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH,
#else
APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH,
#endif
APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH,
#ifndef SOFTDEVICE_PRESENT
APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW,
#else
APP_IRQ_PRIORITY_MID = _PRIO_APP_MID,
#endif
APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW,
APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST,
APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */
} app_irq_priority_t;
//lint -restore
So all my user interrupt priority is the lowest(3). I reference from here link text and here link text to know that the BLE Event interrupt priority is 2, is that right? So the ble_evt_dispatch
function will not be affected by other user interrupts(ADC UART APP TIMER) because its interrupt priority is higher than they are,right?
Then, if what i said above is right, here's my problem.I use a variable named m_conn_tx_packet_count
to record tx packet count, when connect be established I call sd_ble_tx_packet_count_get
to get the total number of available guaranteed application transmission packets, when ble_nus_c_string_send
return NRF_SUCCESS
i decreasing m_conn_tx_packet_count
,when receive BLE_EVT_TX_COMPLETE
event i increasing m_conn_tx_packet_count
,so i can call ble_nus_c_string_send
only when there are free tx packets. The code is:
static void on_ble_central_evt(const ble_evt_t * const p_ble_evt)
{
const ble_gap_evt_t * const p_gap_evt = &p_ble_evt->evt.gap_evt;
ret_code_t err_code;
switch (p_ble_evt->header.evt_id)
{
/** Upon connection, check which peripheral has connected (HR or RSC), initiate DB
* discovery, update LEDs status and resume scanning if necessary. */
case BLE_GAP_EVT_CONNECTED:
{
int i = 0, j = 0;
NRF_LOG_INFO("Central Connected \r\n");
/** If no nus is currently connected, try to find it on this peripheral*/
for (i = 0; i < CENTRAL_LINK_COUNT; i++)
{
for (j = 0; j < 6; j++)
{
if (p_gap_evt->params.connected.peer_addr.addr[j] != g_tMainLoopInterface.peripheral_info[i].mac[5 - j])
{
break;
}
}
if (j != 6)
{
continue;
}
m_conn_handle_nus_c[i] = p_gap_evt->conn_handle;
sd_ble_tx_packet_count_get(p_gap_evt->conn_handle, (uint8_t *)&m_conn_tx_packet_count[i]);
break;
}
} break; // BLE_GAP_EVT_CONNECTED
case BLE_EVT_TX_COMPLETE:
for (uint8_t i = 0; i < CENTRAL_LINK_COUNT; i++)
{
if (p_gap_evt->conn_handle == m_conn_handle_nus_c[i])
{
m_conn_tx_packet_count[i]++;
break;
}
}
break;
default:
// No implementation needed.
break;
}
}
My data send function code:
bool SendDatas(...)
{
....//other code
if (m_conn_tx_packet_count[pars->peripheral_id] != 0)
{
if (ble_nus_c_string_send(p_ble_nus_c, &txbuf[send_index], factlen) == NRF_SUCCESS)
{
m_conn_tx_packet_count[pars->peripheral_id]--;
return true;
}
}
return false;
}
Now the problem is, some times ble_nus_c_string_send
never be called, because m_conn_tx_packet_count[pars->peripheral_id]
always be 0. It seems like the last ble_nus_c_string_send
call return NRF_SUCCESS but there's no BLE_EVT_TX_COMPLETE
event received. Is it possible that the soft device lost BLE event? I've had similar problems before, and I have not solved them well,the link is herelink text . Both the two problem indicate that maybe some SYSTEM EVENT(BLE EVENT) have been lost. So I check all my interrupt config to make sure no interrupt's priority is higher than the priority of SOFTDEVICE_EVT_IRQ.
So, what wrong with my code? Was I not using the S130 correctly? Or is it the issue of S130?