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,686 @@
/****************************************************************************
* $Id:: LPC8xx.h 6437 2012-10-31 11:06:06Z dep00694 $
* Project: NXP LPC8xx software example
*
* Description:
* CMSIS Cortex-M0+ Core Peripheral Access Layer Header File for
* NXP LPC800 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.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#ifndef __LPC8xx_H__
#define __LPC8xx_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup LPC8xx_Definitions LPC8xx Definitions
This file defines all structures and symbols for LPC8xx:
- Registers and bitfields
- peripheral base address
- PIO definitions
@{
*/
/******************************************************************************/
/* Processor and Core Peripherals */
/******************************************************************************/
/** @addtogroup LPC8xx_CMSIS LPC8xx CMSIS Definitions
Configuration of the Cortex-M0+ Processor and Core Peripherals
@{
*/
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn
{
/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/
Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset*/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */
/****** LPC8xx Specific Interrupt Numbers ********************************************************/
SPI0_IRQn = 0, /*!< SPI0 */
SPI1_IRQn = 1, /*!< SPI1 */
Reserved0_IRQn = 2, /*!< Reserved Interrupt */
UART0_IRQn = 3, /*!< USART0 */
UART1_IRQn = 4, /*!< USART1 */
UART2_IRQn = 5, /*!< USART2 */
Reserved1_IRQn = 6, /*!< Reserved Interrupt */
Reserved2_IRQn = 7, /*!< Reserved Interrupt */
I2C_IRQn = 8, /*!< I2C */
SCT_IRQn = 9, /*!< SCT */
MRT_IRQn = 10, /*!< MRT */
CMP_IRQn = 11, /*!< CMP */
WDT_IRQn = 12, /*!< WDT */
BOD_IRQn = 13, /*!< BOD */
Reserved3_IRQn = 14, /*!< Reserved Interrupt */
WKT_IRQn = 15, /*!< WKT Interrupt */
Reserved4_IRQn = 16, /*!< Reserved Interrupt */
Reserved5_IRQn = 17, /*!< Reserved Interrupt */
Reserved6_IRQn = 18, /*!< Reserved Interrupt */
Reserved7_IRQn = 19, /*!< Reserved Interrupt */
Reserved8_IRQn = 20, /*!< Reserved Interrupt */
Reserved9_IRQn = 21, /*!< Reserved Interrupt */
Reserved10_IRQn = 22, /*!< Reserved Interrupt */
Reserved11_IRQn = 23, /*!< Reserved Interrupt */
PININT0_IRQn = 24, /*!< External Interrupt 0 */
PININT1_IRQn = 25, /*!< External Interrupt 1 */
PININT2_IRQn = 26, /*!< External Interrupt 2 */
PININT3_IRQn = 27, /*!< External Interrupt 3 */
PININT4_IRQn = 28, /*!< External Interrupt 4 */
PININT5_IRQn = 29, /*!< External Interrupt 5 */
PININT6_IRQn = 30, /*!< External Interrupt 6 */
PININT7_IRQn = 31, /*!< External Interrupt 7 */
} IRQn_Type;
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
/* Configuration of the Cortex-M0+ Processor and Core Peripherals */
#define __MPU_PRESENT 0 /*!< MPU present or not */
#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
/*@}*/ /* end of group LPC8xx_CMSIS */
#include "core_cm0plus.h" /* Cortex-M0+ processor and core peripherals */
#include "system_LPC8xx.h" /* System Header */
/******************************************************************************/
/* Device Specific Peripheral Registers structures */
/******************************************************************************/
#if defined ( __CC_ARM )
#pragma anon_unions
#endif
/*------------- System Control (SYSCON) --------------------------------------*/
/** @addtogroup LPC8xx_SYSCON LPC8xx System Control Block
@{
*/
typedef struct
{
__IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 System memory remap (R/W) */
__IO uint32_t PRESETCTRL; /*!< Offset: 0x004 Peripheral reset control (R/W) */
__IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 System PLL control (R/W) */
__IO uint32_t SYSPLLSTAT; /*!< Offset: 0x00C System PLL status (R/W ) */
uint32_t RESERVED0[4];
__IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 System oscillator control (R/W) */
__IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 Watchdog oscillator control (R/W) */
uint32_t RESERVED1[2];
__IO uint32_t SYSRSTSTAT; /*!< Offset: 0x030 System reset status Register (R/W ) */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 System PLL clock source select (R/W) */
__IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 System PLL clock source update enable (R/W) */
uint32_t RESERVED3[10];
__IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 Main clock source select (R/W) */
__IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 Main clock source update enable (R/W) */
__IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 System AHB clock divider (R/W) */
uint32_t RESERVED4[1];
__IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 System AHB clock control (R/W) */
uint32_t RESERVED5[4];
__IO uint32_t UARTCLKDIV; /*!< Offset: 0x094 UART clock divider (R/W) */
uint32_t RESERVED6[18];
__IO uint32_t CLKOUTSEL; /*!< Offset: 0x0E0 CLKOUT clock source select (R/W) */
__IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 CLKOUT clock source update enable (R/W) */
__IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 CLKOUT clock divider (R/W) */
uint32_t RESERVED7;
__IO uint32_t UARTFRGDIV; /*!< Offset: 0x0F0 UART fractional divider SUB(R/W) */
__IO uint32_t UARTFRGMULT; /*!< Offset: 0x0F4 UART fractional divider ADD(R/W) */
uint32_t RESERVED8[1];
__IO uint32_t EXTTRACECMD; /*!< (@ 0x400480FC) External trace buffer command register */
__IO uint32_t PIOPORCAP0; /*!< Offset: 0x100 POR captured PIO status 0 (R/ ) */
uint32_t RESERVED9[12];
__IO uint32_t IOCONCLKDIV[7]; /*!< (@0x40048134-14C) Peripheral clock x to the IOCON block for programmable glitch filter */
__IO uint32_t BODCTRL; /*!< Offset: 0x150 BOD control (R/W) */
__IO uint32_t SYSTCKCAL; /*!< Offset: 0x154 System tick counter calibration (R/W) */
uint32_t RESERVED10[6];
__IO uint32_t IRQLATENCY; /*!< (@ 0x40048170) IRQ delay */
__IO uint32_t NMISRC; /*!< (@ 0x40048174) NMI Source Control */
__IO uint32_t PINTSEL[8]; /*!< (@ 0x40048178) GPIO Pin Interrupt Select register 0 */
uint32_t RESERVED11[27];
__IO uint32_t STARTERP0; /*!< Offset: 0x204 Start logic signal enable Register 0 (R/W) */
uint32_t RESERVED12[3];
__IO uint32_t STARTERP1; /*!< Offset: 0x214 Start logic signal enable Register 0 (R/W) */
uint32_t RESERVED13[6];
__IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 Power-down states in Deep-sleep mode (R/W) */
__IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 Power-down states after wake-up (R/W) */
__IO uint32_t PDRUNCFG; /*!< Offset: 0x238 Power-down configuration Register (R/W) */
uint32_t RESERVED14[110];
__I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 Device ID (R/ ) */
} LPC_SYSCON_TypeDef;
/*@}*/ /* end of group LPC8xx_SYSCON */
/**
* @brief Product name title=UM10462 Chapter title=LPC8xx I/O configuration Modification date=3/16/2011 Major revision=0 Minor revision=3 (IOCONFIG)
*/
typedef struct { /*!< (@ 0x40044000) IOCONFIG Structure */
__IO uint32_t PIO0_17; /*!< (@ 0x40044000) I/O configuration for pin PIO0_17 */
__IO uint32_t PIO0_13; /*!< (@ 0x40044004) I/O configuration for pin PIO0_13 */
__IO uint32_t PIO0_12; /*!< (@ 0x40044008) I/O configuration for pin PIO0_12 */
__IO uint32_t PIO0_5; /*!< (@ 0x4004400C) I/O configuration for pin PIO0_5 */
__IO uint32_t PIO0_4; /*!< (@ 0x40044010) I/O configuration for pin PIO0_4 */
__IO uint32_t PIO0_3; /*!< (@ 0x40044014) I/O configuration for pin PIO0_3 */
__IO uint32_t PIO0_2; /*!< (@ 0x40044018) I/O configuration for pin PIO0_2 */
__IO uint32_t PIO0_11; /*!< (@ 0x4004401C) I/O configuration for pin PIO0_11 */
__IO uint32_t PIO0_10; /*!< (@ 0x40044020) I/O configuration for pin PIO0_10 */
__IO uint32_t PIO0_16; /*!< (@ 0x40044024) I/O configuration for pin PIO0_16 */
__IO uint32_t PIO0_15; /*!< (@ 0x40044028) I/O configuration for pin PIO0_15 */
__IO uint32_t PIO0_1; /*!< (@ 0x4004402C) I/O configuration for pin PIO0_1 */
__IO uint32_t Reserved; /*!< (@ 0x40044030) I/O configuration for pin (Reserved) */
__IO uint32_t PIO0_9; /*!< (@ 0x40044034) I/O configuration for pin PIO0_9 */
__IO uint32_t PIO0_8; /*!< (@ 0x40044038) I/O configuration for pin PIO0_8 */
__IO uint32_t PIO0_7; /*!< (@ 0x4004403C) I/O configuration for pin PIO0_7 */
__IO uint32_t PIO0_6; /*!< (@ 0x40044040) I/O configuration for pin PIO0_6 */
__IO uint32_t PIO0_0; /*!< (@ 0x40044044) I/O configuration for pin PIO0_0 */
__IO uint32_t PIO0_14; /*!< (@ 0x40044048) I/O configuration for pin PIO0_14 */
} LPC_IOCON_TypeDef;
/*@}*/ /* end of group LPC8xx_IOCON */
/**
* @brief Product name title=UM10462 Chapter title=LPC8xx Flash programming firmware Major revision=0 Minor revision=3 (FLASHCTRL)
*/
typedef struct { /*!< (@ 0x40040000) FLASHCTRL Structure */
__I uint32_t RESERVED0[4];
__IO uint32_t FLASHCFG; /*!< (@ 0x40040010) Flash configuration register */
__I uint32_t RESERVED1[3];
__IO uint32_t FMSSTART; /*!< (@ 0x40040020) Signature start address register */
__IO uint32_t FMSSTOP; /*!< (@ 0x40040024) Signature stop-address register */
__I uint32_t RESERVED2;
__I uint32_t FMSW0;
} LPC_FLASHCTRL_TypeDef;
/*@}*/ /* end of group LPC8xx_FLASHCTRL */
/*------------- Power Management Unit (PMU) --------------------------*/
/** @addtogroup LPC8xx_PMU LPC8xx Power Management Unit
@{
*/
typedef struct
{
__IO uint32_t PCON; /*!< Offset: 0x000 Power control Register (R/W) */
__IO uint32_t GPREG0; /*!< Offset: 0x004 General purpose Register 0 (R/W) */
__IO uint32_t GPREG1; /*!< Offset: 0x008 General purpose Register 1 (R/W) */
__IO uint32_t GPREG2; /*!< Offset: 0x00C General purpose Register 2 (R/W) */
__IO uint32_t GPREG3; /*!< Offset: 0x010 General purpose Register 3 (R/W) */
__IO uint32_t DPDCTRL; /*!< Offset: 0x014 Deep power-down control register (R/W) */
} LPC_PMU_TypeDef;
/*@}*/ /* end of group LPC8xx_PMU */
/*------------- Switch Matrix Port --------------------------*/
/** @addtogroup LPC8xx_SWM LPC8xx Switch Matrix Port
@{
*/
typedef struct
{
union {
__IO uint32_t PINASSIGN[9];
struct {
__IO uint32_t PINASSIGN0;
__IO uint32_t PINASSIGN1;
__IO uint32_t PINASSIGN2;
__IO uint32_t PINASSIGN3;
__IO uint32_t PINASSIGN4;
__IO uint32_t PINASSIGN5;
__IO uint32_t PINASSIGN6;
__IO uint32_t PINASSIGN7;
__IO uint32_t PINASSIGN8;
};
};
__I uint32_t RESERVED0[103];
__IO uint32_t PINENABLE0;
} LPC_SWM_TypeDef;
/*@}*/ /* end of group LPC8xx_SWM */
// ------------------------------------------------------------------------------------------------
// ----- GPIO_PORT -----
// ------------------------------------------------------------------------------------------------
/**
* @brief Product name title=UM10462 Chapter title=LPC8xx GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (GPIO_PORT)
*/
typedef struct {
__IO uint8_t B0[18]; /*!< (@ 0xA0000000) Byte pin registers port 0 */
__I uint16_t RESERVED0[2039];
__IO uint32_t W0[18]; /*!< (@ 0xA0001000) Word pin registers port 0 */
uint32_t RESERVED1[1006];
__IO uint32_t DIR0; /* 0x2000 */
uint32_t RESERVED2[31];
__IO uint32_t MASK0; /* 0x2080 */
uint32_t RESERVED3[31];
__IO uint32_t PIN0; /* 0x2100 */
uint32_t RESERVED4[31];
__IO uint32_t MPIN0; /* 0x2180 */
uint32_t RESERVED5[31];
__IO uint32_t SET0; /* 0x2200 */
uint32_t RESERVED6[31];
__O uint32_t CLR0; /* 0x2280 */
uint32_t RESERVED7[31];
__O uint32_t NOT0; /* 0x2300 */
} LPC_GPIO_PORT_TypeDef;
// ------------------------------------------------------------------------------------------------
// ----- PIN_INT -----
// ------------------------------------------------------------------------------------------------
/**
* @brief Product name title=UM10462 Chapter title=LPC8xx GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (PIN_INT)
*/
typedef struct { /*!< (@ 0xA0004000) PIN_INT Structure */
__IO uint32_t ISEL; /*!< (@ 0xA0004000) Pin Interrupt Mode register */
__IO uint32_t IENR; /*!< (@ 0xA0004004) Pin Interrupt Enable (Rising) register */
__IO uint32_t SIENR; /*!< (@ 0xA0004008) Set Pin Interrupt Enable (Rising) register */
__IO uint32_t CIENR; /*!< (@ 0xA000400C) Clear Pin Interrupt Enable (Rising) register */
__IO uint32_t IENF; /*!< (@ 0xA0004010) Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t SIENF; /*!< (@ 0xA0004014) Set Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t CIENF; /*!< (@ 0xA0004018) Clear Pin Interrupt Enable Falling Edge / Active Level address */
__IO uint32_t RISE; /*!< (@ 0xA000401C) Pin Interrupt Rising Edge register */
__IO uint32_t FALL; /*!< (@ 0xA0004020) Pin Interrupt Falling Edge register */
__IO uint32_t IST; /*!< (@ 0xA0004024) Pin Interrupt Status register */
__IO uint32_t PMCTRL; /*!< (@ 0xA0004028) GPIO pattern match interrupt control register */
__IO uint32_t PMSRC; /*!< (@ 0xA000402C) GPIO pattern match interrupt bit-slice source register */
__IO uint32_t PMCFG; /*!< (@ 0xA0004030) GPIO pattern match interrupt bit slice configuration register */
} LPC_PIN_INT_TypeDef;
/*------------- CRC Engine (CRC) -----------------------------------------*/
/** @addtogroup LPC8xx_CRC
@{
*/
typedef struct
{
__IO uint32_t MODE;
__IO uint32_t SEED;
union {
__I uint32_t SUM;
__O uint32_t WR_DATA_DWORD;
__O uint16_t WR_DATA_WORD;
uint16_t RESERVED_WORD;
__O uint8_t WR_DATA_BYTE;
uint8_t RESERVED_BYTE[3];
};
} LPC_CRC_TypeDef;
/*@}*/ /* end of group LPC8xx_CRC */
/*------------- Comparator (CMP) --------------------------------------------------*/
/** @addtogroup LPC8xx_CMP LPC8xx Comparator
@{
*/
typedef struct { /*!< (@ 0x40024000) CMP Structure */
__IO uint32_t CTRL; /*!< (@ 0x40024000) Comparator control register */
__IO uint32_t LAD; /*!< (@ 0x40024004) Voltage ladder register */
} LPC_CMP_TypeDef;
/*@}*/ /* end of group LPC8xx_CMP */
/*------------- Wakeup Timer (WKT) --------------------------------------------------*/
/** @addtogroup LPC8xx_WKT
@{
*/
typedef struct { /*!< (@ 0x40028000) WKT Structure */
__IO uint32_t CTRL; /*!< (@ 0x40028000) Alarm/Wakeup Timer Control register */
uint32_t Reserved[2];
__IO uint32_t COUNT; /*!< (@ 0x4002800C) Alarm/Wakeup TImer counter register */
} LPC_WKT_TypeDef;
/*@}*/ /* end of group LPC8xx_WKT */
/*------------- Multi-Rate Timer(MRT) --------------------------------------------------*/
typedef struct {
__IO uint32_t INTVAL;
__IO uint32_t TIMER;
__IO uint32_t CTRL;
__IO uint32_t STAT;
} MRT_Channel_cfg_Type;
typedef struct {
MRT_Channel_cfg_Type Channel[4];
uint32_t Reserved0[1];
__IO uint32_t IDLE_CH;
__IO uint32_t IRQ_FLAG;
} LPC_MRT_TypeDef;
/*------------- Universal Asynchronous Receiver Transmitter (USART) -----------*/
/** @addtogroup LPC8xx_UART LPC8xx Universal Asynchronous Receiver/Transmitter
@{
*/
/**
* @brief Product name title=LPC8xx MCU Chapter title=USART Modification date=4/18/2012 Major revision=0 Minor revision=9 (USART)
*/
typedef struct
{
__IO uint32_t CFG; /* 0x00 */
__IO uint32_t CTRL;
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR; /* 0x10 */
__I uint32_t RXDATA;
__I uint32_t RXDATA_STAT;
__IO uint32_t TXDATA;
__IO uint32_t BRG; /* 0x20 */
__IO uint32_t INTSTAT;
} LPC_USART_TypeDef;
/*@}*/ /* end of group LPC8xx_USART */
/*------------- Synchronous Serial Interface Controller (SPI) -----------------------*/
/** @addtogroup LPC8xx_SPI LPC8xx Synchronous Serial Port
@{
*/
typedef struct
{
__IO uint32_t CFG; /* 0x00 */
__IO uint32_t DLY;
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR; /* 0x10 */
__I uint32_t RXDAT;
__IO uint32_t TXDATCTL;
__IO uint32_t TXDAT;
__IO uint32_t TXCTRL; /* 0x20 */
__IO uint32_t DIV;
__I uint32_t INTSTAT;
} LPC_SPI_TypeDef;
/*@}*/ /* end of group LPC8xx_SPI */
/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
/** @addtogroup LPC8xx_I2C I2C-Bus Interface
@{
*/
typedef struct
{
__IO uint32_t CFG; /* 0x00 */
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR;
__IO uint32_t TIMEOUT; /* 0x10 */
__IO uint32_t DIV;
__IO uint32_t INTSTAT;
uint32_t Reserved0[1];
__IO uint32_t MSTCTL; /* 0x20 */
__IO uint32_t MSTTIME;
__IO uint32_t MSTDAT;
uint32_t Reserved1[5];
__IO uint32_t SLVCTL; /* 0x40 */
__IO uint32_t SLVDAT;
__IO uint32_t SLVADR0;
__IO uint32_t SLVADR1;
__IO uint32_t SLVADR2; /* 0x50 */
__IO uint32_t SLVADR3;
__IO uint32_t SLVQUAL0;
uint32_t Reserved2[9];
__I uint32_t MONRXDAT; /* 0x80 */
} LPC_I2C_TypeDef;
/*@}*/ /* end of group LPC8xx_I2C */
/**
* @brief State Configurable Timer (SCT) (SCT)
*/
/**
* @brief Product name title=UM10430 Chapter title=LPC8xx State Configurable Timer (SCT) Modification date=1/18/2011 Major revision=0 Minor revision=7 (SCT)
*/
#define CONFIG_SCT_nEV (6) /* Number of events */
#define CONFIG_SCT_nRG (5) /* Number of match/compare registers */
#define CONFIG_SCT_nOU (4) /* Number of outputs */
typedef struct
{
__IO uint32_t CONFIG; /* 0x000 Configuration Register */
union {
__IO uint32_t CTRL_U; /* 0x004 Control Register */
struct {
__IO uint16_t CTRL_L; /* 0x004 low control register */
__IO uint16_t CTRL_H; /* 0x006 high control register */
};
};
__IO uint16_t LIMIT_L; /* 0x008 limit register for counter L */
__IO uint16_t LIMIT_H; /* 0x00A limit register for counter H */
__IO uint16_t HALT_L; /* 0x00C halt register for counter L */
__IO uint16_t HALT_H; /* 0x00E halt register for counter H */
__IO uint16_t STOP_L; /* 0x010 stop register for counter L */
__IO uint16_t STOP_H; /* 0x012 stop register for counter H */
__IO uint16_t START_L; /* 0x014 start register for counter L */
__IO uint16_t START_H; /* 0x016 start register for counter H */
uint32_t RESERVED1[10]; /* 0x018-0x03C reserved */
union {
__IO uint32_t COUNT_U; /* 0x040 counter register */
struct {
__IO uint16_t COUNT_L; /* 0x040 counter register for counter L */
__IO uint16_t COUNT_H; /* 0x042 counter register for counter H */
};
};
__IO uint16_t STATE_L; /* 0x044 state register for counter L */
__IO uint16_t STATE_H; /* 0x046 state register for counter H */
__I uint32_t INPUT; /* 0x048 input register */
__IO uint16_t REGMODE_L; /* 0x04C match - capture registers mode register L */
__IO uint16_t REGMODE_H; /* 0x04E match - capture registers mode register H */
__IO uint32_t OUTPUT; /* 0x050 output register */
__IO uint32_t OUTPUTDIRCTRL; /* 0x054 Output counter direction Control Register */
__IO uint32_t RES; /* 0x058 conflict resolution register */
uint32_t RESERVED2[37]; /* 0x05C-0x0EC reserved */
__IO uint32_t EVEN; /* 0x0F0 event enable register */
__IO uint32_t EVFLAG; /* 0x0F4 event flag register */
__IO uint32_t CONEN; /* 0x0F8 conflict enable register */
__IO uint32_t CONFLAG; /* 0x0FC conflict flag register */
union {
__IO union { /* 0x100-... Match / Capture value */
uint32_t U; /* SCTMATCH[i].U Unified 32-bit register */
struct {
uint16_t L; /* SCTMATCH[i].L Access to L value */
uint16_t H; /* SCTMATCH[i].H Access to H value */
};
} MATCH[CONFIG_SCT_nRG];
__I union {
uint32_t U; /* SCTCAP[i].U Unified 32-bit register */
struct {
uint16_t L; /* SCTCAP[i].L Access to H value */
uint16_t H; /* SCTCAP[i].H Access to H value */
};
} CAP[CONFIG_SCT_nRG];
};
uint32_t RESERVED3[32-CONFIG_SCT_nRG]; /* ...-0x17C reserved */
union {
__IO uint16_t MATCH_L[CONFIG_SCT_nRG]; /* 0x180-... Match Value L counter */
__I uint16_t CAP_L[CONFIG_SCT_nRG]; /* 0x180-... Capture Value L counter */
};
uint16_t RESERVED4[32-CONFIG_SCT_nRG]; /* ...-0x1BE reserved */
union {
__IO uint16_t MATCH_H[CONFIG_SCT_nRG]; /* 0x1C0-... Match Value H counter */
__I uint16_t CAP_H[CONFIG_SCT_nRG]; /* 0x1C0-... Capture Value H counter */
};
uint16_t RESERVED5[32-CONFIG_SCT_nRG]; /* ...-0x1FE reserved */
union {
__IO union { /* 0x200-... Match Reload / Capture Control value */
uint32_t U; /* SCTMATCHREL[i].U Unified 32-bit register */
struct {
uint16_t L; /* SCTMATCHREL[i].L Access to L value */
uint16_t H; /* SCTMATCHREL[i].H Access to H value */
};
} MATCHREL[CONFIG_SCT_nRG];
__IO union {
uint32_t U; /* SCTCAPCTRL[i].U Unified 32-bit register */
struct {
uint16_t L; /* SCTCAPCTRL[i].L Access to H value */
uint16_t H; /* SCTCAPCTRL[i].H Access to H value */
};
} CAPCTRL[CONFIG_SCT_nRG];
};
uint32_t RESERVED6[32-CONFIG_SCT_nRG]; /* ...-0x27C reserved */
union {
__IO uint16_t MATCHREL_L[CONFIG_SCT_nRG]; /* 0x280-... Match Reload value L counter */
__IO uint16_t CAPCTRL_L[CONFIG_SCT_nRG]; /* 0x280-... Capture Control value L counter */
};
uint16_t RESERVED7[32-CONFIG_SCT_nRG]; /* ...-0x2BE reserved */
union {
__IO uint16_t MATCHREL_H[CONFIG_SCT_nRG]; /* 0x2C0-... Match Reload value H counter */
__IO uint16_t CAPCTRL_H[CONFIG_SCT_nRG]; /* 0x2C0-... Capture Control value H counter */
};
uint16_t RESERVED8[32-CONFIG_SCT_nRG]; /* ...-0x2FE reserved */
__IO struct { /* 0x300-0x3FC SCTEVENT[i].STATE / SCTEVENT[i].CTRL*/
uint32_t STATE; /* Event State Register */
uint32_t CTRL; /* Event Control Register */
} EVENT[CONFIG_SCT_nEV];
uint32_t RESERVED9[128-2*CONFIG_SCT_nEV]; /* ...-0x4FC reserved */
__IO struct { /* 0x500-0x57C SCTOUT[i].SET / SCTOUT[i].CLR */
uint32_t SET; /* Output n Set Register */
uint32_t CLR; /* Output n Clear Register */
} OUT[CONFIG_SCT_nOU];
uint32_t RESERVED10[191-2*CONFIG_SCT_nOU]; /* ...-0x7F8 reserved */
__I uint32_t MODULECONTENT; /* 0x7FC Module Content */
} LPC_SCT_TypeDef;
/*@}*/ /* end of group LPC8xx_SCT */
/*------------- Watchdog Timer (WWDT) -----------------------------------------*/
/** @addtogroup LPC8xx_WDT LPC8xx WatchDog Timer
@{
*/
typedef struct
{
__IO uint32_t MOD; /*!< Offset: 0x000 Watchdog mode register (R/W) */
__IO uint32_t TC; /*!< Offset: 0x004 Watchdog timer constant register (R/W) */
__O uint32_t FEED; /*!< Offset: 0x008 Watchdog feed sequence register (W) */
__I uint32_t TV; /*!< Offset: 0x00C Watchdog timer value register (R) */
uint32_t RESERVED; /*!< Offset: 0x010 RESERVED */
__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 LPC8xx_WDT */
#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_ROM_BASE (0x1FFF0000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_WWDT_BASE (LPC_APB0_BASE + 0x00000)
#define LPC_MRT_BASE (LPC_APB0_BASE + 0x04000)
#define LPC_WKT_BASE (LPC_APB0_BASE + 0x08000)
#define LPC_SWM_BASE (LPC_APB0_BASE + 0x0C000)
#define LPC_PMU_BASE (LPC_APB0_BASE + 0x20000)
#define LPC_CMP_BASE (LPC_APB0_BASE + 0x24000)
#define LPC_FLASHCTRL_BASE (LPC_APB0_BASE + 0x40000)
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
#define LPC_I2C_BASE (LPC_APB0_BASE + 0x50000)
#define LPC_SPI0_BASE (LPC_APB0_BASE + 0x58000)
#define LPC_SPI1_BASE (LPC_APB0_BASE + 0x5C000)
#define LPC_USART0_BASE (LPC_APB0_BASE + 0x64000)
#define LPC_USART1_BASE (LPC_APB0_BASE + 0x68000)
#define LPC_USART2_BASE (LPC_APB0_BASE + 0x6C000)
/* AHB peripherals */
#define LPC_CRC_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_SCT_BASE (LPC_AHB_BASE + 0x04000)
#define LPC_GPIO_PORT_BASE (0xA0000000)
#define LPC_PIN_INT_BASE (LPC_GPIO_PORT_BASE + 0x4000)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define LPC_WWDT ((LPC_WWDT_TypeDef *) LPC_WWDT_BASE )
#define LPC_MRT ((LPC_MRT_TypeDef *) LPC_MRT_BASE )
#define LPC_WKT ((LPC_WKT_TypeDef *) LPC_WKT_BASE )
#define LPC_SWM ((LPC_SWM_TypeDef *) LPC_SWM_BASE )
#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE )
#define LPC_CMP ((LPC_CMP_TypeDef *) LPC_CMP_BASE )
#define LPC_FLASHCTRL ((LPC_FLASHCTRL_TypeDef *) LPC_FLASHCTRL_BASE )
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE )
#define LPC_SPI0 ((LPC_SPI_TypeDef *) LPC_SPI0_BASE )
#define LPC_SPI1 ((LPC_SPI_TypeDef *) LPC_SPI1_BASE )
#define LPC_USART0 ((LPC_USART_TypeDef *) LPC_USART0_BASE )
#define LPC_USART1 ((LPC_USART_TypeDef *) LPC_USART1_BASE )
#define LPC_USART2 ((LPC_USART_TypeDef *) LPC_USART2_BASE )
#define LPC_CRC ((LPC_CRC_TypeDef *) LPC_CRC_BASE )
#define LPC_SCT ((LPC_SCT_TypeDef *) LPC_SCT_BASE )
#define LPC_GPIO_PORT ((LPC_GPIO_PORT_TypeDef *) LPC_GPIO_PORT_BASE )
#define LPC_PIN_INT ((LPC_PIN_INT_TypeDef *) LPC_PIN_INT_BASE )
#ifdef __cplusplus
}
#endif
#endif /* __LPC8xx_H__ */

