From 5072f4a553d046b4192084ef11662b6f54921e28 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 7 Dec 2011 23:38:23 +0000 Subject: [PATCH] Fix PIC32 timer source frequency git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4146 42af7a65-404d-4744-a932-0658087f49c3 --- arch/mips/src/pic32mx/pic32mx-timerisr.c | 44 +++++++++++++++++++----- configs/sure-pic32mx/include/board.h | 7 ++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/mips/src/pic32mx/pic32mx-timerisr.c b/arch/mips/src/pic32mx/pic32mx-timerisr.c index 906ec0cc473..f6ad7f41b6c 100644 --- a/arch/mips/src/pic32mx/pic32mx-timerisr.c +++ b/arch/mips/src/pic32mx/pic32mx-timerisr.c @@ -59,28 +59,53 @@ * Definitions ****************************************************************************/ /* Timer Setup **************************************************************/ +/* Timer 1 is a type A timer. Setting the TCS bit in the timer control + * register will select the SOSC as the clock source. Otherwise, PBCLOCK + * is the clock source. + */ + +#ifdef BOARD_TIMER1_SOSC +# define TIMER1_SRC_FREQ BOARD_SOSC_FREQ +# define TIMER1_CON_TCS TIMER_CON_TCS +#else +# define TIMER1_SRC_FREQ BOARD_PBCLOCK +# define TIMER1_CON_TCS (0) +#endif + /* Select a timer 1 prescale value. Our goal is to select the timer MATCH - * register value given the board's SOSC clock frequency and the desired + * register value given the timer 1 input clock frequency and the desired * system timer frequency: * - * TIMER1_MATCH = BOARD_SOSC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC + * TIMER1_MATCH = TIMER1_SRC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC * * We want the largest possible value for MATCH that is less than 65,535, the * maximum value for the 16-bit timer register: * - * TIMER1_PRESCALE >= BOARD_SOSC_FREQ / CLOCKS_PER_SEC / 65535 + * TIMER1_PRESCALE >= TIMER1_SRC_FREQ / CLOCKS_PER_SEC / 65535 * * Timer 1 does not have very many options for the perscaler value. So we * can pick the best by brute force. Example: * + * Example 1. Given: + * BOARD_TIMER1_SOSC = Defined * BOARD_SOSC_FREQ = 32768 * CLOCKS_PER_SEC = 100 + * Then: * OPTIMAL_PRESCALE = 1 * TIMER1_PRESCALE = 1 - * TIMER1_MATCH = 328 -> 99.90 ticks/sec + * TIMER1_MATCH = 327 -> 100.3 ticks/sec + * + * Example 2. Given: + * BOARD_TIMER1_SOSC = Not defined + * BOARD_PBCLOCK = 60000000 + * CLOCKS_PER_SEC = 100 + * Then: + * OPTIMAL_PRESCALE = 9.2 + * TIMER1_PRESCALE = 64 + * TIMER1_MATCH = 9375 -> 100.0 ticks/sec */ -#define OPTIMAL_PRESCALE (BOARD_SOSC_FREQ / CLOCKS_PER_SEC / 65535) +#define OPTIMAL_PRESCALE (TIMER1_SRC_FREQ / CLOCKS_PER_SEC / 65535) #if OPTIMAL_PRESCALE <= 1 # define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_1 # define TIMER1_PRESCALE 1 @@ -97,7 +122,7 @@ # error "This timer frequency cannot be represented" #endif -#define TIMER1_MATCH (BOARD_SOSC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC) +#define TIMER1_MATCH (TIMER1_SRC_FREQ / TIMER1_PRESCALE / CLOCKS_PER_SEC) /**************************************************************************** * Private Types @@ -143,9 +168,12 @@ int up_timerisr(int irq, uint32_t *regs) void up_timerinit(void) { - /* Configure and enable TIMER1 -- source internal SOSC (TCS=0) */ + /* Configure and enable TIMER1. Used the computed TCKPS divider and timer + * match valude. The source will be either the internal PBCLOCK (TCS=0) or + * the external SOSC (TCS=1) + */ - putreg32(TIMER1_CON_TCKPS, PIC32MX_TIMER1_CON); + putreg32((TIMER1_CON_TCKPS|TIMER1_CON_TCS), PIC32MX_TIMER1_CON); putreg32(0, PIC32MX_TIMER1_CNT); putreg32(TIMER1_MATCH-1, PIC32MX_TIMER1_PR); putreg32(TIMER_CON_ON, PIC32MX_TIMER1_CONSET); diff --git a/configs/sure-pic32mx/include/board.h b/configs/sure-pic32mx/include/board.h index dffb8c5190a..44eff5b6235 100644 --- a/configs/sure-pic32mx/include/board.h +++ b/configs/sure-pic32mx/include/board.h @@ -83,6 +83,13 @@ #define BOARD_WD_ENABLE 0 /* Watchdog is disabled */ #define BOARD_WD_PRESCALER 8 /* Watchdog pre-scaler */ +/* Timer 1 is a type A timer and is used as system clock. It can be clocked + * with either the SOSC or the PBCLOCK. We will use the PBCLOCK because it + * is much more accurate. + */ + +#undef BOARD_TIMER1_SOSC + /* LED definitions **********************************************************/ /* The Sure PIC32MX board has five LEDs. One (D4, lablel "Power") is not * controllable by software. Four are controllable by software: