Debugging an LPC810 Breakout Board via SWD/J-Link

I’m playing with a LPC810 Breakout Board connected with the IAR EW IDE via a SEGGER J-Link debugger utilizing SWD. The J-Link is connected via a small 20 to 10-pin adapter board. Since I am unable to power the µC via the 3.3V J-Link pin (not sure why), I’m also using a USB connection with the PC to provide power to the board.

Contrary to the User Manual, I needed to enable the SWDIO and SWCLK pins on the LPC810 to get this to work. After compiling inside the IAR EW IDE, I upload the iHex format file to the µC via the FlashMagic program. When the debugger is started, it outputs a warning about the target not having enough memory. I simply ignore the warning and it all seems to work okay. Debugging is with full symbol support, and I’m able to set breakpoints once inside the debugger.

In the picture, the µC is running a simplified version of a LED blink program.

LPC810 BoB J-Link SWD Debugging

Posted in Uncategorized | Tagged , , , , , , , | Leave a comment

LPC812 on a 20MHz External Crystal

oscillators

Because the NXP LPC800 clock options and the setup are somewhat confusing, I thought I would post this example. Here is my LPC812 dev board running on a 20MHz external crystal. The frequency counter is reading the clockout pin which is divided by 2. The clock and pin setup code is below.

LPC812 at 20MHZ

//----------------------------------------------------------------------------
// Name:    Blinky_PLL_Test.c
// Purpose: LED Flasher
// pin #6 set for LED
// pin #1 set for grounding xtal
// pin #15 set to CLKOUT
//----------------------------------------------------------------------------
#include <stdint.h>
#include <string.h>
#include "LPC812.h" //my bare metal version

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

