NXP LPC812 Clocks and Timers

clocks

Oscillators and Clocks

The System Oscillator, not to be confused with the System Clock, can be fed by an external source (XTAL pins or CLKIN pin) or from the 12MHz Internal Oscillator. The external sources are limited to a maximum frequency of 25MHz. The Phase Lock Loop (PLL), if needed, can be clocked from the System Oscillator.

The PLL is unique because it can produce an output frequency higher than its input. The PLL accepts a source between 10 and 25MHz, can then be multiplied up to 32 times, and operate at a maximum frequency of 100MHz.

In turn, the Main Clock can be sourced from the System Oscillator, the PLL or the Watchdog Oscillator. The Watchdog Oscillator is for low frequency (0.6 – 4.6MHz) and therefore low power consumption.

Finally, the Main Clock feeds the System Clock through the SYSAHBCLKDIV divider register (1-255). The System Clock runs the core, the memories and peripherals at this resulting frequency. The System Clock can operate up to a maximum frequency of 30MHz.

All of the individual peripherals must be clocked prior to use. Nineteen peripherals are clocked via the SYSAHBCLKCTRL register. The System Clock is always on and is represented by bit #1 (read-only). Separately, the UART peripheral operates off the Main Clock through its own divider register (UARTCLKDIV) and fractional generator (UARTFRGDIV).

By default (and upon reset), the System Clock is fed from the 12MHz Internal Oscillator, and therefore clock configuration is not necessarily required if this is acceptable. Any other clock configuration requires setup.

NXP MS Excel spreadsheet to assist configuring PLL parameters.

The LPC800 clock diagram:
lpc800 clock diagram

48MHz PLL/24MHz System Clock Example:

#include <stdint.h>
#include "LPC812.h" //my bare metal version

//our systick interrupt handler
void SysTick_Handler(void) {
  //toggle led pin
  GPIO_NOT = (1<<6);
}

//setup system clock for PLL
void SystemInit(void) {
  //enable AHB clock to SWM and IOCON
  SYSCON_SYSAHBCLKCTRL |= (1<<SWM) | (1<<IOCON);
  //power-up PLL 
  SYSCON_PDRUNCFG &= ~(1<<7);
  //set irc as input to PLL & toggle update enable 
  SYSCON_SYSPLLCLKSEL = 0UL;
  SYSCON_SYSPLLCLKUEN = 0UL;
  SYSCON_SYSPLLCLKUEN = 1UL;
  //set PLL to 48MHz M=4=(48/12), so MSEL=3 and P=4 (48*4=192), so PSEL=2
  SYSCON_SYSPLLCTRL = (3 + (2<<5));
  //wait until PLL locked
  while (!(SYSCON_SYSPLLSTAT&0x01));
  //set PLL as main clock & toggle update enable
  SYSCON_MAINCLKSEL = 3UL;
  SYSCON_MAINCLKUEN = 0UL;
  SYSCON_MAINCLKUEN = 1UL;
  //wait until update complted
  while (!(SYSCON_MAINCLKUEN&0x01));
  //set system clock divider = 2
  SYSCON_SYSAHBCLKDIV = 2;
  //main clock speed
  SystemMainClock = 12000000UL*((SYSCON_SYSPLLCTRL&0x1f) + 1);
  //core clock speed
  SystemCoreClock = SystemMainClock/SYSCON_SYSAHBCLKDIV;
}

int main(void) {
  //initate PLL & clocks
  SystemInit();
  //init gpio port
  GpioInit();
  //make gpio #6 pin an output (physical pin #10)
  GPIO_DIR |= (1<<6);
  //set systick clock interrupt
  SysTickConfig(1000000UL);
  //loop forever
  while(1)
    asm("wfi"); //wait for interrupt
}

I know you’re thinking about it, so here is some information on overclocking the µC.

SysTick Timer

Every Cortex-M processor incorporates a basic 24-bit system timer. This Systick timer can be used to create basic time delays or generate periodic interrupts. It consists of 3 registers which are used to configure and set the load/reload max counter value. The combination of counter register (zero based) and System Clock frequency together define the period.

SysTick Example:

//12MHz
#define SYSTEM_CORE_CLOCK 12000000UL

//millisecond counter
volatile uint32_t millis = 0;

//Initializes the System Timer and its interrupt, and starts the System Tick Timer.
//ticks = number of ticks between two interrupts.
static inline uint32_t SysTickConfig(uint32_t ticks) {
  if (ticks > 0xFFFFFFUL)
    return (1); //reload value impossible
  //set reload register, counter rolls over @0, hence -1
  NVIC_ST_RELOAD = (ticks&0xFFFFFFUL) - 1;
  //set priority for Systick Interrupt
  SCB_SHP1 = 0xC0000000;
  //load the SysTick counter
  NVIC_ST_CURRENT = 0;
  //enable SysTick IRQ and timer 
  NVIC_ST_CTRL = 0x07;
  return (0);
}

//our systick interrupt handler
void SysTick_Handler(void) {
  millis++;
}

//delay (ms)
void delay_ms(uint32_t ms) {
  uint32_t now = millis;
  while ((millis - now) < ms);
}

int main(void) {
  …
  //setup systick clock interrupt @1ms
  SysTickConfig(SYSTEM_CORE_CLOCK/1000);
  …
}

Multi-rate Timer (MRT)

The MRT comprises 4 individual 31-bit count-down timers (called channels) capable of producing repetitive or one-shot interrupts, or performing a unique short (10-50 clock cycle) bus-stall operation. All 4 channels trigger the same interrupt routine, which can be made to determine the activating channel.

The repetitive interrupt mode operates similar to the SysTick Timer. Unlike a polling timer, the bus-stall function halts bus transaction and results in low power consumption.

See this blog for MRT bus-stall and MRT millisecond delay/callback examples.

System Configurable Timer (SCTimer/PWM)

The State Configurable Timer (SCTimer/PWM) is a peripheral unique to NXP. It is capable of operating like a traditional µC timer, a state machine, multiple PWMs and other advanced features. An in-depth demonstration of the SCTimer/PWM features is beyond the scope of this tutorial. NXP Application Note 11538 gives many examples of SCTimer/PWM use.

Basic SCTimer/PWM repetitive IRQ Example:

  //enable SCT peripheral clock
  SYSCON_SYSAHBCLKCTRL = (1<<8) | (SYSCON_SYSAHBCLKCTRL&~0xda100000);
  //assert/de-assert peripheral reset
  SYSCON_PRESETCTRL &= ~((1<<SCT_RST_N) | 0xfffe2000);
  SYSCON_PRESETCTRL = (1<<SCT_RST_N) |  (SYSCON_PRESETCTRL&~0xfffe2000);
  //unified 32-bit counter & auto limit
  SCT_CONFIG = (1<<0) | (1<<17);
  //set match count & match reload
  SCT_MATCH0 = (SYSTEM_CORE_CLOCK/100);
  SCT_MATCHREL0 = (SYSTEM_CORE_CLOCK/100);
  //set event #0 to all states
  SCT_EV0_STATE = 0xffffffff;
  //match 0 condition only 
  SCT_EV0_CTRL = (1<<12);
  //event 0 generates an interrupt
  SCT_EVEN = (1<<0);
  //enable SCTimer/PWM interrupt
  NVIC_EnableIRQ(9);
  //unhalt SCT by clearing bit 2 of CTRL
  SCT_CTRL &= ~(1<<2);

The above examples use this LPC812.h header file:

//LPC812.h