View File

@@ -0,0 +1,168 @@
/*
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 LPC8xx/ext_lld.c
* @brief LPC8xx EXT subsystem low level driver source.
*
* @addtogroup EXT
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_EXT || defined(__DOXYGEN__)
#include "ext_lld_isr.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief EXTD1 driver identifier.
*/
EXTDriver EXTD1;
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level EXT driver initialization.
*
* @notapi
*/
void ext_lld_init(void) {
/* Driver initialization.*/
extObjectInit(&EXTD1);
}
/**
* @brief Configures and activates the EXT peripheral.
*
* @param[in] extp pointer to the @p EXTDriver object
*
* @notapi
*/
void ext_lld_start(EXTDriver *extp) {
int i;
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
/* Configuration of automatic channels.*/
for (i = 0; i < EXT_MAX_CHANNELS; i++)
if (extp->config->channels[i].mode & EXT_CH_MODE_AUTOSTART)
ext_lld_channel_enable(extp, i);
else
ext_lld_channel_disable(extp, i);
}
/**
* @brief Deactivates the EXT peripheral.
*
* @param[in] extp pointer to the @p EXTDriver object
*
* @notapi
*/
void ext_lld_stop(EXTDriver *extp) {
int i;
if (extp->state == EXT_ACTIVE)
for (i = 0; i < EXT_MAX_CHANNELS; i++)
ext_lld_exti_irq_disable(i);
LPC_PIN_INT->ISEL = 0;
LPC_PIN_INT->CIENR = EXT_CHANNELS_MASK;
LPC_PIN_INT->RISE = EXT_CHANNELS_MASK;
LPC_PIN_INT->FALL = EXT_CHANNELS_MASK;
LPC_PIN_INT->IST = EXT_CHANNELS_MASK;
/* Leave clock enabled, its shared with GPIO */
/*LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<6);*/
}
/**
* @brief Enables an EXT channel.
*
* @param[in] extp pointer to the @p EXTDriver object
* @param[in] channel channel to be enabled
*
* @notapi
*/
void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {
/* program the IOpin for this channel */
LPC_SYSCON->PINTSEL[channel] = extp->config->channels[channel].iopin;
/* Programming edge irq enables */
if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE)
LPC_PIN_INT->SIENR = (1 << channel);
else
LPC_PIN_INT->CIENR = (1 << channel);
if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE)
LPC_PIN_INT->SIENF = (1 << channel);
else
LPC_PIN_INT->CIENF = (1 << channel);
LPC_PIN_INT->RISE = (1<<channel);
LPC_PIN_INT->FALL = (1<<channel);
LPC_PIN_INT->IST = (1<<channel);
ext_lld_exti_irq_enable( channel );
}
/**
* @brief Disables an EXT channel.
*
* @param[in] extp pointer to the @p EXTDriver object
* @param[in] channel channel to be disabled
*
* @notapi
*/
void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) {
(void)extp;
ext_lld_exti_irq_disable(channel);
LPC_PIN_INT->ISEL &= ~(1 << channel);
LPC_PIN_INT->CIENR = (1 << channel);
LPC_PIN_INT->RISE = (1 << channel);
LPC_PIN_INT->FALL = (1 << channel);
LPC_PIN_INT->IST = (1 << channel);
}
#endif /* HAL_USE_EXT */
/** @} */