int main(void) {
  uint32_t reg;
 
  //init gpio port
  GpioInit();
  //make gpio #6 pin an output (physical pin #10)
  GPIO_DIR |= (1<<6);

  //enable AHB clock to SWM and IOCON
  SYSCON_SYSAHBCLKCTRL |= (1<<SWM) | (1<<IOCON);

  //
  //external crystal setup
  //
  
//pin modes
#define INACTIVE_MODE  0x00
#define PULL_DOWN_MODE 0x01
#define PULL_UP_MODE   0x02
#define REPEATER_MODE  0x03
  //set pull-down on pio01 for ext crystal grounding pin
  reg = IOCON_PIO0_1 & ~(0x3<<3);
  IOCON_PIO0_1 = reg | (PULL_DOWN_MODE<<3);
  GPIO0_1 = 0;

  //disable pull-up/down on pio08/9
  reg = IOCON_PIO0_8 & ~(0x3<<3);
  IOCON_PIO0_8 = reg | (INACTIVE_MODE<<3);
  reg = IOCON_PIO0_9 & ~(0x3<<3);
  IOCON_PIO0_9 = reg | (INACTIVE_MODE<<3);
  //enable XTALIN & XTALOUT on PIO08 & PIO09
  PINENABLE0 &= ~((1<<(uint32_t)4) | (~0x1ff));
  PINENABLE0 &= ~((1<<(uint32_t)5) | (~0x1ff));

  //
  //sys osc setup
  //
  
  //sys osc bypass options
#define SYSOSC_BYPASS_DISABLE 0
#define SYSOSC_BYPASS_ENABLE  1 //pll fed directly from xtal
  //sys osc bypass 
  SYSCON_SYSOSCCTRL |= SYSOSC_BYPASS_DISABLE;
  //power up sys osc
  reg = SYSCON_PDRUNCFG & (0x000080ef);
  reg &= ~((1<<5)&0x000080ef);
  SYSCON_PDRUNCFG = (0x00006d10 | reg);
  //delay for power up
  for (reg=0; reg<200; reg++)
    asm("nop");
  
  //
  //PLL setup
  //

  //power-up PLL 
  reg = SYSCON_PDRUNCFG & (0x000080ef);
  reg &= ~((1<<7)&0x000080ef);
  SYSCON_PDRUNCFG = (0x00006d10 | reg);
//pll input options
#define PLL_IRC    0UL
#define PLL_SYSOSC 1UL
#define PLL_CLKIN  3UL
  //set sys osc as input to PLL & toggle update enable 
  SYSCON_SYSPLLCLKSEL = PLL_SYSOSC;
  //toggle to enable update
  SYSCON_SYSPLLCLKUEN = 0UL;
  SYSCON_SYSPLLCLKUEN = 1UL;
  //set PLL frequency
  SYSCON_SYSPLLCTRL = (0 + (0<<5));
  //wait until PLL locked
  while (!(SYSCON_SYSPLLSTAT&0x01));

  //
  //main clock setup
  //
  
//main clock input options
#define MAINCLK_IRC     0
#define MAINCLK_PLL_IN  1 //sys osc (irc, xtal or clkin?)
#define MAINCLK_WDG     2
#define MAINCLK_PLL_OUT 3
  //set pll input to main clock & toggle update enable
  SYSCON_MAINCLKSEL = MAINCLK_PLL_OUT;
  //toggle to enable update
  SYSCON_MAINCLKUEN = 0UL;
  SYSCON_MAINCLKUEN = 1UL;
  //wait until update complted
  while (!(SYSCON_MAINCLKUEN&0x01));
  //set system clock divider 
  SYSCON_SYSAHBCLKDIV = 1;
  //main clock speed
  SystemMainClock = 20000000UL*((SYSCON_SYSPLLCTRL&0x1f) + 1);
  //core clock speed
  SystemCoreClock = SystemMainClock/SYSCON_SYSAHBCLKDIV;

  //
  //clockout pin setup
  //
 	
  //configure PIO015 with pull-up 
  reg = IOCON_PIO0_15 & ~(0x3<<3);
  IOCON_PIO0_15 = reg | (PULL_UP_MODE<<3);
  //assign CLKOUT to PIO0_15 
  reg = PINASSIGN8 & (~(0xff<<0x10));
  PINASSIGN8 = reg | (0xf<<0x10);
//clockout sources
#define CLKOUT_IRC        0 //Internal oscillator for CLKOUT 
#define CLKOUT_SYSOSC     1 //System oscillator for CLKOUT 
#define CLKOUT_WDTOSC     2 //Watchdog oscillator for CLKOUT
#define CLKOUT_MAINSYSCLK 3 //Main system clock for CLKOUT 
  //set CLKOUT pin source
  SYSCON_CLKOUTSEL = (uint32_t)CLKOUT_MAINSYSCLK;
  //toggle to enable update
  SYSCON_CLKOUTUEN = 0UL;
  SYSCON_CLKOUTUEN = 1UL;
  //set clockout divider
  SYSCON_CLKOUTDIV = 2;

  //disable clock to SWM peripheral
  SYSCON_SYSAHBCLKCTRL &= ~(1<<SWM);

  //set systick clock interrupt to Hz
  SysTickConfig(1000000UL);
  
  //loop forever
  while(1)
    asm("wfi"); //wait for interrupt
}

LPC812 defines 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)))

//IOCON
#define IOCON_BASE           0x40044000
#define IOCON_PIO0_17        (*((volatile unsigned int *)(IOCON_BASE + 0x000)))
#define IOCON_PIO0_13        (*((volatile unsigned int *)(IOCON_BASE + 0x004)))
#define IOCON_PIO0_12        (*((volatile unsigned int *)(IOCON_BASE + 0x008)))
#define IOCON_PIO0_5         (*((volatile unsigned int *)(IOCON_BASE + 0x00C)))
#define IOCON_PIO0_4         (*((volatile unsigned int *)(IOCON_BASE + 0x010)))
#define IOCON_PIO0_3         (*((volatile unsigned int *)(IOCON_BASE + 0x014)))
#define IOCON_PIO0_2         (*((volatile unsigned int *)(IOCON_BASE + 0x018)))
#define IOCON_PIO0_11        (*((volatile unsigned int *)(IOCON_BASE + 0x01C)))
#define IOCON_PIO0_10        (*((volatile unsigned int *)(IOCON_BASE + 0x020)))
#define IOCON_PIO0_16        (*((volatile unsigned int *)(IOCON_BASE + 0x024)))
#define IOCON_PIO0_15        (*((volatile unsigned int *)(IOCON_BASE + 0x028)))
#define IOCON_PIO0_1         (*((volatile unsigned int *)(IOCON_BASE + 0x02c)))
#define IOCON_PIO0_9         (*((volatile unsigned int *)(IOCON_BASE + 0x034)))
#define IOCON_PIO0_8         (*((volatile unsigned int *)(IOCON_BASE + 0x038)))
#define IOCON_PIO0_7         (*((volatile unsigned int *)(IOCON_BASE + 0x03c)))
#define IOCON_PIO0_6         (*((volatile unsigned int *)(IOCON_BASE + 0x040)))
#define IOCON_PIO0_0         (*((volatile unsigned int *)(IOCON_BASE + 0x044)))
#define IOCON_PIO0_14        (*((volatile unsigned int *)(IOCON_BASE + 0x048)))

//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 = 12000000UL;
uint32_t SystemCoreClock = 12000000UL;

void GpioInit(void) {
  //enable AHB clock to the GPIO domain
  SYSCON_SYSAHBCLKCTRL |= (1<<GPIO);
  //reset gpio peripheral control
  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);
}
Posted in Uncategorized | Tagged , , , , , , , , , , , , | Leave a comment

LPC810 Breakout Board

LPC810 DIP

This basic Arm Cortex-M0+ NXP LPC810 breakout board features a FTDI programming header, USB (mini-B) connector for power only, a LM117-3.3v voltage regulator, power LED, ISP and Reset buttons and a standard 2×5-pin 0.05″ SWD debug connector. All pins are brought out to the edge of the board. Three PCBs from OSHPark.com cost me $6.55 USD delivered via the USPS. Eagle board package and BOM can be downloaded below.

Breakout board running a LED blinky program while powered via USB:
LPC810 BoB v1.00

Eagle Schematic:
LPC810s

Eagle Board:
LPC810BoB

Download the Eagle schematic and board file here.

LPC810BoB BOM
#  description            part#           package
1  microcontroller        LPC810M021JN8   DIP8
2  voltage regulator      LM117-N-3.3     SOT223
3  usb mini-b connector   UX60SC-MB-5ST   ---
4  cortex debug connector 3220-10-0100-00 ---
5  (2) 10uF ceramic cap   ---             0805
6  (2) 10k resistor       ---             0805
7  470 resistor           ---             0805
8  LED                    ---             1206
9  (2) smt tactile switch 147873-2        SMD
10 (3) pin header         ---             1x4, 1x4, 1x6
11 (optional) socket      ---             DIP8

Simple LED Blink program (compiled to 701 bytes):

//----------------------------------------------------------------------------
// Name:    LPC810_Blink.c
// Purpose: LED Flasher
// pin #8 set for LED
//----------------------------------------------------------------------------
#include <stdint.h>

//registers used for gpio & systick setup
#define GPIO_NOT             (*((volatile unsigned int *)(0xA0002300)))
#define GPIO_DIR             (*((volatile unsigned int *)(0xA0002000)))
#define SYSCON_PRESETCTRL    (*((volatile unsigned int *)(0x40048004)))
#define SYSCON_SYSAHBCLKCTRL (*((volatile unsigned int *)(0x40048080)))
#define NVIC_ST_CTRL         (*((volatile unsigned int *)(0xE000E010)))
#define NVIC_ST_RELOAD       (*((volatile unsigned int *)(0xE000E014))) 
#define NVIC_ST_CURRENT      (*((volatile unsigned int *)(0xE000E018))) 
#define SCB_SHP1             (*((volatile unsigned int *)(0xE000ED20)))

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

int main(void) {
  //enable AHB clock to the GPIO domain
  SYSCON_SYSAHBCLKCTRL |= (1<<6);
  //reset gpio peripheral control
  SYSCON_PRESETCTRL &= ~(1<<10);
  SYSCON_PRESETCTRL |= (1<<10);
  //make gpio #0 pin an output (physical pin #8)
  GPIO_DIR |= (1<<0);

  //set systick clock interrupt reload count
  NVIC_ST_RELOAD = (1200000UL & 0xFFFFFFUL) - 1;
  //set SysTick IRQ to lowest priority
  SCB_SHP1 = 0xC0000000;
  //reset the counter
  NVIC_ST_CURRENT = 0;
  //enable the IRQ and go
  NVIC_ST_CTRL = 0x07;

  //loop forever
  while(1)
    asm("wfi"); //wait for interrupt
}
Posted in Uncategorized | Tagged , , , , , , , , , , | Leave a comment

