diff --git a/ports/arm/atomport.h b/ports/arm/atomport.h index 19a2bfd..ee33428 100644 --- a/ports/arm/atomport.h +++ b/ports/arm/atomport.h @@ -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 diff --git a/ports/arm/platforms/dm36x/Makefile b/ports/arm/platforms/dm36x/Makefile index 29e1615..247422b 100644 --- a/ports/arm/platforms/dm36x/Makefile +++ b/ports/arm/platforms/dm36x/Makefile @@ -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 diff --git a/ports/arm/platforms/dm36x/atomport-private.c b/ports/arm/platforms/dm36x/atomport-private.c index 107f117..a7b2064 100644 --- a/ports/arm/platforms/dm36x/atomport-private.c +++ b/ports/arm/platforms/dm36x/atomport-private.c @@ -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) diff --git a/ports/arm/platforms/dm36x/dm36x-io.h b/ports/arm/platforms/dm36x/dm36x-io.h index 048b845..2b3eb14 100644 --- a/ports/arm/platforms/dm36x/dm36x-io.h +++ b/ports/arm/platforms/dm36x/dm36x-io.h @@ -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 diff --git a/ports/arm/platforms/dm36x/timer.c b/ports/arm/platforms/dm36x/timer.c new file mode 100644 index 0000000..b27d572 --- /dev/null +++ b/ports/arm/platforms/dm36x/timer.c @@ -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(); + } + +}