View File

@@ -0,0 +1,152 @@
/*
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 LPC8xx/ext_lld.h
* @brief LPC8xx EXT subsystem low level driver header.
*
* @addtogroup EXT
* @{
*/
#ifndef _EXT_LLD_H_
#define _EXT_LLD_H_
#if HAL_USE_EXT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Available number of EXT channels.
*/
#define EXT_MAX_CHANNELS 8
/**
* @brief Mask of the available channels.
*/
#define EXT_CHANNELS_MASK ((1 << EXT_MAX_CHANNELS) - 1)
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief EXT channel identifier.
*/
typedef uint32_t expchannel_t;
/**
* @brief EXT channel callback reason.
*/
typedef uint32_t expreason_t;
/**
* @brief Type of an EXT generic notification callback.
*
* @param[in] extp pointer to the @p EXPDriver object triggering the
* callback
*/
typedef void (*extcallback_t)(EXTDriver *extp,
expchannel_t channel,
expreason_t reason);
/**
* @brief Channel configuration structure.
*/
typedef struct {
/**
* @brief Channel mode.
*/
uint8_t mode;
/**
* @brief IO Pin.
*/
uint8_t iopin;
/**
* @brief Channel callback.
*/
extcallback_t cb;
} EXTChannelConfig;
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
*/
typedef struct {
/**
* @brief Channel configurations.
*/
EXTChannelConfig channels[EXT_MAX_CHANNELS];
/* End of the mandatory fields.*/
} EXTConfig;
/**
* @brief Structure representing an EXT driver.
*/
struct EXTDriver {
/**
* @brief Driver state.
*/
extstate_t state;
/**
* @brief Current configuration data.
*/
const EXTConfig *config;
/* End of the mandatory fields.*/
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if !defined(__DOXYGEN__)
extern EXTDriver EXTD1;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void ext_lld_init(void);
void ext_lld_start(EXTDriver *extp);
void ext_lld_stop(EXTDriver *extp);
void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel);
void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_EXT */
#endif /* _EXT_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,194 @@
/*
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 LPC8xx/ext_lld_isr.c
* @brief LPC8xx EXT subsystem low level driver ISR code.
*
* @addtogroup EXT
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_EXT || defined(__DOXYGEN__)
#include "ext_lld_isr.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
static void ext_lld_interrupt( uint32_t n ) {
uint32_t reason;
reason = ((LPC_PIN_INT->RISE)>> n ) & 0x01;
reason |= ((LPC_PIN_INT->FALL)>>(n-1)) & 0x02;
LPC_PIN_INT->RISE = (1<<n);
LPC_PIN_INT->FALL = (1<<n);
LPC_PIN_INT->IST = (1<<n);
EXTD1.config->channels[n].cb(&EXTD1, n, reason);
}
/**
* @brief EXT[0] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorA0) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(0);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXT[1] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorA4) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(1);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXT[2] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorA8) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(2);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXT[3] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorAC) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(3);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXT[4] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorB0) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(4);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXT[5] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorB4) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(5);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXT[6] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorB8) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(6);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXT[7] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorBC) {
CH_IRQ_PROLOGUE();
ext_lld_interrupt(7);
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
static const uint8_t LPC8xx_EXT_EXTIn_IRQ_PRIORITY[] =
{ LPC8xx_EXT_EXTI0_IRQ_PRIORITY,
LPC8xx_EXT_EXTI1_IRQ_PRIORITY,
LPC8xx_EXT_EXTI2_IRQ_PRIORITY,
LPC8xx_EXT_EXTI3_IRQ_PRIORITY,
LPC8xx_EXT_EXTI4_IRQ_PRIORITY,
LPC8xx_EXT_EXTI5_IRQ_PRIORITY,
LPC8xx_EXT_EXTI6_IRQ_PRIORITY,
LPC8xx_EXT_EXTI7_IRQ_PRIORITY };
/**
* @brief Enables EXTI IRQ sources.
*
* @notapi
*/
void ext_lld_exti_irq_enable( uint32_t exti_n ) {
nvicEnableVector(PININT0_IRQn + exti_n,
CORTEX_PRIORITY_MASK(LPC8xx_EXT_EXTIn_IRQ_PRIORITY[exti_n]));
}
/**
* @brief Disables EXTI IRQ sources.
*
* @notapi
*/
void ext_lld_exti_irq_disable( uint32_t exti_n ) {
nvicDisableVector(PININT0_IRQn + exti_n);
}
#endif /* HAL_USE_EXT */
/** @} */

View File

@@ -0,0 +1,129 @@
/*
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 LPC8xx/ext_lld_isr.h
* @brief LPC8xx EXT subsystem low level driver ISR header.
*
* @addtogroup EXT
* @{
*/
#ifndef _EXT_LLD_ISR_H_
#define _EXT_LLD_ISR_H_
#if HAL_USE_EXT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief EXTI0 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI0_IRQ_PRIORITY 3
#endif
/**
* @brief EXTI1 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI1_IRQ_PRIORITY 3
#endif
/**
* @brief EXTI2 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI2_IRQ_PRIORITY 3
#endif
/**
* @brief EXTI3 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI3_IRQ_PRIORITY 3
#endif
/**
* @brief EXTI4 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI4_IRQ_PRIORITY 3
#endif
/**
* @brief EXTI5 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI5_IRQ_PRIORITY 3
#endif
/**
* @brief EXTI6 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI6_IRQ_PRIORITY 3
#endif
/**
* @brief EXTI7 interrupt priority level setting.
*/
#if !defined(LPC8xx_EXT_EXTI7_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_EXT_EXTI7_IRQ_PRIORITY 3
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void ext_lld_exti_irq_enable( uint32_t exti_n );
void ext_lld_exti_irq_disable( uint32_t exti_n );
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_EXT */
#endif /* _EXT_LLD_ISR_H_ */
/** @} */

View File

@@ -0,0 +1,278 @@
/*
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 LPC8xx/gpt_lld.c
* @brief LPC8xx 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 MRT channel0 when enabled.
*/
#if LPC8xx_GPT_USE_MRT0 || defined(__DOXYGEN__)
GPTDriver GPTD1;
#endif
/**
* @brief GPT2 driver identifier.
* @note The driver GPT1 allocates MRT channel1 when enabled.
*/
#if LPC8xx_GPT_USE_MRT1 || defined(__DOXYGEN__)
GPTDriver GPTD2;
#endif
/**
* @brief GPT3 driver identifier.
* @note The driver GPT1 allocates MRT channel2 when enabled.
*/
#if LPC8xx_GPT_USE_MRT2 || defined(__DOXYGEN__)
GPTDriver GPTD3;
#endif
/**
* @brief GPT4 driver identifier.
* @note The driver GPT1 allocates MRT channel3 when enabled.
*/
#if LPC8xx_GPT_USE_MRT3 || defined(__DOXYGEN__)
GPTDriver GPTD4;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
static uint32_t clk_enabled;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Shared IRQ handler.
*
* @param[in] gptp pointer to a @p GPTDriver object
* @param[in] irq_flag irq flag bit
*/
static void gpt_lld_serve_interrupt( GPTDriver *gptp ) {
if (gptp->tmr->STAT & 0x01) {
gptp->tmr->STAT |= 0x01;
if (gptp->state == GPT_ONESHOT) {
gptp->state = GPT_READY; /* Back in GPT_READY state. */
}
gptp->config->callback(gptp);
}
return;
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief MRT IRQ handler.
*
*/
CH_IRQ_HANDLER(Vector68) {
CH_IRQ_PROLOGUE();
#if LPC8xx_GPT_USE_MRT0
gpt_lld_serve_interrupt( &GPTD1 );
#endif
#if LPC8xx_GPT_USE_MRT1
gpt_lld_serve_interrupt( &GPTD2 );
#endif
#if LPC8xx_GPT_USE_MRT2
gpt_lld_serve_interrupt( &GPTD3 );
#endif
#if LPC8xx_GPT_USE_MRT3
gpt_lld_serve_interrupt( &GPTD4 );
#endif
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level GPT driver initialization.
*
* @notapi
*/
void gpt_lld_init(void) {
#if LPC8xx_GPT_USE_MRT0
GPTD1.tmr = &(LPC_MRT->Channel[0]);
gptObjectInit(&GPTD1);
GPTD1.mask = (1<<0);
#endif
#if LPC8xx_GPT_USE_MRT1
GPTD2.tmr = &(LPC_MRT->Channel[1]);
gptObjectInit(&GPTD2);
GPTD1.mask = (1<<1);
#endif
#if LPC8xx_GPT_USE_MRT2
GPTD3.tmr = &(LPC_MRT->Channel[2]);
gptObjectInit(&GPTD3);
GPTD1.mask = (1<<2);
#endif
#if LPC8xx_GPT_USE_MRT3
GPTD4.tmr = &(LPC_MRT->Channel[3]);
gptObjectInit(&GPTD4);
GPTD1.mask = (1<<3);
#endif
clk_enabled = FALSE;
return;
}
/**
* @brief Configures and activates a GPT channel.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_start(GPTDriver *gptp) {
if( !clk_enabled ) {
/* Enable clock & reset MRT */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10);
LPC_SYSCON->PRESETCTRL &= ~(1<<7);
LPC_SYSCON->PRESETCTRL |= (1<<7);
nvicEnableVector(MRT_IRQn,
CORTEX_PRIORITY_MASK(LPC8xx_GPT_MRT_IRQ_PRIORITY));
clk_enabled |= gptp->mask;
}
/* Prescaler value calculation.*/
gptp->pr = (LPC8xx_SYSCLK / gptp->config->frequency);
chDbgAssert((gptp->pr * gptp->config->frequency) == LPC8xx_SYSCLK,
"gpt_lld_start(), #1", "invalid frequency");
/* MRT Channel configuration.*/
gptp->tmr->CTRL = 0;
gptp->tmr->STAT |= 1;
}
/**
* @brief Deactivates a GPT channel.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_stop(GPTDriver *gptp) {
/* Shared peripheral -
mark this channel as disabled */
clk_enabled &= ~gptp->mask;
/* All channels disabled? */
if( !clk_enabled )
{
/* Disable periheral */
nvicDisableVector(MRT_IRQn);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<10);
}
return;
}
/**
* @brief Starts the timer in continuous/One shot 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->INTVAL = (1<<31)|((interval*gptp->pr) - 1);
if (gptp->state == GPT_ONESHOT)
gptp->tmr->CTRL = (1<<1)|1;
else
gptp->tmr->CTRL = 1;
}
/**
* @brief Stops the timer.
*
* @param[in] gptp pointer to the @p GPTDriver object
*
* @notapi
*/
void gpt_lld_stop_timer(GPTDriver *gptp) {
gptp->tmr->INTVAL = (1<<31);
gptp->tmr->CTRL = 0;
gptp->tmr->STAT |= 1;
}
/**
* @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->INTVAL = (1<<31)|((interval*gptp->pr) - 1);
gptp->tmr->CTRL = (1<<1);
while (gptp->tmr->STAT & (1<<1))
;
gptp->tmr->CTRL = 0;
gptp->tmr->STAT |= 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 LPC8xx/gpt_lld.h
* @brief LPC8xx 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(LPC8xx_GPT_USE_MRT0) || defined(__DOXYGEN__)
#define LPC8xx_GPT_USE_MRT0 TRUE
#endif
/**
* @brief GPT2 driver enable switch.
* @details If set to @p TRUE the support for GPT2 is included.
* @note The default is @p FALSE.
*/
#if !defined(LPC8xx_GPT_USE_MRT1) || defined(__DOXYGEN__)
#define LPC8xx_GPT_USE_MRT1 FALSE
#endif
/**
* @brief GPT3 driver enable switch.
* @details If set to @p TRUE the support for GPT3 is included.
* @note The default is @p FALSE.
*/
#if !defined(LPC8xx_GPT_USE_MRT2) || defined(__DOXYGEN__)
#define LPC8xx_GPT_USE_MRT2 FALSE
#endif
/**
* @brief GPT4 driver enable switch.
* @details If set to @p TRUE the support for GPT4 is included.
* @note The default is @p FALSE.
*/
#if !defined(LPC8xx_GPT_USE_MRT3) || defined(__DOXYGEN__)
#define LPC8xx_GPT_USE_MRT3 FALSE
#endif
/**
* @brief GPT interrupt priority level setting.
*/
#if !defined(LPC8xx_GPT_MRT_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_GPT_MRT_IRQ_PRIORITY 2
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !LPC8xx_GPT_USE_MRT0 && !LPC8xx_GPT_USE_MRT1 && \
!LPC8xx_GPT_USE_MRT2 && !LPC8xx_GPT_USE_MRT3
#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 Pointer to the MRT Channelx registers block.
*/
MRT_Channel_cfg_Type *tmr;
/**
* @brief Prescaler.
*/
uint32_t pr;
/**
* @brief channel bitmask.
*/
uint32_t mask;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Changes the interval of GPT peripheral.
* @details This function changes the interval of a running GPT unit.
* @pre The GPT unit must have been activated using @p gptStart().
* @pre The GPT unit must have been running in continuous mode using
* @p gptStartContinuous().
* @post The GPT unit interval is changed to the new value.
* @note The function has effect at the next cycle start.
*
* @param[in] gptp pointer to a @p GPTDriver object
* @param[in] interval new cycle time in timer ticks
* @notapi
*/
#define gpt_lld_change_interval(gptp, interval) \
((gptp)->tmr->INTVAL = ((interval*(gptp)->pr) - 1))
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if LPC8xx_GPT_USE_MRT0 && !defined(__DOXYGEN__)
extern GPTDriver GPTD1;
#endif
#if LPC8xx_GPT_USE_MRT1 && !defined(__DOXYGEN__)
extern GPTDriver GPTD2;
#endif
#if LPC8xx_GPT_USE_MRT2 && !defined(__DOXYGEN__)
extern GPTDriver GPTD3;
#endif
#if LPC8xx_GPT_USE_MRT3 && !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,140 @@
/*
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 LPC8xx/hal_lld.c
* @brief LPC8xx HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* 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 = LPC8xx_SYSCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
}
/**
* @brief LPC8xx clocks and PLL initialization.
* @note This function must be invoked only after the system reset.
*
* @special
*/
void lpc8xx_clock_init(void) {
int i;
/* Enable clocks to IOCON & SWM. */
LPC_SYSCON->SYSAHBCLKCTRL |= ((1<<18)|(1<<7));
/* System oscillator initialization.*/
#if (LPC8xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC)
// switch off pull-ups
LPC_IOCON->PIO0_8 &= ~(3<<3);
LPC_IOCON->PIO0_9 &= ~(3<<3);
// enable xtalin/xtalout
LPC_SWM->PINENABLE0 &= ~(3<<4);
LPC_SYSCON->SYSOSCCTRL = LPC8xx_SYSOSCCTRL;
LPC_SYSCON->PDRUNCFG &= ~(1<<5); /* System oscillator ON. */
for (i = 0; i<200; i++)
__NOP(); /* Stabilization delay. */
#endif
/* CLKIN initialization.*/
#if (LPC8xx_PLLCLK_SOURCE == SYSPLLCLKSEL_CLKIN)
// switch off pull-up
LPC_IOCON->PIO0_1 &= ~(3<<3);
// enable clkin
LPC_SWM->PINENABLE0 &= ~(1<<7);
#endif
/* Always set PLL clock source -
PLL IN can be a main clock source */
LPC_SYSCON->SYSPLLCLKSEL = LPC8xx_PLLCLK_SOURCE;
LPC_SYSCON->SYSPLLCLKUEN = 1;
while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
/* PLL initialization.*/
#if LPC8xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
LPC_SYSCON->SYSPLLCTRL = LPC8xx_SYSPLLCTRL_MSEL | LPC8xx_SYSPLLCTRL_PSEL;
LPC_SYSCON->PDRUNCFG &= ~(1<<7); /* System PLL ON. */
while (!(LPC_SYSCON->SYSPLLSTAT & 1)) /* Wait PLL lock. */
;
#endif
#if LPC8xx_MAINCLK_SOURCE == SYSMAINCLKSEL_WDGOSC
#error "WatchDog Oscillator not configured! Dont use as main clock source"
LPC_SYSCON->WDTOSCCTRL = ??;
LPC_SYSCON->PDRUNCFG &= ~(1<<6); /* WDT OSC On */
for (i = 0; i<200; i++)
__NOP(); /* Stabilization delay. */
#endif
/* Flash wait states setting, the code takes care to not touch TBD bits.*/
LPC_FLASHCTRL->FLASHCFG = (LPC_FLASHCTRL->FLASHCFG & ~1) |
LPC8xx_FLASHCFG_FLASHTIM;
/* ABH divider initialization. Set this **before** switching Main clock
source to ensure AHB clock stays in spec */
LPC_SYSCON->SYSAHBCLKDIV = LPC8xx_SYSABHCLK_DIV;
/* Main clock source selection.*/
LPC_SYSCON->MAINCLKSEL = LPC8xx_MAINCLK_SOURCE;
LPC_SYSCON->MAINCLKUEN = 1;
while (!(LPC_SYSCON->MAINCLKUEN & 1)); /* Wait switch completion. */
/* Disable clocks to IOCON, SWM, FLASHREG & ROM. */
LPC_SYSCON->SYSAHBCLKCTRL &= ~((1<<18)|(1<<7)|(1<<3)|(1<<1));
}
/** @} */

View File

