Merge pull request #531 from toyowata/master

Platform: LPC824 - new platform addition
pull/526/merge
Martin Kojtal 2014-10-06 09:53:12 +01:00
commit b30176a071
30 changed files with 4257 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
LR_IROM1 0x00000000 0x8000 { ; load region size_region (32k)
ER_IROM1 0x00000000 0x8000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
; 8KB - 0xC0 = 0x1F40
RW_IRAM1 0x10000000+0xC0 0x2000-0xC0 {
.ANY (+RW +ZI)
}
}

View File

@ -0,0 +1,218 @@
;/*****************************************************************************
; * @file: startup_LPC8xx.s
; * @purpose: CMSIS Cortex-M0+ Core Device Startup File
; * for the NXP LPC8xx Device Series
; * @version: V1.0
; * @date: 16. Aug. 2012
; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
; *
; * Copyright (C) 2012 ARM Limited. All rights reserved.
; * ARM Limited (ARM) is supplying this software for use with Cortex-M0+
; * processor based microcontrollers. This file can be freely distributed
; * within development tools that are supporting such ARM based processors.
; *
; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
; *
; *****************************************************************************/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
AREA STACK, NOINIT, READWRITE, ALIGN=3
EXPORT __initial_sp
__initial_sp EQU 0x10002000
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
EXPORT __heap_base
EXPORT __heap_limit
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD SPI0_IRQHandler ; SPI0 controller
DCD SPI1_IRQHandler ; SPI1 controller
DCD 0 ; Reserved
DCD UART0_IRQHandler ; UART0
DCD UART1_IRQHandler ; UART1
DCD UART2_IRQHandler ; UART2
DCD 0 ; Reserved
DCD I2C1_IRQHandler ; I2C1 controller
DCD I2C0_IRQHandler ; I2C0 controller
DCD SCT_IRQHandler ; Smart Counter Timer
DCD MRT_IRQHandler ; Multi-Rate Timer
DCD CMP_IRQHandler ; Comparator
DCD WDT_IRQHandler ; PIO1 (0:11)
DCD BOD_IRQHandler ; Brown Out Detect
DCD Flash_IRQHandler ; Flash interrupt
DCD WKT_IRQHandler ; Wakeup timer
DCD ADC_SEQA_IRQHandler ; ADC sequence A completion
DCD ADC_SEQB_IRQHandler ; ADC sequence B completion
DCD ADC_THCMP_IRQHandler ; ADC threshold compare
DCD ADC_OVR_IRQHandler ; ADC overrun
DCD DMA__RQHandler ; DMA interrupt
DCD I2C2_IRQHandler ; I2C2 controller
DCD I2C3_IRQHandler ; I2C3 controller
DCD 0 ; Reserved
DCD PININT0_IRQHandler ; PIO INT0
DCD PININT1_IRQHandler ; PIO INT1
DCD PININT2_IRQHandler ; PIO INT2
DCD PININT3_IRQHandler ; PIO INT3
DCD PININT4_IRQHandler ; PIO INT4
DCD PININT5_IRQHandler ; PIO INT5
DCD PININT6_IRQHandler ; PIO INT6
DCD PININT7_IRQHandler ; PIO INT7
IF :LNOT::DEF:NO_CRP
AREA |.ARM.__at_0x02FC|, CODE, READONLY
CRP_Key DCD 0xFFFFFFFF
ENDIF
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT NMI_Handler [WEAK]
EXPORT SPI0_IRQHandler [WEAK]
EXPORT SPI1_IRQHandler [WEAK]
EXPORT UART0_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT UART2_IRQHandler [WEAK]
EXPORT I2C1_IRQHandler [WEAK]
EXPORT I2C0_IRQHandler [WEAK]
EXPORT SCT_IRQHandler [WEAK]
EXPORT MRT_IRQHandler [WEAK]
EXPORT CMP_IRQHandler [WEAK]
EXPORT WDT_IRQHandler [WEAK]
EXPORT BOD_IRQHandler [WEAK]
EXPORT Flash_IRQHandler [WEAK]
EXPORT WKT_IRQHandler [WEAK]
EXPORT ADC_SEQA_IRQHandler [WEAK]
EXPORT ADC_SEQB_IRQHandler [WEAK]
EXPORT ADC_THCMP_IRQHandler [WEAK]
EXPORT ADC_OVR_IRQHandler [WEAK]
EXPORT DMA__RQHandler [WEAK]
EXPORT I2C2_IRQHandler [WEAK]
EXPORT I2C3_IRQHandler [WEAK]
EXPORT PININT0_IRQHandler [WEAK]
EXPORT PININT1_IRQHandler [WEAK]
EXPORT PININT2_IRQHandler [WEAK]
EXPORT PININT3_IRQHandler [WEAK]
EXPORT PININT4_IRQHandler [WEAK]
EXPORT PININT5_IRQHandler [WEAK]
EXPORT PININT6_IRQHandler [WEAK]
EXPORT PININT7_IRQHandler [WEAK]
NMI_Handler
SPI0_IRQHandler
SPI1_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
I2C1_IRQHandler
I2C0_IRQHandler
SCT_IRQHandler
MRT_IRQHandler
CMP_IRQHandler
WDT_IRQHandler
BOD_IRQHandler
Flash_IRQHandler
WKT_IRQHandler
ADC_SEQA_IRQHandler
ADC_SEQB_IRQHandler
ADC_THCMP_IRQHandler
ADC_OVR_IRQHandler
DMA__RQHandler
I2C2_IRQHandler
I2C3_IRQHandler
PININT0_IRQHandler
PININT1_IRQHandler
PININT2_IRQHandler
PININT3_IRQHandler
PININT4_IRQHandler
PININT5_IRQHandler
PININT6_IRQHandler
PININT7_IRQHandler
B .
ENDP
ALIGN
END

View File

