ChibiOS 2.6.8, until I can figure out where to get it from git.

This commit is contained in:
Jared Boone
2015-07-08 08:40:23 -07:00
parent dc6fee8370
commit e1eea8e08a
1929 changed files with 575326 additions and 0 deletions

View File

@@ -0,0 +1,570 @@
/****************************************************************************
* $Id:: LPC13xx.h 7402 2011-05-25 18:48:12Z usb00175 $
* Project: NXP LPC13xx software example
*
* Description:
* CMSIS Cortex-M0 Core Peripheral Access Layer Header File for
* NXP LPC13xx Device Series
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
****************************************************************************/
#ifndef __LPC13xx_H__
#define __LPC13xx_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup LPC13xx_Definitions LPC13xx Definitions
This file defines all structures and symbols for LPC13xx:
- Registers and bitfields
- peripheral base address
- peripheral ID
- PIO definitions
@{
*/
/******************************************************************************/
/* Processor and Core Peripherals */
/******************************************************************************/
/** @addtogroup LPC13xx_CMSIS LPC13xx CMSIS Definitions
Configuration of the Cortex-M3 Processor and Core Peripherals
@{
*/
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** LPC13xx Specific Interrupt Numbers *******************************************************/
WAKEUP0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */
WAKEUP1_IRQn = 1, /*!< There are 40 pins in total for LPC17xx */
WAKEUP2_IRQn = 2,
WAKEUP3_IRQn = 3,
WAKEUP4_IRQn = 4,
WAKEUP5_IRQn = 5,
WAKEUP6_IRQn = 6,
WAKEUP7_IRQn = 7,
WAKEUP8_IRQn = 8,
WAKEUP9_IRQn = 9,
WAKEUP10_IRQn = 10,
WAKEUP11_IRQn = 11,
WAKEUP12_IRQn = 12,
WAKEUP13_IRQn = 13,
WAKEUP14_IRQn = 14,
WAKEUP15_IRQn = 15,
WAKEUP16_IRQn = 16,
WAKEUP17_IRQn = 17,
WAKEUP18_IRQn = 18,
WAKEUP19_IRQn = 19,
WAKEUP20_IRQn = 20,
WAKEUP21_IRQn = 21,
WAKEUP22_IRQn = 22,
WAKEUP23_IRQn = 23,
WAKEUP24_IRQn = 24,
WAKEUP25_IRQn = 25,
WAKEUP26_IRQn = 26,
WAKEUP27_IRQn = 27,
WAKEUP28_IRQn = 28,
WAKEUP29_IRQn = 29,
WAKEUP30_IRQn = 30,
WAKEUP31_IRQn = 31,
WAKEUP32_IRQn = 32,
WAKEUP33_IRQn = 33,
WAKEUP34_IRQn = 34,
WAKEUP35_IRQn = 35,
WAKEUP36_IRQn = 36,
WAKEUP37_IRQn = 37,
WAKEUP38_IRQn = 38,
WAKEUP39_IRQn = 39,
I2C_IRQn = 40, /*!< I2C Interrupt */
TIMER_16_0_IRQn = 41, /*!< 16-bit Timer0 Interrupt */
TIMER_16_1_IRQn = 42, /*!< 16-bit Timer1 Interrupt */
TIMER_32_0_IRQn = 43, /*!< 32-bit Timer0 Interrupt */
TIMER_32_1_IRQn = 44, /*!< 32-bit Timer1 Interrupt */
SSP0_IRQn = 45, /*!< SSP Interrupt */
UART_IRQn = 46, /*!< UART Interrupt */
USB_IRQn = 47, /*!< USB Regular Interrupt */
USB_FIQn = 48, /*!< USB Fast Interrupt */
ADC_IRQn = 49, /*!< A/D Converter Interrupt */
WDT_IRQn = 50, /*!< Watchdog timer Interrupt */
BOD_IRQn = 51, /*!< Brown Out Detect(BOD) Interrupt */
EINT3_IRQn = 53, /*!< External Interrupt 3 Interrupt */
EINT2_IRQn = 54, /*!< External Interrupt 2 Interrupt */
EINT1_IRQn = 55, /*!< External Interrupt 1 Interrupt */
EINT0_IRQn = 56, /*!< External Interrupt 0 Interrupt */
SSP1_IRQn = 57, /*!< SSP1 Interrupt */
} IRQn_Type;
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
/* Configuration of the Cortex-M3 Processor and Core Peripherals */
#define __MPU_PRESENT 1 /*!< MPU present or not */
#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
/*@}*/ /* end of group LPC13xx_CMSIS */
#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
#include "system_LPC13xx.h" /* System Header */
/******************************************************************************/
/* Device Specific Peripheral Registers structures */
/******************************************************************************/
#if defined ( __CC_ARM )
#pragma anon_unions
#endif
/*------------- System Control (SYSCON) --------------------------------------*/
/** @addtogroup LPC13xx_SYSCON LPC13xx System Control Block
@{
*/
typedef struct
{
__IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 (R/W) System memory remap Register */
__IO uint32_t PRESETCTRL; /*!< Offset: 0x004 (R/W) Peripheral reset control Register */
__IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 (R/W) System PLL control Register */
__I uint32_t SYSPLLSTAT; /*!< Offset: 0x00C (R/ ) System PLL status Register */
__IO uint32_t USBPLLCTRL; /* USB PLL control, offset 0x10 */
__IO uint32_t USBPLLSTAT;
uint32_t RESERVED0[2];
__IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 (R/W) System oscillator control Register */
__IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 (R/W) Watchdog oscillator control Register */
__IO uint32_t IRCCTRL; /*!< Offset: 0x028 (R/W) IRC control Register */
uint32_t RESERVED1[1];
__IO uint32_t SYSRSTSTAT; /*!< Offset: 0x030 (R/W) System reset status Register */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 (R/W) System PLL clock source select Register */
__IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 (R/W) System PLL clock source update enable Register */
__IO uint32_t USBPLLCLKSEL;
__IO uint32_t USBPLLCLKUEN;
uint32_t RESERVED3[8];
__IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 (R/W) Main clock source select Register */
__IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 (R/W) Main clock source update enable Register */
__IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 (R/W) System AHB clock divider Register */
uint32_t RESERVED4[1];
__IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 (R/W) System AHB clock control Register */
uint32_t RESERVED5[4];
__IO uint32_t SSP0CLKDIV;
__IO uint32_t UARTCLKDIV;
__IO uint32_t SSP1CLKDIV; /*!< Offset: 0x09C SSP1 clock divider (R/W) */
uint32_t RESERVED6[3];
__IO uint32_t TRACECLKDIV;
__IO uint32_t SYSTICKCLKDIV; /* Offset 0xB0 */
uint32_t RESERVED7[3];
__IO uint32_t USBCLKSEL; /* Offset 0xC0 */
__IO uint32_t USBCLKUEN;
__IO uint32_t USBCLKDIV;
uint32_t RESERVED8[1];
__IO uint32_t WDTCLKSEL; /*!< Offset: 0x0D0 (R/W) WDT clock source select Register */
__IO uint32_t WDTCLKUEN; /*!< Offset: 0x0D4 (R/W) WDT clock source update enable Register */
__IO uint32_t WDTCLKDIV; /*!< Offset: 0x0D8 (R/W) WDT clock divider Register */
uint32_t RESERVED9[1];
__IO uint32_t CLKOUTCLKSEL; /*!< Offset: 0x0E0 (R/W) CLKOUT clock source select Register */
__IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 (R/W) CLKOUT clock source update enable Register */
__IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 (R/W) CLKOUT clock divider Register */
uint32_t RESERVED10[5];
__I uint32_t PIOPORCAP0; /*!< Offset: 0x100 (R/ ) POR captured PIO status 0 Register */
__I uint32_t PIOPORCAP1; /*!< Offset: 0x104 (R/ ) POR captured PIO status 1 Register */
uint32_t RESERVED11[11];
uint32_t RESERVED12[7];
__IO uint32_t BODCTRL; /*!< Offset: 0x150 (R/W) BOD control Register */
uint32_t RESERVED13[1];
__IO uint32_t SYSTCKCAL; /*!< Offset: 0x158 (R/W) System tick counter calibration Register */
uint32_t RESERVED14[41];
__IO uint32_t STARTAPRP0; /*!< Offset: 0x200 (R/W) Start logic edge control Register 0 */
__IO uint32_t STARTERP0; /*!< Offset: 0x204 (R/W) Start logic signal enable Register 0 */
__O uint32_t STARTRSRP0CLR; /*!< Offset: 0x208 ( /W) Start logic reset Register 0 */
__I uint32_t STARTSRP0; /*!< Offset: 0x20C (R/ ) Start logic status Register 0 */
__IO uint32_t STARTAPRP1; /*!< Offset: 0x210 (R/W) Start logic edge control Register 1 (LPC11UXX only) */
__IO uint32_t STARTERP1; /*!< Offset: 0x214 (R/W) Start logic signal enable Register 1 (LPC11UXX only) */
__O uint32_t STARTRSRP1CLR; /*!< Offset: 0x218 ( /W) Start logic reset Register 1 (LPC11UXX only) */
__I uint32_t STARTSRP1; /*!< Offset: 0x21C (R/ ) Start logic status Register 1 (LPC11UXX only) */
uint32_t RESERVED17[4];
__IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 (R/W) Power-down states in Deep-sleep mode Register */
__IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 (R/W) Power-down states after wake-up from Deep-sleep mode Register*/
__IO uint32_t PDRUNCFG; /*!< Offset: 0x238 (R/W) Power-down configuration Register*/
uint32_t RESERVED18[110];
__I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 (R/ ) Device ID Register */
} LPC_SYSCON_TypeDef;
/*@}*/ /* end of group LPC13xx_SYSCON */
/*------------- Pin Connect Block (IOCON) --------------------------------*/
/** @addtogroup LPC13xx_IOCON LPC13xx I/O Configuration Block
@{
*/
typedef struct
{
__IO uint32_t PIO2_6; /*!< Offset: 0x000 (R/W) I/O configuration for pin PIO2_6 */
uint32_t RESERVED0[1];
__IO uint32_t PIO2_0; /*!< Offset: 0x008 (R/W) I/O configuration for pin PIO2_0/DTR/SSEL1 */
__IO uint32_t RESET_PIO0_0; /*!< Offset: 0x00C (R/W) I/O configuration for pin RESET/PIO0_0 */
__IO uint32_t PIO0_1; /*!< Offset: 0x010 (R/W) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2 */
__IO uint32_t PIO1_8; /*!< Offset: 0x014 (R/W) I/O configuration for pin PIO1_8/CT16B1_CAP0 */
uint32_t RESERVED1[1];
__IO uint32_t PIO0_2; /*!< Offset: 0x01C (R/W) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */
__IO uint32_t PIO2_7; /*!< Offset: 0x020 (R/W) I/O configuration for pin PIO2_7 */
__IO uint32_t PIO2_8; /*!< Offset: 0x024 (R/W) I/O configuration for pin PIO2_8 */
__IO uint32_t PIO2_1; /*!< Offset: 0x028 (R/W) I/O configuration for pin PIO2_1/nDSR/SCK1 */
__IO uint32_t PIO0_3; /*!< Offset: 0x02C (R/W) I/O configuration for pin PIO0_3 */
__IO uint32_t PIO0_4; /*!< Offset: 0x030 (R/W) I/O configuration for pin PIO0_4/SCL */
__IO uint32_t PIO0_5; /*!< Offset: 0x034 (R/W) I/O configuration for pin PIO0_5/SDA */
__IO uint32_t PIO1_9; /*!< Offset: 0x038 (R/W) I/O configuration for pin PIO1_9/CT16B1_MAT0 */
__IO uint32_t PIO3_4; /*!< Offset: 0x03C (R/W) I/O configuration for pin PIO3_4 */
__IO uint32_t PIO2_4; /*!< Offset: 0x040 (R/W) I/O configuration for pin PIO2_4 */
__IO uint32_t PIO2_5; /*!< Offset: 0x044 (R/W) I/O configuration for pin PIO2_5 */
__IO uint32_t PIO3_5; /*!< Offset: 0x048 (R/W) I/O configuration for pin PIO3_5 */
__IO uint32_t PIO0_6; /*!< Offset: 0x04C (R/W) I/O configuration for pin PIO0_6/SCK0 */
__IO uint32_t PIO0_7; /*!< Offset: 0x050 (R/W) I/O configuration for pin PIO0_7/nCTS */
__IO uint32_t PIO2_9; /*!< Offset: 0x054 (R/W) I/O configuration for pin PIO2_9 */
__IO uint32_t PIO2_10; /*!< Offset: 0x058 (R/W) I/O configuration for pin PIO2_10 */
__IO uint32_t PIO2_2; /*!< Offset: 0x05C (R/W) I/O configuration for pin PIO2_2/DCD/MISO1 */
__IO uint32_t PIO0_8; /*!< Offset: 0x060 (R/W) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 */
__IO uint32_t PIO0_9; /*!< Offset: 0x064 (R/W) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 */
__IO uint32_t SWCLK_PIO0_10; /*!< Offset: 0x068 (R/W) I/O configuration for pin SWCLK/PIO0_10/SCK0/CT16B0_MAT2 */
__IO uint32_t PIO1_10; /*!< Offset: 0x06C (R/W) I/O configuration for pin PIO1_10/AD6/CT16B1_MAT1 */
__IO uint32_t PIO2_11; /*!< Offset: 0x070 (R/W) I/O configuration for pin PIO2_11/SCK0 */
__IO uint32_t R_PIO0_11; /*!< Offset: 0x074 (R/W) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */
__IO uint32_t R_PIO1_0; /*!< Offset: 0x078 (R/W) I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 */
__IO uint32_t R_PIO1_1; /*!< Offset: 0x07C (R/W) I/O configuration for pin TDO/PIO1_1/AD2/CT32B1_MAT0 */
__IO uint32_t R_PIO1_2; /*!< Offset: 0x080 (R/W) I/O configuration for pin nTRST/PIO1_2/AD3/CT32B1_MAT1 */
__IO uint32_t PIO3_0; /*!< Offset: 0x084 (R/W) I/O configuration for pin PIO3_0/nDTR */
__IO uint32_t PIO3_1; /*!< Offset: 0x088 (R/W) I/O configuration for pin PIO3_1/nDSR */
__IO uint32_t PIO2_3; /*!< Offset: 0x08C (R/W) I/O configuration for pin PIO2_3/RI/MOSI1 */
__IO uint32_t SWDIO_PIO1_3; /*!< Offset: 0x090 (R/W) I/O configuration for pin SWDIO/PIO1_3/AD4/CT32B1_MAT2 */
__IO uint32_t PIO1_4; /*!< Offset: 0x094 (R/W) I/O configuration for pin PIO1_4/AD5/CT32B1_MAT3 */
__IO uint32_t PIO1_11; /*!< Offset: 0x098 (R/W) I/O configuration for pin PIO1_11/AD7 */
__IO uint32_t PIO3_2; /*!< Offset: 0x09C (R/W) I/O configuration for pin PIO3_2/nDCD */
__IO uint32_t PIO1_5;
__IO uint32_t PIO1_6;
__IO uint32_t PIO1_7;
__IO uint32_t PIO3_3;
__IO uint32_t SCK_LOC; /*!< Offset: 0x0B0 SCK pin location select Register (R/W) */
__IO uint32_t DSR_LOC; /*!< Offset: 0x0B4 DSR pin location select Register (R/W) */
__IO uint32_t DCD_LOC; /*!< Offset: 0x0B8 DCD pin location select Register (R/W) */
__IO uint32_t RI_LOC; /*!< Offset: 0x0BC RI pin location Register (R/W) */
} LPC_IOCON_TypeDef;
/*@}*/ /* end of group LPC13xx_IOCON */
/*------------- Power Management Unit (PMU) --------------------------*/
/** @addtogroup LPC13xx_PMU LPC13xx Power Management Unit
@{
*/
typedef struct
{
__IO uint32_t PCON; /*!< Offset: 0x000 (R/W) Power control Register */
__IO uint32_t GPREG0; /*!< Offset: 0x004 (R/W) General purpose Register 0 */
__IO uint32_t GPREG1; /*!< Offset: 0x008 (R/W) General purpose Register 1 */
__IO uint32_t GPREG2; /*!< Offset: 0x00C (R/W) General purpose Register 2 */
__IO uint32_t GPREG3; /*!< Offset: 0x010 (R/W) General purpose Register 3 */
__IO uint32_t GPREG4; /*!< Offset: 0x014 (R/W) General purpose Register 4 */
} LPC_PMU_TypeDef;
/*@}*/ /* end of group LPC13xx_PMU */
/*------------- General Purpose Input/Output (GPIO) --------------------------*/
/** @addtogroup LPC13xx_GPIO LPC13xx General Purpose Input/Output
@{
*/
typedef struct
{
union {
__IO uint32_t MASKED_ACCESS[4096]; /*!< Offset: 0x0000 (R/W) Port data Register for pins PIOn_0 to PIOn_11 */
struct {
uint32_t RESERVED0[4095];
__IO uint32_t DATA; /*!< Offset: 0x3FFC (R/W) Port data Register */
};
};
uint32_t RESERVED1[4096];
__IO uint32_t DIR; /*!< Offset: 0x8000 (R/W) Data direction Register */
__IO uint32_t IS; /*!< Offset: 0x8004 (R/W) Interrupt sense Register */
__IO uint32_t IBE; /*!< Offset: 0x8008 (R/W) Interrupt both edges Register */
__IO uint32_t IEV; /*!< Offset: 0x800C (R/W) Interrupt event Register */
__IO uint32_t IE; /*!< Offset: 0x8010 (R/W) Interrupt mask Register */
__I uint32_t RIS; /*!< Offset: 0x8014 (R/ ) Raw interrupt status Register */
__I uint32_t MIS; /*!< Offset: 0x8018 (R/ ) Masked interrupt status Register */
__O uint32_t IC; /*!< Offset: 0x801C ( /W) Interrupt clear Register */
} LPC_GPIO_TypeDef;
/*@}*/ /* end of group LPC13xx_GPIO */
/*------------- Timer (TMR) --------------------------------------------------*/
/** @addtogroup LPC13xx_TMR LPC13xx 16/32-bit Counter/Timer
@{
*/
typedef struct
{
__IO uint32_t IR; /*!< Offset: 0x000 (R/W) Interrupt Register */
__IO uint32_t TCR; /*!< Offset: 0x004 (R/W) Timer Control Register */
__IO uint32_t TC; /*!< Offset: 0x008 (R/W) Timer Counter Register */
__IO uint32_t PR; /*!< Offset: 0x00C (R/W) Prescale Register */
__IO uint32_t PC; /*!< Offset: 0x010 (R/W) Prescale Counter Register */
__IO uint32_t MCR; /*!< Offset: 0x014 (R/W) Match Control Register */
__IO uint32_t MR0; /*!< Offset: 0x018 (R/W) Match Register 0 */
__IO uint32_t MR1; /*!< Offset: 0x01C (R/W) Match Register 1 */
__IO uint32_t MR2; /*!< Offset: 0x020 (R/W) Match Register 2 */
__IO uint32_t MR3; /*!< Offset: 0x024 (R/W) Match Register 3 */
__IO uint32_t CCR; /*!< Offset: 0x028 (R/W) Capture Control Register */
__I uint32_t CR0; /*!< Offset: 0x02C (R/ ) Capture Register 0 */
uint32_t RESERVED1[3];
__IO uint32_t EMR; /*!< Offset: 0x03C (R/W) External Match Register */
uint32_t RESERVED2[12];
__IO uint32_t CTCR; /*!< Offset: 0x070 (R/W) Count Control Register */
__IO uint32_t PWMC; /*!< Offset: 0x074 (R/W) PWM Control Register */
} LPC_TMR_TypeDef;
/*@}*/ /* end of group LPC13xx_TMR */
/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
/** @addtogroup LPC13xx_UART LPC13xx Universal Asynchronous Receiver/Transmitter
@{
*/
typedef struct
{
union {
__I uint32_t RBR; /*!< Offset: 0x000 (R/ ) Receiver Buffer Register */
__O uint32_t THR; /*!< Offset: 0x000 ( /W) Transmit Holding Register */
__IO uint32_t DLL; /*!< Offset: 0x000 (R/W) Divisor Latch LSB */
};
union {
__IO uint32_t DLM; /*!< Offset: 0x004 (R/W) Divisor Latch MSB */
__IO uint32_t IER; /*!< Offset: 0x000 (R/W) Interrupt Enable Register */
};
union {
__I uint32_t IIR; /*!< Offset: 0x008 (R/ ) Interrupt ID Register */
__O uint32_t FCR; /*!< Offset: 0x008 ( /W) FIFO Control Register */
};
__IO uint32_t LCR; /*!< Offset: 0x00C (R/W) Line Control Register */
__IO uint32_t MCR; /*!< Offset: 0x010 (R/W) Modem control Register */
__I uint32_t LSR; /*!< Offset: 0x014 (R/ ) Line Status Register */
__I uint32_t MSR; /*!< Offset: 0x018 (R/ ) Modem status Register */
__IO uint32_t SCR; /*!< Offset: 0x01C (R/W) Scratch Pad Register */
__IO uint32_t ACR; /*!< Offset: 0x020 (R/W) Auto-baud Control Register */
uint32_t RESERVED0[1];
__IO uint32_t FDR; /*!< Offset: 0x028 (R/W) Fractional Divider Register */
uint32_t RESERVED1[1];
__IO uint32_t TER; /*!< Offset: 0x030 (R/W) Transmit Enable Register */
uint32_t RESERVED2[6];
__IO uint32_t RS485CTRL; /*!< Offset: 0x04C (R/W) RS-485/EIA-485 Control Register */
__IO uint32_t ADRMATCH; /*!< Offset: 0x050 (R/W) RS-485/EIA-485 address match Register */
__IO uint32_t RS485DLY; /*!< Offset: 0x054 (R/W) RS-485/EIA-485 direction control delay Register */
} LPC_UART_TypeDef;
/*@}*/ /* end of group LPC13xx_UART */
/*------------- Synchronous Serial Communication (SSP) -----------------------*/
/** @addtogroup LPC13xx_SSP LPC13xx Synchronous Serial Port
@{
*/
typedef struct
{
__IO uint32_t CR0; /*!< Offset: 0x000 (R/W) Control Register 0 */
__IO uint32_t CR1; /*!< Offset: 0x004 (R/W) Control Register 1 */
__IO uint32_t DR; /*!< Offset: 0x008 (R/W) Data Register */
__I uint32_t SR; /*!< Offset: 0x00C (R/ ) Status Register */
__IO uint32_t CPSR; /*!< Offset: 0x010 (R/W) Clock Prescale Register */
__IO uint32_t IMSC; /*!< Offset: 0x014 (R/W) Interrupt Mask Set and Clear Register */
__I uint32_t RIS; /*!< Offset: 0x018 (R/ ) Raw Interrupt Status Register */
__I uint32_t MIS; /*!< Offset: 0x01C (R/ ) Masked Interrupt Status Register */
__O uint32_t ICR; /*!< Offset: 0x020 ( /W) SSPICR Interrupt Clear Register */
} LPC_SSP_TypeDef;
/*@}*/ /* end of group LPC13xx_SSP */
/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
/** @addtogroup LPC13xx_I2C LPC13xx I2C-Bus Interface
@{
*/
typedef struct
{
__IO uint32_t CONSET; /*!< Offset: 0x000 (R/W) I2C Control Set Register */
__I uint32_t STAT; /*!< Offset: 0x004 (R/ ) I2C Status Register */
__IO uint32_t DAT; /*!< Offset: 0x008 (R/W) I2C Data Register */
__IO uint32_t ADR0; /*!< Offset: 0x00C (R/W) I2C Slave Address Register 0 */
__IO uint32_t SCLH; /*!< Offset: 0x010 (R/W) SCH Duty Cycle Register High Half Word */
__IO uint32_t SCLL; /*!< Offset: 0x014 (R/W) SCL Duty Cycle Register Low Half Word */
__O uint32_t CONCLR; /*!< Offset: 0x018 ( /W) I2C Control Clear Register */
__IO uint32_t MMCTRL; /*!< Offset: 0x01C (R/W) Monitor mode control register */
__IO uint32_t ADR1; /*!< Offset: 0x020 (R/W) I2C Slave Address Register 1 */
__IO uint32_t ADR2; /*!< Offset: 0x024 (R/W) I2C Slave Address Register 2 */
__IO uint32_t ADR3; /*!< Offset: 0x028 (R/W) I2C Slave Address Register 3 */
__I uint32_t DATA_BUFFER; /*!< Offset: 0x02C (R/ ) Data buffer Register */
__IO uint32_t MASK0; /*!< Offset: 0x030 (R/W) I2C Slave address mask register 0 */
__IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) I2C Slave address mask register 1 */
__IO uint32_t MASK2; /*!< Offset: 0x038 (R/W) I2C Slave address mask register 2 */
__IO uint32_t MASK3; /*!< Offset: 0x03C (R/W) I2C Slave address mask register 3 */
} LPC_I2C_TypeDef;
/*@}*/ /* end of group LPC13xx_I2C */
/*------------- Windowed Watchdog Timer (WWDT) -----------------------------------------*/
/** @addtogroup LPC13xx_WWDT LPC13xx Windowed WatchDog Timer
@{
*/
typedef struct
{
__IO uint32_t MOD;
__IO uint32_t TC;
__O uint32_t FEED;
__I uint32_t TV;
uint32_t RESERVED0;
__IO uint32_t WARNINT; /*!< Offset: 0x014 Watchdog timer warning int. register (R/W) */
__IO uint32_t WINDOW; /*!< Offset: 0x018 Watchdog timer window value register (R/W) */
} LPC_WWDT_TypeDef;
/*@}*/ /* end of group LPC13xx_WWDT */
/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
/** @addtogroup LPC13xx_ADC LPC13xx Analog-to-Digital Converter
@{
*/
typedef struct
{
__IO uint32_t CR; /*!< Offset: 0x000 (R/W) A/D Control Register */
__IO uint32_t GDR; /*!< Offset: 0x004 (R/W) A/D Global Data Register */
uint32_t RESERVED0[1];
__IO uint32_t INTEN; /*!< Offset: 0x00C (R/W) A/D Interrupt Enable Register */
__IO uint32_t DR[8]; /*!< Offset: 0x010 (R/W) A/D Channel 0..7 Data Register */
__I uint32_t STAT; /*!< Offset: 0x030 (R/ ) A/D Status Register */
} LPC_ADC_TypeDef;
/*@}*/ /* end of group LPC13xx_ADC */
/*------------- Universal Serial Bus (USB) -----------------------------------*/
/** @addtogroup LPC13xx_USB LPC13xx Universal Serial Bus
@{
*/
typedef struct
{
__I uint32_t DevIntSt; /*!< Offset: 0x000 (R/ ) USB Device Interrupt Status Register */
__IO uint32_t DevIntEn; /*!< Offset: 0x004 (R/W) USB Device Interrupt Enable Register */
__O uint32_t DevIntClr; /*!< Offset: 0x008 ( /W) USB Device Interrupt Clear Register */
__O uint32_t DevIntSet; /*!< Offset: 0x00C ( /W) USB Device Interrupt Set Register */
__O uint32_t CmdCode; /*!< Offset: 0x010 ( /W) USB Command Code Register */
__I uint32_t CmdData; /*!< Offset: 0x014 (R/ ) USB Command Data Register */
__I uint32_t RxData; /*!< Offset: 0x018 (R/ ) USB Receive Data Register */
__O uint32_t TxData; /*!< Offset: 0x01C ( /W) USB Transmit Data Register */
__I uint32_t RxPLen; /*!< Offset: 0x020 (R/ ) USB Receive Packet Length Register */
__O uint32_t TxPLen; /*!< Offset: 0x024 ( /W) USB Transmit Packet Length Register */
__IO uint32_t Ctrl; /*!< Offset: 0x028 (R/ ) USB Control Register */
__O uint32_t DevFIQSel; /*!< Offset: 0x02C ( /W) USB Device FIQ select Register */
} LPC_USB_TypeDef;
/*@}*/ /* end of group LPC13xx_USB */
#if defined ( __CC_ARM )
#pragma no_anon_unions
#endif
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000)
#define LPC_WWDT_BASE (LPC_APB0_BASE + 0x04000)
#define LPC_UART_BASE (LPC_APB0_BASE + 0x08000)
#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000)
#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000)
#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000)
#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000)
#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000)
#define LPC_USB_BASE (LPC_APB0_BASE + 0x20000)
#define LPC_PMU_BASE (LPC_APB0_BASE + 0x38000)
#define LPC_SSP0_BASE (LPC_APB0_BASE + 0x40000)
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x58000)
/* AHB peripherals */
#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000)
#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000)
#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE )
#define LPC_WWDT ((LPC_WWDT_TypeDef *) LPC_WWDT_BASE )
#define LPC_UART ((LPC_UART_TypeDef *) LPC_UART_BASE )
#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE)
#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE)
#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE)
#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE)
#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )
#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE )
#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE )
#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE )
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE )
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
#ifdef __cplusplus
}
#endif
#endif /* __LPC13xx_H__ */