// GPIO_PORTs
#define GPIO_BASE            0xA0000000
#define GPIO0_0              (*((volatile unsigned char *)(GPIO_BASE + 0x00)))
#define GPIO0_1              (*((volatile unsigned char *)(GPIO_BASE + 0x01)))
#define GPIO0_2              (*((volatile unsigned char *)(GPIO_BASE + 0x02)))
#define GPIO0_3              (*((volatile unsigned char *)(GPIO_BASE + 0x03)))
#define GPIO0_4              (*((volatile unsigned char *)(GPIO_BASE + 0x04)))
#define GPIO0_5              (*((volatile unsigned char *)(GPIO_BASE + 0x05)))
#define GPIO0_6              (*((volatile unsigned char *)(GPIO_BASE + 0x06)))
#define GPIO0_7              (*((volatile unsigned char *)(GPIO_BASE + 0x07)))
#define GPIO0_8              (*((volatile unsigned char *)(GPIO_BASE + 0x08)))
#define GPIO0_9              (*((volatile unsigned char *)(GPIO_BASE + 0x09)))
#define GPIO0_10             (*((volatile unsigned char *)(GPIO_BASE + 0x0A)))
#define GPIO0_11             (*((volatile unsigned char *)(GPIO_BASE + 0x0B)))
#define GPIO0_12             (*((volatile unsigned char *)(GPIO_BASE + 0x0C)))
#define GPIO0_13             (*((volatile unsigned char *)(GPIO_BASE + 0x0D)))
#define GPIO0_14             (*((volatile unsigned char *)(GPIO_BASE + 0x0E)))
#define GPIO0_15             (*((volatile unsigned char *)(GPIO_BASE + 0x0F)))
#define GPIO0_16             (*((volatile unsigned char *)(GPIO_BASE + 0x10)))
#define GPIO0_17             (*((volatile unsigned char *)(GPIO_BASE + 0x11)))
#define GPIO_DIR             (*((volatile unsigned int *)(GPIO_BASE + 0x2000)))
#define GPIO_MASK            (*((volatile unsigned int *)(GPIO_BASE + 0x2080)))
#define GPIO_PORT            (*((volatile unsigned int *)(GPIO_BASE + 0x2100)))
#define GPIO_MPORT           (*((volatile unsigned int *)(GPIO_BASE + 0x2180)))
#define GPIO_SET             (*((volatile unsigned int *)(GPIO_BASE + 0x2200)))
#define GPIO_CLR             (*((volatile unsigned int *)(GPIO_BASE + 0x2280)))
#define GPIO_NOT             (*((volatile unsigned int *)(GPIO_BASE + 0x2300)))

// Switch Matrix
#define SWM_BASE             0x4000C000
#define PINASSIGN0           (*((volatile unsigned int *)(SWM_BASE + 0x000)))
#define PINASSIGN1           (*((volatile unsigned int *)(SWM_BASE + 0x004)))
#define PINASSIGN2           (*((volatile unsigned int *)(SWM_BASE + 0x008)))
#define PINASSIGN3           (*((volatile unsigned int *)(SWM_BASE + 0x00c)))
#define PINASSIGN4           (*((volatile unsigned int *)(SWM_BASE + 0x010)))
#define PINASSIGN5           (*((volatile unsigned int *)(SWM_BASE + 0x014)))
#define PINASSIGN6           (*((volatile unsigned int *)(SWM_BASE + 0x018)))
#define PINASSIGN7           (*((volatile unsigned int *)(SWM_BASE + 0x01c)))
#define PINASSIGN8           (*((volatile unsigned int *)(SWM_BASE + 0x020)))
#define PINENABLE0           (*((volatile unsigned int *)(SWM_BASE + 0x1c0)))