@ -0,0 +1,389 @@
/******************************************************************************
* @file: system_LPC8xx.c
* @purpose: CMSIS Cortex-M0+ Device Peripheral Access Layer Source File
* for the NXP LPC8xx Device Series
* @version: V1.0
* @date: 16. Aug. 2012
*----------------------------------------------------------------------------
*
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M0+
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
#include "LPC82x.h"
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
/*--------------------- Clock Configuration ----------------------------------*/
//
// <e> Clock Configuration
#define CLOCK_SETUP 1
// <h> System Oscillator Control Register (SYSOSCCTRL)
// <o.0> BYPASS: System Oscillator Bypass Enable
// <i> If enabled then PLL input (sys_osc_clk) is fed
// <i> directly from XTALIN and XTALOUT pins.
// <o.1> FREQRANGE: System Oscillator Frequency Range
// <i> Determines frequency range for Low-power oscillator.
// <0=> 1 - 20 MHz
// <1=> 15 - 25 MHz
// </h>
#define SYSOSCCTRL_Val 0x00000000 // Reset: 0x000
//
// <h> Watchdog Oscillator Control Register (WDTOSCCTRL)
// <o.0..4> DIVSEL: Select Divider for Fclkana
// <i> wdt_osc_clk = Fclkana/ (2 * (1 + DIVSEL))
// <0-31>
// <o.5..8> FREQSEL: Select Watchdog Oscillator Analog Output Frequency (Fclkana)
// <0=> Undefined
// <1=> 0.6 MHz
// <2=> 1.05 MHz
// <3=> 1.4 MHz
// <4=> 1.75 MHz
// <5=> 2.1 MHz
// <6=> 2.4 MHz
// <7=> 2.7 MHz
// <8=> 3.0 MHz
// <9=> 3.25 MHz
// <10=> 3.5 MHz
// <11=> 3.75 MHz
// <12=> 4.0 MHz
// <13=> 4.2 MHz
// <14=> 4.4 MHz
// <15=> 4.6 MHz
#define WDTOSCCTRL_Val 0x00000000 // Reset: 0x000
// </h>
// <h> System PLL Control Register (SYSPLLCTRL)
// <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
// <i> F_clkin must be in the range of 10 MHz to 25 MHz
// <i> F_CCO must be in the range of 156 MHz to 320 MHz
// <o.0..4> MSEL: Feedback Divider Selection
// <i> M = MSEL + 1
// <0-31>
// <o.5..6> PSEL: Post Divider Selection
// <0=> P = 1
// <1=> P = 2
// <2=> P = 4
// <3=> P = 8
// </h>
#define SYSPLLCTRL_Val 0x00000024 // Reset: 0x000
//
// <h> System PLL Clock Source Select Register (SYSPLLCLKSEL)
// <o.0..1> SEL: System PLL Clock Source
// <0=> IRC
// <1=> Crystal Oscillator
// <2=> Reserved
// <3=> CLKIN. External clock input.
// </h>
#define SYSPLLCLKSEL_Val 0x00000000 // Reset: 0x000
//
// <h> Main Clock Source Select Register (MAINCLKSEL)
// <o.0..1> SEL: Clock Source for Main Clock
// <0=> IRC Oscillator
// <1=> PLL input
// <2=> Watchdog Oscillator
// <3=> PLL output
// </h>
#define MAINCLKSEL_Val 0x00000003 // Reset: 0x000
// <h> System AHB Clock Divider Register (SYSAHBCLKDIV)
// <o.0..7> DIV: System AHB Clock Divider
// <i> Divides main clock to provide system clock to core, memories, and peripherals.
// <i> 0 = is disabled
// <0-255>
// </h>
#define SYSAHBCLKDIV_Val 0x00000002 // Reset: 0x001
// </e>
//#define CLOCK_SETUP 0 // 1 == IRC: 2 == System Oscillator 12Mhz Xtal:
/*
#if (CLOCK_SETUP == 0)
#define SYSOSCCTRL_Val 0x00000000 // Reset: 0x000
#define WDTOSCCTRL_Val 0x00000024 // Reset: 0x000
#define SYSPLLCTRL_Val 0x00000041 // Reset: 0x000
#define SYSPLLCLKSEL_Val 0x00000003 // Reset: 0x000
#define MAINCLKSEL_Val 0x00000000 // Reset: 0x000
#define SYSAHBCLKDIV_Val 0x00000001 // Reset: 0x001
#elif (CLOCK_SETUP == 2)
// #define SYSOSCCTRL_Val 0x00000000 // Reset: 0x000
#define WDTOSCCTRL_Val 0x00000000 // Reset: 0x000
#define SYSPLLCTRL_Val 0x00000040 // Reset: 0x000
#define SYSPLLCLKSEL_Val 0x00000001 // Reset: 0x000
#define MAINCLKSEL_Val 0x00000003 // Reset: 0x000
#define SYSAHBCLKDIV_Val 0x00000001 // Reset: 0x001
#endif
*/
/*
//-------- <<< end of configuration section >>> ------------------------------
*/
/*----------------------------------------------------------------------------
Check the register settings
*----------------------------------------------------------------------------*/
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
#define CHECK_RSVD(val, mask) (val & mask)
/* Clock Configuration -------------------------------------------------------*/
#if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003))
#error "SYSOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF))
#error "WDTOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 3))
#error "SYSPLLCLKSEL: Value out of range!"
#endif
#if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF))
#error "SYSPLLCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003))
#error "MAINCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
#error "SYSAHBCLKDIV: Value out of range!"
#endif
/*----------------------------------------------------------------------------
DEFINES
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define __XTAL (12000000UL) /* Oscillator frequency */
#define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */
#define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */
#define __CLKIN_CLK (12000000UL) /* CLKIN pin frequency */
#define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F)
#define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
#if (CLOCK_SETUP) /* Clock Setup */
#if (__FREQSEL == 0)
#define __WDT_OSC_CLK ( 0) /* undefined */
#elif (__FREQSEL == 1)
#define __WDT_OSC_CLK ( 500000 / __DIVSEL)
#elif (__FREQSEL == 2)
#define __WDT_OSC_CLK ( 800000 / __DIVSEL)
#elif (__FREQSEL == 3)
#define __WDT_OSC_CLK (1100000 / __DIVSEL)
#elif (__FREQSEL == 4)
#define __WDT_OSC_CLK (1400000 / __DIVSEL)
#elif (__FREQSEL == 5)
#define __WDT_OSC_CLK (1600000 / __DIVSEL)
#elif (__FREQSEL == 6)
#define __WDT_OSC_CLK (1800000 / __DIVSEL)
#elif (__FREQSEL == 7)
#define __WDT_OSC_CLK (2000000 / __DIVSEL)
#elif (__FREQSEL == 8)
#define __WDT_OSC_CLK (2200000 / __DIVSEL)
#elif (__FREQSEL == 9)
#define __WDT_OSC_CLK (2400000 / __DIVSEL)
#elif (__FREQSEL == 10)
#define __WDT_OSC_CLK (2600000 / __DIVSEL)
#elif (__FREQSEL == 11)
#define __WDT_OSC_CLK (2700000 / __DIVSEL)
#elif (__FREQSEL == 12)
#define __WDT_OSC_CLK (2900000 / __DIVSEL)
#elif (__FREQSEL == 13)
#define __WDT_OSC_CLK (3100000 / __DIVSEL)
#elif (__FREQSEL == 14)
#define __WDT_OSC_CLK (3200000 / __DIVSEL)
#else
#define __WDT_OSC_CLK (3400000 / __DIVSEL)
#endif
/* sys_pllclkin calculation */
#if ((SYSPLLCLKSEL_Val & 0x03) == 0)
#define __SYS_PLLCLKIN (__IRC_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
#define __SYS_PLLCLKIN (__SYS_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 3)
#define __SYS_PLLCLKIN (__CLKIN_CLK)
#else
#define __SYS_PLLCLKIN (0)
#endif
#define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
/* main clock calculation */
#if ((MAINCLKSEL_Val & 0x03) == 0)
#define __MAIN_CLOCK (__IRC_OSC_CLK)
#elif ((MAINCLKSEL_Val & 0x03) == 1)
#define __MAIN_CLOCK (__SYS_PLLCLKIN)
#elif ((MAINCLKSEL_Val & 0x03) == 2)
#if (__FREQSEL == 0)
#error "MAINCLKSEL: WDT Oscillator selected but FREQSEL is undefined!"
#else
#define __MAIN_CLOCK (__WDT_OSC_CLK)
#endif
#elif ((MAINCLKSEL_Val & 0x03) == 3)
#define __MAIN_CLOCK (__SYS_PLLCLKOUT)
#else
#define __MAIN_CLOCK (0)
#endif
#define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val)
#else
#define __SYSTEM_CLOCK (__IRC_OSC_CLK)
#endif // CLOCK_SETUP
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/
uint32_t MainClock = __MAIN_CLOCK; /*!< Main Clock Frequency */
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
uint32_t wdt_osc = 0;
/* Determine clock frequency according to clock register values */
switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
case 0: wdt_osc = 0; break;
case 1: wdt_osc = 500000; break;
case 2: wdt_osc = 800000; break;
case 3: wdt_osc = 1100000; break;
case 4: wdt_osc = 1400000; break;
case 5: wdt_osc = 1600000; break;
case 6: wdt_osc = 1800000; break;
case 7: wdt_osc = 2000000; break;
case 8: wdt_osc = 2200000; break;
case 9: wdt_osc = 2400000; break;
case 10: wdt_osc = 2600000; break;
case 11: wdt_osc = 2700000; break;
case 12: wdt_osc = 2900000; break;
case 13: wdt_osc = 3100000; break;
case 14: wdt_osc = 3200000; break;
case 15: wdt_osc = 3400000; break;
}
wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* Input Clock to System PLL */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* System oscillator */
SystemCoreClock = __SYS_OSC_CLK;
break;
case 2: /* Reserved */
SystemCoreClock = 0;
break;
case 3: /* CLKIN pin */
SystemCoreClock = __CLKIN_CLK;
break;
}
break;
case 2: /* WDT Oscillator */
SystemCoreClock = wdt_osc;
break;
case 3: /* System PLL Clock Out */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
break;
case 1: /* System oscillator */
SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
break;
case 2: /* Reserved */
SystemCoreClock = 0;
break;
case 3: /* CLKIN pin */
SystemCoreClock = __CLKIN_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
break;
}
break;
}
SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;
}
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void) {
volatile uint32_t i;
/* System clock to the IOCON & the SWM need to be enabled or
most of the I/O related peripherals won't work. */
LPC_SYSCON->SYSAHBCLKCTRL |= ( (0x1 << 7) | (0x1 << 18) );
#if (CLOCK_SETUP) /* Clock Setup */
#if ((SYSPLLCLKSEL_Val & 0x03) == 1)
LPC_IOCON->PIO0_8 &= ~(0x3 << 3);
LPC_IOCON->PIO0_9 &= ~(0x3 << 3);
LPC_SWM->PINENABLE0 &= ~(0x3 << 6); /* XTALIN and XTALOUT */
LPC_SYSCON->PDRUNCFG &= ~(0x1 << 5); /* Power-up System Osc */
for (i = 0; i < 200; i++) __NOP();
LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
#endif
#if ((SYSPLLCLKSEL_Val & 0x03) == 3)
LPC_IOCON->PIO0_1 &= ~(0x3 << 3);
LPC_SWM->PINENABLE0 &= ~(0x1 << 9); /* CLKIN */
for (i = 0; i < 200; i++) __NOP();
#endif
LPC_SYSCON->PDRUNCFG &= ~(0x1 << 7); /* Power-up System PLL */
LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
LPC_SYSCON->SYSPLLCLKUEN = 0;
LPC_SYSCON->SYSPLLCLKUEN = 1; /* Update Clock Source */
while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
#if ((MAINCLKSEL_Val & 0x03) == 3) /* Main Clock is PLL Out */
LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(0x1 << 7); /* Power-up SYSPLL */
while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
#endif
#if (((MAINCLKSEL_Val & 0x03) == 2) )
LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(0x1 << 6); /* Power-up WDT Clock */
for (i = 0; i < 200; i++) __NOP();
#endif
LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */
LPC_SYSCON->MAINCLKUEN = 0;
LPC_SYSCON->MAINCLKUEN = 1; /* Update MCLK Clock Source */
while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
#endif
}