LPC812 Switch Matrix

train tracks

One unique feature of the LPC8xx µC is the ability to swap pin functions. Want an UART TX on pin #10 and RX on #2? No problem. You can assign the pin functions via the Switch Matrix. This allows great flexibility when performing PCB layout. The Switch Matrix allows the flexible selection of the following peripheral pins:

USART0/1/2:

  • TX
  • RX
  • RTS
  • CTS
  • CLK

SPI0/1:

  • SCK
  • MISO
  • MISO
  • SSEL

I2C:

  • SDA
  • SCL

SCTimer (0-4):

  • Input
  • Output

Analog Comparator Output
Clock Out

Additionally, the Switch Matrix allows for turning fixed-pin functionality off if not needed. This frees up pins for alternate functionality. The following functions can be selected:

  • ACMP
  • External Crystal in/out
  • SWD
  • Reset
  • Clock in/out
  • VDDCMP

NXP produces both an online and downloadable version of LPC Initializer and Pin-muxing Tool. These are great tools for learning about and using the LPC Switch Matrix and I/O functions. There is even a video tutorial about using the tool.

Here is the code I used to inactivate the pull-up/down functions on PIO0s 8 and 9, then turn on the external crystal functionality (XTALIN and XTALOUT). The code then enables CLKOUT functionality on PIO01. This allowed me to connect a 20MHz crystal to the LPC812 to feed the PLL, and measure the clock frequency via the clock-out pin. Cool!

  //enable clock to SWM peripheral
  SYSCON_SYSAHBCLKCTRL |= (1<<SWM);

  //disable pull-up/down on pio08/9
  reg = IOCON_PIO0_8 & ~(0x3<<3);
  IOCON_PIO0_8 = reg | (0x0<<3);
  reg = IOCON_PIO0_9 & ~(0x3<<3);
  IOCON_PIO0_9 = reg | (0x0<<3);
  //enable XTALIN & XTALOUT on PIO08 & PIO09
  PINENABLE0 &= ~((1<<(uint32_t)4) | (~0x1ff));
  PINENABLE0 &= ~((1<<(uint32_t)5) | (~0x1ff));

  //feed PLL from external crystal bypassing sys osc 
  SYSCON_SYSOSCCTRL |= 1;
  //configure PIO01 with pull-up 
  reg = IOCON_PIO0_8 & ~(0x3<<3);
  IOCON_PIO0_8 = reg | (0x0<<3);
  //assign CLKOUT to PIO0_1 
  reg = PINASSIGN8 & (~(0xff<<0x10));
  PINASSIGN8 = reg | (0x01<<0x10);
  /*
  IRC        0 //Internal oscillator for CLKOUT 
  SYSOSC     1 //System oscillator for CLKOUT 
  WDTOSC     2 //Watchdog oscillator for CLKOUT
  MAINSYSCLK 3 //Main system clock for CLKOUT 
  */
  //set CLKOUT source & divider
  SYSCON_CLKOUTSEL = (uint32_t)3;
  SYSCON_CLKOUTUEN = 0UL;
  SYSCON_CLKOUTUEN = 1UL;
  SYSCON_CLKOUTDIV = 1;

  //disable clock to SWM peripheral
  SYSCON_SYSAHBCLKCTRL &= ~(1<<SWM);
Posted in Uncategorized | Tagged , , , , , , , | Leave a comment

NXP LPC812 Clocks and Timers

clocks

ARM Cortex-M0+ Architecture Basics

Based upon Harvard Architecture, the LPC812 uses an ARM Cortex-M0+ processor. This means it has separate instruction (flash) and data (SRAM) memory. The basic architecture includes the core components and peripherals.

The core consists of:

  • Processor
  • Memories
  • GPIO
  • Pin interrupts
  • SCTimer/PWM

Peripherals:

  • USARTs
  • SPIs
  • I2C
  • ADC
  • IOCON
  • Multi-rate Timer
  • Watchdog Timer

All output is routed through the Switch Matrix to the individual pins. The switch matrix allows the flexibility of swapping the digital peripheral functions amongst the pins. Obviously, the basic functions like GPIO, power, ground and some others cannot be swapped.