@@ -0,0 +1,221 @@
/*
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 LPC8xx/hal_lld.h
* @brief HAL subsystem low level driver header template.
*
* @addtogroup HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "LPC8xx.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 "LPC8xx"
#define IRCOSCCLK 12000000 /**< High speed internal clock. */
#define WDGOSCCLK ??????? /**< Watchdog internal clock. */
#define SYSPLLCLKSEL_IRCOSC 0 /**< Internal RC oscillator
clock source. */
#define SYSPLLCLKSEL_SYSOSC 1 /**< System oscillator clock
source. */
#define SYSPLLCLKSEL_CLKIN 3 /**< External CLKIN 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(LPC8xx_PLLCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC8xx_PLLCLK_SOURCE SYSPLLCLKSEL_IRCOSC
#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(LPC8xx_SYSPLL_MUL) || defined(__DOXYGEN__)
#define LPC8xx_SYSPLL_MUL 4
#endif
/**
* @brief System PLL divider.
* @note The value must be chosen between (2, 4, 8, 16).
*/
#if !defined(LPC8xx_SYSPLL_DIV) || defined(__DOXYGEN__)
#define LPC8xx_SYSPLL_DIV 4
#endif
/**
* @brief System main clock source.
*/
#if !defined(LPC8xx_MAINCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC8xx_MAINCLK_SOURCE SYSMAINCLKSEL_PLLOUT
#endif
/**
* @brief AHB clock divider.
* @note The value must be chosen between (1...255).
*/
#if !defined(LPC8xx_SYSABHCLK_DIV) || defined(__DOXYGEN__)
#define LPC8xx_SYSABHCLK_DIV 1
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/**
* @brief Calculated SYSOSCCTRL setting.
*/
#if (SYSOSCCLK < 18000000) || defined(__DOXYGEN__)
#define LPC8xx_SYSOSCCTRL 0
#else
#define LPC8xx_SYSOSCCTRL 2
#endif
/**
* @brief PLL input clock frequency.
*/
#if (LPC8xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC) || defined(__DOXYGEN__)
#define LPC8xx_SYSPLLCLKIN SYSOSCCLK
#elif LPC8xx_PLLCLK_SOURCE == SYSPLLCLKSEL_IRCOSC
#define LPC8xx_SYSPLLCLKIN IRCOSCCLK
#elif LPC8xx_PLLCLK_SOURCE == SYSPLLCLKSEL_CLKIN
#define LPC8xx_SYSPLLCLKIN CLKINCLK
#else
#error "invalid LPC8xx_PLLCLK_SOURCE clock source specified"
#endif
/**
* @brief MSEL mask in SYSPLLCTRL register.
*/
#if (LPC8xx_SYSPLL_MUL >= 1) && (LPC8xx_SYSPLL_MUL <= 32) || \
defined(__DOXYGEN__)
#define LPC8xx_SYSPLLCTRL_MSEL (LPC8xx_SYSPLL_MUL - 1)
#else
#error "LPC8xx_SYSPLL_MUL out of range (1...32)"
#endif
/**
* @brief PSEL mask in SYSPLLCTRL register.
*/
#if (LPC8xx_SYSPLL_DIV == 2) || defined(__DOXYGEN__)
#define LPC8xx_SYSPLLCTRL_PSEL (0 << 5)
#elif LPC8xx_SYSPLL_DIV == 4
#define LPC8xx_SYSPLLCTRL_PSEL (1 << 5)
#elif LPC8xx_SYSPLL_DIV == 8
#define LPC8xx_SYSPLLCTRL_PSEL (2 << 5)
#elif LPC8xx_SYSPLL_DIV == 16
#define LPC8xx_SYSPLLCTRL_PSEL (3 << 5)
#else
#error "invalid LPC8xx_SYSPLL_DIV value (2,4,8,16)"
#endif
/**
* @brief CCO frequency.
*/
#define LPC8xx_SYSPLLCCO (LPC8xx_SYSPLLCLKIN * LPC8xx_SYSPLL_MUL * \
LPC8xx_SYSPLL_DIV)
#if (LPC8xx_SYSPLLCCO < 156000000) || (LPC8xx_SYSPLLCCO > 320000000)
#error "CCO frequency out of the acceptable range (156...320MHz)"
#endif
/**
* @brief PLL output clock frequency.
*/
#define LPC8xx_SYSPLLCLKOUT (LPC8xx_SYSPLLCCO / LPC8xx_SYSPLL_DIV)
#if (LPC8xx_MAINCLK_SOURCE == SYSMAINCLKSEL_IRCOSC) || defined(__DOXYGEN__)
#define LPC8xx_MAINCLK IRCOSCCLK
#elif LPC8xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLIN
#define LPC8xx_MAINCLK LPC8xx_SYSPLLCLKIN
#elif LPC8xx_MAINCLK_SOURCE == SYSMAINCLKSEL_WDGOSC
#define LPC8xx_MAINCLK WDGOSCCLK
#elif LPC8xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
#define LPC8xx_MAINCLK LPC8xx_SYSPLLCLKOUT
#else
#error "invalid LPC8xx_MAINCLK_SOURCE clock source specified"
#endif
/**
* @brief AHB clock.
*/
#define LPC8xx_SYSCLK (LPC8xx_MAINCLK / LPC8xx_SYSABHCLK_DIV)
#if LPC8xx_SYSCLK > 30000000
#error "AHB clock frequency out of the acceptable range (30MHz max)"
#endif
/**
* @brief Flash wait states.
*/
#if (LPC8xx_SYSCLK <= 20000000) || defined(__DOXYGEN__)
#define LPC8xx_FLASHCFG_FLASHTIM 0
#else
#define LPC8xx_FLASHCFG_FLASHTIM 1
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void lpc8xx_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,105 @@
/*
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 LPC8xx/pal_lld.c
* @brief LPC8xx 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. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief LPC8xx I/O ports configuration.
* @details GPIO unit registers initialization.
*
* @param[in] config the LPC8xx ports configuration
*
* @notapi
*/
void _pal_lld_init(const PALConfig *config) {
/* Enable clocks to GPIO */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
LPC_GPIO_PORT->DIR0 = config->dir;
LPC_GPIO_PORT->PIN0 = config->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->DIR0 &= ~mask;
break;
case PAL_MODE_UNCONNECTED:
palSetPort(port, PAL_WHOLE_PORT);
//no break
case PAL_MODE_OUTPUT_PUSHPULL:
port->DIR0 |= mask;
break;
}
return;
}
#endif /* HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,290 @@
/*
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 LPC8xx/pal_lld.h
* @brief LPC8xx 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.
*/
/**
* @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 {
/** Initial value for FIO_PIN register.*/
uint32_t data;
/** Initial value for FIO_DIR register.*/
uint32_t dir;
} PALConfig;
/**
* @brief Width, in bits, of the 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)0x3FFFF)
/**
* @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_PORT_TypeDef *ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief GPIO0 port identifier.
*/
#define IOPORT1 LPC_GPIO_PORT
#define GPIO0 LPC_GPIO_PORT
/*===========================================================================*/
/* 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)->PIN0)
/**
* @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)->SET0)
/**
* @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)->PIN0 = (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)->SET0 = (bits))
/**
* @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)->CLR0 = (bits))
/**
* @brief Toggles 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 XORed on the specified port
*
* @api
*/
#define pal_lld_toggleport(port, bits) ((port)->NOT0 = (bits))
/**
* @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)->MASK0 = (~(mask) << (offset)); \
(port)->MPIN0 = ((bits) << (offset))
/**
* @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)->W0[(pad)] = (bit))
/**
* @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)->W0[(pad)] = 1)
/**
* @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)->W0[(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,104 @@
/*
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 LPC8xx LPC8xx Drivers
* @details This section describes all the supported drivers on the LPC8xx
* platform and the implementation details of the single drivers.
*
* @ingroup platforms
*/
/**
* @defgroup LPC8xx_HAL LPC8xx Initialization Support
* @details The LPC8xx HAL support is responsible for system initialization.
*
* @section lpc8xx_hal_1 Supported HW resources
* - SYSCON.
* - Flash.
* .
* @section lpc8xx_hal_2 LPC8xx HAL driver implementation features
* - Clock tree initialization.
* - Clock source selection.
* - Flash controller initialization.
* - SYSTICK initialization based on current clock and kernel required rate.
* .
* @ingroup LPC8xx
*/
/**
* @defgroup LPC8xx_GPT LPC8xx GPT Support
* @details The LPC8xx GPT driver uses the MRT peripheral.
*
* @section lpc8xx_gpt_1 Supported HW resources
* - MRT.
* .
* @section lpc8xx_gpt_2 LPC8xx GPT driver implementation features
* - Each timer can be independently enabled and programmed.
* - Programmable MRT interrupt priority level.
* .
* @ingroup LPC8xx
*/
/**
* @defgroup LPC8xx_PAL LPC8xx PAL Support
* @details The LPC8xx PAL driver uses the GPIO peripheral.
*
* @section lpc8xx_pal_1 Supported HW resources
* - GPIO_PORT.
* .
* @section lpc8xx_pal_2 LPC8xx PAL driver implementation features
* - 18 bits wide ports.
* - Atomic set/reset functions.
* - Atomic Toggle 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 lpc8xx_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 lpc8xx_pal_4 Suboptimal behavior
* Some GPIO features are less than optimal:
* - Group 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.
* .
* @ingroup LPC8xx
*/
/**
* @defgroup LPC8xx_SERIAL LPC8xx Serial Support
* @details The LPC8xx Serial driver uses the UART peripheral in a
* buffered, interrupt driven, implementation.
*
* @section lpc8xx_serial_1 Supported HW resources
* The serial driver can support any of the following hardware resources:
* - UART.
* .
* @section lpc8xx_serial_2 LPC8xx Serial driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Fully interrupt driven.
* - Programmable priority level.
* .
* @ingroup LPC8xx
*/

View File

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

View File