View File

@ -0,0 +1,31 @@
/* mbed Microcontroller Library - stackheap
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* Setup a fixed single stack/heap memory model,
* between the top of the RW/ZI region and the stackpointer
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <rt_misc.h>
#include <stdint.h>
extern char Image$$RW_IRAM1$$ZI$$Limit[];
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
uint32_t sp_limit = __current_sp();
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
struct __initial_stackheap r;
r.heap_base = zi_limit;
r.heap_limit = sp_limit;
return r;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,13 @@
/* mbed Microcontroller Library - CMSIS
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* A generic CMSIS include header, pulling in LPC8xx specifics
*/
#ifndef MBED_CMSIS_H
#define MBED_CMSIS_H
#include "LPC82x.h"
#include "cmsis_nvic.h"
#endif

View File

@ -0,0 +1,30 @@
/* mbed Microcontroller Library - cmsis_nvic for LPC11U24
* Copyright (c) 2011 ARM Limited. All rights reserved.
*
* CMSIS-style functionality to support dynamic vectors
*/
#include "cmsis_nvic.h"
#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
uint32_t *vectors = (uint32_t*)SCB->VTOR;
uint32_t i;
// Copy and switch to dynamic vectors if the first time called
if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) {
uint32_t *old_vectors = vectors;
vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
for (i=0; i<NVIC_NUM_VECTORS; i++) {
vectors[i] = old_vectors[i];
}
SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS;
}
vectors[IRQn + 16] = vector;
}
uint32_t NVIC_GetVector(IRQn_Type IRQn) {
uint32_t *vectors = (uint32_t*)SCB->VTOR;
return vectors[IRQn + 16];
}

View File

@ -0,0 +1,26 @@
/* mbed Microcontroller Library - cmsis_nvic
* Copyright (c) 2009-2011 ARM Limited. All rights reserved.
*
* CMSIS-style functionality to support dynamic vectors
*/
#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
uint32_t NVIC_GetVector(IRQn_Type IRQn);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,63 @@
/******************************************************************************
* @file: system_LPC8xx.h
* @purpose: CMSIS Cortex-M0+ Device Peripheral Access Layer Header File
* for the NXP LPC8xx Device Series
* @version: V1.0
* @date: 16. Aug. 2012
*----------------------------------------------------------------------------
*
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M0+
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC8xx_H
#define __SYSTEM_LPC8xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern uint32_t MainClock; /*!< Main Clock Frequency */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC8xx_H */

View File

@ -0,0 +1,30 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
Port0 = 0,
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,55 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
// Default peripherals
// SPI: MOSI, MISO, CLK, SEL
#define MBED_SPI0 P0_26, P0_25, P0_24, P0_15
#define MBED_UART0 P0_7, P0_18
#define MBED_UARTUSB USBTX, USBRX
#define MBED_I2C0 P0_10, P0_11
typedef enum {
ADC_0 = 0,
ADC_1,
ADC_2,
ADC_3,
ADC_4,
ADC_5,
ADC_6,
ADC_7,
ADC_8,
ADC_9,
ADC_10,
ADC_11,
} ADCName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,135 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
#define PIN_SHIFT 8
typedef enum {
// LPC824 Pin Names (PIN[11:8] + IOCON offset[7:0])
P0_0 = ( 0 << PIN_SHIFT) | 0x44,
P0_1 = ( 1 << PIN_SHIFT) | 0x2C,
P0_2 = ( 2 << PIN_SHIFT) | 0x18,
P0_3 = ( 3 << PIN_SHIFT) | 0x14,
P0_4 = ( 4 << PIN_SHIFT) | 0x10,
P0_5 = ( 5 << PIN_SHIFT) | 0x0C,
P0_6 = ( 6 << PIN_SHIFT) | 0x40,
P0_7 = ( 7 << PIN_SHIFT) | 0x3C,
P0_8 = ( 8 << PIN_SHIFT) | 0x38,
P0_9 = ( 9 << PIN_SHIFT) | 0x34,
P0_10 = (10 << PIN_SHIFT) | 0x20,
P0_11 = (11 << PIN_SHIFT) | 0x1C,
P0_12 = (12 << PIN_SHIFT) | 0x08,
P0_13 = (13 << PIN_SHIFT) | 0x04,
P0_14 = (14 << PIN_SHIFT) | 0x48,
P0_15 = (15 << PIN_SHIFT) | 0x28,
P0_16 = (16 << PIN_SHIFT) | 0x24,
P0_17 = (17 << PIN_SHIFT) | 0x00,
P0_18 = (18 << PIN_SHIFT) | 0x78,
P0_19 = (19 << PIN_SHIFT) | 0x74,
P0_20 = (20 << PIN_SHIFT) | 0x70,
P0_21 = (21 << PIN_SHIFT) | 0x6C,
P0_22 = (22 << PIN_SHIFT) | 0x68,
P0_23 = (23 << PIN_SHIFT) | 0x64,
P0_24 = (24 << PIN_SHIFT) | 0x60,
P0_25 = (25 << PIN_SHIFT) | 0x5C,
P0_26 = (26 << PIN_SHIFT) | 0x58,
P0_27 = (27 << PIN_SHIFT) | 0x54,
P0_28 = (28 << PIN_SHIFT) | 0x50,
D0 = P0_0,
D1 = P0_4,
D2 = P0_19,
D3 = P0_12, // LED_RED
D4 = P0_18,
D5 = P0_28,
D6 = P0_16, // LED_GREEN
D7 = P0_17,
D8 = P0_13,
D9 = P0_27, // LED_BLUE
D10 = P0_15,
D11 = P0_26,
D12 = P0_25,
D13 = P0_24,
D14 = P0_11,
D15 = P0_10,
A0 = P0_6,
A1 = P0_14,
A2 = P0_23,
A3 = P0_22,
A4 = P0_21,
A5 = P0_20,
// LPC824-MAX board
LED_RED = P0_12,
LED_GREEN = P0_16,
LED_BLUE = P0_27,
// mbed original LED naming
LED1 = LED_RED,
LED2 = LED_GREEN,
LED3 = LED_BLUE,
LED4 = LED_BLUE,
// Serial to USB pins
USBTX = P0_7,
USBRX = P0_18,
// I2C pins
SDA = P0_10,
SCL = P0_11,
I2C_SDA = P0_10,
I2C_SCL = P0_11,
// Not connected
NC = (int)0xFFFFFFFF,
} PinName;
typedef enum {
PullUp = 2,
PullDown = 1,
PullNone = 0,
Repeater = 3,
OpenDrain = 4,
PullDefault = PullDown
} PinMode;
#define STDIO_UART_TX USBTX
#define STDIO_UART_RX USBRX
typedef struct {
unsigned char n;
unsigned char offset;
} SWM_Map;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,58 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H
#define DEVICE_PORTIN 0
#define DEVICE_PORTOUT 0
#define DEVICE_PORTINOUT 0
#define DEVICE_INTERRUPTIN 1
#define DEVICE_ANALOGIN 1
#define DEVICE_ANALOGOUT 0
#define DEVICE_SERIAL 1
#define DEVICE_SERIAL_FC 0
#define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 0
#define DEVICE_SPI 1
#define DEVICE_SPISLAVE 1
#define DEVICE_CAN 0
#define DEVICE_RTC 0
#define DEVICE_ETHERNET 0
#define DEVICE_PWMOUT 1
#define DEVICE_SEMIHOST 0
#define DEVICE_LOCALFILESYSTEM 0
#define DEVICE_SLEEP 1
#define DEVICE_DEBUG_AWARENESS 0
#define DEVICE_STDIO_MESSAGES 0
#define DEVICE_ERROR_RED 1
#include "objects.h"
#endif

View File

@ -0,0 +1,131 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "analogin_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralNames.h"
#if DEVICE_ANALOGIN
#define ANALOGIN_MEDIAN_FILTER 1
#define ADC_RANGE 0xFFF
static const PinMap PinMap_ADC[] = {
{P0_7 , ADC_0, 0},
{P0_6 , ADC_1, 0},
{P0_14, ADC_2, 0},
{P0_23, ADC_3, 0},
{P0_22, ADC_4, 0},
{P0_21, ADC_5, 0},
{P0_20, ADC_6, 0},
{P0_19, ADC_7, 0},
{P0_18, ADC_8, 0},
{P0_17, ADC_9, 0},
{P0_13, ADC_10,0},
{P0_4 , ADC_11,0},
};
void analogin_init(analogin_t *obj, PinName pin)
{
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj->adc != (ADCName)NC);
LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 6);
// pin enable
LPC_SWM->PINENABLE0 &= ~(1UL << (13 + obj->adc));
// configure GPIO as input
LPC_GPIO_PORT->DIR0 &= ~(1UL << (pin >> PIN_SHIFT));
LPC_SYSCON->PDRUNCFG &= ~(1 << 4);
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 24);
__IO LPC_ADC_Type *adc_reg = LPC_ADC;
// determine the system clock divider for a 500kHz ADC clock during calibration
uint32_t clkdiv = (SystemCoreClock / 500000) - 1;
// perform a self-calibration
adc_reg->CTRL = (1UL << 30) | (clkdiv & 0xFF);
while ((adc_reg->CTRL & (1UL << 30)) != 0);
}
static inline uint32_t adc_read(analogin_t *obj)
{
uint32_t channels;
__IO LPC_ADC_Type *adc_reg = LPC_ADC;
channels = (obj->adc & 0x1F);
// select channel
adc_reg->SEQA_CTRL &= ~(0xFFF);
adc_reg->SEQA_CTRL |= (1UL << channels);
// start conversion and sequence enable
adc_reg->SEQA_CTRL |= ((1UL << 26) | (1UL << 31));
// Repeatedly get the sample data until DONE bit
volatile uint32_t data;
do {
data = adc_reg->SEQA_GDAT;
} while ((data & (1UL << 31)) == 0);
// Stop conversion
adc_reg->SEQA_CTRL &= ~(1UL << 31);
return ((data >> 4) & ADC_RANGE);
}
static inline void order(uint32_t *a, uint32_t *b)
{
if (*a > *b) {
uint32_t t = *a;
*a = *b;
*b = t;
}
}
static inline uint32_t adc_read_u32(analogin_t *obj)
{
uint32_t value;
#if ANALOGIN_MEDIAN_FILTER
uint32_t v1 = adc_read(obj);
uint32_t v2 = adc_read(obj);
uint32_t v3 = adc_read(obj);
order(&v1, &v2);
order(&v2, &v3);
order(&v1, &v2);
value = v2;
#else
value = adc_read(obj);
#endif
return value;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
uint32_t value = adc_read_u32(obj);
return (value << 4) | ((value >> 8) & 0x000F); // 12 bit
}
float analogin_read(analogin_t *obj)
{
uint32_t value = adc_read_u32(obj);
return (float)value * (1.0f / (float)ADC_RANGE);
}
#endif

View File

@ -0,0 +1,72 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "gpio_api.h"
#include "pinmap.h"
static int gpio_enabled = 0;
static void gpio_enable(void)
{
gpio_enabled = 1;
/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6);
/* Peripheral reset control to GPIO and GPIO INT, a "1" bring it out of reset. */
LPC_SYSCON->PRESETCTRL &= ~(1 << 10);
LPC_SYSCON->PRESETCTRL |= (1 << 10);
}
uint32_t gpio_set(PinName pin)
{
if (!gpio_enabled)
gpio_enable();
return (1 << ((int)pin >> PIN_SHIFT));
}
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (pin == (PinName)NC)
return;
obj->mask = gpio_set(pin);
obj->reg_set = &LPC_GPIO_PORT->SET0;
obj->reg_clr = &LPC_GPIO_PORT->CLR0;
obj->reg_in = &LPC_GPIO_PORT->PIN0;
obj->reg_dir = &LPC_GPIO_PORT->DIR0;
}
void gpio_mode(gpio_t *obj, PinMode mode)
{
pin_mode(obj->pin, mode);
}
void gpio_dir(gpio_t *obj, PinDirection direction)
{
MBED_ASSERT(obj->pin != (PinName)NC);
switch (direction) {
case PIN_INPUT :
*obj->reg_dir &= ~obj->mask;
break;
case PIN_OUTPUT:
*obj->reg_dir |= obj->mask;
break;
}
}

View File

@ -0,0 +1,145 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include "cmsis.h"
#include "gpio_irq_api.h"
#include "mbed_error.h"
#if DEVICE_INTERRUPTIN
#define CHANNEL_NUM 8
#define LPC_GPIO_X LPC_PIN_INT
#define PININT_IRQ PIN_INT0_IRQn
static uint32_t channel_ids[CHANNEL_NUM] = {0};
static gpio_irq_handler irq_handler;
static inline void handle_interrupt_in(uint32_t channel)
{
uint32_t ch_bit = (1 << channel);
// Return immediately if:
// * The interrupt was already served
// * There is no user handler
// * It is a level interrupt, not an edge interrupt
if ( ((LPC_GPIO_X->IST & ch_bit) == 0) ||
(channel_ids[channel] == 0 ) ||
(LPC_GPIO_X->ISEL & ch_bit ) ) return;
if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) {
irq_handler(channel_ids[channel], IRQ_RISE);
LPC_GPIO_X->RISE = ch_bit;
}
if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) {
irq_handler(channel_ids[channel], IRQ_FALL);
}
LPC_GPIO_X->IST = ch_bit;
}
void gpio_irq0(void) {handle_interrupt_in(0);}
void gpio_irq1(void) {handle_interrupt_in(1);}
void gpio_irq2(void) {handle_interrupt_in(2);}
void gpio_irq3(void) {handle_interrupt_in(3);}
void gpio_irq4(void) {handle_interrupt_in(4);}
void gpio_irq5(void) {handle_interrupt_in(5);}
void gpio_irq6(void) {handle_interrupt_in(6);}
void gpio_irq7(void) {handle_interrupt_in(7);}
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
if (pin == NC) return -1;
irq_handler = handler;
int found_free_channel = 0;
int i = 0;
for (i=0; i<CHANNEL_NUM; i++) {
if (channel_ids[i] == 0) {
channel_ids[i] = id;
obj->ch = i;
found_free_channel = 1;
break;
}
}
if (!found_free_channel) return -1;
/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
LPC_SYSCON->PINTSEL[obj->ch] = (pin >> PIN_SHIFT);
// Interrupt Wake-Up Enable
LPC_SYSCON->STARTERP0 |= 1 << obj->ch;
void (*channels_irq)(void) = NULL;
switch (obj->ch) {
case 0: channels_irq = &gpio_irq0; break;
case 1: channels_irq = &gpio_irq1; break;
case 2: channels_irq = &gpio_irq2; break;
case 3: channels_irq = &gpio_irq3; break;
case 4: channels_irq = &gpio_irq4; break;
case 5: channels_irq = &gpio_irq5; break;
case 6: channels_irq = &gpio_irq6; break;
case 7: channels_irq = &gpio_irq7; break;
}
NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq);
NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
return 0;
}
void gpio_irq_free(gpio_irq_t *obj)
{
channel_ids[obj->ch] = 0;
LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch);
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
unsigned int ch_bit = (1 << obj->ch);
// Clear interrupt
if (!(LPC_GPIO_X->ISEL & ch_bit))
LPC_GPIO_X->IST = ch_bit;
// Edge trigger
LPC_GPIO_X->ISEL &= ~ch_bit;
if (event == IRQ_RISE) {
if (enable) {
LPC_GPIO_X->IENR |= ch_bit;
} else {
LPC_GPIO_X->IENR &= ~ch_bit;
}
} else {
if (enable) {
LPC_GPIO_X->IENF |= ch_bit;
} else {
LPC_GPIO_X->IENF &= ~ch_bit;
}
}
}
void gpio_irq_enable(gpio_irq_t *obj)
{
NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}
void gpio_irq_disable(gpio_irq_t *obj)
{
NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}
#endif

View File