// SCTimer/PWM
#define SCT_BASE             (0x50004000UL)
#define SCT_CONFIG           (*((volatile unsigned int *)(SCT_BASE + 0x000)))
#define SCT_CTRL             (*((volatile unsigned int *)(SCT_BASE + 0x004)))
#define SCT_LIMIT            (*((volatile unsigned int *)(SCT_BASE + 0x008)))
#define SCT_HALT             (*((volatile unsigned int *)(SCT_BASE + 0x00C)))
#define SCT_STOP             (*((volatile unsigned int *)(SCT_BASE + 0x010)))
#define SCT_START            (*((volatile unsigned int *)(SCT_BASE + 0x014)))
#define SCT_COUNT            (*((volatile unsigned int *)(SCT_BASE + 0x040)))
#define SCT_STATE            (*((volatile unsigned int *)(SCT_BASE + 0x044)))
#define SCT_INPUT            (*((volatile unsigned int *)(SCT_BASE + 0x048)))
#define SCT_REGMODE          (*((volatile unsigned int *)(SCT_BASE + 0x04C)))
#define SCT_OUTPUT           (*((volatile unsigned int *)(SCT_BASE + 0x050)))
#define SCT_OUTPUTDIRCTRL    (*((volatile unsigned int *)(SCT_BASE + 0x054)))
#define SCT_RES              (*((volatile unsigned int *)(SCT_BASE + 0x058)))
#define SCT_EVEN             (*((volatile unsigned int *)(SCT_BASE + 0x0F0)))
#define SCT_EVFLAG           (*((volatile unsigned int *)(SCT_BASE + 0x0F4)))
#define SCT_CONEN            (*((volatile unsigned int *)(SCT_BASE + 0x0F8)))
#define SCT_CONFLAG          (*((volatile unsigned int *)(SCT_BASE + 0x0FC)))
#define SCT_MATCH0           (*((volatile unsigned int *)(SCT_BASE + 0x100)))
#define SCT_MATCH1           (*((volatile unsigned int *)(SCT_BASE + 0x104)))
#define SCT_MATCH2           (*((volatile unsigned int *)(SCT_BASE + 0x108)))
#define SCT_MATCH3           (*((volatile unsigned int *)(SCT_BASE + 0x10C)))
#define SCT_MATCH4           (*((volatile unsigned int *)(SCT_BASE + 0x110)))
#define SCT_CAP0             (*((volatile unsigned int *)(SCT_BASE + 0x100)))
#define SCT_CAP1             (*((volatile unsigned int *)(SCT_BASE + 0x104)))
#define SCT_CAP2             (*((volatile unsigned int *)(SCT_BASE + 0x108)))
#define SCT_CAP3             (*((volatile unsigned int *)(SCT_BASE + 0x10C)))
#define SCT_CAP4             (*((volatile unsigned int *)(SCT_BASE + 0x110)))
#define SCT_MATCHREL0        (*((volatile unsigned int *)(SCT_BASE + 0x200)))
#define SCT_MATCHREL1        (*((volatile unsigned int *)(SCT_BASE + 0x204)))
#define SCT_MATCHREL2        (*((volatile unsigned int *)(SCT_BASE + 0x208)))
#define SCT_MATCHREL3        (*((volatile unsigned int *)(SCT_BASE + 0x20C)))
#define SCT_MATCHREL4        (*((volatile unsigned int *)(SCT_BASE + 0x210)))
#define SCT_CAPCTRL0         (*((volatile unsigned int *)(SCT_BASE + 0x200)))
#define SCT_CAPCTRL1         (*((volatile unsigned int *)(SCT_BASE + 0x204)))
#define SCT_CAPCTRL2         (*((volatile unsigned int *)(SCT_BASE + 0x208)))
#define SCT_CAPCTRL3         (*((volatile unsigned int *)(SCT_BASE + 0x20C)))
#define SCT_CAPCTRL4         (*((volatile unsigned int *)(SCT_BASE + 0x210)))
#define SCT_EV0_STATE        (*((volatile unsigned int *)(SCT_BASE + 0x300)))
#define SCT_EV1_STATE        (*((volatile unsigned int *)(SCT_BASE + 0x308)))
#define SCT_EV2_STATE        (*((volatile unsigned int *)(SCT_BASE + 0x310)))
#define SCT_EV3_STATE        (*((volatile unsigned int *)(SCT_BASE + 0x318)))
#define SCT_EV4_STATE        (*((volatile unsigned int *)(SCT_BASE + 0x320)))
#define SCT_EV5_STATE        (*((volatile unsigned int *)(SCT_BASE + 0x328)))
#define SCT_EV0_CTRL         (*((volatile unsigned int *)(SCT_BASE + 0x304)))
#define SCT_EV1_CTRL         (*((volatile unsigned int *)(SCT_BASE + 0x30C)))
#define SCT_EV2_CTRL         (*((volatile unsigned int *)(SCT_BASE + 0x314)))
#define SCT_EV3_CTRL         (*((volatile unsigned int *)(SCT_BASE + 0x31C)))
#define SCT_EV4_CTRL         (*((volatile unsigned int *)(SCT_BASE + 0x324)))
#define SCT_EV5_CTRL         (*((volatile unsigned int *)(SCT_BASE + 0x32C)))
#define SCT_OUT0_SET         (*((volatile unsigned int *)(SCT_BASE + 0x500)))
#define SCT_OUT1_SET         (*((volatile unsigned int *)(SCT_BASE + 0x508)))
#define SCT_OUT2_SET         (*((volatile unsigned int *)(SCT_BASE + 0x510)))
#define SCT_OUT3_SET         (*((volatile unsigned int *)(SCT_BASE + 0x518)))
#define SCT_OUT0_CLR         (*((volatile unsigned int *)(SCT_BASE + 0x504)))
#define SCT_OUT1_CLR         (*((volatile unsigned int *)(SCT_BASE + 0x50C)))
#define SCT_OUT2_CLR         (*((volatile unsigned int *)(SCT_BASE + 0x514)))
#define SCT_OUT3_CLR         (*((volatile unsigned int *)(SCT_BASE + 0x51C)))

