Hi,
I combined the two examples /peripheral/saadc and /peripheral/spi and added a second timer that throws a compare event after 5 spi transactions.
I configured nrf_drv_spi_xfer with the flags
NRF_DRV_SPI_FLAG_HOLD_XFER for triggering the transfer externally by PPI
NRF_DRV_SPI_FLAG_RX_POSTINC to increment the buffer address
The Problem is that only the first spi event reads the correct sensor data, after that I’ always getting zeros. How to setup up nrf_drv_spi_xfer to trigger the spi event correctly?
#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi_inst = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);
volatile uint8_t state = 1;
static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(0);
static const nrf_drv_timer_t m_timer_1 = NRF_DRV_TIMER_INSTANCE(1);
//static nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t m_ppi_channel;
static nrf_ppi_channel_t m_ppi_channel_timer1;
uint8_t tx_buffer_adc[1] = {0x10};
uint8_t rx_buffer_adc[9] = {1,1,1,
1,1,1,
1,1,1};
nrf_drv_spi_xfer_desc_t const transfer_buffers = {
.p_tx_buffer = tx_buffer_adc,
.tx_length = 1,
.p_rx_buffer = rx_buffer_adc,
.rx_length = 3
};
void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
void * p_context)
{
NRF_LOG_INFO("rx_buffer_adc012 %x %x %x", transfer_buffers.p_rx_buffer[0], transfer_buffers.p_rx_buffer[1], transfer_buffers.p_rx_buffer[2]);
NRF_LOG_INFO("rx_buffer_adc345 %x %x %x", transfer_buffers.p_rx_buffer[3], transfer_buffers.p_rx_buffer[4], transfer_buffers.p_rx_buffer[5]);
NRF_LOG_INFO("rx_buffer_adc678 %x %x %x", transfer_buffers.p_rx_buffer[3], transfer_buffers.p_rx_buffer[4], transfer_buffers.p_rx_buffer[5]);
NRF_LOG_INFO("PTR: %i", NRF_SPIM0->RXD.PTR);
//nrf_drv_spi_xfer(&spi_inst, &transfer_buffers, NRF_DRV_SPI_FLAG_HOLD_XFER|NRF_DRV_SPI_FLAG_RX_POSTINC); //| NRF_DRV_SPI_FLAG_REPEATED_XFER
}
void timer_handler(nrf_timer_event_t event_type, void * p_context)
{
}
void timer_1_event_handler(nrf_timer_event_t event_type, void * p_context)
{
NRF_LOG_INFO("Processing Data");
//Set RX.PTR to start Address
NRF_SPIM0->RXD.PTR = (int32_t)&rx_buffer_adc;
}
void spi_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);
/* setup m_timer for compare event every 400ms */
uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 1000);
nrf_drv_timer_extended_compare(&m_timer,
NRF_TIMER_CC_CHANNEL0,
ticks,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
false);
//Timer 1 for counting spi events
nrf_drv_timer_config_t timer_cfg_1 = NRF_DRV_TIMER_DEFAULT_CONFIG;
timer_cfg_1.mode = NRF_TIMER_MODE_COUNTER;
err_code = nrf_drv_timer_init(&m_timer_1, &timer_cfg_1, timer_1_event_handler);
//Event after 3 events
nrf_drv_timer_extended_compare(&m_timer_1, NRF_TIMER_CC_CHANNEL0, 3, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
nrf_drv_timer_enable(&m_timer);
nrf_drv_timer_enable(&m_timer_1);
uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,NRF_TIMER_CC_CHANNEL0);
uint32_t timer_count_task_addr = nrf_drv_timer_task_address_get(&m_timer_1, NRF_TIMER_TASK_COUNT);
err_code = nrf_drv_spi_xfer(&spi_inst,
&transfer_buffers,
NRF_DRV_SPI_FLAG_HOLD_XFER |
NRF_DRV_SPI_FLAG_RX_POSTINC); //NRF_DRV_SPI_FLAG_REPEATED_XFER | NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER);
uint32_t spi_task_addr = nrf_drv_spi_start_task_get(&spi_inst);
uint32_t spi_end_evt_addr = nrf_drv_spi_end_event_get(&spi_inst);
//setup ppi Channels
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,
spi_task_addr);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel_timer1);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_assign(m_ppi_channel_timer1,
spi_end_evt_addr,
timer_count_task_addr);
}
void spi_sampling_event_enable(void)
{
ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_enable(m_ppi_channel_timer1);
APP_ERROR_CHECK(err_code);
}
void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
/*
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
ret_code_t err_code;
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
int i;
NRF_LOG_INFO("ADC event number: %d", (int)m_adc_evt_counter);
for (i = 0; i < SAMPLES_IN_BUFFER; i++)
{
NRF_LOG_INFO("%d", p_event->data.done.p_buffer[i]);
}
m_adc_evt_counter++;
}
*/
}
int main(void)
{
uint32_t err_code = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEFAULT_BACKENDS_INIT();
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = SPI_SS_PIN;
spi_config.miso_pin = SPI_MISO_PIN;
spi_config.mosi_pin = SPI_MOSI_PIN;
spi_config.sck_pin = SPI_SCK_PIN;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi_inst, &spi_config, spi_event_handler, NULL));
nrf_drv_spi_transfer(&spi_inst, tx_buffer_adc, 1, rx_buffer_adc, 3);
NRF_LOG_INFO("Setup %x %x %x", rx_buffer_adc[0], rx_buffer_adc[1], rx_buffer_adc[2]);
spi_sampling_event_init();
spi_sampling_event_enable();
while (1)
{
NRF_LOG_FLUSH();
}
}