@ -0,0 +1,54 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#include "mbed_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PinName pin;
uint32_t mask;
__IO uint32_t *reg_dir;
__IO uint32_t *reg_set;
__IO uint32_t *reg_clr;
__I uint32_t *reg_in;
} gpio_t;
static inline void gpio_write(gpio_t *obj, int value)
{
MBED_ASSERT(obj->pin != (PinName)NC);
if (value)
*obj->reg_set = obj->mask;
else
*obj->reg_clr = obj->mask;
}
static inline int gpio_read(gpio_t *obj)
{
MBED_ASSERT(obj->pin != (PinName)NC);
return ((*obj->reg_in & obj->mask) ? 1 : 0);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,358 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include "i2c_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "rom_i2c_8xx.h"
#if DEVICE_I2C
typedef struct ROM_API {
const uint32_t unused[5];
const I2CD_API_T *pI2CD; /*!< I2C driver routines functions table */
} LPC_ROM_API_T;
/* Pointer to ROM API function address */
#define LPC_ROM_API_BASE_LOC 0x1FFF1FF8UL
#define LPC_ROM_API (*(LPC_ROM_API_T * *) LPC_ROM_API_BASE_LOC)
/* Pointer to @ref I2CD_API_T functions in ROM */
#define LPC_I2CD_API ((LPC_ROM_API)->pI2CD)
static const SWM_Map SWM_I2C_SDA[] = {
{ 9, 8},
{ 9, 24},
{10, 8},
};
static const SWM_Map SWM_I2C_SCL[] = {
{ 9, 16},
{10, 0},
{10, 16},
};
static int i2c_used = 0;
static uint8_t repeated_start = 0;
static uint32_t *i2c_buffer;
#define I2C_DAT(x) (x->i2c->MSTDAT)
#define I2C_STAT(x) ((x->i2c->STAT >> 1) & (0x07))
static inline int i2c_status(i2c_t *obj)
{
return I2C_STAT(obj);
}
// Wait until the Serial Interrupt (SI) is set
static int i2c_wait_SI(i2c_t *obj)
{
volatile int timeout = 0;
while (!(obj->i2c->STAT & (1 << 0))) {
timeout++;
if (timeout > 100000) return -1;
}
return 0;
}
static inline void i2c_interface_enable(i2c_t *obj)
{
obj->i2c->CFG |= 1;
}
static inline void i2c_power_enable(int ch)
{
switch(ch) {
case 0:
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5);
LPC_SYSCON->PRESETCTRL &= ~(1 << 6);
LPC_SYSCON->PRESETCTRL |= (1 << 6);
break;
case 1:
case 2:
case 3:
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (20 + ch));
LPC_SYSCON->PRESETCTRL &= ~(1 << (13 + ch));
LPC_SYSCON->PRESETCTRL |= (1 << (13 + ch));
break;
default:
break;
}
}
static int get_available_i2c(void) {
int i;
for (i=0; i<3; i++) {
if ((i2c_used & (1 << i)) == 0)
return i+1;
}
return -1;
}
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
const SWM_Map *swm;
uint32_t regVal;
int i2c_ch = 0;
if (sda == I2C_SDA && scl == I2C_SCL) {
LPC_SWM->PINENABLE0 &= ~(0x3 << 11);
}
else {
i2c_ch = get_available_i2c();
if (i2c_ch == -1)
return;
swm = &SWM_I2C_SDA[i2c_ch - 1];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((sda >> PIN_SHIFT) << swm->offset);
swm = &SWM_I2C_SCL[i2c_ch - 1];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((scl >> PIN_SHIFT) << swm->offset);
}
switch(i2c_ch) {
case 0:
obj->i2c = (LPC_I2C0_Type *)LPC_I2C0;
break;
case 1:
obj->i2c = (LPC_I2C0_Type *)LPC_I2C1;
break;
case 2:
obj->i2c = (LPC_I2C0_Type *)LPC_I2C2;
break;
case 3:
obj->i2c = (LPC_I2C0_Type *)LPC_I2C3;
break;
default:
break;
}
// enable power
i2c_power_enable(i2c_ch);
i2c_interface_enable(obj);
uint32_t size_in_bytes = LPC_I2CD_API->i2c_get_mem_size();
i2c_buffer = malloc(size_in_bytes);
obj->handler = LPC_I2CD_API->i2c_setup((uint32_t)(obj->i2c), i2c_buffer);
LPC_I2CD_API->i2c_set_bitrate(obj->handler, SystemCoreClock, 100000);
LPC_I2CD_API->i2c_set_timeout(obj->handler, 100000);
}
inline int i2c_start(i2c_t *obj)
{
int status = 0;
if (repeated_start) {
obj->i2c->MSTCTL = (1 << 1) | (1 << 0);
repeated_start = 0;
} else {
obj->i2c->MSTCTL = (1 << 1);
}
return status;
}
inline int i2c_stop(i2c_t *obj)
{
volatile int timeout = 0;
obj->i2c->MSTCTL = (1 << 2) | (1 << 0);
while ((obj->i2c->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))) {
timeout ++;
if (timeout > 100000) return 1;
}
return 0;
}
static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr)
{
// write the data
I2C_DAT(obj) = value;
if (!addr)
obj->i2c->MSTCTL = (1 << 0);
// wait and return status
i2c_wait_SI(obj);
return i2c_status(obj);
}
static inline int i2c_do_read(i2c_t *obj, int last)
{
// wait for it to arrive
i2c_wait_SI(obj);
if (!last)
obj->i2c->MSTCTL = (1 << 0);
// return the data
return (I2C_DAT(obj) & 0xFF);
}
void i2c_frequency(i2c_t *obj, int hz)
{
LPC_I2CD_API->i2c_set_bitrate(obj->handler, SystemCoreClock, 100000);
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
ErrorCode_t err;
I2C_PARAM_T i2c_param;
I2C_RESULT_T i2c_result;
uint8_t *buf = malloc(length + 1);
buf[0] = (uint8_t)((address | 0x01) & 0xFF);
i2c_param.buffer_ptr_rec = buf;
i2c_param.num_bytes_rec = length + 1;
i2c_param.stop_flag = stop;
err = LPC_I2CD_API->i2c_master_receive_poll(obj->handler, &i2c_param, &i2c_result);
memcpy(data, buf + 1, i2c_result.n_bytes_recd);
free(buf);
if (err == 0)
return i2c_result.n_bytes_recd;
else
return -1;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
ErrorCode_t err;
I2C_PARAM_T i2c_param;
I2C_RESULT_T i2c_result;
uint8_t *buf = malloc(length + 1);
buf[0] = (uint8_t)(address & 0xFE);
memcpy(buf + 1, data, length);
i2c_param.buffer_ptr_send = buf;
i2c_param.num_bytes_send = length + 1;
i2c_param.stop_flag = stop;
err = LPC_I2CD_API->i2c_master_transmit_poll(obj->handler, &i2c_param, &i2c_result);
free(buf);
if (err == 0)
return i2c_result.n_bytes_sent;
else
return -1;
}
void i2c_reset(i2c_t *obj)
{
i2c_stop(obj);
}
int i2c_byte_read(i2c_t *obj, int last)
{
return (i2c_do_read(obj, last) & 0xFF);
}
int i2c_byte_write(i2c_t *obj, int data)
{
int ack;
int status = i2c_do_write(obj, (data & 0xFF), 0);
switch(status) {
case 2:
ack = 1;
break;
default:
ack = 0;
break;
}
return ack;
}
#if DEVICE_I2CSLAVE
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
obj->handler = LPC_I2CD_API->i2c_setup((uint32_t)(obj->i2c), i2c_buffer);
if (enable_slave != 0) {
obj->i2c->CFG &= ~(1 << 0);
obj->i2c->CFG |= (1 << 1);
}
else {
obj->i2c->CFG |= (1 << 0);
obj->i2c->CFG &= ~(1 << 1);
}
}
int i2c_slave_receive(i2c_t *obj)
{
CHIP_I2C_MODE_T mode;
int ret;
mode = LPC_I2CD_API->i2c_get_status(obj->handler);
switch(mode) {
case SLAVE_SEND:
ret = 1;
break;
case SLAVE_RECEIVE:
ret = 3;
break;
case MASTER_SEND:
case MASTER_RECEIVE:
default:
ret = 0;
break;
}
return ret;
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
ErrorCode_t err;
I2C_PARAM_T i2c_param;
I2C_RESULT_T i2c_result;
i2c_param.buffer_ptr_send = (uint8_t *)data;
i2c_param.num_bytes_send = length;
err = LPC_I2CD_API->i2c_slave_transmit_poll(obj->handler, &i2c_param, &i2c_result);
if (err == 0)
return i2c_result.n_bytes_sent;
else
return -1;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
ErrorCode_t err;
I2C_PARAM_T i2c_param;
I2C_RESULT_T i2c_result;
i2c_param.buffer_ptr_rec = (uint8_t *)data;
i2c_param.num_bytes_rec = length;
err = LPC_I2CD_API->i2c_slave_receive_poll(obj->handler, &i2c_param, &i2c_result);
if (err == 0)
return i2c_result.n_bytes_recd;
else
return -1;
}
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
LPC_I2CD_API->i2c_set_slave_addr(obj->handler, address, 0);
}
#endif
#endif

View File