// USART0
#define USART0_BASE	         0x40064000
#define USART0_CFG           (*((volatile unsigned int *)(USART0_BASE + 0x00)))
#define USART0_CTL           (*((volatile unsigned int *)(USART0_BASE + 0x04)))
#define USART0_STAT          (*((volatile unsigned int *)(USART0_BASE + 0x08)))
#define USART0_INTENSET      (*((volatile unsigned int *)(USART0_BASE + 0x0c)))
#define USART0_INTENCLR      (*((volatile unsigned int *)(USART0_BASE + 0x10)))
#define USART0_RXDAT         (*((volatile unsigned int *)(USART0_BASE + 0x14)))
#define USART0_RXDATSTAT     (*((volatile unsigned int *)(USART0_BASE + 0x18)))
#define USART0_TXDAT         (*((volatile unsigned int *)(USART0_BASE + 0x1c)))
#define USART0_BRG           (*((volatile unsigned int *)(USART0_BASE + 0x20)))
#define USART0_INTSTAT       (*((volatile unsigned int *)(USART0_BASE + 0x24)))

// USART1
#define USART1_BASE          0x40068000
#define USART1_CFG           (*((volatile unsigned int *)(USART1_BASE + 0x00)))
#define USART1_CTL           (*((volatile unsigned int *)(USART1_BASE + 0x04)))
#define USART1_STAT          (*((volatile unsigned int *)(USART1_BASE + 0x08)))
#define USART1_INTENSET      (*((volatile unsigned int *)(USART1_BASE + 0x0c)))
#define USART1_INTENCLR      (*((volatile unsigned int *)(USART1_BASE + 0x10)))
#define USART1_RXDAT         (*((volatile unsigned int *)(USART1_BASE + 0x14)))
#define USART1_RXDATSTAT     (*((volatile unsigned int *)(USART1_BASE + 0x18)))
#define USART1_TXDAT         (*((volatile unsigned int *)(USART1_BASE + 0x1c)))
#define USART1_BRG           (*((volatile unsigned int *)(USART1_BASE + 0x20)))
#define USART1_INTSTAT       (*((volatile unsigned int *)(USART1_BASE + 0x24)))

// USART2
#define USART2_BASE			     0x4006C000
#define USART2_CFG           (*((volatile unsigned int *)(USART2_BASE + 0x00)))
#define USART2_CTL           (*((volatile unsigned int *)(USART2_BASE + 0x04)))
#define USART2_STAT          (*((volatile unsigned int *)(USART2_BASE + 0x08)))
#define USART2_INTENSET      (*((volatile unsigned int *)(USART2_BASE + 0x0c)))
#define USART2_INTENCLR      (*((volatile unsigned int *)(USART2_BASE + 0x10)))
#define USART2_RXDAT         (*((volatile unsigned int *)(USART2_BASE + 0x14)))
#define USART2_RXDATSTA      (*((volatile unsigned int *)(USART2_BASE + 0x18)))
#define USART2_TXDAT         (*((volatile unsigned int *)(USART2_BASE + 0x1c)))
#define USART2_BRG           (*((volatile unsigned int *)(USART2_BASE + 0x20)))
#define USART2_INTSTAT       (*((volatile unsigned int *)(USART2_BASE + 0x24)))