View File

@@ -0,0 +1,338 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/gpt_lld.c
* @brief LPC13xx GPT subsystem low level driver source.
*
* @addtogroup GPT
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_GPT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief GPT1 driver identifier.
* @note The driver GPT1 allocates the complex timer CT16B0 when enabled.
*/
#if LPC13xx_GPT_USE_CT16B0 || defined(__DOXYGEN__)
GPTDriver GPTD1;
#endif
/**
* @brief GPT2 driver identifier.
* @note The driver GPT2 allocates the timer CT16B1 when enabled.
*/
#if LPC13xx_GPT_USE_CT16B1 || defined(__DOXYGEN__)
GPTDriver GPTD2;
#endif
/**
* @brief GPT3 driver identifier.
* @note The driver GPT3 allocates the timer CT32B0 when enabled.
*/
#if LPC13xx_GPT_USE_CT32B0 || defined(__DOXYGEN__)
GPTDriver GPTD3;
#endif
/**
* @brief GPT4 driver identifier.
* @note The driver GPT4 allocates the timer CT32B1 when enabled.
*/
#if LPC13xx_GPT_USE_CT32B1 || defined(__DOXYGEN__)
GPTDriver GPTD4;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Shared IRQ handler.
*
* @param[in] gptp pointer to a @p GPTDriver object
*/
static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
gptp->tmr->IR = 1; /* Clear interrupt on match MR0.*/
if (gptp->state == GPT_ONESHOT) {
gptp->state = GPT_READY; /* Back in GPT_READY state. */
gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
}
gptp->config->callback(gptp);
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if LPC13xx_GPT_USE_CT16B0
/**
* @brief CT16B0 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorE4) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD1);
CH_IRQ_EPILOGUE();
}
#endif /* LPC13xx_GPT_USE_CT16B0 */
#if LPC13xx_GPT_USE_CT16B1
/**
* @brief CT16B1 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorE8) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD2);
CH_IRQ_EPILOGUE();
}
#endif /* LPC13xx_GPT_USE_CT16B0 */
#if LPC13xx_GPT_USE_CT32B0
/**
* @brief CT32B0 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorEC) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD3);
CH_IRQ_EPILOGUE();
}
#endif /* LPC13xx_GPT_USE_CT32B0 */
#if LPC13xx_GPT_USE_CT32B1
/**
* @brief CT32B1 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorF0) {
CH_IRQ_PROLOGUE();
gpt_lld_serve_interrupt(&GPTD4);
CH_IRQ_EPILOGUE();
}
#endif /* LPC13xx_GPT_USE_CT32B1 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level GPT driver initialization.
*
* @notapi
*/
void gpt_lld_init(void) {
#if LPC13xx_GPT_USE_CT16B0
/* Driver initialization.*/
GPTD1.tmr = LPC_TMR16B0;
gptObjectInit(&GPTD1);
#endif
#if LPC13xx_GPT_USE_CT16B1
/* Driver initialization.*/
GPTD2.tmr = LPC_TMR16B1;
gptObjectInit(&GPTD2);
#endif
#if LPC13xx_GPT_USE_CT32B0
/* Driver initialization.*/
GPTD3.tmr = LPC_TMR32B0;
gptObjectInit(&GPTD3);
#endif
#if LPC13xx_GPT_USE_CT32B1
/* Driver initialization.*/
GPTD4.tmr = LPC_TMR32B1;
gptObjectInit(&GPTD4);
#endif
}
/**
* @brief Configures and activates the GPT peripheral.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_start(GPTDriver *gptp) {
uint32_t pr;
if (gptp->state == GPT_STOP) {
/* Clock activation.*/
#if LPC13xx_GPT_USE_CT16B0
if (&GPTD1 == gptp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
nvicEnableVector(TIMER_16_0_IRQn, CORTEX_PRIORITY_MASK(2));
}
#endif
#if LPC13xx_GPT_USE_CT16B1
if (&GPTD2 == gptp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
nvicEnableVector(TIMER_16_1_IRQn, CORTEX_PRIORITY_MASK(3));
}
#endif
#if LPC13xx_GPT_USE_CT32B0
if (&GPTD3 == gptp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);
nvicEnableVector(TIMER_32_0_IRQn, CORTEX_PRIORITY_MASK(2));
}
#endif
#if LPC13xx_GPT_USE_CT32B1
if (&GPTD4 == gptp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
nvicEnableVector(TIMER_32_1_IRQn, CORTEX_PRIORITY_MASK(2));
}
#endif
}
/* Prescaler value calculation.*/
pr = (uint16_t)((LPC13xx_SYSCLK / gptp->config->frequency) - 1);
chDbgAssert(((uint32_t)(pr + 1) * gptp->config->frequency) == LPC13xx_SYSCLK,
"gpt_lld_start(), #1", "invalid frequency");
/* Timer configuration.*/
gptp->tmr->PR = pr;
gptp->tmr->IR = 1;
gptp->tmr->MCR = 0;
gptp->tmr->TCR = 0;
}
/**
* @brief Deactivates the GPT peripheral.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_stop(GPTDriver *gptp) {
if (gptp->state == GPT_READY) {
gptp->tmr->MCR = 0;
gptp->tmr->TCR = 0;
#if LPC13xx_GPT_USE_CT16B0
if (&GPTD1 == gptp) {
nvicDisableVector(TIMER_16_0_IRQn);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 7);
}
#endif
#if LPC13xx_GPT_USE_CT16B1
if (&GPTD2 == gptp) {
nvicDisableVector(TIMER_16_1_IRQn);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
}
#endif
#if LPC13xx_GPT_USE_CT32B0
if (&GPTD3 == gptp) {
nvicDisableVector(TIMER_32_0_IRQn);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 9);
}
#endif
#if LPC13xx_GPT_USE_CT32B1
if (&GPTD4 == gptp) {
nvicDisableVector(TIMER_32_1_IRQn);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 10);
}
#endif
}
}
/**
* @brief Starts the timer in continuous mode.
*
* @param[in] gptp pointer to the @p GPTDriver object
* @param[in] interval period in ticks
*
* @notapi
*/
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
gptp->tmr->MR0 = interval - 1;
gptp->tmr->IR = 1;
gptp->tmr->MCR = 3; /* IRQ and clr TC on match MR0. */
gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
gptp->tmr->TCR = 1; /* Timer enabled. */
}
/**
* @brief Stops the timer.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_stop_timer(GPTDriver *gptp) {
gptp->tmr->IR = 1;
gptp->tmr->MCR = 0;
gptp->tmr->TCR = 0;
}
/**
* @brief Starts the timer in one shot mode and waits for completion.
* @details This function specifically polls the timer waiting for completion
* in order to not have extra delays caused by interrupt servicing,
* this function is only recommended for short delays.
*
* @param[in] gptp pointer to the @p GPTDriver object
* @param[in] interval time interval in ticks
*
* @notapi
*/
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
gptp->tmr->MR0 = interval - 1;
gptp->tmr->IR = 1;
gptp->tmr->MCR = 4; /* Stop TC on match MR0. */
gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
gptp->tmr->TCR = 1; /* Timer enabled. */
while (gptp->tmr->TCR & 1)
;
}
#endif /* HAL_USE_GPT */
/** @} */