@ -0,0 +1,62 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gpio_irq_s {
uint32_t ch;
};
struct serial_s {
LPC_USART0_Type *uart;
unsigned char index;
};
struct i2c_s {
LPC_I2C0_Type *i2c;
void *handler;
};
struct spi_s {
LPC_SPI0_Type *spi;
unsigned char spi_n;
};
struct analogin_s {
ADCName adc;
};
struct pwmout_s {
LPC_SCT_Type* pwm;
uint32_t pwm_ch;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,46 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "pinmap.h"
#include "mbed_error.h"
void pin_function(PinName pin, int function)
{
// do nothing
return;
}
void pin_mode(PinName pin, PinMode mode)
{
MBED_ASSERT(pin != (PinName)NC);
if ((pin == P0_10) || (pin == P0_11)) {
// True open-drain pins can be configured for different I2C-bus speeds
return;
}
__IO uint32_t *reg = (uint32_t *)(LPC_IOCON_BASE + (pin & 0xFF));
if (mode == OpenDrain) {
*reg |= (1 << 10);
} else {
uint32_t tmp = *reg;
tmp &= ~(0x3 << 3);
tmp |= (mode & 0x3) << 3;
*reg = tmp;
}
}

View File

@ -0,0 +1,173 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "pwmout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#if DEVICE_PWMOUT
// bit flags for used SCTs
static unsigned char sct_used = 0;
static int get_available_sct()
{
int i;
for (i = 0; i < 4; i++) {
if ((sct_used & (1 << i)) == 0)
return i;
}
return -1;
}
void pwmout_init(pwmout_t* obj, PinName pin)
{
MBED_ASSERT(pin != (uint32_t)NC);
int sct_n = get_available_sct();
if (sct_n == -1) {
error("No available SCT");
}
sct_used |= (1 << sct_n);
obj->pwm = (LPC_SCT_Type*)LPC_SCT;
obj->pwm_ch = sct_n;
LPC_SCT_Type* pwm = obj->pwm;
// Enable the SCT clock
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
// Clear peripheral reset the SCT:
LPC_SYSCON->PRESETCTRL |= (1 << 8);
switch(sct_n) {
case 0:
// SCT_OUT0
LPC_SWM->PINASSIGN[7] &= ~0xFF000000;
LPC_SWM->PINASSIGN[7] |= ((pin >> PIN_SHIFT) << 24);
break;
case 1:
// SCT_OUT1
LPC_SWM->PINASSIGN[8] &= ~0x000000FF;
LPC_SWM->PINASSIGN[8] |= (pin >> PIN_SHIFT);
break;
case 2:
// SCT2_OUT2
LPC_SWM->PINASSIGN[8] &= ~0x0000FF00;
LPC_SWM->PINASSIGN[8] |= ((pin >> PIN_SHIFT) << 8);
break;
case 3:
// SCT3_OUT3
LPC_SWM->PINASSIGN[8] &= ~0x00FF0000;
LPC_SWM->PINASSIGN[8] |= ((pin >> PIN_SHIFT) << 16);
break;
default:
break;
}
// Two 16-bit counters, autolimit
pwm->CONFIG &= ~(0x1);
pwm->CONFIG |= (1 << 17);
// halt and clear the counter
pwm->CTRL |= (1 << 2) | (1 << 3);
// System Clock -> us_ticker (1)MHz
pwm->CTRL &= ~(0x7F << 5);
pwm->CTRL |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5);
pwm->OUT[sct_n].SET = (1 << ((sct_n * 2) + 0));
pwm->OUT[sct_n].CLR = (1 << ((sct_n * 2) + 1));
pwm->EVENT[(sct_n * 2) + 0].CTRL = (1 << 12) | ((sct_n * 2) + 0); // match event
pwm->EVENT[(sct_n * 2) + 0].STATE = 0xFFFFFFFF;
pwm->EVENT[(sct_n * 2) + 1].CTRL = (1 << 12) | ((sct_n * 2) + 1);
pwm->EVENT[(sct_n * 2) + 1].STATE = 0xFFFFFFFF;
// unhalt the counter:
// - clearing bit 2 of the CTRL register
pwm->CTRL &= ~(1 << 2);
// default to 20ms: standard for servos, and fine for e.g. brightness control
pwmout_period_ms(obj, 20);
pwmout_write (obj, 0);
}
void pwmout_free(pwmout_t* obj)
{
// Disable the SCT clock
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
sct_used &= ~(1 << obj->pwm_ch);
}
void pwmout_write(pwmout_t* obj, float value)
{
if (value < 0.0f) {
value = 0.0;
} else if (value > 1.0f) {
value = 1.0;
}
uint32_t t_on = (uint32_t)((float)(obj->pwm->MATCHREL[obj->pwm_ch * 2]) * value);
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = t_on;
}
float pwmout_read(pwmout_t* obj)
{
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0];
uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1];
float v = (float)t_on/(float)t_off;
return (v > 1.0f) ? (1.0f) : (v);
}
void pwmout_period(pwmout_t* obj, float seconds)
{
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t* obj, int ms)
{
pwmout_period_us(obj, ms * 1000);
}
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t* obj, int us)
{
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0];
uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1];
float v = (float)t_on/(float)t_off;
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] = (uint64_t)us;
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint64_t)((float)us * (float)v);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
{
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
{
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
{
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint64_t)us;
}
#endif

View File

@ -0,0 +1,127 @@
/*
* @brief LPC8xx I2C ROM API declarations and functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __ROM_I2C_8XX_H_
#define __ROM_I2C_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CHIP_I2CROM_8XX CHIP: LPC8xx I2C ROM API declarations and functions
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx I2C ROM driver handle structure
*/
typedef void *I2C_HANDLE_T;
typedef uint32_t ErrorCode_t;
/**
* @brief LPC8xx I2C ROM driver callback function
*/
typedef void (*I2C_CALLBK_T)(uint32_t err_code, uint32_t n);
/**
* LPC8xx I2C ROM driver parameter structure
*/
typedef struct I2C_PARAM {
uint32_t num_bytes_send; /*!< No. of bytes to send */
uint32_t num_bytes_rec; /*!< No. of bytes to receive */
uint8_t *buffer_ptr_send; /*!< Pointer to send buffer */
uint8_t *buffer_ptr_rec; /*!< Pointer to receive buffer */
I2C_CALLBK_T func_pt; /*!< Callback function */
uint8_t stop_flag; /*!< Stop flag */
uint8_t dummy[3];
} I2C_PARAM_T;
/**
* LPC8xx I2C ROM driver result structure
*/
typedef struct I2C_RESULT {
uint32_t n_bytes_sent; /*!< No. of bytes sent */
uint32_t n_bytes_recd; /*!< No. of bytes received */
} I2C_RESULT_T;
/**
* LPC8xx I2C ROM driver modes enum
*/
typedef enum CHIP_I2C_MODE {
IDLE, /*!< IDLE state */
MASTER_SEND, /*!< Master send state */
MASTER_RECEIVE, /*!< Master Receive state */
SLAVE_SEND, /*!< Slave send state */
SLAVE_RECEIVE /*!< Slave receive state */
} CHIP_I2C_MODE_T;
/**
* LPC8xx I2C ROM driver APIs structure
*/
typedef struct I2CD_API {
/*!< Interrupt Support Routine */
void (*i2c_isr_handler)(I2C_HANDLE_T *handle);
/*!< MASTER functions */
ErrorCode_t (*i2c_master_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_tx_rx_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_master_tx_rx_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
/*!< SLAVE functions */
ErrorCode_t (*i2c_slave_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_slave_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_slave_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_slave_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result);
ErrorCode_t (*i2c_set_slave_addr)(I2C_HANDLE_T *handle, uint32_t slave_addr_0_3, uint32_t slave_mask_0_3);
/*!< OTHER support functions */
uint32_t (*i2c_get_mem_size)(void);
I2C_HANDLE_T * (*i2c_setup)( uint32_t i2c_base_addr, uint32_t * start_of_ram);
ErrorCode_t (*i2c_set_bitrate)(I2C_HANDLE_T *handle, uint32_t p_clk_in_hz, uint32_t bitrate_in_bps);
uint32_t (*i2c_get_firmware_version)(void);
CHIP_I2C_MODE_T (*i2c_get_status)(I2C_HANDLE_T *handle);
ErrorCode_t (*i2c_set_timeout)(I2C_HANDLE_T *handle, uint32_t timeout);
} I2CD_API_T;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ROM_I2C_8XX_H_ */

View File

@ -0,0 +1,333 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// math.h required for floating point operations for baud rate calculation
#include "mbed_assert.h"
#include <math.h>
#include <string.h>
#include "serial_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#if DEVICE_SERIAL
/******************************************************************************
* INITIALIZATION
******************************************************************************/
#define UART_NUM 3
static const SWM_Map SWM_UART_TX[] = {
{0, 0},
{1, 8},
{2, 16},
};
static const SWM_Map SWM_UART_RX[] = {
{0, 8},
{1, 16},
{2, 24},
};
static const SWM_Map SWM_UART_RTS[] = {
{0, 16},
{1, 24},
{3, 0},
};
static const SWM_Map SWM_UART_CTS[] = {
{0, 24},
{2, 0},
{3, 8}
};
// bit flags for used UARTs
static unsigned char uart_used = 0;
static int get_available_uart(void)
{
int i;
for (i=0; i<UART_NUM; i++) {
if ((uart_used & (1 << i)) == 0)
return i;
}
return -1;
}
#define UART_EN (0x01<<0)
#define CTS_DELTA (0x01<<5)
#define RXBRK (0x01<<10)
#define DELTA_RXBRK (0x01<<11)
#define RXRDY (0x01<<0)
#define TXRDY (0x01<<2)
#define TXBRKEN (0x01<<1)
#define CTSEN (0x01<<9)
static uint32_t UARTSysClk;
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uart_irq_handler irq_handler;
int stdio_uart_inited = 0;
serial_t stdio_uart;
void serial_init(serial_t *obj, PinName tx, PinName rx)
{
int is_stdio_uart = 0;
int uart_n = get_available_uart();
if (uart_n == -1) {
error("No available UART");
}
obj->index = uart_n;
obj->uart = (LPC_USART0_Type *)(LPC_USART0_BASE + (0x4000 * uart_n));
uart_used |= (1 << uart_n);
const SWM_Map *swm;
uint32_t regVal;
swm = &SWM_UART_TX[uart_n];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((tx >> PIN_SHIFT) << swm->offset);
swm = &SWM_UART_RX[uart_n];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((rx >> PIN_SHIFT) << swm->offset);
/* uart clock divided by 1 */
LPC_SYSCON->UARTCLKDIV = 1;
/* disable uart interrupts */
NVIC_DisableIRQ((IRQn_Type)(UART0_IRQn + uart_n));
/* Enable UART clock */
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (14 + uart_n));
/* Peripheral reset control to UART, a "1" bring it out of reset. */
LPC_SYSCON->PRESETCTRL &= ~(0x1 << (3 + uart_n));
LPC_SYSCON->PRESETCTRL |= (0x1 << (3 + uart_n));
UARTSysClk = MainClock / LPC_SYSCON->UARTCLKDIV;
// set default baud rate and format
serial_baud (obj, 9600);
serial_format(obj, 8, ParityNone, 1);
/* Clear all status bits. */
obj->uart->STAT = CTS_DELTA | DELTA_RXBRK;
/* enable uart interrupts */
NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + uart_n));
/* Enable UART */
obj->uart->CFG |= UART_EN;
is_stdio_uart = ((tx == USBTX) && (rx == USBRX));
if (is_stdio_uart) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj)
{
uart_used &= ~(1 << obj->index);
serial_irq_ids[obj->index] = 0;
}
void serial_baud(serial_t *obj, int baudrate)
{
/* Integer divider:
BRG = UARTSysClk/(Baudrate * 16) - 1
Frational divider:
FRG = ((UARTSysClk / (Baudrate * 16 * (BRG + 1))) - 1)
where
FRG = (LPC_SYSCON->UARTFRDADD + 1) / (LPC_SYSCON->UARTFRDSUB + 1)
(1) The easiest way is set SUB value to 256, -1 encoded, thus SUB
register is 0xFF.
(2) In ADD register value, depending on the value of UartSysClk,
baudrate, BRG register value, and SUB register value, be careful
about the order of multiplier and divider and make sure any
multiplier doesn't exceed 32-bit boundary and any divider doesn't get
down below one(integer 0).
(3) ADD should be always less than SUB.
*/
obj->uart->BRG = UARTSysClk / 16 / baudrate - 1;
LPC_SYSCON->UARTFRGDIV = 0xFF;
LPC_SYSCON->UARTFRGMULT = ( ((UARTSysClk / 16) * (LPC_SYSCON->UARTFRGDIV + 1)) /
(baudrate * (obj->uart->BRG + 1))
) - (LPC_SYSCON->UARTFRGDIV + 1);
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
// 0: 1 stop bits, 1: 2 stop bits
MBED_ASSERT((stop_bits == 1) || (stop_bits == 2));
MBED_ASSERT((data_bits > 6) && (data_bits < 10)); // 0: 7 data bits ... 2: 9 data bits
MBED_ASSERT((parity == ParityNone) || (parity == ParityEven) || (parity == ParityOdd));
stop_bits -= 1;
data_bits -= 7;
int paritysel;
switch (parity) {
case ParityNone: paritysel = 0; break;
case ParityEven: paritysel = 2; break;
case ParityOdd : paritysel = 3; break;
default:
break;
}
obj->uart->CFG = (data_bits << 2)
| (paritysel << 4)
| (stop_bits << 6);
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
static inline void uart_irq(uint32_t iir, uint32_t index)
{
SerialIrq irq_type;
switch (iir) {
case 1: irq_type = TxIrq; break;
case 2: irq_type = RxIrq; break;
default: return;
}
if (serial_irq_ids[index] != 0)
irq_handler(serial_irq_ids[index], irq_type);
}
void uart0_irq() {uart_irq((LPC_USART0->STAT & (1 << 2)) ? 2 : 1, 0);}
void uart1_irq() {uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 1);}
void uart2_irq() {uart_irq((LPC_USART2->STAT & (1 << 2)) ? 2 : 1, 2);}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
irq_handler = handler;
serial_irq_ids[obj->index] = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0;
switch ((int)obj->uart) {
case LPC_USART0_BASE: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
case LPC_USART1_BASE: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
case LPC_USART2_BASE: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
}
if (enable) {
obj->uart->INTENSET = (1 << ((irq == RxIrq) ? 0 : 2));
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
} else { // disable
int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
obj->uart->INTENSET &= ~(1 << ((irq == RxIrq) ? 0 : 2));
all_disabled = (obj->uart->INTENSET & (1 << ((other_irq == RxIrq) ? 0 : 2))) == 0;
if (all_disabled)
NVIC_DisableIRQ(irq_n);
}
}
/******************************************************************************
* READ/WRITE
******************************************************************************/
int serial_getc(serial_t *obj)
{
while (!serial_readable(obj));
return obj->uart->RXDAT;
}
void serial_putc(serial_t *obj, int c)
{
while (!serial_writable(obj));
obj->uart->TXDAT = c;
}
int serial_readable(serial_t *obj)
{
return obj->uart->STAT & RXRDY;
}
int serial_writable(serial_t *obj)
{
return obj->uart->STAT & TXRDY;
}
void serial_clear(serial_t *obj)
{
// [TODO]
}
void serial_pinout_tx(PinName tx)
{
}
void serial_break_set(serial_t *obj)
{
obj->uart->CTL |= TXBRKEN;
}
void serial_break_clear(serial_t *obj)
{
obj->uart->CTL &= ~TXBRKEN;
}
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
{
const SWM_Map *swm_rts, *swm_cts;
uint32_t regVal_rts, regVal_cts;
swm_rts = &SWM_UART_RTS[obj->index];
swm_cts = &SWM_UART_CTS[obj->index];
regVal_rts = LPC_SWM->PINASSIGN[swm_rts->n] & ~(0xFF << swm_rts->offset);
regVal_cts = LPC_SWM->PINASSIGN[swm_cts->n] & ~(0xFF << swm_cts->offset);
if (FlowControlNone == type) {
LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset);
LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset);
obj->uart->CFG &= ~CTSEN;
return;
}
if ((FlowControlRTS == type || FlowControlRTSCTS == type) && (rxflow != NC)) {
LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | ((rxflow >> PIN_SHIFT) << swm_rts->offset);
if (FlowControlRTS == type) {
LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset);
obj->uart->CFG &= ~CTSEN;
}
}
if ((FlowControlCTS == type || FlowControlRTSCTS == type) && (txflow != NC)) {
LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | ((txflow >> PIN_SHIFT) << swm_cts->offset);
obj->uart->CFG |= CTSEN;
if (FlowControlCTS == type) {
LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset);
}
}
}
#endif

