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

SPIM not working in NRF52832?

I am writing drivers for external ADC and I need to write my own SPIM driver using hal of NRF52 SPIM. However, after trying for a day I am not able to see my waveform in my Oscilloscope.

#define SPI_MODULE                      (NRF_SPIM_Type *)NRF_SPIM0
#define TIMER_MODULE                    NRF_TIMER2
#define CCD_STOP_COUNTER_MODULE         NRF_TIMER4

#define SPI_CS_PIN          10 // 0
#define SPI_SDO_PIN         8  //  1
#define SPI_SCK_PIN         9  //  2
#define SPI_SDI_PIN         7  //  3 => Useless pin

#define CS_PIN_PPI_NDX      0


uint16_t buffer[SAMPLES_IN_BUFFER];

static nrf_ppi_channel_t mGpioteSetTimerCCPPI;
static nrf_ppi_channel_t mSpiEndStartPPI;
static nrf_ppi_channel_t mSpiEndTimerStartPPI;
static nrf_ppi_channel_t mSpiEndGpioteClearPPI;

static nrf_ppi_channel_t mCounterTimerStopPPI;
static nrf_ppi_channel_t mCounterCompSpiStopPPI;
static nrf_ppi_channel_t mSpiEndCountCountPPI;

static ret_code_t ccd_ppi_init(void)
{
    ret_code_t err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&mGpioteSetTimerCCPPI);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&mSpiEndStartPPI);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&mSpiEndTimerStartPPI);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&mSpiEndGpioteClearPPI);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&mCounterTimerStopPPI);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&mCounterCompSpiStopPPI);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&mSpiEndCountCountPPI);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mSpiEndStartPPI,
                                          nrf_spim_event_address_get(SPI_MODULE, NRF_SPIM_EVENT_END),
                                          nrf_spim_task_address_get(SPI_MODULE, NRF_SPIM_TASK_START));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mSpiEndTimerStartPPI,
                                  nrf_spim_event_address_get(SPI_MODULE, NRF_SPIM_EVENT_END),
                                  (uint32_t)nrf_timer_task_address_get(TIMER_MODULE, NRF_TIMER_TASK_START));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mGpioteSetTimerCCPPI,
                                  (uint32_t)nrf_timer_event_address_get(TIMER_MODULE, NRF_TIMER_EVENT_COMPARE0),
                                  nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_SET_0));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mSpiEndGpioteClearPPI,
                                  nrf_spim_event_address_get(SPI_MODULE, NRF_SPIM_EVENT_END),
                                  nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_CLR_0));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mCounterTimerStopPPI,
                                  (uint32_t)nrf_timer_event_address_get(CCD_STOP_COUNTER_MODULE, NRF_TIMER_EVENT_COMPARE0),
                                  (uint32_t)nrf_timer_task_address_get(TIMER_MODULE, NRF_TIMER_TASK_STOP));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mCounterCompSpiStopPPI,
                                  (uint32_t)nrf_timer_event_address_get(CCD_STOP_COUNTER_MODULE, NRF_TIMER_EVENT_COMPARE0),
                                  nrf_spim_task_address_get(SPI_MODULE, NRF_SPIM_TASK_STOP));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mSpiEndCountCountPPI,
                                  nrf_spim_event_address_get(SPI_MODULE, NRF_SPIM_EVENT_END),
                                  (uint32_t)nrf_timer_task_address_get(CCD_STOP_COUNTER_MODULE, NRF_TIMER_TASK_COUNT));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_enable(mSpiEndStartPPI);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(mSpiEndTimerStartPPI);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(mGpioteSetTimerCCPPI);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(mSpiEndGpioteClearPPI);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(mCounterTimerStopPPI);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(mCounterCompSpiStopPPI);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(mSpiEndCountCountPPI);
    APP_ERROR_CHECK(err_code);
    return 0;
}

void ccd_init(void)
{
    // Configure SPI Master to communicate with External ADC
    nrf_spim_disable(SPI_MODULE);

    nrf_spim_configure(SPI_MODULE, NRF_SPIM_MODE_3, NRF_SPIM_BIT_ORDER_MSB_FIRST);
    nrf_spim_pins_set(SPI_MODULE, SPI_SCK_PIN, NRF_SPIM_PIN_NOT_CONNECTED, SPI_SDO_PIN);
    nrf_spim_frequency_set(SPI_MODULE, NRF_SPI_FREQ_8M);
    

    gpio_output_cfg(SPI_SCK_PIN);
    gpio_input_cfg(SPI_SDO_PIN);
    gpio_output_cfg(SPI_CS_PIN);    


    // // Configure Timer to generate CS Pulses
    // nrf_timer_mode_set(TIMER_MODULE, NRF_TIMER_MODE_TIMER);
    // nrf_timer_bit_width_set(TIMER_MODULE, NRF_TIMER_BIT_WIDTH_32);
    // nrf_timer_frequency_set(TIMER_MODULE, NRF_TIMER_FREQ_16MHz);

    // nrf_timer_event_clear(TIMER_MODULE, NRF_TIMER_EVENT_COMPARE0);
    // nrf_timer_task_trigger(TIMER_MODULE, NRF_TIMER_TASK_CLEAR);

    // nrf_timer_shorts_enable(TIMER_MODULE, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK);
    // nrf_timer_shorts_enable(TIMER_MODULE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK);

    // // Counter to stop CCD
    // nrf_timer_mode_set(CCD_STOP_COUNTER_MODULE, NRF_TIMER_MODE_COUNTER);
    // nrf_timer_bit_width_set(CCD_STOP_COUNTER_MODULE, NRF_TIMER_BIT_WIDTH_32);
    // nrf_timer_shorts_enable(CCD_STOP_COUNTER_MODULE, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK);

    // nrf_timer_event_clear(CCD_STOP_COUNTER_MODULE, NRF_TIMER_EVENT_COMPARE0);
    // nrf_timer_task_trigger(CCD_STOP_COUNTER_MODULE, NRF_TIMER_TASK_CLEAR);

    // // GPIOTE to control CS pin pulse
    // nrf_gpiote_task_configure(CS_PIN_PPI_NDX, SPI_CS_PIN, NRF_GPIOTE_POLARITY_LOTOHI, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    // nrf_gpiote_task_enable(CS_PIN_PPI_NDX);


    // ccd_ppi_init();
}