View File

@@ -0,0 +1,208 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/gpt_lld.h
* @brief LPC13xx GPT subsystem low level driver header.
*
* @addtogroup GPT
* @{
*/
#ifndef _GPT_LLD_H_
#define _GPT_LLD_H_
#if HAL_USE_GPT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief GPT1 driver enable switch.
* @details If set to @p TRUE the support for GPT1 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC13xx_GPT_USE_CT16B0) || defined(__DOXYGEN__)
#define LPC13xx_GPT_USE_CT16B0 TRUE
#endif
/**
* @brief GPT2 driver enable switch.
* @details If set to @p TRUE the support for GPT2 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC13xx_GPT_USE_CT16B1) || defined(__DOXYGEN__)
#define LPC13xx_GPT_USE_CT16B1 TRUE
#endif
/**
* @brief GPT3 driver enable switch.
* @details If set to @p TRUE the support for GPT3 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC13xx_GPT_USE_CT32B0) || defined(__DOXYGEN__)
#define LPC13xx_GPT_USE_CT32B0 TRUE
#endif
/**
* @brief GPT4 driver enable switch.
* @details If set to @p TRUE the support for GPT4 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC13xx_GPT_USE_CT32B1) || defined(__DOXYGEN__)
#define LPC13xx_GPT_USE_CT32B1 TRUE
#endif
/**
* @brief GPT1 interrupt priority level setting.
*/
#if !defined(LPC13xx_GPT_CT16B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_GPT_CT16B0_IRQ_PRIORITY 2
#endif
/**
* @brief GPT2 interrupt priority level setting.
*/
#if !defined(LPC13xx_GPT_CT16B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_GPT_CT16B1_IRQ_PRIORITY 2
#endif
/**
* @brief GPT3 interrupt priority level setting.
*/
#if !defined(LPC13xx_GPT_CT32B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_GPT_CT32B0_IRQ_PRIORITY 2
#endif
/**
* @brief GPT4 interrupt priority level setting.
*/
#if !defined(LPC13xx_GPT_CT32B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_GPT_CT32B1_IRQ_PRIORITY 2
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !LPC13xx_GPT_USE_CT16B0 && !LPC13xx_GPT_USE_CT16B1 && \
!LPC13xx_GPT_USE_CT32B0 && !LPC13xx_GPT_USE_CT32B1
#error "GPT driver activated but no CT peripheral assigned"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief GPT frequency type.
*/
typedef uint32_t gptfreq_t;
/**
* @brief GPT counter type.
*/
typedef uint32_t gptcnt_t;
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
*/
typedef struct {
/**
* @brief Timer clock in Hz.
* @note The low level can use assertions in order to catch invalid
* frequency specifications.
*/
gptfreq_t frequency;
/**
* @brief Timer callback pointer.
* @note This callback is invoked on GPT counter events.
*/
gptcallback_t callback;
/* End of the mandatory fields.*/
} GPTConfig;
/**
* @brief Structure representing a GPT driver.
*/
struct GPTDriver {
/**
* @brief Driver state.
*/
gptstate_t state;
/**
* @brief Current configuration data.
*/
const GPTConfig *config;
/* End of the mandatory fields.*/
/**
* @brief Timer base clock.
*/
uint32_t clock;
/**
* @brief Pointer to the CTxxBy registers block.
*/
LPC_TMR_TypeDef *tmr;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if LPC13xx_GPT_USE_CT16B0 && !defined(__DOXYGEN__)
extern GPTDriver GPTD1;
#endif
#if LPC13xx_GPT_USE_CT16B1 && !defined(__DOXYGEN__)
extern GPTDriver GPTD2;
#endif
#if LPC13xx_GPT_USE_CT32B0 && !defined(__DOXYGEN__)
extern GPTDriver GPTD3;
#endif
#if LPC13xx_GPT_USE_CT32B1 && !defined(__DOXYGEN__)
extern GPTDriver GPTD4;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void gpt_lld_init(void);
void gpt_lld_start(GPTDriver *gptp);
void gpt_lld_stop(GPTDriver *gptp);
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
void gpt_lld_stop_timer(GPTDriver *gptp);
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_GPT */
#endif /* _GPT_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,120 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/hal_lld.c
* @brief LPC13xx HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/**
* @brief Register missing in NXP header file.
*/
#define FLASHCFG (*((volatile uint32_t *)0x4003C010))
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*
* @notapi
*/
void hal_lld_init(void) {
/* SysTick initialization using the system clock.*/
nvicSetSystemHandlerPriority(HANDLER_SYSTICK, CORTEX_PRIORITY_SYSTICK);
SysTick->LOAD = LPC13xx_SYSCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
}
/**
* @brief LPC13xx clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
* @note This function must be invoked only after the system reset.
*
* @special
*/
void LPC13xx_clock_init(void) {
unsigned i;
/* Flash wait states setting, the code takes care to not touch TBD bits.*/
FLASHCFG = (FLASHCFG & ~3) | LPC13xx_FLASHCFG_FLASHTIM;
/* System oscillator initialization if required.*/
#if LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
#if LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC
LPC_SYSCON->SYSOSCCTRL = LPC13xx_SYSOSCCTRL;
LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* System oscillator ON. */
for (i = 0; i < 200; i++)
__NOP(); /* Stabilization delay. */
#endif /* LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC */
/* PLL initialization if required.*/
LPC_SYSCON->SYSPLLCLKSEL = LPC13xx_PLLCLK_SOURCE;
LPC_SYSCON->SYSPLLCLKUEN = 1; /* Really required? */
LPC_SYSCON->SYSPLLCLKUEN = 0;
LPC_SYSCON->SYSPLLCLKUEN = 1;
LPC_SYSCON->SYSPLLCTRL = LPC13xx_SYSPLLCTRL_MSEL | LPC13xx_SYSPLLCTRL_PSEL;
LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* System PLL ON. */
while ((LPC_SYSCON->SYSPLLSTAT & 1) == 0) /* Wait PLL lock. */
;
#endif /* LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT */
/* Main clock source selection.*/
LPC_SYSCON->MAINCLKSEL = LPC13xx_MAINCLK_SOURCE;
LPC_SYSCON->MAINCLKUEN = 1; /* Really required? */
LPC_SYSCON->MAINCLKUEN = 0;
LPC_SYSCON->MAINCLKUEN = 1;
while ((LPC_SYSCON->MAINCLKUEN & 1) == 0) /* Wait switch completion. */
;
/* ABH divider initialization, peripheral clocks are initially disabled,
the various device drivers will handle their own setup except GPIO and
IOCON that are left enabled.*/
LPC_SYSCON->SYSAHBCLKDIV = LPC13xx_SYSABHCLK_DIV;
LPC_SYSCON->SYSAHBCLKCTRL = 0x0001005F;
/* Memory remapping, vectors always in ROM.*/
LPC_SYSCON->SYSMEMREMAP = 2;
}
/** @} */

View File

@@ -0,0 +1,219 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/hal_lld.h
* @brief HAL subsystem low level driver header template.
*
* @addtogroup HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "LPC13xx.h"
#include "nvic.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Defines the support for realtime counters in the HAL.
*/
#define HAL_IMPLEMENTS_COUNTERS FALSE
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "LPC13xx"
#define IRCOSCCLK 12000000 /**< High speed internal clock. */
#define WDGOSCCLK 1600000 /**< Watchdog internal clock. */
#define SYSPLLCLKSEL_IRCOSC 0 /**< Internal RC oscillator
clock source. */
#define SYSPLLCLKSEL_SYSOSC 1 /**< System oscillator clock
source. */
#define SYSMAINCLKSEL_IRCOSC 0 /**< Clock source is IRC. */
#define SYSMAINCLKSEL_PLLIN 1 /**< Clock source is PLLIN. */
#define SYSMAINCLKSEL_WDGOSC 2 /**< Clock source is WDGOSC. */
#define SYSMAINCLKSEL_PLLOUT 3 /**< Clock source is PLLOUT. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief System PLL clock source.
*/
#if !defined(LPC13xx_PLLCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC13xx_PLLCLK_SOURCE SYSPLLCLKSEL_SYSOSC
#endif
/**
* @brief System PLL multiplier.
* @note The value must be in the 1..32 range and the final frequency
* must not exceed the CCO ratings.
*/
#if !defined(LPC13xx_SYSPLL_MUL) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLL_MUL 6
#endif
/**
* @brief System PLL divider.
* @note The value must be chosen between (2, 4, 8, 16).
*/
#if !defined(LPC13xx_SYSPLL_DIV) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLL_DIV 4
#endif
/**
* @brief System main clock source.
*/
#if !defined(LPC13xx_MAINCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC13xx_MAINCLK_SOURCE SYSMAINCLKSEL_PLLOUT
#endif
/**
* @brief AHB clock divider.
* @note The value must be chosen between (1...255).
*/
#if !defined(LPC13xx_SYSCLK_DIV) || defined(__DOXYGEN__)
#define LPC13xx_SYSABHCLK_DIV 1
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/**
* @brief Calculated SYSOSCCTRL setting.
*/
#if (SYSOSCCLK < 18000000) || defined(__DOXYGEN__)
#define LPC13xx_SYSOSCCTRL 0
#else
#define LPC13xx_SYSOSCCTRL 1
#endif
/**
* @brief PLL input clock frequency.
*/
#if (LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLLCLKIN SYSOSCCLK
#elif LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_IRCOSC
#define LPC13xx_SYSPLLCLKIN IRCOSCCLK
#else
#error "invalid LPC13xx_PLLCLK_SOURCE clock source specified"
#endif
/**
* @brief MSEL mask in SYSPLLCTRL register.
*/
#if (LPC13xx_SYSPLL_MUL >= 1) && (LPC13xx_SYSPLL_MUL <= 32) || \
defined(__DOXYGEN__)
#define LPC13xx_SYSPLLCTRL_MSEL (LPC13xx_SYSPLL_MUL - 1)
#else
#error "LPC13xx_SYSPLL_MUL out of range (1...32)"
#endif
/**
* @brief PSEL mask in SYSPLLCTRL register.
*/
#if (LPC13xx_SYSPLL_DIV == 2) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLLCTRL_PSEL (0 << 5)
#elif LPC13xx_SYSPLL_DIV == 4
#define LPC13xx_SYSPLLCTRL_PSEL (1 << 5)
#elif LPC13xx_SYSPLL_DIV == 8
#define LPC13xx_SYSPLLCTRL_PSEL (2 << 5)
#elif LPC13xx_SYSPLL_DIV == 16
#define LPC13xx_SYSPLLCTRL_PSEL (3 << 5)
#else
#error "invalid LPC13xx_SYSPLL_DIV value (2,4,8,16)"
#endif
/**
* @brief CCP frequency.
*/
#define LPC13xx_SYSPLLCCO (LPC13xx_SYSPLLCLKIN * LPC13xx_SYSPLL_MUL * \
LPC13xx_SYSPLL_DIV)
#if (LPC13xx_SYSPLLCCO < 156000000) || (LPC13xx_SYSPLLCCO > 320000000)
#error "CCO frequency out of the acceptable range (156...320)"
#endif
/**
* @brief PLL output clock frequency.
*/
#define LPC13xx_SYSPLLCLKOUT (LPC13xx_SYSPLLCCO / LPC13xx_SYSPLL_DIV)
#if (LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_IRCOSC) || defined(__DOXYGEN__)
#define LPC13xx_MAINCLK IRCOSCCLK
#elif LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLIN
#define LPC13xx_MAINCLK LPC13xx_SYSPLLCLKIN
#elif LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_WDGOSC
#define LPC13xx_MAINCLK WDGOSCCLK
#elif LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
#define LPC13xx_MAINCLK LPC13xx_SYSPLLCLKOUT
#else
#error "invalid LPC13xx_MAINCLK_SOURCE clock source specified"
#endif
/**
* @brief AHB clock.
*/
#define LPC13xx_SYSCLK (LPC13xx_MAINCLK / LPC13xx_SYSABHCLK_DIV)
#if LPC13xx_SYSCLK > 72000000
#error "AHB clock frequency out of the acceptable range (72MHz max)"
#endif
/**
* @brief Flash wait states.
*/
#if (LPC13xx_SYSCLK <= 20000000) || defined(__DOXYGEN__)
#define LPC13xx_FLASHCFG_FLASHTIM 0
#elif LPC13xx_SYSCLK <= 40000000
#define LPC13xx_FLASHCFG_FLASHTIM 1
#else
#define LPC13xx_FLASHCFG_FLASHTIM 2
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void LPC13xx_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,103 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/pal_lld.c
* @brief LPC13xx GPIO low level driver code.
*
* @addtogroup PAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief LPC13xx I/O ports configuration.
* @details GPIO unit registers initialization.
*
* @param[in] config the LPC13xx ports configuration
*
* @notapi
*/
void _pal_lld_init(const PALConfig *config) {
LPC_GPIO0->DIR = config->P0.dir;
LPC_GPIO1->DIR = config->P1.dir;
LPC_GPIO2->DIR = config->P2.dir;
LPC_GPIO3->DIR = config->P3.dir;
LPC_GPIO0->DATA = config->P0.data;
LPC_GPIO1->DATA = config->P1.data;
LPC_GPIO2->DATA = config->P2.data;
LPC_GPIO3->DATA = config->P3.data;
}
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with
* high state.
* @note This function does not alter the @p PINSELx registers. Alternate
* functions setup must be handled by device-specific code.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @notapi
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode) {
switch (mode) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT:
port->DIR &= ~mask;
break;
case PAL_MODE_UNCONNECTED:
palSetPort(port, PAL_WHOLE_PORT);
case PAL_MODE_OUTPUT_PUSHPULL:
port->DIR |= mask;
break;
}
}
#endif /* HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,316 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/pal_lld.h
* @brief LPC13xx GPIO low level driver header.
*
* @addtogroup PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
#undef PAL_MODE_INPUT_PULLUP
#undef PAL_MODE_INPUT_PULLDOWN
#undef PAL_MODE_INPUT_ANALOG
#undef PAL_MODE_OUTPUT_OPENDRAIN
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @brief GPIO port setup info.
*/
typedef struct {
/** Initial value for FIO_PIN register.*/
uint32_t data;
/** Initial value for FIO_DIR register.*/
uint32_t dir;
} lpc13xx_gpio_setup_t;
/**
* @brief GPIO static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized the digital I/O
* subsystem. This represents only the initial setup, specific pads
* or whole ports can be reprogrammed at later time.
* @note The @p IOCON block is not configured, initially all pins have
* enabled pullups and are programmed as GPIO. It is responsibility
* of the various drivers to reprogram the pins in the proper mode.
* Pins that are not handled by any driver may be programmed in
* @p board.c.
*/
typedef struct {
/** @brief GPIO 0 setup data.*/
lpc13xx_gpio_setup_t P0;
/** @brief GPIO 1 setup data.*/
lpc13xx_gpio_setup_t P1;
/** @brief GPIO 2 setup data.*/
lpc13xx_gpio_setup_t P2;
/** @brief GPIO 3 setup data.*/
lpc13xx_gpio_setup_t P3;
} PALConfig;
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32
/**
* @brief Whole port mask.
* @brief This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFF)
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Digital I/O modes.
*/
typedef uint32_t iomode_t;
/**
* @brief Port Identifier.
*/
typedef LPC_GPIO_TypeDef *ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief GPIO0 port identifier.
*/
#define IOPORT1 LPC_GPIO0
#define GPIO0 LPC_GPIO0
/**
* @brief GPIO1 port identifier.
*/
#define IOPORT2 LPC_GPIO1
#define GPIO1 LPC_GPIO1
/**
* @brief GPIO2 port identifier.
*/
#define IOPORT3 LPC_GPIO2
#define GPIO2 LPC_GPIO2
/**
* @brief GPIO3 port identifier.
*/
#define IOPORT4 LPC_GPIO3
#define GPIO3 LPC_GPIO3
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @param[in] config architecture-dependent ports configuration
*
* @notapi
*/
#define pal_lld_init(config) _pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
*
* @param[in] port port identifier
* @return The port bits.
*
* @notapi
*/
#define pal_lld_readport(port) ((port)->DATA)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
*
* @param[in] port port identifier
* @return The latched logical states.
*
* @notapi
*/
#define pal_lld_readlatch(port) ((port)->DATA)
/**
* @brief Writes a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*
* @notapi
*/
#define pal_lld_writeport(port, bits) ((port)->DATA = (bits))
/**
* @brief Sets a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*
* @notapi
*/
#define pal_lld_setport(port, bits) ((port)->MASKED_ACCESS[bits] = 0xFFFFFFFF)
/**
* @brief Clears a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*
* @notapi
*/
#define pal_lld_clearport(port, bits) ((port)->MASKED_ACCESS[bits] = 0)
/**
* @brief Reads a group of bits.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @return The group logical states.
*
* @notapi
*/
#define pal_lld_readgroup(port, mask, offset) \
((port)->MASKED_ACCESS[(mask) << (offset)])
/**
* @brief Writes a group of bits.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] bits bits to be written. Values exceeding the group width
* are masked.
*
* @notapi
*/
#define pal_lld_writegroup(port, mask, offset, bits) \
((port)->MASKED_ACCESS[(mask) << (offset)] = (bits))
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] mode group mode
*
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, offset, mode) \
_pal_lld_setgroupmode(port, mask << offset, mode)
/**
* @brief Writes a logical state on an output pad.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @param[in] bit logical value, the value must be @p PAL_LOW or
* @p PAL_HIGH
*
* @notapi
*/
#define pal_lld_writepad(port, pad, bit) \
((port)->MASKED_ACCESS[1 << (pad)] = (bit) << (pad))
/**
* @brief Sets a pad logical state to @p PAL_HIGH.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*
* @notapi
*/
#define pal_lld_setpad(port, pad) \
((port)->MASKED_ACCESS[1 << (pad)] = 1 << (pad))
/**
* @brief Clears a pad logical state to @p PAL_LOW.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*
* @notapi
*/
#define pal_lld_clearpad(port, pad) \
((port)->MASKED_ACCESS[1 << (pad)] = 0)
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_init(const PALConfig *config);
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_PAL */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,136 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @defgroup LPC13xx LPC13xx Drivers
* @details This section describes all the supported drivers on the LPC13xx
* platform and the implementation details of the single drivers.
*
* @ingroup platforms
*/
/**
* @defgroup LPC13xx_HAL LPC13xx Initialization Support
* @details The LPC13xx HAL support is responsible for system initialization.
*
* @section lpc13xx_hal_1 Supported HW resources
* - SYSCON.
* - Flash.
* .
* @section lpc13xx_hal_2 LPC13xx HAL driver implementation features
* - Clock tree initialization.
* - Clock source selection.
* - Flash controller initialization.
* - SYSTICK initialization based on current clock and kernel required rate.
* .
* @ingroup LPC13xx
*/
/**
* @defgroup LPC13xx_GPT LPC13xx GPT Support
* @details The LPC13xx GPT driver uses the CTxxBy peripherals.
*
* @section lpc13xx_gpt_1 Supported HW resources
* - CT16B0.
* - CT16B1.
* - CT32B0.
* - CT32B1.
* .
* @section lpc13xx_gpt_2 LPC13xx GPT driver implementation features
* - Each timer can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Programmable CTxxBy interrupts priority level.
* .
* @ingroup LPC13xx
*/
/**
* @defgroup LPC13xx_PAL LPC13xx PAL Support
* @details The LPC13xx PAL driver uses the GPIO peripherals.
*
* @section lpc13xx_pal_1 Supported HW resources
* - GPIO0.
* - GPIO1.
* - GPIO2.
* - GPIO3.
* .
* @section lpc13xx_pal_2 LPC13xx PAL driver implementation features
* - 12 bits wide ports.
* - Atomic set/reset functions.
* - Atomic set+reset function (atomic bus operations).
* - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
* @section lpc13xx_pal_3 Supported PAL setup modes
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* .
* Any attempt to setup an invalid mode is ignored.
*
* @section lpc13xx_pal_4 Suboptimal behavior
* Some GPIO features are less than optimal:
* - Pad/port toggling operations are not atomic.
* - Pull-up and Pull-down resistors cannot be programmed through the PAL
* driver and must be programmed separately using the IOCON peripheral.
* - Reading of the output latch for pads programmed as input is not possible,
* the input pin value is returned instead.
* .
* @ingroup LPC13xx
*/
/**
* @defgroup LPC13xx_SERIAL LPC13xx Serial Support
* @details The LPC13xx Serial driver uses the UART peripheral in a
* buffered, interrupt driven, implementation. The serial driver
* also takes advantage of the LPC13xx UARTs deep hardware buffers.
*
* @section lpc13xx_serial_1 Supported HW resources
* The serial driver can support any of the following hardware resources:
* - UART.
* .
* @section lpc13xx_serial_2 LPC13xx Serial driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Fully interrupt driven.
* - Programmable priority level.
* - Takes advantage of the input and output FIFOs.
* .
* @ingroup LPC13xx
*/
/**
* @defgroup LPC13xx_SPI LPC13xx SPI Support
* @details The SPI driver supports the LPC13xx SSP peripherals in an interrupt
* driven implementation.
* @note Being the SPI a fast peripheral, much care must be taken to
* not saturate the CPU bandwidth with an excessive IRQ rate. The
* maximum transfer bit rate is likely limited by the IRQ
* handling.
*
* @section lpc13xx_spi_1 Supported HW resources
* - SSP0.
* - SSP1 (where present).
* .
* @section lpc13xx_spi_2 LPC13xx SPI driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Each SSP can be independently enabled and programmed. Unused
* peripherals are left in low power mode.
* - Fully interrupt driven.
* - Programmable interrupt priority levels for each SSP.
* .
* @ingroup LPC13xx
*/