@@ -0,0 +1,352 @@
/*
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 LPC8xx/serial_lld.c
* @brief LPC8xx low level serial driver code.
*
* @addtogroup SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if LPC8xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
/** @brief UART0 serial driver identifier.*/
SerialDriver SD1;
#endif
#if LPC8xx_SERIAL_USE_UART1 || defined(__DOXYGEN__)
/** @brief UART1 serial driver identifier.*/
SerialDriver SD2;
#endif
#if LPC8xx_SERIAL_USE_UART2 || defined(__DOXYGEN__)
/** @brief UART2 serial driver identifier.*/
SerialDriver SD3;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/** @brief Driver default configuration.*/
static const SerialConfig default_config = {
SERIAL_DEFAULT_BITRATE,
(CFG_DL8 | CFG_NOPARITY | CFG_STOP1)
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Error handling routine.
*
* @param[in] sdp communication channel associated to the UART
* @param[in] err UART STAT register value
*/
static void set_error(SerialDriver *sdp, IOREG32 err) {
flagsmask_t sts = 0;
if (err & STAT_OVERRUN)
sts |= SD_OVERRUN_ERROR;
if (err & STAT_PARITYERR)
sts |= SD_PARITY_ERROR;
if (err & STAT_FRAMERR)
sts |= SD_FRAMING_ERROR;
if (err & STAT_RXBRK)
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_USART_TypeDef *u = sdp->uart;
while (u->INTSTAT) {
if (u->INTSTAT & STAT_RXRDY) {
chSysLockFromIsr();
if (chIQIsEmptyI(&sdp->iqueue))
chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
if (chIQPutI(&sdp->iqueue, u->RXDATA) < Q_OK)
chnAddFlagsI(sdp, SD_OVERRUN_ERROR);
chSysUnlockFromIsr();
}
if (u->INTSTAT & STAT_TXRDY) {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->oqueue);
chSysUnlockFromIsr();
if (b < Q_OK) {
u->INTENCLR = STAT_TXRDY;
chSysLockFromIsr();
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
chSysUnlockFromIsr();
break;
}
else {
u->TXDATA = b;
}
}
if (u->INTSTAT & (STAT_OVERRUN | STAT_DELTARXBRK |
STAT_FRAMERR | STAT_PARITYERR) ) {
IOREG32 stat = u->STAT;
set_error(sdp, stat);
u->STAT = stat;
}
}
}
/**
* @brief Attempts a TX preload.
*/
static void preload(SerialDriver *sdp) {
LPC_USART_TypeDef *u = sdp->uart;
if (u->STAT & STAT_TXIDLE) {
msg_t b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
return;
}
u->TXDATA = b;
}
u->INTENSET = STAT_TXRDY;
}
/**
* @brief Driver output notification.
*/
#if LPC8xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
static void notify1(GenericQueue *qp) {
(void)qp;
preload(&SD1);
}
#endif
#if LPC8xx_SERIAL_USE_UART1 || defined(__DOXYGEN__)
static void notify2(GenericQueue *qp) {
(void)qp;
preload(&SD2);
}
#endif
#if LPC8xx_SERIAL_USE_UART2 || defined(__DOXYGEN__)
static void notify3(GenericQueue *qp) {
(void)qp;
preload(&SD3);
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief UARTn IRQ handlers.
*
* @isr
*/
#if LPC8xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(Vector4C) {
CH_IRQ_PROLOGUE();
serve_interrupt( &SD1 );
CH_IRQ_EPILOGUE();
}
#endif
#if LPC8xx_SERIAL_USE_UART1 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(Vector50) {
CH_IRQ_PROLOGUE();
serve_interrupt( &SD2 );
CH_IRQ_EPILOGUE();
}
#endif
#if LPC8xx_SERIAL_USE_UART2 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(Vector54) {
CH_IRQ_PROLOGUE();
serve_interrupt( &SD3 );
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*
* @notapi
*/
void sd_lld_init(void) {
#if LPC8xx_SERIAL_USE_UART0
sdObjectInit(&SD1, NULL, notify1);
SD1.uart = LPC_USART0;
#endif
#if LPC8xx_SERIAL_USE_UART1
sdObjectInit(&SD2, NULL, notify2);
SD2.uart = LPC_USART1;
#endif
#if LPC8xx_SERIAL_USE_UART2
sdObjectInit(&SD3, NULL, notify3);
SD3.uart = LPC_USART2;
#endif
/* Reset fractional baudrate generator */
LPC_SYSCON->PRESETCTRL &= ~(1<<2);
LPC_SYSCON->PRESETCTRL |= (1<<2);
LPC_SYSCON->UARTCLKDIV = LPC8xx_SERIAL_UARTCLKDIV;
LPC_SYSCON->UARTFRGDIV = LPC8xx_SERIAL_UARTFRGDIV;
LPC_SYSCON->UARTFRGMULT = LPC8xx_SERIAL_UARTFRGMULT;
}
/**
* @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 LPC8xx_SERIAL_USE_UART0
if (&SD1 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<14); // Enable Clk
LPC_SYSCON->PRESETCTRL &= ~(1<<3); // Reset peripheral
LPC_SYSCON->PRESETCTRL |= (1<<3);
nvicEnableVector(UART0_IRQn,
CORTEX_PRIORITY_MASK(LPC8xx_SERIAL_UART0_IRQ_PRIORITY));
}
#endif
#if LPC8xx_SERIAL_USE_UART1
if (&SD2 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15); // Enable Clk
LPC_SYSCON->PRESETCTRL &= ~(1<<4); // Reset peripheral
LPC_SYSCON->PRESETCTRL |= (1<<4);
nvicEnableVector(UART1_IRQn,
CORTEX_PRIORITY_MASK(LPC8xx_SERIAL_UART1_IRQ_PRIORITY));
}
#endif
#if LPC8xx_SERIAL_USE_UART2
if (&SD3 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16); // Enable Clk
LPC_SYSCON->PRESETCTRL &= ~(1<<5); // Reset peripheral
LPC_SYSCON->PRESETCTRL |= (1<<5);
nvicEnableVector(UART2_IRQn,
CORTEX_PRIORITY_MASK(LPC8xx_SERIAL_UART2_IRQ_PRIORITY));
}
#endif
}
sdp->uart->BRG = (LPC8xx_SERIAL_U_PCLK / (config->sc_speed << 4)) -1;
sdp->uart->INTENSET = STAT_FRAMERR | STAT_OVERRUN |
STAT_PARITYERR | STAT_DELTARXBRK |
STAT_RXRDY;
sdp->uart->CFG = config->sc_cfg | CFG_ENA;
}
/**
* @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) {
sdp->uart->INTENCLR = STAT_TXRDY | STAT_RXRDY;
sdp->uart->CFG = 0;
#if LPC8xx_SERIAL_USE_UART0
if (&SD1 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<12);
nvicDisableVector(UART0_IRQn);
return;
}
#endif
#if LPC8xx_SERIAL_USE_UART1
if (&SD2 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<13);
nvicDisableVector(UART1_IRQn);
return;
}
#endif
#if LPC8xx_SERIAL_USE_UART2
if (&SD3 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<14);
nvicDisableVector(UART2_IRQn);
return;
}
#endif
}
}
#endif /* HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,269 @@
/*
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 LPC8xx/serial_lld.h
* @brief LPC8xx low level serial driver header.
*
* @addtogroup SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define CFG_ENA 0x0001
#define CFG_DL7 0x0000
#define CFG_DL8 0x0004
#define CFG_DL9 0x0008
#define CFG_NOPARITY 0x0000
#define CFG_PARITYEVEN 0x0020
#define CFG_PARITYODD 0x0030
#define CFG_STOP1 0x0000
#define CFG_STOP2 0x0040
#define CFG_CTSEN 0x0200
#define CFG_SYNCEN 0x0800
#define CFG_CLKPOL_FALL 0x0000
#define CFG_CLKPOL_RISE 0x1000
#define CFG_SYNC_SLV 0x0000
#define CFG_SYNC_MAST 0x4000
#define CFG_LOOP_EN 0x8000
#define CTRL_TXBRKEN 0x0002
#define CTRL_ADDRDET 0x0004
#define CTRL_TXDIS 0x0040
#define CTRL_CC 0x0100
#define CTRL_CLRCC 0x0200
#define STAT_RXRDY 0x0001
#define STAT_RXIDLE 0x0002
#define STAT_TXRDY 0x0004
#define STAT_TXIDLE 0x0008
#define STAT_CTS 0x0010
#define STAT_DELTACTS 0x0020
#define STAT_TXDIS 0x0040
#define STAT_OVERRUN 0x0100
#define STAT_RXBRK 0x0400
#define STAT_DELTARXBRK 0x0800
#define STAT_START 0x1000
#define STAT_FRAMERR 0x2000
#define STAT_PARITYERR 0x4000
#define STAT_RXNOISE 0x8000
/*===========================================================================*/
/* 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(LPC8xx_SERIAL_USE_UART0) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_USE_UART0 TRUE
#endif
/**
* @brief UART1 driver enable switch.
* @details If set to @p TRUE the support for UART1 is included.
* @note The default is @p FALSE .
*/
#if !defined(LPC8xx_SERIAL_USE_UART1) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_USE_UART1 FALSE
#endif
/**
* @brief UART2 driver enable switch.
* @details If set to @p TRUE the support for UART2 is included.
* @note The default is @p FALSE .
*/
#if !defined(LPC8xx_SERIAL_USE_UART2) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_USE_UART2 FALSE
#endif
/**
* @brief UART0 interrupt priority level setting.
*/
#if !defined(LPC8xx_SERIAL_UART0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_UART0_IRQ_PRIORITY 3
#endif
/**
* @brief UART1 interrupt priority level setting.
*/
#if !defined(LPC8xx_SERIAL_UART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_UART1_IRQ_PRIORITY 3
#endif
/**
* @brief UART2 interrupt priority level setting.
*/
#if !defined(LPC8xx_SERIAL_UART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_UART2_IRQ_PRIORITY 3
#endif
/**
* @brief Uart Baud Clock (U_PCLK).
* @details The Baud clock rate we would like to achieve.
* @note The default is @p 11.0592MHz.
* A multiple of 1.8432MHz will give accurate
* results at all standard baud rates .
*/
#if !defined(LPC8xx_SERIAL_U_PCLK) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_U_PCLK 11059200
#endif
/**
* @brief UARTCLKDIV divider.
*/
#if !defined(LPC8xx_SERIAL_UARTCLKDIV) || defined(__DOXYGEN__)
#define LPC8xx_SERIAL_UARTCLKDIV (LPC8xx_MAINCLK/LPC8xx_SERIAL_U_PCLK)
#endif
// Output from uart clock divider
#define LPC8xx_UARTDIVCLK (LPC8xx_MAINCLK/LPC8xx_SERIAL_UARTCLKDIV)
/**
* @brief UARTFRGDIV
* @details Fractional Baud rate generator denominator.
* @note If used, *must* be set to 256, otherwise set to 0
*/
#if !defined(LPC8xx_SERIAL_UARTFRGDIV) || defined(__DOXYGEN__)
#if (LPC8xx_SERIAL_UARTCLKDIV != LPC8xx_SERIAL_U_PCLK)
#define LPC8xx_SERIAL_UARTFRGDIV 0xFF
#else
#define LPC8xx_SERIAL_UARTFRGDIV 0x00
#endif
#endif
/**
* @brief UARTFRGMUL
* @details Fractional Baud rate generator numerator.
* Refer to LPC8xx User Manual 4.6.19 for calculation
* @note the *2, +1 and /2 are included to round to the nearest integer.
*/
#if !defined(LPC8xx_SERIAL_UARTFRGMUL) || defined(__DOXYGEN__)
#if (LPC8xx_SERIAL_UARTCLKDIV != LPC8xx_SERIAL_U_PCLK)
#define LPC8xx_SERIAL_UARTFRGMULT ( ( ( ( (LPC8xx_UARTDIVCLK- \
LPC8xx_SERIAL_U_PCLK) \
*256*2 ) \
/LPC8xx_SERIAL_U_PCLK ) \
+1 ) \
/2 )
#else
#define LPC8xx_SERIAL_UARTFRGMULT 0x00
#endif
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (LPC8xx_SERIAL_UARTCLKDIV < 1) || (LPC8xx_SERIAL_UARTCLKDIV > 255)
#error "invalid LPC8xx_SERIAL_UARTCLKDIV setting"
#endif
#if (LPC8xx_SERIAL_UARTFRGDIV != 0) && (LPC8xx_SERIAL_UARTFRGDIV != 255)
#error "invalid LPC8xx_SERIAL_UARTFRGDIV setting"
#endif
#if (LPC8xx_SERIAL_UARTFRGMUL != 0) && (LPC8xx_SERIAL_UARTFRGMUL > 255)
#error "invalid LPC8xx_SERIAL_UARTFRGMUL setting"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief LPC8xx 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 CFG register.
*/
uint32_t sc_cfg;
} 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_USART_TypeDef *uart;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if LPC8xx_SERIAL_USE_UART0 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if LPC8xx_SERIAL_USE_UART1 && !defined(__DOXYGEN__)
extern SerialDriver SD2;
#endif
#if LPC8xx_SERIAL_USE_UART2 && !defined(__DOXYGEN__)
extern SerialDriver SD3;
#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,385 @@
/*
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 LPC8xx/spi_lld.c
* @brief LPC8xx low level SPI driver code.
*
* @addtogroup SPI
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if LPC8xx_SPI_USE_SPI0 || defined(__DOXYGEN__)
/** @brief SPI1 driver identifier.*/
SPIDriver SPID1;
#endif
#if LPC8xx_SPI_USE_SPI1 || defined(__DOXYGEN__)
/** @brief SPI2 driver identifier.*/
SPIDriver SPID2;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void spi_load_txdata(SPIDriver *spip) {
LPC_SPI_TypeDef *spi = spip->spi;
if (--spip->txcnt == 0) {
spi->TXCTRL |= SPI_TXCTRL_EOT;
}
if (spip->txptr != NULL) {
if ((spi->TXCTRL & SPI_TXCTRL_FLEN_MASK) > SPI_TXCTRL_FLEN(8)) {
const uint16_t *p = spip->txptr;
spi->TXDAT = *p++;
spip->txptr = p;
}
else {
const uint8_t *p = spip->txptr;
spi->TXDAT = *p++;
spip->txptr = p;
}
}
else
spi->TXDAT = 0xffff;
}
/**
* @brief Common IRQ handler.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
static void spi_serve_interrupt(SPIDriver *spip) {
LPC_SPI_TypeDef *spi = spip->spi;
if (spi->INTSTAT & (SPI_STAT_RXOV | SPI_STAT_TXUR)) {
/* The overflow condition should never happen becausepriority is given
to receive but a hook macro is provided anyway...*/
LPC8xx_SPI_ERROR_HOOK(spip);
spi->STAT = (SPI_STAT_RXOV | SPI_STAT_TXUR);
}
if (spi->INTSTAT & SPI_STAT_TXRDY) {
spi_load_txdata( spip );
}
if (spip->txcnt == 0) {
spi->INTENCLR = (SPI_STAT_TXRDY | SPI_STAT_TXUR);
}
if (spi->INTSTAT & SPI_STAT_RXRDY) {
if (spip->rxptr != NULL) {
if ((spi->TXCTRL & SPI_TXCTRL_FLEN_MASK) > SPI_TXCTRL_FLEN(8)) {
uint16_t *p = spip->rxptr;
*p++ = spi->RXDAT;
spip->rxptr = p;
}
else {
uint8_t *p = spip->rxptr;
*p++ = spi->RXDAT;
spip->rxptr = p;
}
}
else
(void)spi->RXDAT;
if (--spip->rxcnt == 0) {
chDbgAssert(spip->txcnt == 0,
"spi_serve_interrupt(), #1", "counter out of synch");
/* Stops the IRQ sources.*/
spi->INTENCLR = (SPI_STAT_RXRDY | SPI_STAT_TXRDY |
SPI_STAT_RXOV | SPI_STAT_TXUR);
/* Portable SPI ISR code defined in the high level driver, note, it is
a macro.*/
_spi_isr_code(spip);
return;
}
}
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if LPC8xx_SPI_USE_SPI0 || defined(__DOXYGEN__)
/**
* @brief SPI0 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector40) {
CH_IRQ_PROLOGUE();
spi_serve_interrupt(&SPID1);
CH_IRQ_EPILOGUE();
}
#endif
#if LPC8xx_SPI_USE_SPI1 || defined(__DOXYGEN__)
/**
* @brief SPI1 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector44) {
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 LPC8xx_SPI_USE_SPI0
spiObjectInit(&SPID1);
SPID1.spi = LPC_SPI0;
#endif
#if LPC8xx_SPI_USE_SPI1
spiObjectInit(&SPID2);
SPID2.spi = LPC_SPI1;
#endif
}
/**
* @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) {
#if LPC8xx_SPI_USE_SPI0
if (&SPID1 == spip) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);
LPC_SYSCON->PRESETCTRL |= (1<<0);
spip->spi->DIV = LPC8xx_SPI_SPI0CLKDIV;
nvicEnableVector(SPI0_IRQn,
CORTEX_PRIORITY_MASK(LPC8xx_SPI_SPI0_IRQ_PRIORITY));
}
#endif
#if LPC8xx_SPI_USE_SPI1
if (&SPID2 == spip) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
LPC_SYSCON->PRESETCTRL |= (1<<1);
spip->spi->DIV = LPC8xx_SPI_SPI1CLKDIV;
nvicEnableVector(SPI1_IRQn,
CORTEX_PRIORITY_MASK(LPC8xx_SPI_SPI1_IRQ_PRIORITY));
}
#endif
}
spip->spi->DLY = spip->config->dly;
spip->spi->TXCTRL = spip->config->txctrl;
spip->spi->STAT = (SPI_STAT_RXOV | SPI_STAT_TXUR);
spip->spi->CFG = spip->config->cfg | SPI_CFG_ENABLE;
}
/**
* @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->spi->CFG = 0;
#if LPC8xx_SPI_USE_SPI0
if (&SPID1 == spip) {
nvicDisableVector(SPI0_IRQn);
LPC_SYSCON->PRESETCTRL &= ~(1<<0);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<11);
}
#endif
#if LPC8xx_SPI_USE_SPI1
if (&SPID2 == spip) {
nvicDisableVector(SPI1_IRQn);
LPC_SYSCON->PRESETCTRL &= ~(1<<1);
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<12);
}
#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) {
/* Hardware controls SSEL */
(void)spip;
}
/**
* @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) {
/* Hardware controls SSEL */
(void)spip;
}
/**
* @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;
spip->spi->TXCTRL &= ~SPI_TXCTRL_EOT;
spi_load_txdata(spip);
if (spip->txcnt == 0)
spip->spi->INTENSET = (SPI_STAT_RXRDY | SPI_STAT_RXOV);
else
spip->spi->INTENSET = (SPI_STAT_RXRDY | SPI_STAT_TXRDY |
SPI_STAT_RXOV | SPI_STAT_TXUR);
}
/**
* @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) {
spi_lld_exchange( spip, n, NULL, NULL);
}
/**
* @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) {
spi_lld_exchange( spip, n, txbuf, NULL);
}
/**
* @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) {
spi_lld_exchange( spip, n, NULL, rxbuf);
}
/**
* @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->spi->TXCTRL |= SPI_TXCTRL_EOT;
spip->spi->TXDAT = frame;
while ((spip->spi->STAT & SPI_STAT_RXRDY) == 0)
;
return (uint16_t)spip->spi->RXDAT;
}
#endif /* HAL_USE_SPI */
/** @} */

