Hello all!
I am trying to implement a GPSDO (GPS Disciplined Oscillator) using a TM4C123G.
I stumbled on the first step: count (OCXO) clock cycles. I configured WTIMER0A as a edge counter up, this part works, but the prescaler is not incremented when the 32 bit counter wraps.
Thanks in advance.
Edesio
References on GPSDO:
- initial idea: http://www.febo.com/pipermail/time-nuts/2014-February/082820.html
- initial code for Arduino: http://www.febo.com/pipermail/time-nuts/2014-February/082834.html
- revised and simplified code: http://www.febo.com/pipermail/time-nuts/2014-April/084118.html
Environment:
- board: Tive C Series TM4C123G
- processor: TM4C123GH6PM
- Code Composer Studio -- Version: 6.0.0.00190
- External clock at pin PC4: 10 MHz
Debug output:
Ready>
Timer0A: (0, 17060100)
Timer0A: (0, 136109986)
Timer0A: (0, 261279235)
Timer0A: (0, 825797122)
Timer0A: (0, 1589034047)
Timer0A: (0, 1954483747)
Timer0A: (0, 4281694411)
Timer0A: (0, 119617027)
Code:
/*
* main.c
*/
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "driverlib/rom_map.h"
#include "driverlib/gpio.h"
#include "utils/uartstdio.h"
#define USE_PRESCALER .. /* */
static void
PortFunctionInit(void)
{
int bitValue;
//
// Enable Peripheral Clocks
//
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
//
// Enable pin PB6 for TIMER0 T0CCP0
//
MAP_GPIOPinConfigure(GPIO_PB6_T0CCP0);
MAP_GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_6);
//
// Enable pin PB7 for TIMER0 T0CCP1
//
MAP_GPIOPinConfigure(GPIO_PB7_T0CCP1);
MAP_GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_7);
//
// Enable pin PB5 for TIMER1 T1CCP1
//
MAP_GPIOPinConfigure(GPIO_PB5_T1CCP1);
MAP_GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_5);
//
// Enable pin PB4 for TIMER1 T1CCP0
//
MAP_GPIOPinConfigure(GPIO_PB4_T1CCP0);
MAP_GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_4);
//
// Enable pin PA0 for UART0 U0RX
//
MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0);
//
// Enable pin PA1 for UART0 U0TX
//
MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_1);
//
// Enable pin PC5 for WTIMER0 WT0CCP1
//
MAP_GPIOPinConfigure(GPIO_PC5_WT0CCP1);
MAP_GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_5);
//
// Enable pin PC4 for WTIMER0 WT0CCP0
//
MAP_GPIOPinConfigure(GPIO_PC4_WT0CCP0);
MAP_GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_4);
}
//*****************************************************************************
//
// Configure the UART and its pins. This must be called before UARTprintf().
//
//*****************************************************************************
static void
ConfigureUART(void)
{
//
// Enable the GPIO Peripheral used by the UART.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Enable UART0
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
//
// Configure GPIO Pins for UART mode.
//
ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Use the internal 16MHz oscillator as the UART clock source.
//
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
//
// Initialize the UART for console I/O.
//
UARTStdioConfig(0, 9600, 16000000);
}
int main(void) {
unsigned int val, pre;
FPULazyStackingEnable();
/* set clock to 80 MHz */
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
PortFunctionInit();
ConfigureUART();
#if defined(USE_PRESCALER)
TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_COUNT_UP);
#else
TimerConfigure(WTIMER0_BASE, TIMER_CFG_A_CAP_COUNT_UP);
#endif
TimerControlEvent(WTIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
TimerEnable(WTIMER0_BASE, TIMER_A);
UARTprintf("Ready> \n");
while (1)
{
val = TimerValueGet(WTIMER0_BASE, TIMER_A);
pre = TimerPrescaleGet(WTIMER0_BASE, TIMER_A);
UARTprintf("Timer0A: (%u, %u)\n", pre, (val & 0xFFFFFFFF));
}
return 0;
}