// SYSCON
#define SYSCON_BASE          0x40048000
#define SYSCON_MAP           (*((volatile unsigned int *)(SYSCON_BASE + 0x000)))
#define SYSCON_PRESETCTRL    (*((volatile unsigned int *)(SYSCON_BASE + 0x004)))
#define SYSCON_SYSPLLCTRL    (*((volatile unsigned int *)(SYSCON_BASE + 0x008)))
#define SYSCON_SYSPLLSTAT    (*((volatile unsigned int *)(SYSCON_BASE + 0x00C)))
#define SYSCON_SYSOSCCTRL    (*((volatile unsigned int *)(SYSCON_BASE + 0x020)))
#define SYSCON_WDTOSCCTRL    (*((volatile unsigned int *)(SYSCON_BASE + 0x024)))
#define SYSCON_SYSRSTSTAT    (*((volatile unsigned int *)(SYSCON_BASE + 0x030)))
#define SYSCON_SYSPLLCLKSEL  (*((volatile unsigned int *)(SYSCON_BASE + 0x040)))
#define SYSCON_SYSPLLCLKUEN  (*((volatile unsigned int *)(SYSCON_BASE + 0x044)))
#define SYSCON_MAINCLKSEL    (*((volatile unsigned int *)(SYSCON_BASE + 0x070)))
#define SYSCON_MAINCLKUEN    (*((volatile unsigned int *)(SYSCON_BASE + 0x074)))
#define SYSCON_SYSAHBCLKDIV  (*((volatile unsigned int *)(SYSCON_BASE + 0x078)))
#define SYSCON_SYSAHBCLKCTRL (*((volatile unsigned int *)(SYSCON_BASE + 0x080)))
#define SYSCON_UARTCLKDIV    (*((volatile unsigned int *)(SYSCON_BASE + 0x094)))
#define SYSCON_CLKOUTSEL     (*((volatile unsigned int *)(SYSCON_BASE + 0x0E0)))
#define SYSCON_CLKOUTUEN     (*((volatile unsigned int *)(SYSCON_BASE + 0x0E4)))
#define SYSCON_CLKOUTDIV     (*((volatile unsigned int *)(SYSCON_BASE + 0x0E8)))
#define SYSCON_UARTFRGDIV    (*((volatile unsigned int *)(SYSCON_BASE + 0x0F0)))
#define SYSCON_UARTFRGMULT   (*((volatile unsigned int *)(SYSCON_BASE + 0x0F4)))
#define SYSCON_EXTTRACECMD   (*((volatile unsigned int *)(SYSCON_BASE + 0x0FC)))
#define SYSCON_PIOPORCAP0    (*((volatile unsigned int *)(SYSCON_BASE + 0x100)))
#define SYSCON_IOCONCLKDIV6  (*((volatile unsigned int *)(SYSCON_BASE + 0x134)))
#define SYSCON_IOCONCLKDIV5  (*((volatile unsigned int *)(SYSCON_BASE + 0x138)))
#define SYSCON_IOCONCLKDIV4  (*((volatile unsigned int *)(SYSCON_BASE + 0x13c)))
#define SYSCON_IOCONCLKDIV3  (*((volatile unsigned int *)(SYSCON_BASE + 0x140)))
#define SYSCON_IOCONCLKDIV2  (*((volatile unsigned int *)(SYSCON_BASE + 0x144)))
#define SYSCON_IOCONCLKDIV1  (*((volatile unsigned int *)(SYSCON_BASE + 0x148)))
#define SYSCON_IOCONCLKDIV0  (*((volatile unsigned int *)(SYSCON_BASE + 0x14C)))
#define SYSCON_BODCTRL       (*((volatile unsigned int *)(SYSCON_BASE + 0x150)))
#define SYSCON_SYSTCKCAL     (*((volatile unsigned int *)(SYSCON_BASE + 0x154)))
#define SYSCON_IRQLATENCY    (*((volatile unsigned int *)(SYSCON_BASE + 0x170)))
#define SYSCON_NMISRC        (*((volatile unsigned int *)(SYSCON_BASE + 0x174)))
#define SYSCON_PINTSEL0      (*((volatile unsigned int *)(SYSCON_BASE + 0x178)))
#define SYSCON_PINTSEL1      (*((volatile unsigned int *)(SYSCON_BASE + 0x17c)))
#define SYSCON_PINTSEL2      (*((volatile unsigned int *)(SYSCON_BASE + 0x180)))
#define SYSCON_PINTSEL3      (*((volatile unsigned int *)(SYSCON_BASE + 0x184)))
#define SYSCON_PINTSEL4      (*((volatile unsigned int *)(SYSCON_BASE + 0x188)))
#define SYSCON_PINTSEL5      (*((volatile unsigned int *)(SYSCON_BASE + 0x18c)))
#define SYSCON_PINTSEL6      (*((volatile unsigned int *)(SYSCON_BASE + 0x190)))
#define SYSCON_PINTSEL7      (*((volatile unsigned int *)(SYSCON_BASE + 0x194)))
#define SYSCON_STARTERP0     (*((volatile unsigned int *)(SYSCON_BASE + 0x204)))
#define SYSCON_STARTERP1     (*((volatile unsigned int *)(SYSCON_BASE + 0x214)))
#define SYSCON_PDSLEEPCFG    (*((volatile unsigned int *)(SYSCON_BASE + 0x230)))
#define SYSCON_PDAWAKECFG    (*((volatile unsigned int *)(SYSCON_BASE + 0x234)))
#define SYSCON_PDRUNCFG      (*((volatile unsigned int *)(SYSCON_BASE + 0x238)))
#define SYSCON_DEVICE_ID     (*((volatile unsigned int *)(SYSCON_BASE + 0x3f8)))

