Fix PIC32 timer source frequency
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4146 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
f45477ac99
commit
5072f4a553
@ -59,28 +59,53 @@
|
|||||||
* Definitions
|
* Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/* Timer Setup **************************************************************/
|
/* 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
|
/* 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:
|
* 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
|
* We want the largest possible value for MATCH that is less than 65,535, the
|
||||||
* maximum value for the 16-bit timer register:
|
* 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
|
* Timer 1 does not have very many options for the perscaler value. So we
|
||||||
* can pick the best by brute force. Example:
|
* can pick the best by brute force. Example:
|
||||||
*
|
*
|
||||||
|
* Example 1. Given:
|
||||||
|
* BOARD_TIMER1_SOSC = Defined
|
||||||
* BOARD_SOSC_FREQ = 32768
|
* BOARD_SOSC_FREQ = 32768
|
||||||
* CLOCKS_PER_SEC = 100
|
* CLOCKS_PER_SEC = 100
|
||||||
|
* Then:
|
||||||
* OPTIMAL_PRESCALE = 1
|
* OPTIMAL_PRESCALE = 1
|
||||||
* TIMER1_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
|
#if OPTIMAL_PRESCALE <= 1
|
||||||
# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_1
|
# define TIMER1_CON_TCKPS TIMER1_CON_TCKPS_1
|
||||||
# define TIMER1_PRESCALE 1
|
# define TIMER1_PRESCALE 1
|
||||||
@ -97,7 +122,7 @@
|
|||||||
# error "This timer frequency cannot be represented"
|
# error "This timer frequency cannot be represented"
|
||||||
#endif
|
#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
|
* Private Types
|
||||||
@ -143,9 +168,12 @@ int up_timerisr(int irq, uint32_t *regs)
|
|||||||
|
|
||||||
void up_timerinit(void)
|
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(0, PIC32MX_TIMER1_CNT);
|
||||||
putreg32(TIMER1_MATCH-1, PIC32MX_TIMER1_PR);
|
putreg32(TIMER1_MATCH-1, PIC32MX_TIMER1_PR);
|
||||||
putreg32(TIMER_CON_ON, PIC32MX_TIMER1_CONSET);
|
putreg32(TIMER_CON_ON, PIC32MX_TIMER1_CONSET);
|
||||||
|
@ -83,6 +83,13 @@
|
|||||||
#define BOARD_WD_ENABLE 0 /* Watchdog is disabled */
|
#define BOARD_WD_ENABLE 0 /* Watchdog is disabled */
|
||||||
#define BOARD_WD_PRESCALER 8 /* Watchdog pre-scaler */
|
#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 **********************************************************/
|
/* LED definitions **********************************************************/
|
||||||
/* The Sure PIC32MX board has five LEDs. One (D4, lablel "Power") is not
|
/* The Sure PIC32MX board has five LEDs. One (D4, lablel "Power") is not
|
||||||
* controllable by software. Four are controllable by software:
|
* controllable by software. Four are controllable by software:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user