Hi
I'm using NRF52840 + SDK15.0.0 and softdevice 6.0.0
I have joined two program one is ble_app_uart and other SAADC capturing ultrasound noise. (Saadc program works perfectly alone, without softdevice, BLE, etc)
The idea is when the device is connected to cellphone, and the cellphone send "!" by UART, the device start to measure the SAADC and sends the ultrasound data by NUS.
I have assigned SAADC in the timer1. (static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(1);) Even I testedin the timer2
My problem is when activate SAADC (saadc_sampling_event_enable();) the SAADC fuction doesnt execute event saadc_callback, it seems does nothing.
I have writen some output to terminal if the program execute the saadc_callback, but the saadc_callback doesnt running.
I have change the priority of the SAADC to 2. But It didnt work.
Any Sugestion?
Ricardo
static void nus_data_handler(ble_nus_evt_t * p_evt)
{
if (p_evt->type == BLE_NUS_EVT_RX_DATA)
{
uint32_t err_code;
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);
}
if(p_evt->params.rx_data.p_data[0] == '!')
{
Datos_Capturados_Ultrasonido = false;
Capturar_datos_SAADC = true;
saadc_sampling_event_enable();
RealFFT_Instance.fftLenReal= Total_samples;
// ***** HERE IS MY PROBOLEM ************
while (!Datos_Capturados_Ultrasonido){} // HERE...
// I created the while, because I wait to the data is readed ok...
saadc_sampling_event_disable();
Datos_Capturados_Ultrasonido = false;
uint16_t length = (uint16_t)index;
uint8_t Ble_transfer[0]= FFT_Real[0];
uint8_t Ble_transfer[1][] = (uint8_t)FFT_Real[0];
uint16_t length = (uint16_t)sizeof(FFT_Real[0]);
memcpy(Ble_transfer[0], FFT_Real[0], 0x100); //lenght
err_code = ble_nus_data_send(&m_nus, Ble_transfer[0], &length, m_conn_handle); //&length
if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) &&
(err_code != NRF_ERROR_NOT_FOUND) )
{
APP_ERROR_CHECK(err_code);
}
}
}
}
void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
ret_code_t err_code;
//NRF_LOG_INFO("FUERA DEL LOOP");
//printf("fuera del loop %d \r\n",loop_number);
//NRF_LOG_FLUSH();
if (Capturar_datos_SAADC)
{
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
NRF_LOG_INFO("Loop ultrasonido numero");
printf("Loop ultrasonido numero %d \r\n",loop_number);
NRF_LOG_FLUSH();
loop_number++;
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
for (int k=0;k<SAMPLES_IN_BUFFER;k++)
{
In_Data[muestra][k] = (int16_t)((p_event->data.done.p_buffer[k]-512)<<8); //
}
if (muestra==(muestreos))
{
saadc_sampling_event_disable();
Datos_Capturados_Ultrasonido = true;
// nrf_drv_timer_pause(&m_timer);
/*
memset(FFT_Complex, 0, sizeof FFT_Complex);
memset(In_Data, 0, sizeof In_Data);
memset(FFT_Real, 0, sizeof FFT_Real);
memset(p_event->data.done.p_buffer, 0, sizeof p_event->data.done.p_buffer);
m_adc_evt_counter=0;
//nrf_drv_timer_resume(&m_timer);
muestra=0;
*/
}
else
{
muestra++;
}
}
}
}
Main
int main(void)
{
muestra = 0;
bool erase_bonds;
uart_init();
log_init();
timers_init();
buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
// SAADC START
printf("UART 1.\r\n");
NRF_LOG_INFO("Debug logging for UART over RTT started.");
saadc_sampling_event_init();
saadc_init();
//saadc_sampling_event_enable();
RealFFT_Instance.fftLenReal= Total_samples;
printf("SAADC Configured.\r\n");
NRF_LOG_INFO("Debug logging for UART over RTT started.");
// Start execution.
advertising_start();
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
void timer_handler(nrf_timer_event_t event_type, void * p_context)
{
}
void saadc_sampling_event_init(void)
{
ret_code_t err_code;
err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
APP_ERROR_CHECK(err_code);
uint32_t ticks = nrf_drv_timer_us_to_ticks(&m_timer,10); //HERE THE TIMER If i use 50 it is for 10.000 hz
nrf_drv_timer_extended_compare(&m_timer,
NRF_TIMER_CC_CHANNEL0,
ticks,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
false);
nrf_drv_timer_enable(&m_timer);
uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
NRF_TIMER_CC_CHANNEL0);
uint32_t saadc_sample_task_addr = nrf_drv_saadc_sample_task_get();
//setup ppi channel so that timer compare event is triggering sample task in SAADC
err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
timer_compare_event_addr,
saadc_sample_task_addr);
APP_ERROR_CHECK(err_code);
}
void saadc_sampling_event_enable(void)
{
ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
APP_ERROR_CHECK(err_code);
}
void saadc_sampling_event_disable(void)
{
ret_code_t err_code = nrf_drv_ppi_channel_disable(m_ppi_channel);
APP_ERROR_CHECK(err_code);
}
void saadc_init(void)
{
ret_code_t err_code;
nrf_saadc_channel_config_t channel_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
channel_config.acq_time = NRF_SAADC_ACQTIME_3US;
channel_config.burst = NRF_SAADC_BURST_ENABLED ; //NRF_SAADC_BURST_DISABLED es mas lento ///< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM.
channel_config.reference = NRF_SAADC_REFERENCE_VDD4;
channel_config.gain = NRF_SAADC_GAIN1_4;
err_code = nrfx_saadc_calibrate_offset();
//Configure SAADC
nrf_drv_saadc_config_t saadc_config;// = NRF_DRV_SAADC_DEFAULT_CONFIG;
saadc_config.low_power_mode = false; //true
saadc_config.resolution = NRF_SAADC_RESOLUTION_10BIT;
saadc_config.oversample = NRF_SAADC_OVERSAMPLE_DISABLED; //NRF_SAADC_OVERSAMPLE_DISABLED; NRF_SAADC_OVERSAMPLE_2X
saadc_config.interrupt_priority = APP_IRQ_PRIORITY_LOWEST; //APP_IRQ_PRIORITY_LOW;
err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(0, &channel_config);
APP_ERROR_CHECK(err_code);
NRF_SAADC->SAMPLERATE = (1 << 12); // Timer mode
NRF_SAADC->SAMPLERATE |= 80; // 16MHz / 80 counts = 200 000 triggers per second
// See http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52840.ps/saadc.html?cp=2_0_0_5_22_8_11#register.SAMPLERATE for details.
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER); //(m_buffer_pool[0], SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
}