int ccd_run(int runs)
{
    // printf("Hello world\r\n");
    uint32_t lowTicks = 29; // 3625 us => 14.5 SPI 8MHz clock periods
    // nrf_gpiote_task_set(NRF_GPIOTE_TASKS_SET_0);
    // nrf_timer_task_trigger(TIMER_MODULE, NRF_TIMER_TASK_STOP);

    nrf_spim_disable(SPI_MODULE);
    nrf_spim_rx_buffer_set(SPI_MODULE, (uint8_t *)buffer, 2);

    nrf_spim_rx_list_enable(SPI_MODULE);
    nrf_spim_tx_list_disable(SPI_MODULE);

    nrf_spim_shorts_enable(SPI_MODULE, NRF_SPIM_SHORT_END_START_MASK);
    nrf_spim_int_enable(SPI_MODULE, NRF_SPIM_INT_ENDTX_MASK);
    
    nrf_drv_common_irq_enable(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, 2);


    // nrf_timer_int_enable(CCD_STOP_COUNTER_MODULE, NRF_TIMER_INT_COMPARE0_MASK);
    // nrf_drv_common_irq_enable(TIMER4_IRQn, 2);

    nrf_spim_enable(SPI_MODULE);

    // nrf_timer_event_clear(TIMER_MODULE, NRF_TIMER_EVENT_COMPARE0);
    // nrf_timer_task_trigger(TIMER_MODULE, NRF_TIMER_TASK_CLEAR);

    // nrf_timer_event_clear(CCD_STOP_COUNTER_MODULE, NRF_TIMER_EVENT_COMPARE0);
    // nrf_timer_task_trigger(CCD_STOP_COUNTER_MODULE, NRF_TIMER_TASK_CLEAR);

    // nrf_timer_cc_write(TIMER_MODULE, NRF_TIMER_CC_CHANNEL0, lowTicks);
    // nrf_timer_cc_write(CCD_STOP_COUNTER_MODULE, NRF_TIMER_CC_CHANNEL0, SAMPLES_IN_BUFFER);

    // // Lets start
    // nrf_gpiote_task_set(NRF_GPIOTE_TASKS_CLR_0);
    nrf_spim_task_trigger(SPI_MODULE, NRF_SPIM_TASK_START);
    // nrf_timer_task_trigger(TIMER_MODULE, NRF_TIMER_TASK_START);

    return 0;
}

int ccd_stop(void)
{
    // TODO: Stop everything
    return 0;
}

void ccd_write(int from, int to, int jump)
{
    for (; from <= to; from += jump)
        uart_putuint16_unlocked(buffer[SAMPLES_IN_BUFFER - from] * 10);
}

void ccd_print(int from, int to, int jump)
{
    for (; from <= to; from += jump)
        printf("Buffer %d: %d\r\n", from, (unsigned)buffer[from - 1] * 10);
}



#ifdef __cplusplus
extern "C" {
#endif

void TIMER4_IRQHandler(void)
{
    printf("Done Timer\r\n");
    // while (1); 
    nrf_timer_event_clear(CCD_STOP_COUNTER_MODULE, NRF_TIMER_EVENT_COMPARE0);
}

void SPI0_TWI0_IRQHandler(void)
{
    printf("Done SPI\r\n");
    nrf_spim_event_clear(SPI_MODULE, NRF_SPIM_EVENT_ENDTX);
}

I want to use arrayList for SPIM. I have enabled rx SPIM arraylist.However, I am not able to get any interrupt due to NRF_SPIM_EVENT_ENDRX event. If I enable ENDTX interrupt, then interrupt gets executed. The code below is just testing code. I know RAM buffer will be overflowed because of short in SPIM (NRF_SPIM_SHORT_END_START_MASK) but my goal was to check the waveform. But it looks like I am not getting any waveform. Also, I am not able to understand why I am not getting any interrupt on NRF_SPIM_EVENT_ENDRX (if I enable it with nrf_spim_int_enable(SPI_MODULE, NRF_SPIM_INT_ENDTX_MASK)).

Related