Hi,
I am trying to interface with the MAX11198 simultaneous dual ADC over SPI. The ADC has two channels and I am able to read values from one channel at a time using the nRF52832 DK as a SPI master. The ADC has one CLK pin, one CNVST pin (conversion start, acts as chip select) and 2 DOUT pins. I have set the conversion rate to 100kHz using a timer and PPI to toggle the CNVST at this rate. I am reading 2000 samples from the ADC then stoppping sampling to do some processing of the data. To do the repeated SPI master read I use:
ret_code_t ret_0 = nrf_drv_spi_xfer(&spi0, &xfer_0, NRF_DRV_SPI_FLAG_HOLD_XFER | NRF_DRV_SPI_FLAG_REPEATED_XFER );
To read from both DOUT pins at once I am trying to use a SPI slave instance with its CLK and CS pins physically tied to CLK and CNVST of the SPI master instance. However, I cannot figure out how to set up repeated slave SPI reads like can be done with nrf_drv_spi_xfer() function and the NRF_DRV_SPI_FLAG_REPEATED_XFER flag.
I'm open to any suggestions on better ways to accomplish this or if anyone has used this part before with a Nordic MCU.
Here are relevant functions from my project:
void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
void * p_context)
{
if(count0==ADC_QUE_SIZE)
{
spi_sampling_event_disable();
spi_xfer_done = true;
}
else
{
adc0[count0++] = ((uint16_t)(m_rx_buf_0[0]<<8) | m_rx_buf_0[1]);
}
}
void spis_event_handler(nrf_drv_spis_event_t event)
{
if(event.evt_type == NRF_DRV_SPIS_XFER_DONE)
{
adc1[count1++] = ((uint16_t)(m_rx_buf_1[0]<<8) | m_rx_buf_1[1]);
memset(m_rx_buf_1, 0, m_length);
nrf_drv_spis_buffers_set(&spis, m_tx_buf, m_length, m_rx_buf_1, m_length);
}
}
void spi_config(void)
{
// Instance 0 config
nrf_drv_spi_config_t spi_config_0 = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config_0.mode = NRF_DRV_SPI_MODE_1;
spi_config_0.frequency = NRF_DRV_SPI_FREQ_8M;
spi_config_0.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
spi_config_0.miso_pin = SPI_MISO_PIN;
spi_config_0.mosi_pin = NRF_DRV_SPI_PIN_NOT_USED;
spi_config_0.sck_pin = SPI_SCK_PIN;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi0, &spi_config_0, spi_event_handler, NULL));
memset(m_rx_buf_0, 0, m_length);
nrf_drv_spi_xfer_desc_t xfer_0 = NRF_DRV_SPI_XFER_TRX(m_tx_buf, m_length, m_rx_buf_0, m_length);
ret_code_t ret_0 = nrf_drv_spi_xfer(&spi0, &xfer_0, NRF_DRV_SPI_FLAG_HOLD_XFER | NRF_DRV_SPI_FLAG_REPEATED_XFER );
// Instance 1 config
nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;
spis_config.mode = NRF_DRV_SPI_MODE_1;
spis_config.csn_pin = APP_SPIS_CS_PIN;
spis_config.miso_pin = NRFX_SPIS_PIN_NOT_USED;
spis_config.mosi_pin = APP_SPIS_MOSI_PIN;
spis_config.sck_pin = APP_SPIS_SCK_PIN;
APP_ERROR_CHECK(nrf_drv_spis_init(&spis, &spis_config, spis_event_handler));
memset(m_rx_buf_1, 0, m_length);
nrf_drv_spis_buffers_set(&spis, m_tx_buf_1, m_length, m_rx_buf_1, m_length);
}
void spi_sampling_event_init(void)
{
ret_code_t err_code;
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); // Initialize high
err_code = nrf_drv_gpiote_out_init(GPIO_OUTPUT_PIN_NUMBER, &config); //CNVST
// 159 = 100kHz
nrf_drv_timer_extended_compare(&timer, NRF_TIMER_CC_CHANNEL0, 159, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
uint32_t gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_OUTPUT_PIN_NUMBER);
uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&timer,NRF_TIMER_CC_CHANNEL0);
uint32_t spi_start_task_addr = nrf_drv_spi_start_task_get(&spi0);
uint32_t spi_end_evt_addr = nrf_drv_spi_end_event_get(&spi0);
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel_1);
err_code = nrf_drv_ppi_channel_assign(ppi_channel_1, timer_compare_event_addr, gpiote_task_addr);
err_code = nrf_drv_ppi_channel_fork_assign(ppi_channel_1, spi_start_task_addr);
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel_2);
err_code = nrf_drv_ppi_channel_assign(ppi_channel_2, spi_end_evt_addr, gpiote_task_addr);
}
void spi_sampling_event_enable(void)
{
ret_code_t err_code;
nrf_drv_gpiote_out_task_enable(GPIO_OUTPUT_PIN_NUMBER);
err_code = nrf_drv_ppi_channel_enable(ppi_channel_1);
err_code = nrf_drv_ppi_channel_enable(ppi_channel_2);
nrf_drv_timer_enable(&timer);
}
void spi_sampling_event_disable(void)
{
ret_code_t err_code;
nrf_drv_gpiote_out_task_disable(GPIO_OUTPUT_PIN_NUMBER);
err_code = nrf_drv_ppi_channel_disable(ppi_channel_1);
err_code = nrf_drv_ppi_channel_disable(ppi_channel_2);
nrf_drv_timer_disable(&timer);
}
I am developing on the nRF52832 dev kit with Segger Embedded Studio v6.30 using SDK v17.1.0.
Thanks,
Daragh