View File

@ -0,0 +1,62 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sleep_api.h"
#include "cmsis.h"
//#define DEEPSLEEP
#define POWERDOWN
void sleep(void)
{
//Normal sleep mode for PCON:
LPC_PMU->PCON &= ~0x03;
//Normal sleep mode for ARM core:
SCB->SCR = 0;
//And go to sleep
__WFI();
}
// Deepsleep/powerdown modes assume the device is configured to use its internal RC oscillator directly
void deepsleep(void)
{
//Deep sleep in PCON
LPC_PMU->PCON &= ~0x03;
#if defined(DEEPSLEEP)
LPC_PMU->PCON |= 0x01;
#elif defined(POWERDOWN)
LPC_PMU->PCON |= 0x02;
#endif
//If brownout detection and WDT are enabled, keep them enabled during sleep
LPC_SYSCON->PDSLEEPCFG = LPC_SYSCON->PDRUNCFG;
//After wakeup same stuff as currently enabled:
LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
//All interrupts may wake up:
LPC_SYSCON->STARTERP0 = 0xFF;
LPC_SYSCON->STARTERP1 = 0xFFFF;
//Deep sleep for ARM core:
SCB->SCR = 1<<2;
__WFI();
}

View File

@ -0,0 +1,214 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "spi_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#if DEVICE_SPI
static const SWM_Map SWM_SPI_SSEL[] = {
{4, 16},
{5, 16},
};
static const SWM_Map SWM_SPI_SCLK[] = {
{3, 24},
{4, 24},
};
static const SWM_Map SWM_SPI_MOSI[] = {
{4, 0},
{5, 0},
};
static const SWM_Map SWM_SPI_MISO[] = {
{4, 8},
{5, 16},
};
// bit flags for used SPIs
static unsigned char spi_used = 0;
static int get_available_spi(void)
{
int i;
for (i=0; i<2; i++) {
if ((spi_used & (1 << i)) == 0)
return i;
}
return -1;
}
static inline int ssp_disable(spi_t *obj);
static inline int ssp_enable(spi_t *obj);
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
int spi_n = get_available_spi();
if (spi_n == -1) {
error("No available SPI");
}
obj->spi_n = spi_n;
spi_used |= (1 << spi_n);
obj->spi = (spi_n) ? (LPC_SPI0_Type *)(LPC_SPI1_BASE) : (LPC_SPI0_Type *)(LPC_SPI0_BASE);
const SWM_Map *swm;
uint32_t regVal;
if (sclk != (PinName)NC) {
swm = &SWM_SPI_SCLK[obj->spi_n];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((sclk >> PIN_SHIFT) << swm->offset);
}
if (mosi != (PinName)NC) {
swm = &SWM_SPI_MOSI[obj->spi_n];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((mosi >> PIN_SHIFT) << swm->offset);
}
if (miso != (PinName)NC) {
swm = &SWM_SPI_MISO[obj->spi_n];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((miso >> PIN_SHIFT) << swm->offset);
}
if (ssel != (PinName)NC) {
swm = &SWM_SPI_SSEL[obj->spi_n];
regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
LPC_SWM->PINASSIGN[swm->n] = regVal | ((ssel >> PIN_SHIFT) << swm->offset);
}
// clear interrupts
obj->spi->INTENCLR = 0x3f;
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (11 + obj->spi_n));
LPC_SYSCON->PRESETCTRL &= ~(1 << obj->spi_n);
LPC_SYSCON->PRESETCTRL |= (1 << obj->spi_n);
// set default format and frequency
if (ssel == NC) {
spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
} else {
spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
}
spi_frequency(obj, 1000000);
// enable the ssp channel
ssp_enable(obj);
}
void spi_free(spi_t *obj)
{
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
MBED_ASSERT(((bits >= 1) && (bits <= 16)) && ((mode >= 0) && (mode <= 3)));
ssp_disable(obj);
obj->spi->CFG &= ~((0x3 << 4) | (1 << 2));
obj->spi->CFG |= ((mode & 0x3) << 4) | ((slave ? 0 : 1) << 2);
obj->spi->TXDATCTL &= ~( 0xF << 24);
obj->spi->TXDATCTL |= (((bits & 0xF) - 1) << 24);
ssp_enable(obj);
}
void spi_frequency(spi_t *obj, int hz)
{
ssp_disable(obj);
// rise DIV value if it cannot be divided
obj->spi->DIV = (SystemCoreClock + (hz - 1))/hz - 1;
obj->spi->DLY = 0;
ssp_enable(obj);
}
static inline int ssp_disable(spi_t *obj)
{
return obj->spi->CFG &= ~(1 << 0);
}
static inline int ssp_enable(spi_t *obj)
{
return obj->spi->CFG |= (1 << 0);
}
static inline int ssp_readable(spi_t *obj)
{
return obj->spi->STAT & (1 << 0);
}
static inline int ssp_writeable(spi_t *obj)
{
return obj->spi->STAT & (1 << 1);
}
static inline void ssp_write(spi_t *obj, int value)
{
while (!ssp_writeable(obj));
// end of transfer
obj->spi->TXDATCTL |= (1 << 20);
obj->spi->TXDAT = value;
}
static inline int ssp_read(spi_t *obj)
{
while (!ssp_readable(obj));
return obj->spi->RXDAT;
}
static inline int ssp_busy(spi_t *obj)
{
// checking RXOV(Receiver Overrun interrupt flag)
return obj->spi->STAT & (1 << 2);
}
int spi_master_write(spi_t *obj, int value)
{
ssp_write(obj, value);
return ssp_read(obj);
}
int spi_slave_receive(spi_t *obj)
{
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
}
int spi_slave_read(spi_t *obj)
{
return obj->spi->RXDAT;
}
void spi_slave_write(spi_t *obj, int value)
{
while (ssp_writeable(obj) == 0);
obj->spi->TXDAT = value;
}
int spi_busy(spi_t *obj)
{
return ssp_busy(obj);
}
#endif