//MRT
#define MRT_INTVAL0          (*((volatile unsigned int *)0x40004000))
#define MRT_TIMER0           (*((volatile unsigned int *)0x40004004))
#define MRT_CTRL0            (*((volatile unsigned int *)0x40004008))
#define MRT_STAT0            (*((volatile unsigned int *)0x4000400C))
#define MRT_INTVAL1          (*((volatile unsigned int *)0x40004010))
#define MRT_TIMER1           (*((volatile unsigned int *)0x40004014))
#define MRT_CTRL1            (*((volatile unsigned int *)0x40004018))
#define MRT_STAT1            (*((volatile unsigned int *)0x4000401C))
#define MRT_INTVAL2          (*((volatile unsigned int *)0x40004020))
#define MRT_TIMER2           (*((volatile unsigned int *)0x40004024))
#define MRT_CTRL2            (*((volatile unsigned int *)0x40004028))
#define MRT_STAT2            (*((volatile unsigned int *)0x4000402C))
#define MRT_INTVAL3          (*((volatile unsigned int *)0x40004030))
#define MRT_TIMER3           (*((volatile unsigned int *)0x40004034))
#define MRT_CTRL3            (*((volatile unsigned int *)0x40004038))
#define MRT_STAT3            (*((volatile unsigned int *)0x4000403C))
#define MRT_IDLE_CH          (*((volatile unsigned int *)0x400040F4))
#define MRT_IRQ_FLAG         (*((volatile unsigned int *)0x400040F8))

// NVIC 
#define SYS_BASE             0xE000E000
#define NVIC_ST_CTRL         (*((volatile unsigned int *)(SYS_BASE + 0x010)))
#define NVIC_ST_RELOAD       (*((volatile unsigned int *)(SYS_BASE + 0x014))) 
#define NVIC_ST_CURRENT      (*((volatile unsigned int *)(SYS_BASE + 0x018))) 
#define NVIC_ST_CAL          (*((volatile unsigned int *)(SYS_BASE + 0x01C)))
#define NVIC_ISER0           (*((volatile unsigned int *)(SYS_BASE + 0x100)))
#define NVIC_ICER0           (*((volatile unsigned int *)(SYS_BASE + 0x180)))
#define NVIC_ISPR0           (*((volatile unsigned int *)(SYS_BASE + 0x200)))
#define NVIC_ICPR0           (*((volatile unsigned int *)(SYS_BASE + 0x280)))
#define NVIC_IABR0           (*((volatile unsigned int *)(SYS_BASE + 0x300)))
#define NVIC_IPR0            (*((volatile unsigned int *)(SYS_BASE + 0x400)))
#define NVIC_IPR1            (*((volatile unsigned int *)(SYS_BASE + 0x404)))
#define NVIC_IPR2            (*((volatile unsigned int *)(SYS_BASE + 0x408)))
#define NVIC_IPR3            (*((volatile unsigned int *)(SYS_BASE + 0x40c)))
#define NVIC_IPR6            (*((volatile unsigned int *)(SYS_BASE + 0x418)))
#define NVIC_IPR7            (*((volatile unsigned int *)(SYS_BASE + 0x41c)))
#define NVIC_ST_CTRL_CLK_SRC 0x00000004  //Clock Source
#define NVIC_ST_CTRL_ENABLE  0x00000001  //Enable
#define SCB_SHP0             (*((volatile unsigned int *)(0xE000ED1C)))
#define SCB_SHP1             (*((volatile unsigned int *)(0xE000ED20)))