View File

@@ -0,0 +1,285 @@
/*
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 LPC8xx/spi_lld.h
* @brief LPC8xx low level SPI driver header.
*
* @addtogroup SPI
* @{
*/
#ifndef _SPI_LLD_H_
#define _SPI_LLD_H_
#if HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define SPI_CFG_ENABLE (1<<0)
#define SPI_CFG_MASTER (1<<2)
#define SPI_CFG_LSBF (1<<3)
#define SPI_CFG_CHPA (1<<4)
#define SPI_CFG_CPOL (1<<5)
#define SPI_CFG_LOOP (1<<7)
#define SPI_CFG_SPOL (1<<8)
#define SPI_DLY_PRE(n) (((n)&0x0f)<< 0)
#define SPI_DLY_POST(n) (((n)&0x0f)<< 4)
#define SPI_DLY_FRAME(n) (((n)&0x0f)<< 8)
#define SPI_DLY_TFER(n) (((n)&0x0f)<<12)
#define SPI_STAT_RXRDY (1<<0)
#define SPI_STAT_TXRDY (1<<1)
#define SPI_STAT_RXOV (1<<2)
#define SPI_STAT_TXUR (1<<3)
#define SPI_STAT_SSA (1<<4)
#define SPI_STAT_SSD (1<<5)
#define SPI_STAT_STALL (1<<6)
#define SPI_STAT_EOT (1<<7)
#define SPI_STAT_IDLE (1<<8)
#define SPI_TXCTRL_TXSSELN (1<<16)
#define SPI_TXCTRL_EOT (1<<20)
#define SPI_TXCTRL_EOF (1<<21)
#define SPI_TXCTRL_RXIGNORE (1<<22)
#define SPI_TXCTRL_FLEN(n) (((n)-1)<<24)
#define SPI_TXCTRL_FLEN_MASK (0x0f<<24)
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief SPI1 driver enable switch.
* @details If set to @p TRUE the support for device SPI0 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC8xx_SPI_USE_SPI0) || defined(__DOXYGEN__)
#define LPC8xx_SPI_USE_SPI0 TRUE
#endif
/**
* @brief SPI2 driver enable switch.
* @details If set to @p TRUE the support for device SPI1 is included.
* @note The default is @p TRUE.
*/
#if !defined(LPC8xx_SPI_USE_SPI1) || defined(__DOXYGEN__)
#define LPC8xx_SPI_USE_SPI1 FALSE
#endif
/**
* @brief SPI0 PCLK divider.
*/
#if !defined(LPC8xx_SPI_SPI0CLKDIV) || defined(__DOXYGEN__)
#define LPC8xx_SPI_SPI0CLKDIV 1
#endif
/**
* @brief SPI1 PCLK divider.
*/
#if !defined(LPC8xx_SPI_SPI1CLKDIV) || defined(__DOXYGEN__)
#define LPC8xx_SPI_SPI1CLKDIV 1
#endif
/**
* @brief SPI0 interrupt priority level setting.
*/
#if !defined(LPC8xx_SPI_SPI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_SPI_SPI0_IRQ_PRIORITY 1
#endif
/**
* @brief SPI1 interrupt priority level setting.
*/
#if !defined(LPC8xx_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC8xx_SPI_SPI1_IRQ_PRIORITY 1
#endif
/**
* @brief Overflow error hook.
* @details The default action is to stop the system.
*/
#if !defined(LPC8xx_SPI_ERROR_HOOK) || defined(__DOXYGEN__)
#define LPC8xx_SPI_ERROR_HOOK(spip) chSysHalt()
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (LPC8xx_SPI_SPI0CLKDIV < 1) || (LPC8xx_SPI_SPI0CLKDIV > 255)
#error "invalid LPC8xx_SPI_SSP0CLKDIV setting"
#endif
#if (LPC8xx_SPI_SPI1CLKDIV < 1) || (LPC8xx_SPI_SPI1CLKDIV > 255)
#error "invalid LPC8xx_SPI_SSP1CLKDIV setting"
#endif
#if !LPC8xx_SPI_USE_SPI0 && !LPC8xx_SPI_USE_SPI1
#error "SPI driver activated but no SPI peripheral assigned"
#endif
/**
* @brief SPI0 clock.
*/
#define LPC8xx_SPI_SPI0_PCLK \
(LPC8xx_SYSCLK / LPC8xx_SPI_SPI0CLKDIV)
/**
* @brief SPI1 clock.
*/
#define LPC8xx_SPI_SPI1_PCLK \
(LPC8xx_SYSCLK / LPC8xx_SPI_SPI1CLKDIV)
/*===========================================================================*/
/* 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 SPI CFG initialization data.
*/
uint16_t cfg;
/**
* @brief SPI DLY initialization data.
*/
uint16_t dly;
/**
* @brief SPI TXCTRL initialization data.
*/
uint32_t txctrl;
} 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 SPI registers block.
*/
LPC_SPI_TypeDef *spi;
/**
* @brief Number of words yet to be received.
*/
uint32_t rxcnt;
/**
* @brief Receive pointer or @p NULL.
*/
void *rxptr;
/**
* @brief Number of words yet to be transmitted.
*/
uint32_t txcnt;
/**
* @brief Transmit pointer or @p NULL.
*/
const void *txptr;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if LPC8xx_SPI_USE_SPI0 && !defined(__DOXYGEN__)
extern SPIDriver SPID1;
#endif
#if LPC8xx_SPI_USE_SPI1 && !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,62 @@
/******************************************************************************
* @file: system_LPC8xx.h
* @purpose: CMSIS Cortex-M0+ Device Peripheral Access Layer Header File
* for the NXP LPC8xx Device Series
* @version: V1.0
* @date: 16. Aug. 2012
*----------------------------------------------------------------------------
*
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M0+
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC8xx_H
#define __SYSTEM_LPC8xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC8xx_H */