Memory Mapping

Fortunately for us, we don’t need to focus too much on the internal design. The main factor to remember is the peripherals are memory mapped. This means our interaction with them (configuration, control, input, and output) is accomplished through an address. Accessing a peripheral is just like writing or reading a value in memory.

It is good practice to access peripherals using a read-modify-write strategy. This strategy is seen throughout ARM and LPC examples.

Read-Write-Modify Example:

GPIO_DIR |= (1<<9);  //proper method preserves unaffected bits of register
//assembler translation:
         0xd6: 0x4813         LDR.N     R0, [PC, #0x4c]         ; [0x124] DIR0
         0xd8: 0x6800         LDR       R0, [R0]
         0xda: 0x2180         MOVS      R1, #128                ; 0x80
         0xdc: 0x0089         LSLS      R1, R1, #2
         0xde: 0x4301         ORRS      R1, R1, R0
         0xe0: 0x4810         LDR.N     R0, [PC, #0x40]         ; [0x124] DIR0
         0xe2: 0x6001         STR       R1, [R0]
…
        0x124: 0xa0002000     DC32      DIR0
//
//
//
GPIO_DIR = (1<<9);  //improper method clobbers all bit of the register
//assembler translation:
         0xc2: 0x2080         MOVS      R0, #128                ; 0x80
         0xc4: 0x0080         LSLS      R0, R0, #2
         0xc6: 0x4911         LDR.N     R1, [PC, #0x44]         ; [0x10c] DIR0
         0xc8: 0x6008         STR       R0, [R1]
…
        0x10c: 0xa0002000     DC32      DIR0

The Very Basic Memory Map


0x00000000 - 0x00004000: Flash program memory
0x10000000 - 0x10001000: SRAM memory
0x1FFF0000 - 0x1FFF2000: Boot ROM (8kB)
0x40000000 - 0x40070000: All APB peripherals
0x50004000 - 0x50008000: SCTimer/PWM
0xA0000000 - 0xA0008000: GPIO

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);
}
Posted in Uncategorized | Tagged , , , , , , , , , , | Leave a comment

ARM NXP LPC 812 (SysTick) IRQ Blnk

TLA

SysTick IRQ Blink Program:

//----------------------------------------------------------------------------
// Name:    Blink.c
// Purpose: LED Flasher
//----------------------------------------------------------------------------
#include <stdint.h>
#include "LPC812.h" //my bare metal version

#define SYSTEM_CORE_CLOCK 12000000UL //12MHz

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

int main(void) {
  //init peripherals
  SystemInit();
  //init gpio port
  GpioInit();
  //make gpio #9 pin an output (physical pin #10)
  GPIO_DIR |= (1<<9);
  //set systick clock interrupt @1ms
  SysTickConfig(SYSTEM_CORE_CLOCK);
  while(1);
}
Posted in Uncategorized | Tagged , , , , , , , | Leave a comment

An ARM Up

arm

On a recent project I needed a µC in a SOIC-20 package to fill a spot on a self-designed PCB. The project started with an ATtiny4313, but the software quickly outgrew the limited 4K flash program memory. I upgraded to the ATtiny1634, with 16K flash, but I noticed it’s pin-outs are completely different, necessitating a redesign of the PCB traces.

Since this encompassed more work than I originally planned, and if I was going to rework the PCB, I might as well look for alternatives outside of the ATMEL family. That’s when I stumbled upon the ARM LPC812 µC.

While similar to the ATtiny1634 in many respects, the LPC812 has some very compelling features. They both have 16kB flash program memory, the standard USART, I2c, SPI, and ADC peripherals. But that’s about where the similarities end.

The LPC812 is a 32-bit ARM Cortex-M0+ processor, while the ATtiny1634 is only 8-bit. The ARM can operate up to 30MHz, has 4kB SRAM, has switchable pin functions and comes in a variety of packages (DIP8, TSSOP16, and TSSOP20). If a TSSOP20 package is acceptable, then the LPC824 is available with 32kB flash with even more features!

However, the flash memory used for the program is not really a limiting factor, as there are provisions for “In Application Programming” of the flash. This feature enables one to fill the program memory from off-chip sources allowing for program/data expansion, EEPROM emulation (the µC has no EEPROM) and firmware updating.

No doubt, NXP has aimed the ARM’s 32-bit guns directly at the 8-bit chips with the LPC8xx and LPC11xx families. I must admit, I have been looking for an excuse to learn ARM Cortex-M programming for some time, this was the justification I needed. What follows, are my trials in progressing into ARM programming.

Hardware
I could have simply purchased a demo board to start my learning process. Two decent candidates are the LPC812-LPCXpresso Board from NXP, which comes with a removable LPC-Link programmer/debugger interface, and the LPC800/812 MAX board from Embedded Artists which is Arduino Duo “shield compatible”.

LPC812 Breadboard

However, those options wouldn’t be adventurous enough, so I opted to construct a breakout board myself. After a brief internet search, I found eagle files for a very small and basic board online. I quickly ordered 3 PCBs for $3.30 from OSHPark, and the necessary components from mouser.com. In less than a week I had the first example assembled.

I started the assembly process by hand soldering the SMT capacitors, resistors and power regulator on the bottom of the board. Next I used a drag-solder technique to add the LPC812 chip. Liberal use of flux, limited amounts of solder, and post-cleaning with a wick made quick and easy work of the TSSOP-16 package. Next, I added the two momentary buttons (mouser part #506-147873-2, but by the eagle footprint these appear to be a SparkFun part). I finished off the board by adding the three pin headers. Additional information on the board can be found here.

Software

There are many options available for programming environments. I experimented with the following 3 packages that appealed to me for various reasons:

  • LPCxpresso IDE
  • IAR Systems Embedded Workbench
  • Keil uVision

All of these packages have licenses that allow free use. But they come with limitations. Keil and IAR Systems limit program size to 32K, while LPCxpresso is limited to 256K.

LPCxpresso has good documentation, forum support, wide-spread use, and both video and written tutorials. It’s an Eclipse-based environment that uses GCC. However, I found it slightly overwhelming and slow at times.

I’ve had previous experience using Keil uVision from a college course. Keil is a product of ARM itself and uses a version of the ARM compiler suite. I could only find a written tutorial for Keil and the LPC8xx. And I found the tutoral barely adequate. Keil incorporates a simulator for code testing, which I find highly useful. However, I find Keil klunky and it’s overall appearance looks somewhat dated.

In my opinion, IAR Embedded Workbench is the easiest to use, integrates a great simulator, and has an excellent series of online video tutorials produced by Quantum Leaps. While the tutorials are for a TI-based ARM demo board, they are somewhat applicable to the LPC, and will quickly get you up and running with the IDE. IAREW uses a proprietary compiler suite also.

j-link
My Segger J-Link-Edu SWD/JTAG debugger hasn’t arrived yet, so none of my testing has been performed using a debugger. My mind isn’t made up yet as to which IDE will become my favorite.

One last and possibly better option is the free and unlimited CooCox IDE along with the inexpensive ColinkEx debugger. But I haven’t gotten around to downloading and playing with this suite.

Books
I have found no books suitable for learning programming on an ARM LPC8xx µC.

Blink Program
No introduction to the ARM µC would be complete without the ubiquitous Blinking LED program, the “Hello World” for µC. There are many examples of LED blinking program floating around the internet. However, the vast majority of them incorporate ARM’s CMSIS library.

In my opinion, CMSIS is nearly worthless in the embedded world. CMSIS is a hardware abstraction layer inserted between the µC and your program. This typically increases complexity, increases code size and needlessly obfuscates a program. Furthermore, each manufacturer has specific versions of CMSIS for their µCs, which completely destroys the goal of portability.

I set out to write my blink program at the most basic level and not incorporate CMSIS. Sometimes, this coding technique is referred to as, “bare metal programming.” I wrote a small include file for GPIO access and clock initialization. Over the next few weeks I intend to expand this file with additional features of the LPC812, negating having to add the needless abstraction of CMSIS to my programs.

This version of Blink runs on the IAREW and LPCxpresso IDEs (updated 2/6/15):

//----------------------------------------------------------------------------
// Name:    Blink.c
// Purpose: LED Flasher
//----------------------------------------------------------------------------
#include <stdint.h>
#include "LPC812.h" //bare metal version

//12MHz
#define SYSTEM_CORE_CLOCK 12000000UL

//millisecond counter
volatile uint32_t millis = 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) {
  //init peripherals
  SystemInit();
  //setup systick clock interrupt @1ms
  SysTickConfig(SYSTEM_CORE_CLOCK/1000);
  //init gpio port
  GpioInit();
  //make pin an output
  GPIO_DIR |= (1<<9); //LPC812 TSSOP16 pin #10
  //loop forever flashing lED @ 1 second interval
  while (1) {
    GPIO0_9 = 1;    //set pin high
    delay_ms(1000);
    GPIO0_9 = 0;    //set pin low
    delay_ms(1000);
  }
}

My header file (updated 2/7/15):

//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 SM_BASE              0x4000C000
#define PINASSIGN0           (*((volatile unsigned int *)(SM_BASE + 0x000)))
#define PINASSIGN1           (*((volatile unsigned int *)(SM_BASE + 0x004)))
#define PINASSIGN2           (*((volatile unsigned int *)(SM_BASE + 0x008)))
#define PINASSIGN3           (*((volatile unsigned int *)(SM_BASE + 0x00c)))
#define PINASSIGN4           (*((volatile unsigned int *)(SM_BASE + 0x010)))
#define PINASSIGN5           (*((volatile unsigned int *)(SM_BASE + 0x014)))
#define PINASSIGN6           (*((volatile unsigned int *)(SM_BASE + 0x018)))
#define PINASSIGN7           (*((volatile unsigned int *)(SM_BASE + 0x01c)))
#define PINASSIGN8           (*((volatile unsigned int *)(SM_BASE + 0x020)))
#define PINENABLE0           (*((volatile unsigned int *)(SM_BASE + 0x1c0)))

// 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 + 0x010)))
#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)))

// 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)))

//System Tick Configuration
//Initializes the System Timer and its interrupt, and starts the System Tick Timer.
//Counter is 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 impossible
  //set reload register
  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 SysTick Timer 
  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) {
	NVIC_ST_CURRENT = 0; //clear
}

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

