DM36X: Work in progress, add high-speed hardware timer support.

This commit is contained in:
Kelvin Lawson
2013-10-18 01:35:13 +01:00
parent d996dd52c7
commit f2f262aa55
5 changed files with 133 additions and 8 deletions

View File

@@ -39,7 +39,6 @@
/* Required number of system ticks per second (normally 100 for 10ms tick) */
#define SYSTEM_TICKS_PER_SEC 100
/* Size of each stack entry / stack alignment size (32 bits on this platform) */
#define STACK_ALIGN_SIZE sizeof(uint32_t)
@@ -50,7 +49,12 @@
*/
#define POINTER void *
/* *
/**
* Hardware timer functions (optional, not available on all ports)
*/
void archNanosleep (int32_t nanosecs);
/**
*
* Functions defined in atomport_arm.asm
*
@@ -58,7 +62,6 @@
extern uint32_t contextEnterCritical (void) ;
extern void contextExitCritical (uint32_t posture) ;
/**
* Critical region protection: this should disable interrupts
* to protect OS data structures during modification. It must

View File

@@ -42,7 +42,7 @@ TESTS_TTYBAUD=115200
BUILD_DIR=build
# Platform-specific object files
PLATFORM_OBJECTS = atomport-private.o uart.o
PLATFORM_OBJECTS = atomport-private.o uart.o timer.o
PLATFORM_ASM_OBJECTS = startup.o
# Port-specific object files

View File

@@ -41,10 +41,6 @@ extern unsigned long _start_vectors, _end_vectors, _end_text, _start_data, _end_
extern int main(void);
/** Timer input clock speed: 24MHz */
#define TIMER_CLK 24000000
/** Register access macros */
#define TIMER0_REG(offset) *(volatile uint32_t *)(DM36X_TIMER0_BASE + offset)
#define INTC_REG(offset) *(volatile uint32_t *)(DM36X_INTC_BASE + offset)

View File

@@ -33,6 +33,10 @@
#include "atomport.h"
/** Timer input clock speed: 24MHz */
#define TIMER_CLK 24000000
/*
* IO Addresses for use with DM36x
*/
@@ -190,6 +194,7 @@
/** Timer registers */
#define DM36X_TIMER0_BASE 0x01C21400 /* TIMER0 */
#define DM36X_TIMER1_BASE 0x01C21800 /* TIMER1 */
#define DM36X_TIMER_PID12 0x00
#define DM36X_TIMER_EMUMGT 0x04
#define DM36X_TIMER_TIM12 0x10

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2013, Kelvin Lawson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. No personal names or organizations' names associated with the
* Atomthreads project may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* Driver for accurate high-speed hardware timers.
*
* Uses the TIMER1 hardware module of DM36x.
*/
#include "atom.h"
#include "atomport.h"
#include "dm36x-io.h"
/* Constants */
/** Register access macros: using TIMER1 */
#define TIMER_REG(offset) *(volatile uint32_t *)(DM36X_TIMER1_BASE + offset)
/* Local data */
/*
* Initialised flag
*/
static int initialised = FALSE;
/* Forward declarations */
static int timer_init (void);
/**
* \b timer_init
*
* Initialisation of TIMER1 hardware.
*
* @retval ATOM_OK Success
* @retval ATOM_ERROR Failed
*/
static int timer_init (void)
{
int status;
/* Check we are not already initialised */
if (initialised == FALSE)
{
/* Initialise TIMER1 registers for microsecond accuracy timer */
/* Reset & disable all TIMER1 timers */
TIMER_REG(DM36X_TIMER_INTCTL_STAT) = 0; /* Disable interrupts */
TIMER_REG(DM36X_TIMER_TCR) = 0; /* Disable all TIMER1 timers */
TIMER_REG(DM36X_TIMER_TGCR) = 0; /* Put all TIMER1 timers in reset */
TIMER_REG(DM36X_TIMER_TIM12) = 0; /* Clear Timer 1:2 */
/* Set up Timer 1:2 in 32-bit unchained mode */
TIMER_REG(DM36X_TIMER_TGCR) = (1 << 2); /* Select 32-bit unchained mode (TIMMODE) */
TIMER_REG(DM36X_TIMER_TGCR) |= (1 << 0); /* Remove Timer 1:2 from reset (TIM12RS) */
TIMER_REG(DM36X_TIMER_PRD12) = ~0; /* Set period to free-running 24MHz clock (PRD12) */
TIMER_REG(DM36X_TIMER_TCR) |= (0 << 8); /* Select external clock source for Timer 1:2 (CLKSRC12) */
/* Enable timer */
TIMER_REG(DM36X_TIMER_TCR) |= (2 << 6); /* Enable Timer 1:2 continuous (ENAMODE12) */
/* Success */
initialised = TRUE;
status = ATOM_OK;
}
/* Finished */
return (status);
}
/**
* \b archNanosleep
*
* Simple spin loop of at least the specified nanoseconds.
*
* @param[in] nanosecs Number of nanoseconds to sleep
*
* @return None
*
*/
void archNanosleep (int32_t nanosecs)
{
/* Check we are initialised */
if (initialised == FALSE)
{
timer_init();
}
}