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

How to change the GPIO output frequency of nRF52832 over 1MHz ?

Dear Sir,

I had a project is lighting the LED matrix, we choose the LED IC is TLC5958 and MCU is using nRF52832.

Now, we have a question is how to change the GPIO output frequency ?

After calculation, the LED IC clock needs 1.524MHz, but we try to pass the C language or modify the assembly language, GPIO can only output 1MHz.

Have any friends can help us ?

Thank you.

Wesley

2018.07.23

  • You can generate 1.6 MHz using a PWM peripherial. You might need to put the GPIO pin in high drive mode in order to achieve a good signal.

  • Hi Wesley,

    Here is a bare-metal code example to get the PWM peripheral to output 1.6MHz on pin 4:

    /**
     * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    
    #define PWM_PIN 4
    
    int16_t buf[] = {(1 << 15) | 5}; // Inverse polarity (bit 15)
    
    
    int main(void)
    {
    
        // Start accurate HFCLK (XOSC)
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) ;
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    
        // Configure PWM_PIN as output, and set it to 0
        NRF_GPIO->DIRSET = (1 << PWM_PIN);
        NRF_GPIO->OUTCLR = (1 << PWM_PIN);
    
    
        NRF_PWM0->PRESCALER   = PWM_PRESCALER_PRESCALER_DIV_1; // 
        NRF_PWM0->PSEL.OUT[0] = PWM_PIN;
        NRF_PWM0->MODE        = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos);
        NRF_PWM0->DECODER     = (PWM_DECODER_LOAD_Common       << PWM_DECODER_LOAD_Pos) | 
                                (PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos);
        NRF_PWM0->LOOP        = (PWM_LOOP_CNT_Disabled << PWM_LOOP_CNT_Pos);
    
        NRF_PWM0->COUNTERTOP = 10; 
    
    
        NRF_PWM0->SEQ[0].CNT = ((sizeof(buf) / sizeof(uint16_t)) << PWM_SEQ_CNT_CNT_Pos);
        NRF_PWM0->SEQ[0].ENDDELAY = 0;
        NRF_PWM0->SEQ[0].PTR = (uint32_t)&buf[0];
        NRF_PWM0->SEQ[0].REFRESH = 0;
        NRF_PWM0->SHORTS = 0;
    
        NRF_PWM0->ENABLE = 1;
        NRF_PWM0->TASKS_SEQSTART[0] = 1;
    
    
        while (true)
        {
        __WFE();
    
        }
    
    }
    
    
    /** @} */
    

Related