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

NRF52832 SPI with EasyDMA and PPI

 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();
    }
}

Related