I'm working on a BLE application based on the Zephyr RTOS. I need to read a SPI device at fixed time intervals and, as already suggested me here at point 3, I'm trying to implement a PPI channel that connects the TIMER0 event to the SPI task. I wrote a simple code just to test this feature but it' doesn't work, sure cause I lost something:
#include <zephyr.h> #include <logging/log.h> #define LOG_MODULE_NAME main LOG_MODULE_REGISTER( LOG_MODULE_NAME ); #define SCK_PIN 0x04 #define MISO_PIN 0x1D #define MOSI_PIN 0x1C #define CS_PIN 0x03 static const nrfx_timer_t timerInst = NRFX_TIMER_INSTANCE( 0 ); static const nrfx_spim_t spiInst = NRFX_SPIM_INSTANCE( 0 ); static const nrfx_spim_config_t spiConfig = NRFX_SPIM_DEFAULT_CONFIG( SCK_PIN, MOSI_PIN, MISO_PIN, CS_PIN ); nrf_ppi_channel_t readingPpiChan; static uint32_t readingTaskAddr; static uint32_t readingEventAddr; static uint8_t tempBuff[ 2 ]; static uint8_t tempReg; void Timer_Handler( nrf_timer_event_t event_type, void *p_context ) { } nrfx_err_t Spi_Timer_Ppi_Init( void ) { nrfx_err_t err; err = nrfx_spim_init( &spiInst, &spiConfig, NULL, NULL ); if ( err != NRFX_SUCCESS ) { LOG_ERR( "nrfx_spim_init error: %08X", err ); return err; } tempReg = 0x80; nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TRX( &tempReg, 1, tempBuff, 2 ); uint32_t flags = NRFX_SPIM_FLAG_HOLD_XFER | NRFX_SPIM_FLAG_RX_POSTINC | NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER | NRFX_SPIM_FLAG_REPEATED_XFER; err = nrfx_spim_xfer( &spiInst, &xfer, flags ); if ( err == NRFX_SUCCESS ) { readingTaskAddr = nrfx_spim_start_task_get( &spiInst ); } nrfx_timer_config_t timerConfig = NRFX_TIMER_DEFAULT_CONFIG; timerConfig.bit_width = NRF_TIMER_BIT_WIDTH_32; err = nrfx_timer_init( &timerInst, &timerConfig, Timer_Handler ); if ( err != NRFX_SUCCESS ) { LOG_ERR( "nrfx_timer_init error: %08X", err ); return err; } nrfx_timer_compare( &timerInst, NRF_TIMER_CC_CHANNEL0, nrfx_timer_ms_to_ticks( &timerInst, 1000 ), false ); nrfx_timer_enable( &timerInst ); err = nrfx_ppi_channel_alloc( &readingPpiChan ); if ( err != NRFX_SUCCESS ) { LOG_ERR( "nrfx_ppi_channel_alloc error: %08X", err ); return err; } readingEventAddr = nrfx_timer_compare_event_address_get( &timerInst, readingPpiChan ); err = nrfx_ppi_channel_assign( readingPpiChan, readingEventAddr, readingTaskAddr ); if ( err != NRFX_SUCCESS ) { LOG_ERR( "nrfx_ppi_channel_assign error: %08X", err ); return err; } err = nrfx_ppi_channel_enable( readingPpiChan ); if ( err != NRFX_SUCCESS ) { LOG_ERR( "nrfx_ppi_channel_enable error: %08X", err ); return; } return NRFX_SUCCESS; } void main( void ) { Spi_Timer_Ppi_Init(); while ( 1 ) { } }
I have some doubts:
1) Here it describes that if I wanto to use the NRFX_SPIM_FLAG_HOLD_XFER flag I must to set the chip select pin as NRFX_SPIM_PIN_NOT_USED and manage it outside the driver. How I should do it if the tranfers are supposed to be autonomous?
2) To generate the TIMER0 event in the PPI can I set false the enable_int parameter in the nrfx_timer_compare function or I have to set it as true? Because if I enable the interrupt, the Zephyr OS crash and restart the chip.
What am I doing wrong? Can you help me?