View File

@ -0,0 +1,89 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include "us_ticker_api.h"
#include "PeripheralNames.h"
static int us_ticker_inited = 0;
static int ticker_expired = 0;
#define US_TICKER_TIMER_IRQn MRT_IRQn
#define MRT_CLOCK_MHZ 30
void us_ticker_init(void)
{
if (us_ticker_inited)
return;
us_ticker_inited = 1;
// Enable the MRT clock
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
// Clear peripheral reset the MRT
LPC_SYSCON->PRESETCTRL |= (1 << 7);
// Force load interval value
LPC_MRT->INTVAL0 = 0xFFFFFFFFUL;
// Enable ch0 interrupt
LPC_MRT->CTRL0 = 1;
// Force load interval value
LPC_MRT->INTVAL1 = 0x80000000UL;
// Disable ch1 interrupt
LPC_MRT->CTRL1 = 0;
// Set MRT interrupt vector
NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
}
uint32_t us_ticker_read()
{
if (!us_ticker_inited)
us_ticker_init();
// Generate ticker value
// MRT source clock is SystemCoreClock (30MHz) and 31-bit down count timer
// Calculate expected value using number of expired times
return (0x7FFFFFFFUL - LPC_MRT->TIMER0)/MRT_CLOCK_MHZ + (ticker_expired * (0x80000000UL/MRT_CLOCK_MHZ));
}
void us_ticker_set_interrupt(timestamp_t timestamp)
{
// Force load interval value
LPC_MRT->INTVAL1 = (((timestamp - us_ticker_read()) * MRT_CLOCK_MHZ) | 0x80000000UL);
// Enable interrupt
LPC_MRT->CTRL1 |= 1;
}
void us_ticker_disable_interrupt()
{
LPC_MRT->CTRL1 &= ~1;
}
void us_ticker_clear_interrupt()
{
if (LPC_MRT->STAT1 & 1)
LPC_MRT->STAT1 = 1;
if (LPC_MRT->STAT0 & 1) {
LPC_MRT->STAT0 = 1;
ticker_expired++;
}
}

View File

@ -214,6 +214,9 @@ osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL}
#elif defined(TARGET_LPC812)
#define INITIAL_SP (0x10001000UL)
#elif defined(TARGET_LPC824)
#define INITIAL_SP (0x10002000UL)
#elif defined(TARGET_KL25Z)
#define INITIAL_SP (0x20003000UL)

View File

@ -54,7 +54,7 @@
# define OS_TASKCNT 14
# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \
|| defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \
|| defined(TARGET_STM32F103RB)
|| defined(TARGET_STM32F103RB) || defined(TARGET_LPC824)
# define OS_TASKCNT 6
# else
# error "no target defined"
@ -68,7 +68,7 @@
# define OS_SCHEDULERSTKSIZE 256
# elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \
|| defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \
|| defined(TARGET_STM32F103RB)
|| defined(TARGET_STM32F103RB) || defined(TARGET_LPC824)
# define OS_SCHEDULERSTKSIZE 128
# else
# error "no target defined"
@ -123,6 +123,9 @@
# elif defined(TARGET_LPC812)
# define OS_CLOCK 36000000
# elif defined(TARGET_LPC824)
# define OS_CLOCK 30000000
# elif defined(TARGET_STM32F100RB)
# define OS_CLOCK 24000000

View File

@ -33,6 +33,7 @@ OFFICIAL_MBED_LIBRARY_BUILD = (
('ARCH_PRO', ('ARM', 'GCC_ARM', 'GCC_CR', 'GCC_CS', 'IAR')),
('LPC2368', ('ARM',)),
('LPC812', ('uARM',)),
('LPC824', ('uARM',)),
('LPC1347', ('ARM',)),
('LPC4088', ('ARM', 'GCC_ARM', 'GCC_CR')),
('LPC1114', ('uARM','GCC_ARM')),

View File

@ -198,6 +198,17 @@ class LPC810(LPCTarget):
self.is_disk_virtual = True
class LPC824(LPCTarget):
def __init__(self):
LPCTarget.__init__(self)
self.core = "Cortex-M0+"
self.extra_labels = ['NXP', 'LPC82X']
self.supported_toolchains = ["uARM"]
self.default_toolchain = "uARM"
self.supported_form_factors = ["ARDUINO"]
self.is_disk_virtual = True
class LPC4088(LPCTarget):
def __init__(self):
LPCTarget.__init__(self)
@ -695,6 +706,7 @@ TARGETS = [
K22F(),
LPC812(),
LPC810(),
LPC824(),
LPC4088(),
LPC4330_M4(),
LPC4337(),