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