View File

@@ -0,0 +1,9 @@
# List of all the LPC13xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC13xx/hal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/serial_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/spi_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/LPC13xx

View File

@@ -0,0 +1,298 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/serial_lld.c
* @brief LPC13xx low level serial driver code.
*
* @addtogroup SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if LPC13xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
/** @brief UART0 serial driver identifier.*/
SerialDriver SD1;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/** @brief Driver default configuration.*/
static const SerialConfig default_config = {
SERIAL_DEFAULT_BITRATE,
LCR_WL8 | LCR_STOP1 | LCR_NOPARITY,
FCR_TRIGGER0
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief UART initialization.
*
* @param[in] sdp communication channel associated to the UART
* @param[in] config the architecture-dependent serial driver configuration
*/
static void uart_init(SerialDriver *sdp, const SerialConfig *config) {
LPC_UART_TypeDef *u = sdp->uart;
uint32_t div = LPC13xx_SERIAL_UART0_PCLK / (config->sc_speed << 4);
u->LCR = config->sc_lcr | LCR_DLAB;
u->DLL = div;
u->DLM = div >> 8;
u->LCR = config->sc_lcr;
u->FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | config->sc_fcr;
u->ACR = 0;
u->FDR = 0x10;
u->TER = TER_ENABLE;
u->IER = IER_RBR | IER_STATUS;
}
/**
* @brief UART de-initialization.
*
* @param[in] u pointer to an UART I/O block
*/
static void uart_deinit(LPC_UART_TypeDef *u) {
u->LCR = LCR_DLAB;
u->DLL = 1;
u->DLM = 0;
u->LCR = 0;
u->FDR = 0x10;
u->IER = 0;
u->FCR = FCR_RXRESET | FCR_TXRESET;
u->ACR = 0;
u->TER = TER_ENABLE;
}
/**
* @brief Error handling routine.
*
* @param[in] sdp communication channel associated to the UART
* @param[in] err UART LSR register value
*/
static void set_error(SerialDriver *sdp, IOREG32 err) {
flagsmask_t sts = 0;
if (err & LSR_OVERRUN)
sts |= SD_OVERRUN_ERROR;
if (err & LSR_PARITY)
sts |= SD_PARITY_ERROR;
if (err & LSR_FRAMING)
sts |= SD_FRAMING_ERROR;
if (err & LSR_BREAK)
sts |= SD_BREAK_DETECTED;
chSysLockFromIsr();
chnAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
/**
* @brief Common IRQ handler.
* @note Tries hard to clear all the pending interrupt sources, we don't
* want to go through the whole ISR and have another interrupt soon
* after.
*
* @param[in] u pointer to an UART I/O block
* @param[in] sdp communication channel associated to the UART
*/
static void serve_interrupt(SerialDriver *sdp) {
LPC_UART_TypeDef *u = sdp->uart;
while (TRUE) {
switch (u->IIR & IIR_SRC_MASK) {
case IIR_SRC_NONE:
return;
case IIR_SRC_ERROR:
set_error(sdp, u->LSR);
break;
case IIR_SRC_TIMEOUT:
case IIR_SRC_RX:
chSysLockFromIsr();
if (chIQIsEmptyI(&sdp->iqueue))
chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
chSysUnlockFromIsr();
while (u->LSR & LSR_RBR_FULL) {
chSysLockFromIsr();
if (chIQPutI(&sdp->iqueue, u->RBR) < Q_OK)
chnAddFlagsI(sdp, SD_OVERRUN_ERROR);
chSysUnlockFromIsr();
}
break;
case IIR_SRC_TX:
{
int i = LPC13xx_SERIAL_FIFO_PRELOAD;
do {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->oqueue);
chSysUnlockFromIsr();
if (b < Q_OK) {
u->IER &= ~IER_THRE;
chSysLockFromIsr();
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
chSysUnlockFromIsr();
break;
}
u->THR = b;
} while (--i);
}
break;
default:
(void) u->THR;
(void) u->RBR;
}
}
}
/**
* @brief Attempts a TX FIFO preload.
*/
static void preload(SerialDriver *sdp) {
LPC_UART_TypeDef *u = sdp->uart;
if (u->LSR & LSR_THRE) {
int i = LPC13xx_SERIAL_FIFO_PRELOAD;
do {
msg_t b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
return;
}
u->THR = b;
} while (--i);
}
u->IER |= IER_THRE;
}
/**
* @brief Driver SD1 output notification.
*/
#if LPC13xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
static void notify1(GenericQueue *qp) {
(void)qp;
preload(&SD1);
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief UART0 IRQ handler.
*
* @isr
*/
#if LPC13xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(VectorF8) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD1);
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*
* @notapi
*/
void sd_lld_init(void) {
#if LPC13xx_SERIAL_USE_UART0
sdObjectInit(&SD1, NULL, notify1);
SD1.uart = LPC_UART;
LPC_IOCON->PIO1_6 = 0xC1; /* RDX without resistors. */
LPC_IOCON->PIO1_7 = 0xC1; /* TDX without resistors. */
#endif
}
/**
* @brief Low level serial driver configuration and (re)start.
*
* @param[in] sdp pointer to a @p SerialDriver object
* @param[in] config the architecture-dependent serial driver configuration.
* If this parameter is set to @p NULL then a default
* configuration is used.
*
* @notapi
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
if (sdp->state == SD_STOP) {
#if LPC13xx_SERIAL_USE_UART0
if (&SD1 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12);
LPC_SYSCON->UARTCLKDIV = LPC13xx_SERIAL_UART0CLKDIV;
nvicEnableVector(UART_IRQn,
CORTEX_PRIORITY_MASK(LPC13xx_SERIAL_UART0_IRQ_PRIORITY));
}
#endif
}
uart_init(sdp, config);
}
/**
* @brief Low level serial driver stop.
* @details De-initializes the UART, stops the associated clock, resets the
* interrupt vector.
*
* @param[in] sdp pointer to a @p SerialDriver object
*
* @notapi
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->state == SD_READY) {
uart_deinit(sdp->uart);
#if LPC13xx_SERIAL_USE_UART0
if (&SD1 == sdp) {
LPC_SYSCON->UARTCLKDIV = 0;
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 12);
nvicDisableVector(UART_IRQn);
return;
}
#endif
}
}
#endif /* HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,206 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/serial_lld.h
* @brief LPC13xx low level serial driver header.
*
* @addtogroup SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define IIR_SRC_MASK 0x0F
#define IIR_SRC_NONE 0x01
#define IIR_SRC_MODEM 0x00
#define IIR_SRC_TX 0x02
#define IIR_SRC_RX 0x04
#define IIR_SRC_ERROR 0x06
#define IIR_SRC_TIMEOUT 0x0C
#define IER_RBR 1
#define IER_THRE 2
#define IER_STATUS 4
#define LCR_WL5 0
#define LCR_WL6 1
#define LCR_WL7 2
#define LCR_WL8 3
#define LCR_STOP1 0
#define LCR_STOP2 4
#define LCR_NOPARITY 0
#define LCR_PARITYODD 0x08
#define LCR_PARITYEVEN 0x18
#define LCR_PARITYONE 0x28
#define LCR_PARITYZERO 0x38
#define LCR_BREAK_ON 0x40
#define LCR_DLAB 0x80
#define FCR_ENABLE 1
#define FCR_RXRESET 2
#define FCR_TXRESET 4
#define FCR_TRIGGER0 0
#define FCR_TRIGGER1 0x40
#define FCR_TRIGGER2 0x80
#define FCR_TRIGGER3 0xC0
#define LSR_RBR_FULL 1
#define LSR_OVERRUN 2
#define LSR_PARITY 4
#define LSR_FRAMING 8
#define LSR_BREAK 0x10
#define LSR_THRE 0x20
#define LSR_TEMT 0x40
#define LSR_RXFE 0x80
#define TER_ENABLE 0x80
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief UART0 driver enable switch.
* @details If set to @p TRUE the support for UART0 is included.
* @note The default is @p TRUE .
*/
#if !defined(LPC13xx_SERIAL_USE_UART0) || defined(__DOXYGEN__)
#define LPC13xx_SERIAL_USE_UART0 TRUE
#endif
/**
* @brief FIFO preload parameter.
* @details Configuration parameter, this values defines how many bytes are
* preloaded in the HW transmit FIFO for each interrupt, the maximum
* value is 16 the minimum is 1.
* @note An high value reduces the number of interrupts generated but can
* also increase the worst case interrupt response time because the
* preload loops.
*/
#if !defined(LPC13xx_SERIAL_FIFO_PRELOAD) || defined(__DOXYGEN__)
#define LPC13xx_SERIAL_FIFO_PRELOAD 16
#endif
/**
* @brief UART0 PCLK divider.
*/
#if !defined(LPC13xx_SERIAL_UART0CLKDIV) || defined(__DOXYGEN__)
#define LPC13xx_SERIAL_UART0CLKDIV 1
#endif
/**
* @brief UART0 interrupt priority level setting.
*/
#if !defined(LPC13xx_SERIAL_UART0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_SERIAL_UART0_IRQ_PRIORITY 3
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (LPC13xx_SERIAL_UART0CLKDIV < 1) || (LPC11xx_SERIAL_UART0CLKDIV > 255)
#error "invalid LPC13xx_SERIAL_UART0CLKDIV setting"
#endif
#if (LPC13xx_SERIAL_FIFO_PRELOAD < 1) || (LPC13xx_SERIAL_FIFO_PRELOAD > 16)
#error "invalid LPC13xx_SERIAL_FIFO_PRELOAD setting"
#endif
/**
* @brief UART0 clock.
*/
#define LPC13xx_SERIAL_UART0_PCLK \
(LPC13xx_MAINCLK / LPC13xx_SERIAL_UART0CLKDIV)
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief LPC13xx Serial Driver configuration structure.
* @details An instance of this structure must be passed to @p sdStart()
* in order to configure and start a serial driver operations.
*/
typedef struct {
/**
* @brief Bit rate.
*/
uint32_t sc_speed;
/**
* @brief Initialization value for the LCR register.
*/
uint32_t sc_lcr;
/**
* @brief Initialization value for the FCR register.
*/
uint32_t sc_fcr;
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Pointer to the USART registers block.*/ \
LPC_UART_TypeDef *uart;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if LPC13xx_SERIAL_USE_UART0 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void sd_lld_init(void);
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
void sd_lld_stop(SerialDriver *sdp);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,404 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/spi_lld.c
* @brief LPC13xx low level SPI driver code.
*
* @addtogroup SPI
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if LPC13xx_SPI_USE_SSP0 || defined(__DOXYGEN__)
/** @brief SPI1 driver identifier.*/
SPIDriver SPID1;
#endif
#if LPC13xx_SPI_USE_SSP1 || defined(__DOXYGEN__)
/** @brief SPI2 driver identifier.*/
SPIDriver SPID2;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Preloads the transmit FIFO.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
static void ssp_fifo_preload(SPIDriver *spip) {
LPC_SSP_TypeDef *ssp = spip->ssp;
uint32_t n = spip->txcnt > LPC13xx_SSP_FIFO_DEPTH ?
LPC13xx_SSP_FIFO_DEPTH : spip->txcnt;
while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
if (spip->txptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
const uint16_t *p = spip->txptr;
ssp->DR = *p++;
spip->txptr = p;
}
else {
const uint8_t *p = spip->txptr;
ssp->DR = *p++;
spip->txptr = p;
}
}
else
ssp->DR = 0xFFFFFFFF;
n--;
spip->txcnt--;
}
}
/**
* @brief Common IRQ handler.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_serve_interrupt(SPIDriver *spip) {
LPC_SSP_TypeDef *ssp = spip->ssp;
if ((ssp->MIS & MIS_ROR) != 0) {
/* The overflow condition should never happen because priority is given
to receive but a hook macro is provided anyway...*/
LPC13xx_SPI_SSP_ERROR_HOOK(spip);
}
ssp->ICR = ICR_RT | ICR_ROR;
while ((ssp->SR & SR_RNE) != 0) {
if (spip->rxptr != NULL) {
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
uint16_t *p = spip->rxptr;
*p++ = ssp->DR;
spip->rxptr = p;
}
else {
uint8_t *p = spip->rxptr;
*p++ = ssp->DR;
spip->rxptr = p;
}
}
else
(void)ssp->DR;
if (--spip->rxcnt == 0) {
chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
ssp->IMSC = 0;
/* Portable SPI ISR code defined in the high level driver, note, it is
a macro.*/
_spi_isr_code(spip);
return;
}
}
ssp_fifo_preload(spip);
if (spip->txcnt == 0)
ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if LPC13xx_SPI_USE_SSP0 || defined(__DOXYGEN__)
/**
* @brief SSP0 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorF4) {
CH_IRQ_PROLOGUE();
spi_serve_interrupt(&SPID1);
CH_IRQ_EPILOGUE();
}
#endif
#if LPC13xx_SPI_USE_SSP1 || defined(__DOXYGEN__)
/**
* @brief SSP1 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector124) {
CH_IRQ_PROLOGUE();
spi_serve_interrupt(&SPID2);
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level SPI driver initialization.
*
* @notapi
*/
void spi_lld_init(void) {
#if LPC13xx_SPI_USE_SSP0
spiObjectInit(&SPID1);
SPID1.ssp = LPC_SSP0;
LPC_IOCON->SCK_LOC = LPC13xx_SPI_SCK0_SELECTOR;
#if LPC13xx_SPI_SCK0_SELECTOR == SCK0_IS_PIO0_10
LPC_IOCON->SWCLK_PIO0_10 = 0xC2; /* SCK0 without resistors. */
#elif LPC13xx_SPI_SCK0_SELECTOR == SCK0_IS_PIO2_11
LPC_IOCON->PIO2_11 = 0xC1; /* SCK0 without resistors. */
#else /* LPC13xx_SPI_SCK0_SELECTOR == SCK0_IS_PIO0_6 */
LPC_IOCON->PIO0_6 = 0xC2; /* SCK0 without resistors. */
#endif
LPC_IOCON->PIO0_8 = 0xC1; /* MISO0 without resistors. */
LPC_IOCON->PIO0_9 = 0xC1; /* MOSI0 without resistors. */
#endif /* LPC13xx_SPI_USE_SSP0 */
#if LPC13xx_SPI_USE_SSP1
spiObjectInit(&SPID2);
SPID2.ssp = LPC_SSP1;
LPC_IOCON->PIO2_1 = 0xC2; /* SCK1 without resistors. */
LPC_IOCON->PIO2_2 = 0xC2; /* MISO1 without resistors. */
LPC_IOCON->PIO2_3 = 0xC2; /* MOSI1 without resistors. */
#endif /* LPC13xx_SPI_USE_SSP0 */
}
/**
* @brief Configures and activates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_start(SPIDriver *spip) {
if (spip->state == SPI_STOP) {
/* Clock activation.*/
#if LPC13xx_SPI_USE_SSP0
if (&SPID1 == spip) {
LPC_SYSCON->SSP0CLKDIV = LPC13xx_SPI_SSP0CLKDIV;
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11);
LPC_SYSCON->PRESETCTRL |= 1;
nvicEnableVector(SSP0_IRQn,
CORTEX_PRIORITY_MASK(LPC13xx_SPI_SSP0_IRQ_PRIORITY));
}
#endif
#if LPC13xx_SPI_USE_SSP1
if (&SPID2 == spip) {
LPC_SYSCON->SSP1CLKDIV = LPC13xx_SPI_SSP1CLKDIV;
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 18);
LPC_SYSCON->PRESETCTRL |= 4;
nvicEnableVector(SSP1_IRQn,
CORTEX_PRIORITY_MASK(LPC13xx_SPI_SSP1_IRQ_PRIORITY));
}
#endif
}
/* Configuration.*/
spip->ssp->CR1 = 0;
spip->ssp->ICR = ICR_RT | ICR_ROR;
spip->ssp->CR0 = spip->config->cr0;
spip->ssp->CPSR = spip->config->cpsr;
spip->ssp->CR1 = CR1_SSE;
}
/**
* @brief Deactivates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_stop(SPIDriver *spip) {
if (spip->state != SPI_STOP) {
spip->ssp->CR1 = 0;
spip->ssp->CR0 = 0;
spip->ssp->CPSR = 0;
#if LPC13xx_SPI_USE_SSP0
if (&SPID1 == spip) {
LPC_SYSCON->PRESETCTRL &= ~1;
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 11);
LPC_SYSCON->SSP0CLKDIV = 0;
nvicDisableVector(SSP0_IRQn);
}
#endif
#if LPC13xx_SPI_USE_SSP1
if (&SPID2 == spip) {
LPC_SYSCON->PRESETCTRL &= ~4;
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 18);
LPC_SYSCON->SSP1CLKDIV = 0;
nvicDisableVector(SSP1_IRQn);
}
#endif
}
}
/**
* @brief Asserts the slave select signal and prepares for transfers.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_select(SPIDriver *spip) {
palClearPad(spip->config->ssport, spip->config->sspad);
}
/**
* @brief Deasserts the slave select signal.
* @details The previously selected peripheral is unselected.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_unselect(SPIDriver *spip) {
palSetPad(spip->config->ssport, spip->config->sspad);
}
/**
* @brief Ignores data on the SPI bus.
* @details This function transmits a series of idle words on the SPI bus and
* ignores the received data. This function can be invoked even
* when a slave select signal has not been yet asserted.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
*
* @notapi
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
spip->rxptr = NULL;
spip->txptr = NULL;
spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
* @brief Exchanges data on the SPI bus.
* @details This asynchronous function starts a simultaneous transmit/receive
* operation.
* @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be exchanged
* @param[in] txbuf the pointer to the transmit buffer
* @param[out] rxbuf the pointer to the receive buffer
*
* @notapi
*/
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
spip->rxptr = rxbuf;
spip->txptr = txbuf;
spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
* @brief Sends data over the SPI bus.
* @details This asynchronous function starts a transmit operation.
* @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer
*
* @notapi
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
spip->rxptr = NULL;
spip->txptr = txbuf;
spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
* @brief Receives data from the SPI bus.
* @details This asynchronous function starts a receive operation.
* @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to receive
* @param[out] rxbuf the pointer to the receive buffer
*
* @notapi
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
spip->rxptr = rxbuf;
spip->txptr = NULL;
spip->rxcnt = spip->txcnt = n;
ssp_fifo_preload(spip);
spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
}
/**
* @brief Exchanges one frame using a polled wait.
* @details This synchronous function exchanges one frame using a polled
* synchronization method. This function is useful when exchanging
* small amount of data on high speed channels, usually in this
* situation is much more efficient just wait for completion using
* polling than suspending the thread waiting for an interrupt.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] frame the data frame to send over the SPI bus
* @return The received data frame from the SPI bus.
*/
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
spip->ssp->DR = (uint32_t)frame;
while ((spip->ssp->SR & SR_RNE) == 0)
;
return (uint16_t)spip->ssp->DR;
}
#endif /* HAL_USE_SPI */
/** @} */

