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

Timer in Counter Mode is not counting via PPI?

I have designed my own custom PCB with nrf52832. The schematics of my PCB is attached with this post.

I am programming the soft device hex file but not initializing it in my application. I want to first test my PCB and waveforms for ADS7044 before moving forward.

I have one external ADC (ADS7044) which samples a CCD (TCD1304) and has to transfer 3694 * 2 bytes continuously. I have written a driver for external ADC using timer (to generate CS pulses with specific waveform as mentioned in datasheet of ADS7044), timer in counter mode (to stop SPI after fetching 3694 * 2 pulses), GPIOTE (to generate CS pulses) and SPIM (in array list mode). I am currently testing my driver and found out one problem that is stopping me to move ahead. My timer in Counter mode should counts SPI END events and stop the SPI when it has transferred required number of bytes. However, my counter is not counting. I need help.

As you can see in my code, I have connected SPI End Event to CCD_STOP_COUNTER_MODULE (Timer4) count task. But I am not getting event of Timer4 Compare match.

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

#define SPI_CS_PIN          0 // SPIM0_SS_PIN        // 0
#define SPI_SDO_PIN         1 //SPIM0_MISO_PIN      //  1
#define SPI_SCK_PIN         2 // SPIM0_SCK_PIN       //  2
#define SPI_SDI_PIN         3 // SPIM0_MOSI_PIN      //  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(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(NRF_SPIM0, NRF_SPIM_TASK_STOP));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mSpiEndCountCountPPI,
                                  nrf_spim_event_address_get(NRF_SPIM0, 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_assign(mSpiEndStartPPI,
                                          nrf_spim_event_address_get(NRF_SPIM0, NRF_SPIM_EVENT_END),
                                          nrf_spim_task_address_get(NRF_SPIM0, NRF_SPIM_TASK_START));
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(mSpiEndTimerStartPPI,
                                  nrf_spim_event_address_get(NRF_SPIM0, 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(NRF_SPIM0, 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_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;
}

// TIMER_MODULE (TIMER2) has been used to generate CS pulse

void ccd_init(void)
{

    // Configure SPI Master to communicate with External ADC
    nrf_spim_disable(NRF_SPIM0);

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

    // 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_task_trigger(CCD_STOP_COUNTER_MODULE, NRF_TIMER_TASK_CLEAR);
    nrf_timer_event_clear(CCD_STOP_COUNTER_MODULE, NRF_TIMER_EVENT_COMPARE0);

    nrf_timer_shorts_enable(CCD_STOP_COUNTER_MODULE, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK);
    nrf_timer_shorts_enable(CCD_STOP_COUNTER_MODULE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK);


    // 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);


    // Initialize PPI
    ccd_ppi_init();
}

int ccd_run(int runs)
{

    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(NRF_SPIM0);
    nrf_spim_rx_buffer_set(NRF_SPIM0, (uint8_t *)buffer, 2);

    // nrf_spim_rx_list_enable(NRF_SPIM0);

    nrf_spim_int_disable(NRF_SPIM0, NRF_SPIM_INT_STOPPED_MASK | NRF_SPIM_INT_STARTED_MASK);
    nrf_spim_int_enable(NRF_SPIM0, NRF_SPIM_INT_END_MASK);
    nrf_drv_common_irq_enable(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, 2);

    nrf_spim_enable(NRF_SPIM0);

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

    nrf_timer_int_enable(TIMER_MODULE, NRF_TIMER_INT_COMPARE0_MASK);
    nrf_drv_common_irq_enable(TIMER2_IRQn, 2);


    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, 5);

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


    return 0;
}


#ifdef __cplusplus
extern "C" {
#endif

void TIMER2_IRQHandler(void)
{
    // printf("Done Timer 2\r\n");
    nrf_timer_event_clear(TIMER_MODULE, NRF_TIMER_EVENT_COMPARE0);
}

void TIMER4_IRQHandler(void)
{
    // printf("xxxxxxxxxxxxx Timer 4\r\n");
    nrf_timer_event_clear(CCD_STOP_COUNTER_MODULE, NRF_TIMER_EVENT_COMPARE0);

    // while (1);
}

void SPI0_TWI0_IRQHandler(void)
{
    // printf("Done SPI\r\n");
    nrf_spim_event_clear(NRF_SPIM0, NRF_SPIM_EVENT_END);
}

#ifdef __cplusplus
}
#endif

EDIT:

I have attached my own code base. You can extract it under nRF5_SDK_14.0.0_3bcc1f7/examples/ble_peripheral/testright.

You can check files related to CCD, ADC is on testright/app/ccd.c. main.c has main function. I have been loading nRF5_SDK_14.0.0_3bcc1f7/examples/ble_peripheral/testright/pca10040/s132/armgcc/s132_nrf52_5.0.0_softdevice.hex for soft device but as you can see in my main function. I am not initializing the soft device.testright.zip

Related