TMS570: Add system timer logic
This commit is contained in:
parent
fa36531fee
commit
a76f2b853a
@ -137,53 +137,44 @@
|
||||
/* Register Bit-Field Definitions *******************************************************************/
|
||||
|
||||
/* RTI Global Control Register */
|
||||
#define RTI_GCTRL_
|
||||
|
||||
#define RTI_GCTRL_CNT0EN (1 << 0) /* Bit 0: Counter 0 enable */
|
||||
#define RTI_GCTRL_CNT1EN (1 << 1) /* Bit 1: Counter 1 enable */
|
||||
#define RTI_GCTRL_COS (1 << 15) /* Bit 15: Continue on suspend */
|
||||
|
||||
/* RTI Capture Control Register */
|
||||
#define RTI_CAPCTRL_
|
||||
|
||||
#define RTI_CAPCTRL_CAPCNTR0 (1 << 0) /* Bit 0: Capture counter 0 */
|
||||
#define RTI_CAPCTRL_CAPCNTR1 (1 << 1) /* Bit 1: Capture counter 1 */
|
||||
|
||||
/* RTI Compare Control Register */
|
||||
#define RTI_COMPCTRL_
|
||||
/* RTI Free Running Counter 0 Register */
|
||||
#define RTI_FRC0_
|
||||
/* RTI Up Counter 0 Register */
|
||||
#define RTI_UC0_
|
||||
/* RTI Compare Up Counter 0 Register */
|
||||
#define RTI_CPUC0_
|
||||
/* RTI Capture Free Running Counter 0 Register */
|
||||
#define RTI_CAFRC0_
|
||||
/* RTI Capture Up Counter 0 Register */
|
||||
#define RTI_CAUC0_
|
||||
/* RTI Free Running Counter 1 Register */
|
||||
#define RTI_FRC1_
|
||||
/* RTI Up Counter 1 Register */
|
||||
#define RTI_UC1_
|
||||
/* RTI Compare Up Counter 1 Register */
|
||||
#define RTI_CPUC1_
|
||||
/* RTI Capture Free Running Counter 1 Register */
|
||||
#define RTI_CAFRC1_
|
||||
/* RTI Capture Up Counter 1 Register */
|
||||
#define RTI_CAUC1_
|
||||
/* RTI Compare 0 Register Section */
|
||||
#define RTI_COMP0_
|
||||
/* RTI Update Compare 0 Register */
|
||||
#define RTI_UDCP0_
|
||||
/* RTI Compare 1 Register */
|
||||
#define RTI_COMP1_
|
||||
/* RTI Update Compare 1 Register */
|
||||
#define RTI_UDCP1_
|
||||
/* RTI Compare 2 Register */
|
||||
#define RTI_COMP2_
|
||||
/* RTI Update Compare 2 Register */
|
||||
#define RTI_UDCP2_
|
||||
/* RTI Compare 3 Register */
|
||||
#define RTI_COMP3_
|
||||
/* RTI Update Compare 3 Register */
|
||||
#define RTI_UDCP3_
|
||||
/* RTI Set Interrupt Enable Register */
|
||||
#define RTI_SETINTENA_
|
||||
/* RTI Clear Interrupt Enable Register */
|
||||
#define RTI_CLEARINTENA_
|
||||
/* RTI Interrupt Flag Register */
|
||||
#define RTI_INTFLAG_
|
||||
|
||||
#define RTI_COMPCTRL_COMPSEL0 (1 << 0) /* Bit 0: Compare select 0 */
|
||||
#define RTI_COMPCTRL_COMPSEL1 (1 << 4) /* Bit 4: Compare select 1 */
|
||||
#define RTI_COMPCTRL_COMPSEL2 (1 << 8) /* Bit 8: Compare select 2 */
|
||||
#define RTI_COMPCTRL_COMPSEL3 (1 << 12) /* Bit 12: Compare select 3 */
|
||||
|
||||
/* RTI Free Running Counter 0/1 Register (32-bit counter value) */
|
||||
/* RTI Up Counter 0/1 Register (32-bit counter value) */
|
||||
/* RTI Compare Up Counter 0/1 Register (32-bit counter value) */
|
||||
/* RTI Capture Free Running Counter 0/1 Register (32-bit counter value) */
|
||||
/* RTI Capture Up Counter 0/1 Register (32-bit counter value) */
|
||||
/* RTI Compare 0/1/2/3 Register Section (32-bit counter value) */
|
||||
/* RTI Update Compare 0/1/2/3 Register (32-bit counter value) */
|
||||
|
||||
/* RTI Set Interrupt Enable Register, RTI Clear Interrupt Enable Register, and
|
||||
* RTI Interrupt Flag Register
|
||||
*/
|
||||
|
||||
#define RTI_INT0 (1 << 0) /* Bit 0: Compare interrupt 0 */
|
||||
#define RTI_INT1 (1 << 1) /* Bit 1: Compare interrupt 1 */
|
||||
#define RTI_INT2 (1 << 2) /* Bit 2: Compare interrupt 2 */
|
||||
#define RTI_INT3 (1 << 3) /* Bit 3: Compare interrupt 3 */
|
||||
#define RTI_TBINT (1 << 16) /* Bit 16: Timebase interrupt */
|
||||
#define RTI_OVL0INT (1 << 17) /* Bit 17: Free running counter 0 overflow interrupt */
|
||||
#define RTI_OVL1INT (1 << 18) /* Bit 18: Free running counter 1 overflow interrupt */
|
||||
#define RTI_ALLINTS 0x0007000f
|
||||
|
||||
/* Digital Watchdog Control Register */
|
||||
#define RTI_DWDCTRL_
|
||||
/* Digital Watchdog Preload Register */
|
||||
|
@ -61,6 +61,50 @@
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BOARD_VCLK_DIVIDER
|
||||
# error BOARD_VCLK_DIVIDER is not defined
|
||||
#endif
|
||||
|
||||
#if BOARD_VCLK_DIVIDER == 1
|
||||
# define SYS_CLKCNTL_VCLKR SYS_CLKCNTL_VCLKR_DIV1
|
||||
#elif BOARD_VCLK_DIVIDER == 2
|
||||
# define SYS_CLKCNTL_VCLKR SYS_CLKCNTL_VCLKR_DIV2
|
||||
#else
|
||||
# error Invalid value for BOARD_VCLK_DIVIDER
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_VCLK2_DIVIDER
|
||||
# error BOARD_VCLK2_DIVIDER is not defined
|
||||
#endif
|
||||
|
||||
#if BOARD_VCLK2_DIVIDER == 1
|
||||
# define SYS_CLKCNTL_VCLKR2 SYS_CLKCNTL_VCLKR2_DIV1
|
||||
#elif BOARD_VCLK2_DIVIDER == 2
|
||||
# define SYS_CLKCNTL_VCLKR2 SYS_CLKCNTL_VCLKR_DIV2
|
||||
#else
|
||||
# error Invalid value for SYS_CLKCNTL_VCLKR2_DIV2
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_RTICLK_DIVIDER
|
||||
# error BOARD_RTICLK_DIVIDER is not defined
|
||||
#endif
|
||||
|
||||
#if BOARD_RTICLK_DIVIDER == 1
|
||||
# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV1
|
||||
#elif BOARD_RTICLK_DIVIDER == 2
|
||||
# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV2
|
||||
#elif BOARD_RTICLK_DIVIDER == 4
|
||||
# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV4
|
||||
#elif BOARD_RTICLK_DIVIDER == 78
|
||||
# define SYS_RCLKSRC_RTI1DIV SYS_RCLKSRC_RTI1DIV_DIV8
|
||||
#else
|
||||
# error Invalid value for SYS_CLKCNTL_VCLKR2_DIV2
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -434,12 +478,12 @@ static void tms570_clocksrc_configure(void)
|
||||
|
||||
regval = getreg32(TMS570_SYS_CLKCNTL);
|
||||
regval &= ~(SYS_CLKCNTL_VCLKR2_MASK | SYS_CLKCNTL_VCLKR_MASK);
|
||||
regval |= SYS_CLKCNTL_VCLKR2_DIV1 | SYS_CLKCNTL_VCLKR_DIV1;
|
||||
regval |= SYS_CLKCNTL_VCLKR2 | SYS_CLKCNTL_VCLKR;
|
||||
putreg32(regval, TMS570_SYS_CLKCNTL);
|
||||
|
||||
/* Setup RTICLK1 and RTICLK2 clocks */
|
||||
|
||||
regval = SYS_RCLKSRC_RTI1SRC_VCLK | SYS_RCLKSRC_RTI1DIV_DIV2;
|
||||
regval = SYS_RCLKSRC_RTI1SRC_VCLK | SYS_RCLKSRC_RTI1DIV;
|
||||
putreg32(regval, TMS570_SYS_RCLKSRC);
|
||||
|
||||
/* Setup asynchronous peripheral clock sources for AVCLK1 */
|
||||
|
@ -137,6 +137,10 @@ void up_irqinitialize(void)
|
||||
|
||||
putreg32((uint32_t)tms570_error_handler, TMS570_VIM_FBPARERR);
|
||||
|
||||
/* Assign all interrupt requests to the VIM channel of the same value.
|
||||
* NOTE: Nothing need be done. That is the power-on default mapping.
|
||||
*/
|
||||
|
||||
/* Assign all channels to IRQs */
|
||||
|
||||
putreg32(0, TMS570_VIM_FIRQPR0);
|
||||
@ -184,27 +188,6 @@ void up_irqinitialize(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tms570_vim_channel
|
||||
*
|
||||
* Description:
|
||||
* Allocate a VIM channel and assign it to the 'request'.
|
||||
*
|
||||
* Input Parameters:
|
||||
* request - The interrupt request to be mapped to a channel
|
||||
*
|
||||
* Returned Value:
|
||||
* One sucess, the allocated channel number is returned. A negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tms570_vim_channel(int request)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_decodeirq
|
||||
*
|
||||
|
@ -61,23 +61,6 @@ extern "C"
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tms570_vim_channel
|
||||
*
|
||||
* Description:
|
||||
* Allocate a VIM channel and assign it to the 'request'.
|
||||
*
|
||||
* Input Parameters:
|
||||
* request - The interrupt request to be mapped to a channel
|
||||
*
|
||||
* Returned Value:
|
||||
* One sucess, the allocated channel number is returned. A negated errno
|
||||
* value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tms570_vim_channel(int request);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enable_fiq
|
||||
*
|
||||
|
@ -39,10 +39,160 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "chip/tms570_rti.h"
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* The input clock to the RTI is the RTICLK. The RTI source is always VCLK
|
||||
* which may be divided down by 2. The correct RTICLK frequency must be
|
||||
* provided by board.h file as BOARD_RTICLK_FREQUENCY.
|
||||
*/
|
||||
|
||||
#ifndef BOARD_RTICLK_FREQUENCY
|
||||
# error BOARD_RTICLK_FREQUENCY not defined
|
||||
#endif
|
||||
|
||||
/* Timing Calculations:
|
||||
*
|
||||
* FRC0CLK = RTICLK / (CPUC0 + 1) Hz
|
||||
* Tcount = 1 / FRC0CLK Seconds
|
||||
* = 1,000,000 / FRC0CLK Microseconds
|
||||
* CMP0 = Period / Tcount
|
||||
* = CONFIG_USEC_PER_TICK * FRC0CLK / 1,000,000
|
||||
* = CONFIG_USEC_PER_TICK * RTICLK / (CPUC0 + 1) / 1,000,000
|
||||
*
|
||||
* For Example:
|
||||
* VCLK = 80,000,000 Hz
|
||||
* RTICLK = VCLK / 2 Hz
|
||||
* = 40,000,000 Hz
|
||||
* CPUC0 = 39
|
||||
* FR0CLK = 1,000,000 Hz
|
||||
* Tcount = 1 Microsecond
|
||||
* CONFIG_USEC_PER_TICK = 10,000 Microseconds
|
||||
* CMP0 = 10,000 * 40,000,000 / 40 / 1,000,000
|
||||
* = 10, 000 = CONFIG_USEC_PER_TICK
|
||||
*/
|
||||
|
||||
#if BOARD_RTICLK_FREQUENCY > 10000000
|
||||
/* Use FR0CLK = 1MHz with CPUC0 at least 9 */
|
||||
|
||||
# define RTI_FRC0CLK (1000000)
|
||||
#elif BOARD_RTICLK_FREQUENCY > 5000000
|
||||
/* Use FR0CLK = 500KHz with CPUC0 at least 9 */
|
||||
|
||||
# define RTI_FRC0CLK (500000)
|
||||
#elif BOARD_RTICLK_FREQUENCY > 1000000
|
||||
/* Use FR0CLK = 100KHz with CPUC0 at least 9 */
|
||||
|
||||
# define RTI_FRC0CLK (100000)
|
||||
#else
|
||||
# error No logic for this value of RTICLK
|
||||
#endif
|
||||
|
||||
/* CPUC0 = RTICLK / FRC0CLK - 1
|
||||
*
|
||||
* NOTES:
|
||||
* - The following calculation performs rounding.
|
||||
*/
|
||||
|
||||
#define RTI_CPUC0 (((BOARD_RTICLK_FREQUENCY + RTI_FRC0CLK / 2) / RTI_FRC0CLK) - 1)
|
||||
|
||||
/* CMP0 = CONFIG_USEC_PER_TICK * FRC0CLK / 1,000,000
|
||||
*
|
||||
* NOTES:
|
||||
* - The following calculation performs rounding.
|
||||
* - The following calculation avoids integer overflow by depending on
|
||||
* FRCLK being a multiple of 100,000
|
||||
*/
|
||||
|
||||
#define RTI_CMP0 ((CONFIG_USEC_PER_TICK * (RTI_FRC0CLK / 100000) + 50) / 100)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timerisr
|
||||
*
|
||||
* Description:
|
||||
* The timer ISR will perform a variety of services for various portions
|
||||
* of the systems.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timerisr(int irq, uint32_t *regs)
|
||||
{
|
||||
/* Cleear the RTI Compare 0 interrupts */
|
||||
|
||||
putreg32(RTI_INT0, TMS570_RTI_INTFLAG);
|
||||
|
||||
/* Process timer interrupt */
|
||||
|
||||
sched_process_timer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_initialize
|
||||
*
|
||||
* Description:
|
||||
* This function is called during start-up to initialize the timer
|
||||
* interrupt.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_timer_initialize(void)
|
||||
{
|
||||
/* Disable all RTI interrupts */
|
||||
|
||||
up_disable_irq(TMS570_REQ_RTICMP0);
|
||||
putreg32(RTI_ALLINTS, TMS570_RTI_CLEARINTENA);
|
||||
|
||||
/* Configure RTICOMP0 register and the RTIUDCP0 Register to initialize with
|
||||
* the calculated compare value.
|
||||
*/
|
||||
|
||||
putreg32(RTI_CMP0, TMS570_RTI_COMP0);
|
||||
putreg32(RTI_CMP0, TMS570_RTI_UDCP0);
|
||||
|
||||
/* Configure the FRC0CLK clock by setting the RTICPUC0 register to the
|
||||
* calculated value.
|
||||
*/
|
||||
|
||||
putreg32(RTI_CMP0, TMS570_RTI_CPUC0);
|
||||
|
||||
/* Initialize the free-running counter and the RTI up-counter */
|
||||
|
||||
putreg32(0, TMS570_RTI_FRC0);
|
||||
putreg32(0, TMS570_RTI_UC0);
|
||||
|
||||
/* Clear any pending interrupts */
|
||||
|
||||
putreg32(RTI_ALLINTS, TMS570_RTI_COMP0);
|
||||
|
||||
/* Enable the RTI Compare 0 interrupts (still disabled at the VIM) */
|
||||
|
||||
putreg32(RTI_INT0, TMS570_RTI_SETINTENA);
|
||||
|
||||
/* Enable counter 0 */
|
||||
|
||||
putreg32(RTI_GCTRL_CNT0EN, TMS570_RTI_GCTRL);
|
||||
|
||||
/* Attach the interrupt handler to the RTI Compare 0 interrupt */
|
||||
|
||||
DEBUGVERIFY(irq_attach(TMS570_REQ_RTICMP0, (xcpt_t)up_timerisr));
|
||||
|
||||
/* Enable RTI compare 0 interrupts at the VIM */
|
||||
|
||||
up_enable_irq(TMS570_REQ_RTICMP0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user