This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129ENCPDT: Unable to set timer clock to PIOSC

Part Number: TM4C129ENCPDT


Tool/software:

Hello,

my system clock is 120MHz. For implementation of a TRNG with an acceptable entropy I want to try to run one timer with PIOSC. This is the code used:

 

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"
#include "inc/hw_types.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_uart.h"
#include "inc/hw_timer.h"
#include "inc/hw_hibernate.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/hibernate.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"

void Timer0IntHandler(void);

uint32_t g_ui32SysClock = 0;

void main(void)
{
    // Systemclock auf 120 MHz
    g_ui32SysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_HIBERNATE)) {}
    HibernateEnableExpClk(g_ui32SysClock);
    HWREG(HIB_CC) = HIBERNATE_OUT_SYSCLK;

    // Set ALTCLK to PIOSC.
    SysCtlAltClkConfig(SYSCTL_ALTCLK_PIOSC);

    // GPIO für CCP-Ausgänge (optional für Oszilloskop)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOM))
        ;
//    GPIOPinConfigure(GPIO_PM6_T5CCP0);
//    GPIOPinTypeTimer(GPIO_PORTM_BASE, GPIO_PIN_6);

    GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_6);
    GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, 0);

    // Initialize Timer 0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0))
        ;

//    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_A_PERIODIC);
    TimerClockSourceSet(TIMER0_BASE, TIMER_CLOCK_PIOSC);
    TimerPrescaleSet(TIMER0_BASE, TIMER_A, 255);
    TimerLoadSet(TIMER0_BASE, TIMER_A, 624);

    TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    IntEnable(INT_TIMER0A);
    IntMasterEnable();

    TimerEnable(TIMER0_BASE, TIMER_A);

    while(1)
    {
        __WFI();
    }
}

void Timer0IntHandler(void)
{
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

    uint8_t ui8Pin = GPIOPinRead(GPIO_PORTM_BASE, GPIO_PIN_6);
    GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, ui8Pin ^ GPIO_PIN_6);
}

I tried different things: running as a periodic counter or in PWM mode (as i want to see the frequency on an oszilloscope for debugging). I am using the 16bit-counter TIMER0A, as I was reading in the forum, that the 32bit-mode is not working at all with a different clock source. I even tried to set ALTCLK to PIOSC and activated Hibernation just to try out if this helps. But whatever I try - the timer is running at 120MHz (GPTMCC = 0x01 !!!).

Is there a way to get this timer running with the 16MHz clock of PIOSC? 

Regards

Klaus

  • Hi,

      I just ran your code. When running as is, I see about 13kHz signal on PM6 pin. When I comment out the below two lines, I measured 96kHz. The ratio between on the frequencies is about right compared to 120 divided by 16. What do you mean the the timer is running at 120Mhz? Can you show your waveforms between running with the two lines below added and removed?

    SysCtlAltClkConfig(SYSCTL_ALTCLK_PIOSC);

    TimerClockSourceSet(TIMER0_BASE, TIMER_CLOCK_PIOSC);

  • Hello, these are 6 waveforms with 6 different settings of the following code. The three red line are set according to the caption of the waveform. USE_PIOSC switches between system clock and PIOSC clock. Unfortunately there is no difference. I am using the DK-TM4C129X evaluation board. The microcontroller on this board is a XM4C129XNCZADI (37AK3SW).

    #include <stdint.h>
    #include <stdbool.h>

    #include "inc/hw_memmap.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_types.h"
    #include "inc/hw_sysctl.h"
    #include "inc/hw_uart.h"
    #include "inc/hw_timer.h"
    #include "inc/hw_hibernate.h"
    #include "inc/hw_nvic.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/timer.h"
    #include "driverlib/hibernate.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"

    static void __WFI()                    { __asm volatile ("    wfi"); }

    uint32_t g_ui32SysClock = 0;

    #define USE_16BIT_TMR   1           // Switch between 16 and 32 bit timer
    #define USE_PWM         0           // Switch between PWM and GPIO toggle
    #define USE_PIOSC       1           // Switch between PIOSC and SYSTEM

    #if !USE_PWM
    __interrupt void Timer0IntHandler(void)
    {
        uint8_t ui8Pin = GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0);
        GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, ui8Pin ^ GPIO_PIN_0);

        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    }
    #endif

    void main(void)
    {
        // Systemclock auf 120 MHz
        g_ui32SysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);

    #if USE_PIOSC
        SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_HIBERNATE)) {}
        HibernateEnableExpClk(g_ui32SysClock);
        HWREG(HIB_CC) = HIBERNATE_OUT_SYSCLK;

        // Set ALTCLK to PIOSC.
        SysCtlAltClkConfig(SYSCTL_ALTCLK_PIOSC);
    #endif

        // GPIO für CCP-Ausgänge (optional für Oszilloskop)
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD))
            ;

    #if USE_PWM
        GPIOPinConfigure(GPIO_PD0_T0CCP0);
        GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_0);
    #else
        GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);
        GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0);
    #endif

        // Initialize Timer 0
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        while (!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0))
            ;

    #if USE_16BIT_TMR
    #if USE_PWM
        uint32_t ui32TimerCfg = TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM;
    #else
        uint32_t ui32TimerCfg = TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC;
    #endif
        TimerConfigure(TIMER0_BASE, ui32TimerCfg);
    #else
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    #endif

    #if USE_PIOSC
        TimerClockSourceSet(TIMER0_BASE, TIMER_CLOCK_PIOSC);
    #else
        TimerClockSourceSet(TIMER0_BASE, TIMER_CLOCK_SYSTEM);
    #endif

        TimerLoadSet(TIMER0_BASE, TIMER_A, 10000);
    #if USE_16BIT_TMR
        TimerPrescaleSet(TIMER0_BASE, TIMER_A, 0);
        TimerMatchSet(TIMER0_BASE, TIMER_A, 5000);
    #endif

    #if !USE_PWM
        TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler);
        TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        IntEnable(INT_TIMER0A);
        IntMasterEnable();
    #endif

        TimerEnable(TIMER0_BASE, TIMER_A);

        while(1)
        {
            __WFI();
        }
    }