mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #531 from toyowata/master
Platform: LPC824 - new platform additionpull/526/merge
commit
b30176a071
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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];
|
||||
}
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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++;
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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')),
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in New Issue