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

HFCLK Useage

SDK 15.3 API S132

How can i implement the HFCLK using softdevice or how can i enabled it

I need to be able to run an SK6812 which has the following timing requirements

using the LFCLK and 32MHZ crystal does not do it fast enough.  I tried to make an nrf_delay_fast in which I removed a bunch of NOP lines to try and reduce the delay.

This is not fast enough. How can I implement a faster clock using softdevice 132. I was able to get this timing cycle on sdk 12.1, but i was also able to change clock sources in firmware easily in 12.1 and not so easily in 15.0. Below is how I used it in SDK 12 and then i just set the clock to that. But even if i go into the nrf_sdh.c file and change the values to these it does not work like before.

#define NRF_CLOCK_LFCLKSRC_TLBX     {   .source        = CLOCK_HFCLKSTAT_SRC_RC, \
                                        .rc_ctiv       = 16,                     \
                                        .rc_temp_ctiv  = 2,                     \
                                        .xtal_accuracy =                        \
                                            NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM   }

or if it is not possible with softdevice how would you recommend I am able to get this timing sequence? 

Basically I would like to operate using the LFCLK source but when i need to turn on the LED, have the function turn on the HFCLK source and output using the HFCLK source so i can get the timing needed, then turn the HFCLK source off or maybe run a timer off the HFCLK source that triggers every 100ns and then use a counter or whatever based on t_on and t_off needs

I have been reading on PPI usage and came acrooss this

https://devzone.nordicsemi.com/f/nordic-q-a/44889/toggle-gpio-certain-number-of-times-with-ppi

i can now do a 0.3us pulse a 0.6us pulse and a 0.9us pulse.Unfortunately i cant seem to change this out once i turn it on. Is there a way to change the timer interrupt time

void adsclk_handler(nrf_timer_event_t event_type, void * p_context){
    if(toggle){
        //change the counter 
    }else{
        [CHANGE CC COUNTER]     
    }

    toggle = !toggle;

}

static void ppi_init(void)
{
    uint32_t err_code = NRF_SUCCESS;
    uint32_t compare_evt_addr;
    uint32_t gpiote_task_addr;

    toggle = false;

    if (!nrfx_gpiote_is_init())
    {
        err_code = nrfx_gpiote_init();
        APP_ERROR_CHECK(err_code);
    }

    nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
    err_code = nrfx_timer_init(&m_timer1, &timer_cfg, adsclk_handler);
    APP_ERROR_CHECK(err_code);

    nrfx_gpiote_out_config_t config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
    err_code = nrfx_gpiote_out_init(led_pin, &config);
    APP_ERROR_CHECK(err_code);

    nrfx_timer_extended_compare(&m_timer1, 
                                (nrf_timer_cc_channel_t)0, 
                                TIMER_INTERVAL, 
                                NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, 
                                true);
    
    err_code = nrfx_ppi_channel_alloc(&m_ppi_channel1);
    APP_ERROR_CHECK(err_code);

    compare_evt_addr = nrfx_timer_event_address_get(&m_timer1, NRF_TIMER_EVENT_COMPARE0);
    gpiote_task_addr = nrfx_gpiote_out_task_addr_get(led_pin);
    
    // hook up the compare event to trigger the toggle task
    err_code = nrfx_ppi_channel_assign(m_ppi_channel1, compare_evt_addr, gpiote_task_addr);
    APP_ERROR_CHECK(err_code);

    // enable the ppi channel
    err_code = nrfx_ppi_channel_enable(m_ppi_channel1);
    APP_ERROR_CHECK(err_code); 
}

void sk6812_led_test(void){
    nrfx_gpiote_out_task_enable(led_pin); // start sclk to shift data out
    nrfx_timer_enable(&m_timer1);
    
    nrf_delay_ms(200);
    
    nrfx_gpiote_out_task_disable(led_pin); 
    nrfx_timer_disable(&m_timer1);
}

Parents
  • I feel like this is probably not the most elegant method by which to do this, but i could not figure out how to engage the HFCLK so i can use delay or something off a 62.5ns clock cycle

    Using the normal clock i just tried to take C assembler out of the picture

    void sk6812_show(void){
        uint32_t err_code;
    
        nrf_gpio_pin_write(led_pin, 0);
        nrf_delay_fast(1);
    
        for(int i = 0; i < NUM_OF_LEDS; i++){
            for(int j = 0; j < 24; j++){
                if(pixels[i] << j & 0x800000){
                    NRF_P0->OUTSET = (1UL << led_pin);
                    __ASM(" MOV R0, #7\n\t"
                          " loop:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop\n\t");
    
                    NRF_P0->OUTCLR = (1UL << led_pin);
                    __ASM(" MOV R0, #2\n\t"
                          " loop2:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop2\n\t");
                }else{
                    NRF_P0->OUTSET = (1UL << led_pin);
                    __ASM(" MOV R0, #3\n\t"
                          " loop3:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop3\n\t");
                    NRF_P0->OUTCLR = (1UL << led_pin);
                    __ASM(" MOV R0, #7\n\t"
                          " loop4:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop4\n\t");
                }
            }
        }
        nrf_delay_ms(2);
    }

Reply
  • I feel like this is probably not the most elegant method by which to do this, but i could not figure out how to engage the HFCLK so i can use delay or something off a 62.5ns clock cycle

    Using the normal clock i just tried to take C assembler out of the picture

    void sk6812_show(void){
        uint32_t err_code;
    
        nrf_gpio_pin_write(led_pin, 0);
        nrf_delay_fast(1);
    
        for(int i = 0; i < NUM_OF_LEDS; i++){
            for(int j = 0; j < 24; j++){
                if(pixels[i] << j & 0x800000){
                    NRF_P0->OUTSET = (1UL << led_pin);
                    __ASM(" MOV R0, #7\n\t"
                          " loop:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop\n\t");
    
                    NRF_P0->OUTCLR = (1UL << led_pin);
                    __ASM(" MOV R0, #2\n\t"
                          " loop2:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop2\n\t");
                }else{
                    NRF_P0->OUTSET = (1UL << led_pin);
                    __ASM(" MOV R0, #3\n\t"
                          " loop3:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop3\n\t");
                    NRF_P0->OUTCLR = (1UL << led_pin);
                    __ASM(" MOV R0, #7\n\t"
                          " loop4:\n\t"
                              " SUBS R0, R0, #1\n\t"
                              " NOP\n\t"
                              " NOP\n\t"
                              " BNE loop4\n\t");
                }
            }
        }
        nrf_delay_ms(2);
    }

Children
No Data
Related