//Enable a device-specific interrupt in the NVIC interrupt controller.
static inline void NVIC_EnableIRQ(uint8_t IRQn) {
  NVIC_ISER0 = (1<<((uint32_t)(IRQn)&0x1F));
}

//System Tick Configuration
//Initializes the system timer, its interrupt, and starts timer.
//Counter in free running mode to generate periodic interrupts.
//ticks = number of ticks between two interrupts.
static inline uint32_t SysTickConfig(uint32_t ticks) {
  if (ticks > 0xFFFFFFUL)
    return (1); //reload value out of limit (24-bits)
  //set reload register
  NVIC_ST_RELOAD = (ticks&0xFFFFFFUL) - 1;
  //set IRQ priority
  SCB_SHP1 = 0xC0000000;
  //load the counter
  NVIC_ST_CURRENT = 0;
  //enable IRQ and go
  NVIC_ST_CTRL = 0x07;
  return 0;
}

//enable SysTick
void SysTickEnable(void) {
  NVIC_ST_CTRL |= NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_ENABLE;
}

//disable SysTick
void SysTickDisable(void) {
  NVIC_ST_CTRL &= ~(NVIC_ST_CTRL_ENABLE);
}

void SysTickReset(void) {
  //clear counter
  NVIC_ST_CURRENT = 0; 
}

//System Clock Peripheral Control bits
#define SYS                  0
#define ROM                  1
#define RAM                  2
#define FLASHREG             3
#define FLASH                4
#define I2C                  5
#define GPIO                 6
#define SWM                  7
#define SCT                  8
#define WKT                  9
#define MRT                  10
#define SPIO                 11
#define SPI1                 12
#define CRC                  13
#define UART0                14
#define UART1                15
#define UART2                16
#define WWDT                 17
#define IOCON                18
#define ACMP                 19
//Peripheral Reset Control bits
#define SPIO0_RST_N          0
#define SPIO1_RST_N          1
#define UARTFRG_RST_N        2
#define UART0_RST_N          3
#define UART1_RST_N          4
#define UART2_RST_N          5
#define I2C_RST_N            6
#define MRT_RST_N            7
#define SCT_RST_N            8
#define WKT_RST_N            9
#define GPIO_RST_N           10
#define FLASH_RST_N          11
#define ACMP_RST_N           12

//set to default IRC speed upon reset
uint32_t SystemMainClock = 12000000;
uint32_t SystemCoreClock = 12000000;

void GpioInit(void) {
  //enable AHB clock to the GPIO domain
  SYSCON_SYSAHBCLKCTRL |= (1<<GPIO);
  //peripheral reset control to gpio/gpio int
  SYSCON_PRESETCTRL &= ~(1<<GPIO_RST_N);
  SYSCON_PRESETCTRL |= (1<<GPIO_RST_N);
}

//get port pin digital value
uint32_t GpioGetPin(uint32_t pinbit) {
  uint32_t result = 0;
  
  if (pinbit < 0x20)
    if (GPIO_PORT&(1<<pinbit))
      result = 1;
    else if (pinbit == 0xff)
      result = GPIO_PORT;
  return(result);
}

My next post about ARM Cortex-M0.

Advertisements

About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s