View File

@@ -0,0 +1,339 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
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.
*/
/**
* @file LPC13xx/spi_lld.h
* @brief LPC13xx low level SPI driver header.
*
* @addtogroup SPI
* @{
*/
#ifndef _SPI_LLD_H_
#define _SPI_LLD_H_
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Hardware FIFO depth.
*/
#define LPC13xx_SSP_FIFO_DEPTH 8
#define CR0_DSSMASK 0x0F
#define CR0_DSS4BIT 3
#define CR0_DSS5BIT 4
#define CR0_DSS6BIT 5
#define CR0_DSS7BIT 6
#define CR0_DSS8BIT 7
#define CR0_DSS9BIT 8
#define CR0_DSS10BIT 9
#define CR0_DSS11BIT 0xA
#define CR0_DSS12BIT 0xB
#define CR0_DSS13BIT 0xC
#define CR0_DSS14BIT 0xD
#define CR0_DSS15BIT 0xE
#define CR0_DSS16BIT 0xF
#define CR0_FRFSPI 0
#define CR0_FRFSSI 0x10
#define CR0_FRFMW 0x20
#define CR0_CPOL 0x40
#define CR0_CPHA 0x80
#define CR0_CLOCKRATE(n) ((n) << 8)
#define CR1_LBM 1
#define CR1_SSE 2
#define CR1_MS 4
#define CR1_SOD 8
#define SR_TFE 1
#define SR_TNF 2
#define SR_RNE 4
#define SR_RFF 8
#define SR_BSY 16
#define IMSC_ROR 1
#define IMSC_RT 2
#define IMSC_RX 4
#define IMSC_TX 8
#define RIS_ROR 1
#define RIS_RT 2
#define RIS_RX 4
#define RIS_TX 8
#define MIS_ROR 1
#define MIS_RT 2
#define MIS_RX 4
#define MIS_TX 8
#define ICR_ROR 1
#define ICR_RT 2
/**
* @brief SCK0 signal assigned to pin PIO0_10.
*/
#define SCK0_IS_PIO0_10 0
/**
* @brief SCK0 signal assigned to pin PIO2_11.
*/
#define SCK0_IS_PIO2_11 1
/**
* @brief SCK0 signal assigned to pin PIO0_6.
*/
#define SCK0_IS_PIO0_6 2
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief SPI1 driver enable switch.
* @details If set to @p TRUE the support for device SSP0 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC13xx_SPI_USE_SSP0) || defined(__DOXYGEN__)
#define LPC13xx_SPI_USE_SSP0 TRUE
#endif
/**
* @brief SPI2 driver enable switch.
* @details If set to @p TRUE the support for device SSP1 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC13xx_SPI_USE_SSP1) || defined(__DOXYGEN__)
#define LPC13xx_SPI_USE_SSP1 FALSE
#endif
/**
* @brief SSP0 PCLK divider.
*/
#if !defined(LPC13xx_SPI_SSP0CLKDIV) || defined(__DOXYGEN__)
#define LPC13xx_SPI_SSP0CLKDIV 1
#endif
/**
* @brief SSP1 PCLK divider.
*/
#if !defined(LPC13xx_SPI_SSP1CLKDIV) || defined(__DOXYGEN__)
#define LPC13xx_SPI_SSP1CLKDIV 1
#endif
/**
* @brief SPI0 interrupt priority level setting.
*/
#if !defined(LPC13xx_SPI_SSP0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_SPI_SSP0_IRQ_PRIORITY 5
#endif
/**
* @brief SPI1 interrupt priority level setting.
*/
#if !defined(LPC13xx_SPI_SSP1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_SPI_SSP1_IRQ_PRIORITY 5
#endif
/**
* @brief Overflow error hook.
* @details The default action is to stop the system.
*/
#if !defined(LPC13xx_SPI_SSP_ERROR_HOOK) || defined(__DOXYGEN__)
#define LPC13xx_SPI_SSP_ERROR_HOOK(spip) chSysHalt()
#endif
/**
* @brief SCK0 signal selector.
*/
#if !defined(LPC13xx_SPI_SCK0_SELECTOR) || defined(__DOXYGEN__)
#define LPC13xx_SPI_SCK0_SELECTOR SCK0_IS_PIO2_11
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (LPC13xx_SPI_SSP0CLKDIV < 1) || (LPC13xx_SPI_SSP0CLKDIV > 255)
#error "invalid LPC13xx_SPI_SSP0CLKDIV setting"
#endif
#if (LPC13xx_SPI_SSP1CLKDIV < 1) || (LPC13xx_SPI_SSP1CLKDIV > 255)
#error "invalid LPC13xx_SPI_SSP1CLKDIV setting"
#endif
#if !LPC13xx_SPI_USE_SSP0 && !LPC13xx_SPI_USE_SSP1
#error "SPI driver activated but no SPI peripheral assigned"
#endif
#if (LPC13xx_SPI_SCK0_SELECTOR != SCK0_IS_PIO0_10) && \
(LPC13xx_SPI_SCK0_SELECTOR != SCK0_IS_PIO2_11) && \
(LPC13xx_SPI_SCK0_SELECTOR != SCK0_IS_PIO0_6)
#error "invalid pin assigned to SCK0 signal"
#endif
/**
* @brief SSP0 clock.
*/
#define LPC13xx_SPI_SSP0_PCLK \
(LPC13xx_MAINCLK / LPC13xx_SPI_SSP0CLKDIV)
/**
* @brief SSP1 clock.
*/
#define LPC13xx_SPI_SSP1_PCLK \
(LPC13xx_MAINCLK / LPC13xx_SPI_SSP1CLKDIV)
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a structure representing an SPI driver.
*/
typedef struct SPIDriver SPIDriver;
/**
* @brief SPI notification callback type.
*
* @param[in] spip pointer to the @p SPIDriver object triggering the
* callback
*/
typedef void (*spicallback_t)(SPIDriver *spip);
/**
* @brief Driver configuration structure.
*/
typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
spicallback_t end_cb;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
ioportid_t ssport;
/**
* @brief The chip select line pad number.
*/
uint16_t sspad;
/**
* @brief SSP CR0 initialization data.
*/
uint16_t cr0;
/**
* @brief SSP CPSR initialization data.
*/
uint32_t cpsr;
} SPIConfig;
/**
* @brief Structure representing a SPI driver.
*/
struct SPIDriver {
/**
* @brief Driver state.
*/
spistate_t state;
/**
* @brief Current configuration data.
*/
const SPIConfig *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
Thread *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
Mutex mutex;
#elif CH_USE_SEMAPHORES
Semaphore semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
SPI_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
/**
* @brief Pointer to the SSP registers block.
*/
LPC_SSP_TypeDef *ssp;
/**
* @brief Number of bytes yet to be received.
*/
uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
void *rxptr;
/**
* @brief Number of bytes yet to be transmitted.
*/
uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
const void *txptr;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if LPC13xx_SPI_USE_SSP0 && !defined(__DOXYGEN__)
extern SPIDriver SPID1;
#endif
#if LPC13xx_SPI_USE_SSP1 && !defined(__DOXYGEN__)
extern SPIDriver SPID2;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void spi_lld_init(void);
void spi_lld_start(SPIDriver *spip);
void spi_lld_stop(SPIDriver *spip);
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
void spi_lld_ignore(SPIDriver *spip, size_t n);
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf);
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SPI */
#endif /* _SPI_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,64 @@
/**************************************************************************//**
* @file system_LPC13xx.h
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File
* for the NXP LPC13xx Device Series
* @version V1.10
* @date 24. November 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* 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_LPC13xx_H
#define __SYSTEM_LPC13xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* 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_LPC13xx_H */