This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

High-frequency GPIO

Hello, all.

I am working on a project in which the ultimate goal is to read an 8-bit signal with 10kHz frequency.

To test if this would be possible, I tried to generate a digital signal using a timer. The timer is configured as below:

void digital_signal_event_init(void)
{
    ret_code_t err_code;

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    err_code = nrf_drv_timer_init(&TIMER_DIGITAL, &timer_cfg, digital_signal_handler);
    APP_ERROR_CHECK(err_code);

    // setup m_timer for compare event every 400ms 
    uint32_t ticks = nrf_drv_timer_us_to_ticks(&TIMER_DIGITAL, 1);
    nrf_drv_timer_extended_compare(&TIMER_DIGITAL,
                                   NRF_TIMER_CC_CHANNEL0,
                                   ticks,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   true);
    nrf_drv_timer_enable(&TIMER_DIGITAL);
    
}

And the handle is as shown next:

void digital_signal_handler(nrf_timer_event_t event_type, void * p_context)
{
    switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE0:                 
                if(currentSample < 10){
                  GPIO0_OUT_R = ((SineWave[currentSample])<<14);
                  sprintf(GPIO_Out_current_Value, "GPIO0_OUT register current value: %d\n", (GPIO0_OUT_R>>14)&0xFF);
                  SEGGER_RTT_WriteString(0, GPIO_Out_current_Value);
                  currentSample++;
                }
                else{
                  currentSample = 0;
                }               
                break;

            default:
                //Do nothing.
                break;
        }

}

The signal is in the array SineWave:

const uint16_t SineWave[10] = {12, 14, 14, 12, 8, 3, 1, 1, 3, 7};

The GPIO is initialized as follows:

#define IN1          NRF_GPIO_PIN_MAP(0,14)
#define IN2          NRF_GPIO_PIN_MAP(0,15)
#define IN3          NRF_GPIO_PIN_MAP(0,16)
#define IN4          NRF_GPIO_PIN_MAP(0,17)
#define IN5          NRF_GPIO_PIN_MAP(0,18)
#define IN6          NRF_GPIO_PIN_MAP(0,19)
#define IN7          NRF_GPIO_PIN_MAP(0,20)
#define IN8          NRF_GPIO_PIN_MAP(0,21)

#define IN_NUMBER                        8

static const uint8_t input_list[8] = {IN1, IN2, IN3, IN4, IN5, IN6, IN7, IN8};


for (i = 0; i < IN_NUMBER; ++i)
    {
        nrf_gpio_cfg_output(input_list[i]);  //Configure as Output
    }

But when I measure the generated signal using a DAC and an oscilloscope the frequency of the signal is as seen in the next image:

The achieved period is of 569us, which gives a 1.757kHz frequency.

I saw in other tickets people saying that GPIO frequency can go up to 16Mhz. Then, why can't I generate a high-frequency signal?

Parents
  • Hi,

    as I understood from oscilloscope screenshot, you have a 57-us interval between GPIO switching. I think sprintf() and SEGGER_RTT_WriteString() eat most of these 57 microseconds, try to comment them out. To achieve maximum frequency, use HAL module functions (nrf_timer.h) instead of nrf_drv_timer, and write an irq handler (as short as possible) by yourself.

  • Hello.

    Thank you for your suggestions.

    Just by removing the debugging functions I already noticed a 5x improvement in the frequency. I wrote the code based on the examples found in the nRF5_SDK_16. There, they use the functions in the nrf_drv_timer for timer initialization. Would you know where I could find examples of timer initialization using the functions in the nrf_timer.h?

  • You can look at source code of Contiki-NG timer module. If you're using BLE stack, you'll need to configure other timer instance because TIMER0 is occupied by SoftDevice.

  • Thank you.

    I'll check the reference you provided.

    If you're using BLE stack, you'll need to configure other timer instance because TIMER0 is occupied by SoftDevice.

    Oh! I noticed that before but I didn't know why it happened. Thank you!

Reply Children
No Data
Related