//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);
}

//System clock to the IOCON & the SWM need to be enabled or
//most of the I/O related peripherals won't work.
void SystemInit(void) {
  SYSCON_SYSAHBCLKCTRL |= 0x40080;
}

#define CLKOUTCLK_SRC_IRC_OSC       0
#define CLKOUTCLK_SRC_SYS_OSC       1
#define CLKOUTCLK_SRC_WDT_OSC       2
#define CLKOUTCLK_SRC_MAIN_CLK      3

//Configure CLKOUT for reference clock check.
//parameters: (clock source) irc_osc(0), sys_osc(1), wdt_osc(2), main_clk(3).			 
void ClockSetup(uint32_t clksrc) {
  //debug PLL after configuration
  SYSCON_CLKOUTSEL = clksrc;        //select main clock
  SYSCON_CLKOUTUEN = 0x01;          //update clock
  while (!(SYSCON_CLKOUTUEN&0x01)); //wait until update complete
  SYSCON_CLKOUTDIV = 1;             //divide by 1
  return;
}

Programming The Chip
ftdi cable
Programming the µC is simple. I used the free Flash Magic program, a SparkFun FTDI cable and followed the instructions posted here.

To put the board into ISP (programming) mode, simply hold the ISP button down while pressing/releasing the RESET button, and then release the ISP button. Once programmed, simply press the RESET button to run the uploaded code.

Be careful, the bare µC can be damaged if powered at greater than 3.3V. Typically FTDI cables with 3.3V logic levels, output 5V on the VCC line. However, the board used here incorporates a 3.3V voltage regulator, so this cable works fine. Also remember to swap the TX/RX lines between the cable and the board.

A Very Unscientific Code-Size Comparison
While it’s impossible to make direct comparison of code size between 8 and 32-bit compilers and µCs, I can report the following about my LED Blink program vs. the Arduino Basic Blink demo (ihex file size, release builds, with compiler optimization turned on):

  • IAR code size: 1,008 bytes.
  • LPCxpresso code size: 1,331 bytes.
  • Ardiuno (1.6.0) ATMega328 code size: 1,030 bytes.

More to follow…

Posted in Uncategorized | Tagged , , , , , , , , , | Leave a comment