Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
Revision 554:edd95c0879f8, committed 2015-06-01
- Comitter:
- mbed_official
- Date:
- Mon Jun 01 11:00:11 2015 +0100
- Parent:
- 553:063b9f2f393c
- Child:
- 555:f8b0f61305ee
- Commit message:
- Synchronized with git revision 7a1d25e3dfbe5bc1457774d4af3c73383a0ff81d
Full URL: https://github.com/mbedmicro/mbed/commit/7a1d25e3dfbe5bc1457774d4af3c73383a0ff81d/
Silicon Labs - Initial test framework pin definitions for EFM32 platforms
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/LPC24xx.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,972 @@
+/* mbed Microcontroller Library - LPC24xx CMSIS-like structs
+ * Copyright (C) 2009-2015 ARM Limited. All rights reserved.
+ *
+ * An LPC24xx header file, based on LPC23xx.h
+ */
+
+#ifndef __LPC24xx_H
+#define __LPC24xx_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ * ==========================================================================
+ * ---------- Interrupt Number Definition -----------------------------------
+ * ==========================================================================
+ */
+
+typedef enum IRQn
+{
+/****** LPC23xx Specific Interrupt Numbers *******************************************************/
+ WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */
+
+ TIMER0_IRQn = 4, /*!< Timer0 Interrupt */
+ TIMER1_IRQn = 5, /*!< Timer1 Interrupt */
+ UART0_IRQn = 6, /*!< UART0 Interrupt */
+ UART1_IRQn = 7, /*!< UART1 Interrupt */
+ PWM0_IRQn = 8, /*!< PWM0 Interrupt */
+ PWM1_IRQn = 8, /*!< PWM1 Interrupt */
+ I2C0_IRQn = 9, /*!< I2C0 Interrupt */
+ SPI_IRQn = 10, /*!< SPI Interrupt */
+ SSP0_IRQn = 10, /*!< SSP0 Interrupt */
+ SSP1_IRQn = 11, /*!< SSP1 Interrupt */
+ PLL0_IRQn = 12, /*!< PLL0 Lock (Main PLL) Interrupt */
+ RTC_IRQn = 13, /*!< Real Time Clock Interrupt */
+ EINT0_IRQn = 14, /*!< External Interrupt 0 Interrupt */
+ EINT1_IRQn = 15, /*!< External Interrupt 1 Interrupt */
+ EINT2_IRQn = 16, /*!< External Interrupt 2 Interrupt */
+ EINT3_IRQn = 17, /*!< External Interrupt 3 Interrupt */
+ ADC_IRQn = 18, /*!< A/D Converter Interrupt */
+ I2C1_IRQn = 19, /*!< I2C1 Interrupt */
+ BOD_IRQn = 20, /*!< Brown-Out Detect Interrupt */
+ ENET_IRQn = 21, /*!< Ethernet Interrupt */
+ USB_IRQn = 22, /*!< USB Interrupt */
+ CAN_IRQn = 23, /*!< CAN Interrupt */
+ SDMMC_IRQn = 24, /*!< SD/MMC Interrupt */
+ DMA_IRQn = 25, /*!< General Purpose DMA Interrupt */
+ TIMER2_IRQn = 26, /*!< Timer2 Interrupt */
+ TIMER3_IRQn = 27, /*!< Timer3 Interrupt */
+ UART2_IRQn = 28, /*!< UART2 Interrupt */
+ UART3_IRQn = 29, /*!< UART3 Interrupt */
+ I2C2_IRQn = 30, /*!< I2C2 Interrupt */
+ I2S_IRQn = 31, /*!< I2S Interrupt */
+} IRQn_Type;
+
+/*
+ * ==========================================================================
+ * ----------- Processor and Core Peripheral Section ------------------------
+ * ==========================================================================
+ */
+
+/* Configuration of the ARM7 Processor and Core Peripherals */
+#define __MPU_PRESENT 0 /*!< MPU present or not */
+#define __NVIC_PRIO_BITS 4 /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+
+
+#include <core_arm7.h>
+#include "system_LPC24xx.h" /* System Header */
+
+
+/******************************************************************************/
+/* Device Specific Peripheral registers structures */
+/******************************************************************************/
+#if defined ( __CC_ARM )
+ #pragma anon_unions
+#endif
+
+/*------------- Vector Interupt Controler (VIC) ------------------------------*/
+typedef struct
+{
+ __I uint32_t IRQStatus;
+ __I uint32_t FIQStatus;
+ __I uint32_t RawIntr;
+ __IO uint32_t IntSelect;
+ __IO uint32_t IntEnable;
+ __O uint32_t IntEnClr;
+ __IO uint32_t SoftInt;
+ __O uint32_t SoftIntClr;
+ __IO uint32_t Protection;
+ __IO uint32_t SWPriorityMask;
+ __IO uint32_t RESERVED0[54];
+ __IO uint32_t VectAddr[32];
+ __IO uint32_t RESERVED1[32];
+ __IO uint32_t VectPriority[32];
+ __IO uint32_t RESERVED2[800];
+ __IO uint32_t Address;
+} LPC_VIC_TypeDef;
+
+/*------------- System Control (SC) ------------------------------------------*/
+typedef struct
+{
+ __IO uint32_t MAMCR;
+ __IO uint32_t MAMTIM;
+ uint32_t RESERVED0[14];
+ __IO uint32_t MEMMAP;
+ uint32_t RESERVED1[15];
+ __IO uint32_t PLL0CON; /* Clocking and Power Control */
+ __IO uint32_t PLL0CFG;
+ __I uint32_t PLL0STAT;
+ __O uint32_t PLL0FEED;
+ uint32_t RESERVED2[12];
+ __IO uint32_t PCON;
+ __IO uint32_t PCONP;
+ uint32_t RESERVED3[15];
+ __IO uint32_t CCLKCFG;
+ __IO uint32_t USBCLKCFG;
+ __IO uint32_t CLKSRCSEL;
+ uint32_t RESERVED4[12];
+ __IO uint32_t EXTINT; /* External Interrupts */
+ __IO uint32_t INTWAKE;
+ __IO uint32_t EXTMODE;
+ __IO uint32_t EXTPOLAR;
+ uint32_t RESERVED6[12];
+ __IO uint32_t RSID; /* Reset */
+ __IO uint32_t CSPR;
+ __IO uint32_t AHBCFG1;
+ __IO uint32_t AHBCFG2;
+ uint32_t RESERVED7[4];
+ __IO uint32_t SCS; /* Syscon Miscellaneous Registers */
+ __IO uint32_t IRCTRIM; /* Clock Dividers */
+ __IO uint32_t PCLKSEL0;
+ __IO uint32_t PCLKSEL1;
+ uint32_t RESERVED8[4];
+ __IO uint32_t USBIntSt; /* USB Device/OTG Interrupt Register */
+ uint32_t RESERVED9;
+// __IO uint32_t CLKOUTCFG; /* Clock Output Configuration */
+ } LPC_SC_TypeDef;
+
+/*------------- Pin Connect Block (PINCON) -----------------------------------*/
+typedef struct
+{
+ __IO uint32_t PINSEL0;
+ __IO uint32_t PINSEL1;
+ __IO uint32_t PINSEL2;
+ __IO uint32_t PINSEL3;
+ __IO uint32_t PINSEL4;
+ __IO uint32_t PINSEL5;
+ __IO uint32_t PINSEL6;
+ __IO uint32_t PINSEL7;
+ __IO uint32_t PINSEL8;
+ __IO uint32_t PINSEL9;
+ __IO uint32_t PINSEL10;
+ uint32_t RESERVED0[5];
+ __IO uint32_t PINMODE0;
+ __IO uint32_t PINMODE1;
+ __IO uint32_t PINMODE2;
+ __IO uint32_t PINMODE3;
+ __IO uint32_t PINMODE4;
+ __IO uint32_t PINMODE5;
+ __IO uint32_t PINMODE6;
+ __IO uint32_t PINMODE7;
+ __IO uint32_t PINMODE8;
+ __IO uint32_t PINMODE9;
+ __IO uint32_t PINMODE_OD0;
+ __IO uint32_t PINMODE_OD1;
+ __IO uint32_t PINMODE_OD2;
+ __IO uint32_t PINMODE_OD3;
+ __IO uint32_t PINMODE_OD4;
+} LPC_PINCON_TypeDef;
+
+#define PCTIM0 1
+#define PCTIM1 2
+#define PCUART0 3
+#define PCUART1 4
+#define PCPWM1 6
+#define PCI2C0 7
+#define PCSPI 8
+#define PCRTC 9
+#define PCSSP1 10
+#define PCEMC 11
+#define PCADC 12
+#define PCAN1 13
+#define PCAN2 14
+#define PCI2C1 19
+#define PCSSP0 21
+#define PCTIM2 22
+#define PCTIM3 23
+#define PCUART2 24
+#define PCUART3 25
+#define PCI2C2 26
+#define PCI2S 27
+#define PCSDC 28
+#define PCGPDMA 29
+#define PCENET 30
+#define PCUSB 31
+
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/
+typedef struct
+{
+ __IO uint32_t FIODIR;
+ uint32_t RESERVED0[3];
+ __IO uint32_t FIOMASK;
+ __IO uint32_t FIOPIN;
+ __IO uint32_t FIOSET;
+ __O uint32_t FIOCLR;
+} LPC_GPIO_TypeDef;
+
+typedef struct
+{
+ __I uint32_t IntStatus;
+ __I uint32_t IO0IntStatR;
+ __I uint32_t IO0IntStatF;
+ __O uint32_t IO0IntClr;
+ __IO uint32_t IO0IntEnR;
+ __IO uint32_t IO0IntEnF;
+ uint32_t RESERVED0[3];
+ __I uint32_t IO2IntStatR;
+ __I uint32_t IO2IntStatF;
+ __O uint32_t IO2IntClr;
+ __IO uint32_t IO2IntEnR;
+ __IO uint32_t IO2IntEnF;
+} LPC_GPIOINT_TypeDef;
+
+/*------------- Timer (TIM) --------------------------------------------------*/
+typedef struct
+{
+ __IO uint32_t IR;
+ __IO uint32_t TCR;
+ __IO uint32_t TC;
+ __IO uint32_t PR;
+ __IO uint32_t PC;
+ __IO uint32_t MCR;
+ __IO uint32_t MR0;
+ __IO uint32_t MR1;
+ __IO uint32_t MR2;
+ __IO uint32_t MR3;
+ __IO uint32_t CCR;
+ __I uint32_t CR0;
+ __I uint32_t CR1;
+ uint32_t RESERVED0[2];
+ __IO uint32_t EMR;
+ uint32_t RESERVED1[12];
+ __IO uint32_t CTCR;
+} LPC_TIM_TypeDef;
+
+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/
+typedef struct
+{
+ __IO uint32_t IR;
+ __IO uint32_t TCR;
+ __IO uint32_t TC;
+ __IO uint32_t PR;
+ __IO uint32_t PC;
+ __IO uint32_t MCR;
+ __IO uint32_t MR0;
+ __IO uint32_t MR1;
+ __IO uint32_t MR2;
+ __IO uint32_t MR3;
+ __IO uint32_t CCR;
+ __I uint32_t CR0;
+ __I uint32_t CR1;
+ __I uint32_t CR2;
+ __I uint32_t CR3;
+ uint32_t RESERVED0;
+ __IO uint32_t MR4;
+ __IO uint32_t MR5;
+ __IO uint32_t MR6;
+ __IO uint32_t PCR;
+ __IO uint32_t LER;
+ uint32_t RESERVED1[7];
+ __IO uint32_t CTCR;
+} LPC_PWM_TypeDef;
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+typedef struct
+{
+ union {
+ __I uint8_t RBR;
+ __O uint8_t THR;
+ __IO uint8_t DLL;
+ uint32_t RESERVED0;
+ };
+ union {
+ __IO uint8_t DLM;
+ __IO uint32_t IER;
+ };
+ union {
+ __I uint32_t IIR;
+ __O uint8_t FCR;
+ };
+ __IO uint8_t LCR;
+ uint8_t RESERVED1[7];
+ __IO uint8_t LSR;
+ uint8_t RESERVED2[7];
+ __IO uint8_t SCR;
+ uint8_t RESERVED3[3];
+ __IO uint32_t ACR;
+ __IO uint8_t ICR;
+ uint8_t RESERVED4[3];
+ __IO uint8_t FDR;
+ uint8_t RESERVED5[7];
+ __IO uint8_t TER;
+ uint8_t RESERVED6[27];
+ __IO uint8_t RS485CTRL;
+ uint8_t RESERVED7[3];
+ __IO uint8_t ADRMATCH;
+} LPC_UART_TypeDef;
+
+typedef struct
+{
+ union {
+ __I uint8_t RBR;
+ __O uint8_t THR;
+ __IO uint8_t DLL;
+ uint32_t RESERVED0;
+ };
+ union {
+ __IO uint8_t DLM;
+ __IO uint32_t IER;
+ };
+ union {
+ __I uint32_t IIR;
+ __O uint8_t FCR;
+ };
+ __IO uint8_t LCR;
+ uint8_t RESERVED1[3];
+ __IO uint8_t MCR;
+ uint8_t RESERVED2[3];
+ __IO uint8_t LSR;
+ uint8_t RESERVED3[3];
+ __IO uint8_t MSR;
+ uint8_t RESERVED4[3];
+ __IO uint8_t SCR;
+ uint8_t RESERVED5[3];
+ __IO uint32_t ACR;
+ uint32_t RESERVED6;
+ __IO uint32_t FDR;
+ uint32_t RESERVED7;
+ __IO uint8_t TER;
+ uint8_t RESERVED8[27];
+ __IO uint8_t RS485CTRL;
+ uint8_t RESERVED9[3];
+ __IO uint8_t ADRMATCH;
+ uint8_t RESERVED10[3];
+ __IO uint8_t RS485DLY;
+} LPC_UART1_TypeDef;
+
+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/
+typedef struct
+{
+ __IO uint32_t SPCR;
+ __I uint32_t SPSR;
+ __IO uint32_t SPDR;
+ __IO uint32_t SPCCR;
+ uint32_t RESERVED0[3];
+ __IO uint32_t SPINT;
+} LPC_SPI_TypeDef;
+
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/
+typedef struct
+{
+ __IO uint32_t CR0;
+ __IO uint32_t CR1;
+ __IO uint32_t DR;
+ __I uint32_t SR;
+ __IO uint32_t CPSR;
+ __IO uint32_t IMSC;
+ __IO uint32_t RIS;
+ __IO uint32_t MIS;
+ __IO uint32_t ICR;
+ __IO uint32_t DMACR;
+} LPC_SSP_TypeDef;
+
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
+typedef struct
+{
+ __IO uint32_t I2CONSET;
+ __I uint32_t I2STAT;
+ __IO uint32_t I2DAT;
+ __IO uint32_t I2ADR0;
+ __IO uint32_t I2SCLH;
+ __IO uint32_t I2SCLL;
+ __O uint32_t I2CONCLR;
+ __IO uint32_t MMCTRL;
+ __IO uint32_t I2ADR1;
+ __IO uint32_t I2ADR2;
+ __IO uint32_t I2ADR3;
+ __I uint32_t I2DATA_BUFFER;
+ __IO uint32_t I2MASK0;
+ __IO uint32_t I2MASK1;
+ __IO uint32_t I2MASK2;
+ __IO uint32_t I2MASK3;
+} LPC_I2C_TypeDef;
+
+/*------------- Inter IC Sound (I2S) -----------------------------------------*/
+typedef struct
+{
+ __IO uint32_t I2SDAO;
+ __I uint32_t I2SDAI;
+ __O uint32_t I2STXFIFO;
+ __I uint32_t I2SRXFIFO;
+ __I uint32_t I2SSTATE;
+ __IO uint32_t I2SDMA1;
+ __IO uint32_t I2SDMA2;
+ __IO uint32_t I2SIRQ;
+ __IO uint32_t I2STXRATE;
+ __IO uint32_t I2SRXRATE;
+ __IO uint32_t I2STXBITRATE;
+ __IO uint32_t I2SRXBITRATE;
+ __IO uint32_t I2STXMODE;
+ __IO uint32_t I2SRXMODE;
+} LPC_I2S_TypeDef;
+
+/*------------- Real-Time Clock (RTC) ----------------------------------------*/
+typedef struct
+{
+ __IO uint8_t ILR;
+ uint8_t RESERVED0[3];
+ __IO uint8_t CTC;
+ uint8_t RESERVED1[3];
+ __IO uint8_t CCR;
+ uint8_t RESERVED2[3];
+ __IO uint8_t CIIR;
+ uint8_t RESERVED3[3];
+ __IO uint8_t AMR;
+ uint8_t RESERVED4[3];
+ __I uint32_t CTIME0;
+ __I uint32_t CTIME1;
+ __I uint32_t CTIME2;
+ __IO uint8_t SEC;
+ uint8_t RESERVED5[3];
+ __IO uint8_t MIN;
+ uint8_t RESERVED6[3];
+ __IO uint8_t HOUR;
+ uint8_t RESERVED7[3];
+ __IO uint8_t DOM;
+ uint8_t RESERVED8[3];
+ __IO uint8_t DOW;
+ uint8_t RESERVED9[3];
+ __IO uint16_t DOY;
+ uint16_t RESERVED10;
+ __IO uint8_t MONTH;
+ uint8_t RESERVED11[3];
+ __IO uint16_t YEAR;
+ uint16_t RESERVED12;
+ __IO uint32_t CALIBRATION;
+ __IO uint32_t GPREG0;
+ __IO uint32_t GPREG1;
+ __IO uint32_t GPREG2;
+ __IO uint32_t GPREG3;
+ __IO uint32_t GPREG4;
+ __IO uint8_t WAKEUPDIS;
+ uint8_t RESERVED13[3];
+ __IO uint8_t PWRCTRL;
+ uint8_t RESERVED14[3];
+ __IO uint8_t ALSEC;
+ uint8_t RESERVED15[3];
+ __IO uint8_t ALMIN;
+ uint8_t RESERVED16[3];
+ __IO uint8_t ALHOUR;
+ uint8_t RESERVED17[3];
+ __IO uint8_t ALDOM;
+ uint8_t RESERVED18[3];
+ __IO uint8_t ALDOW;
+ uint8_t RESERVED19[3];
+ __IO uint16_t ALDOY;
+ uint16_t RESERVED20;
+ __IO uint8_t ALMON;
+ uint8_t RESERVED21[3];
+ __IO uint16_t ALYEAR;
+ uint16_t RESERVED22;
+} LPC_RTC_TypeDef;
+
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/
+typedef struct
+{
+ __IO uint8_t WDMOD;
+ uint8_t RESERVED0[3];
+ __IO uint32_t WDTC;
+ __O uint8_t WDFEED;
+ uint8_t RESERVED1[3];
+ __I uint32_t WDTV;
+ __IO uint32_t WDCLKSEL;
+} LPC_WDT_TypeDef;
+
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
+typedef struct
+{
+ __IO uint32_t ADCR;
+ __IO uint32_t ADGDR;
+ uint32_t RESERVED0;
+ __IO uint32_t ADINTEN;
+ __I uint32_t ADDR0;
+ __I uint32_t ADDR1;
+ __I uint32_t ADDR2;
+ __I uint32_t ADDR3;
+ __I uint32_t ADDR4;
+ __I uint32_t ADDR5;
+ __I uint32_t ADDR6;
+ __I uint32_t ADDR7;
+ __I uint32_t ADSTAT;
+ __IO uint32_t ADTRM;
+} LPC_ADC_TypeDef;
+
+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/
+typedef struct
+{
+ __IO uint32_t DACR;
+ __IO uint32_t DACCTRL;
+ __IO uint16_t DACCNTVAL;
+} LPC_DAC_TypeDef;
+
+/*------------- Multimedia Card Interface (MCI) ------------------------------*/
+typedef struct
+{
+ __IO uint32_t MCIPower; /* Power control */
+ __IO uint32_t MCIClock; /* Clock control */
+ __IO uint32_t MCIArgument;
+ __IO uint32_t MMCCommand;
+ __I uint32_t MCIRespCmd;
+ __I uint32_t MCIResponse0;
+ __I uint32_t MCIResponse1;
+ __I uint32_t MCIResponse2;
+ __I uint32_t MCIResponse3;
+ __IO uint32_t MCIDataTimer;
+ __IO uint32_t MCIDataLength;
+ __IO uint32_t MCIDataCtrl;
+ __I uint32_t MCIDataCnt;
+ __I uint32_t MCIStatus;
+ __O uint32_t MCIClear;
+ __IO uint32_t MCIMask0;
+ uint32_t RESERVED1[2];
+ __I uint32_t MCIFifoCnt;
+ uint32_t RESERVED2[13];
+ __IO uint32_t MCIFIFO[16];
+} LPC_MCI_TypeDef;
+
+/*------------- Controller Area Network (CAN) --------------------------------*/
+typedef struct
+{
+ __IO uint32_t mask[512]; /* ID Masks */
+} LPC_CANAF_RAM_TypeDef;
+
+typedef struct /* Acceptance Filter Registers */
+{
+ __IO uint32_t AFMR;
+ __IO uint32_t SFF_sa;
+ __IO uint32_t SFF_GRP_sa;
+ __IO uint32_t EFF_sa;
+ __IO uint32_t EFF_GRP_sa;
+ __IO uint32_t ENDofTable;
+ __I uint32_t LUTerrAd;
+ __I uint32_t LUTerr;
+ __IO uint32_t FCANIE;
+ __IO uint32_t FCANIC0;
+ __IO uint32_t FCANIC1;
+} LPC_CANAF_TypeDef;
+
+typedef struct /* Central Registers */
+{
+ __I uint32_t CANTxSR;
+ __I uint32_t CANRxSR;
+ __I uint32_t CANMSR;
+} LPC_CANCR_TypeDef;
+
+typedef struct /* Controller Registers */
+{
+ __IO uint32_t MOD;
+ __O uint32_t CMR;
+ __IO uint32_t GSR;
+ __I uint32_t ICR;
+ __IO uint32_t IER;
+ __IO uint32_t BTR;
+ __IO uint32_t EWL;
+ __I uint32_t SR;
+ __IO uint32_t RFS;
+ __IO uint32_t RID;
+ __IO uint32_t RDA;
+ __IO uint32_t RDB;
+ __IO uint32_t TFI1;
+ __IO uint32_t TID1;
+ __IO uint32_t TDA1;
+ __IO uint32_t TDB1;
+ __IO uint32_t TFI2;
+ __IO uint32_t TID2;
+ __IO uint32_t TDA2;
+ __IO uint32_t TDB2;
+ __IO uint32_t TFI3;
+ __IO uint32_t TID3;
+ __IO uint32_t TDA3;
+ __IO uint32_t TDB3;
+} LPC_CAN_TypeDef;
+
+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/
+typedef struct /* Common Registers */
+{
+ __I uint32_t DMACIntStat;
+ __I uint32_t DMACIntTCStat;
+ __O uint32_t DMACIntTCClear;
+ __I uint32_t DMACIntErrStat;
+ __O uint32_t DMACIntErrClr;
+ __I uint32_t DMACRawIntTCStat;
+ __I uint32_t DMACRawIntErrStat;
+ __I uint32_t DMACEnbldChns;
+ __IO uint32_t DMACSoftBReq;
+ __IO uint32_t DMACSoftSReq;
+ __IO uint32_t DMACSoftLBReq;
+ __IO uint32_t DMACSoftLSReq;
+ __IO uint32_t DMACConfig;
+ __IO uint32_t DMACSync;
+} LPC_GPDMA_TypeDef;
+
+typedef struct /* Channel Registers */
+{
+ __IO uint32_t DMACCSrcAddr;
+ __IO uint32_t DMACCDestAddr;
+ __IO uint32_t DMACCLLI;
+ __IO uint32_t DMACCControl;
+ __IO uint32_t DMACCConfig;
+} LPC_GPDMACH_TypeDef;
+
+/*------------- Universal Serial Bus (USB) -----------------------------------*/
+typedef struct
+{
+ __I uint32_t HcRevision; /* USB Host Registers */
+ __IO uint32_t HcControl;
+ __IO uint32_t HcCommandStatus;
+ __IO uint32_t HcInterruptStatus;
+ __IO uint32_t HcInterruptEnable;
+ __IO uint32_t HcInterruptDisable;
+ __IO uint32_t HcHCCA;
+ __I uint32_t HcPeriodCurrentED;
+ __IO uint32_t HcControlHeadED;
+ __IO uint32_t HcControlCurrentED;
+ __IO uint32_t HcBulkHeadED;
+ __IO uint32_t HcBulkCurrentED;
+ __I uint32_t HcDoneHead;
+ __IO uint32_t HcFmInterval;
+ __I uint32_t HcFmRemaining;
+ __I uint32_t HcFmNumber;
+ __IO uint32_t HcPeriodicStart;
+ __IO uint32_t HcLSTreshold;
+ __IO uint32_t HcRhDescriptorA;
+ __IO uint32_t HcRhDescriptorB;
+ __IO uint32_t HcRhStatus;
+ __IO uint32_t HcRhPortStatus1;
+ __IO uint32_t HcRhPortStatus2;
+ uint32_t RESERVED0[40];
+ __I uint32_t Module_ID;
+
+ __I uint32_t OTGIntSt; /* USB On-The-Go Registers */
+ __IO uint32_t OTGIntEn;
+ __O uint32_t OTGIntSet;
+ __O uint32_t OTGIntClr;
+ __IO uint32_t OTGStCtrl;
+ __IO uint32_t OTGTmr;
+ uint32_t RESERVED1[58];
+
+ __I uint32_t USBDevIntSt; /* USB Device Interrupt Registers */
+ __IO uint32_t USBDevIntEn;
+ __O uint32_t USBDevIntClr;
+ __O uint32_t USBDevIntSet;
+
+ __O uint32_t USBCmdCode; /* USB Device SIE Command Registers */
+ __I uint32_t USBCmdData;
+
+ __I uint32_t USBRxData; /* USB Device Transfer Registers */
+ __O uint32_t USBTxData;
+ __I uint32_t USBRxPLen;
+ __O uint32_t USBTxPLen;
+ __IO uint32_t USBCtrl;
+ __O uint32_t USBDevIntPri;
+
+ __I uint32_t USBEpIntSt; /* USB Device Endpoint Interrupt Regs */
+ __IO uint32_t USBEpIntEn;
+ __O uint32_t USBEpIntClr;
+ __O uint32_t USBEpIntSet;
+ __O uint32_t USBEpIntPri;
+
+ __IO uint32_t USBReEp; /* USB Device Endpoint Realization Reg*/
+ __O uint32_t USBEpInd;
+ __IO uint32_t USBMaxPSize;
+
+ __I uint32_t USBDMARSt; /* USB Device DMA Registers */
+ __O uint32_t USBDMARClr;
+ __O uint32_t USBDMARSet;
+ uint32_t RESERVED2[9];
+ __IO uint32_t USBUDCAH;
+ __I uint32_t USBEpDMASt;
+ __O uint32_t USBEpDMAEn;
+ __O uint32_t USBEpDMADis;
+ __I uint32_t USBDMAIntSt;
+ __IO uint32_t USBDMAIntEn;
+ uint32_t RESERVED3[2];
+ __I uint32_t USBEoTIntSt;
+ __O uint32_t USBEoTIntClr;
+ __O uint32_t USBEoTIntSet;
+ __I uint32_t USBNDDRIntSt;
+ __O uint32_t USBNDDRIntClr;
+ __O uint32_t USBNDDRIntSet;
+ __I uint32_t USBSysErrIntSt;
+ __O uint32_t USBSysErrIntClr;
+ __O uint32_t USBSysErrIntSet;
+ uint32_t RESERVED4[15];
+
+ __I uint32_t I2C_RX; /* USB OTG I2C Registers */
+ __O uint32_t I2C_WO;
+ __I uint32_t I2C_STS;
+ __IO uint32_t I2C_CTL;
+ __IO uint32_t I2C_CLKHI;
+ __O uint32_t I2C_CLKLO;
+ uint32_t RESERVED5[823];
+
+ union {
+ __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */
+ __IO uint32_t OTGClkCtrl;
+ };
+ union {
+ __I uint32_t USBClkSt;
+ __I uint32_t OTGClkSt;
+ };
+} LPC_USB_TypeDef;
+
+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/
+typedef struct
+{
+ __IO uint32_t MAC1; /* MAC Registers */
+ __IO uint32_t MAC2;
+ __IO uint32_t IPGT;
+ __IO uint32_t IPGR;
+ __IO uint32_t CLRT;
+ __IO uint32_t MAXF;
+ __IO uint32_t SUPP;
+ __IO uint32_t TEST;
+ __IO uint32_t MCFG;
+ __IO uint32_t MCMD;
+ __IO uint32_t MADR;
+ __O uint32_t MWTD;
+ __I uint32_t MRDD;
+ __I uint32_t MIND;
+ uint32_t RESERVED0[2];
+ __IO uint32_t SA0;
+ __IO uint32_t SA1;
+ __IO uint32_t SA2;
+ uint32_t RESERVED1[45];
+ __IO uint32_t Command; /* Control Registers */
+ __I uint32_t Status;
+ __IO uint32_t RxDescriptor;
+ __IO uint32_t RxStatus;
+ __IO uint32_t RxDescriptorNumber;
+ __I uint32_t RxProduceIndex;
+ __IO uint32_t RxConsumeIndex;
+ __IO uint32_t TxDescriptor;
+ __IO uint32_t TxStatus;
+ __IO uint32_t TxDescriptorNumber;
+ __IO uint32_t TxProduceIndex;
+ __I uint32_t TxConsumeIndex;
+ uint32_t RESERVED2[10];
+ __I uint32_t TSV0;
+ __I uint32_t TSV1;
+ __I uint32_t RSV;
+ uint32_t RESERVED3[3];
+ __IO uint32_t FlowControlCounter;
+ __I uint32_t FlowControlStatus;
+ uint32_t RESERVED4[34];
+ __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */
+ __IO uint32_t RxFilterWoLStatus;
+ __IO uint32_t RxFilterWoLClear;
+ uint32_t RESERVED5;
+ __IO uint32_t HashFilterL;
+ __IO uint32_t HashFilterH;
+ uint32_t RESERVED6[882];
+ __I uint32_t IntStatus; /* Module Control Registers */
+ __IO uint32_t IntEnable;
+ __O uint32_t IntClear;
+ __O uint32_t IntSet;
+ uint32_t RESERVED7;
+ __IO uint32_t PowerDown;
+ uint32_t RESERVED8;
+ __IO uint32_t Module_ID;
+} LPC_EMAC_TypeDef;
+
+/*-------------------- External Memory Controller (EMC) ----------------------*/
+typedef struct
+{
+ __IO uint32_t EMCControl;
+ __I uint32_t EMCStatus;
+ __IO uint32_t EMCConfig;
+ uint32_t RESERVED1[5];
+ __IO uint32_t EMCDynamicControl;
+ __IO uint32_t EMCDynamicRefresh;
+ __IO uint32_t EMCDynamicReadConfig;
+ uint32_t RESERVED2;
+ __IO uint32_t EMCDynamicRP;
+ __IO uint32_t EMCDynamicRAS;
+ __IO uint32_t EMCDynamicSREX;
+ __IO uint32_t EMCDynamicAPR;
+ __IO uint32_t EMCDynamicDAL;
+ __IO uint32_t EMCDynamicWR;
+ __IO uint32_t EMCDynamicRC;
+ __IO uint32_t EMCDynamicRFC;
+ __IO uint32_t EMCDynamicXSR;
+ __IO uint32_t EMCDynamicRRD;
+ __IO uint32_t EMCDynamicMRD;
+ uint32_t RESERVED3[9];
+ __IO uint32_t EMCStaticExtendedWait;
+ uint32_t RESERVED4[31];
+ __IO uint32_t EMCDynamicConfig0;
+ __IO uint32_t EMCDynamicRasCas0;
+ uint32_t RESERVED5[6];
+ __IO uint32_t EMCDynamicConfig1;
+ __IO uint32_t EMCDynamicRasCas1;
+ uint32_t RESERVED6[6];
+ __IO uint32_t EMCDynamicConfic2;
+ __IO uint32_t EMCDynamicRasCas2;
+ uint32_t RESERVED7[6];
+ __IO uint32_t EMCDynamicConfig3;
+ __IO uint32_t EMCDynamicRasCas3;
+ uint32_t RESERVED8[38];
+ __IO uint32_t EMCStaticConfig0;
+ __IO uint32_t EMCStaticWaitWen0;
+ __IO uint32_t EMCStaticWaitOen0;
+ __IO uint32_t EMCStaticWaitRd0;
+ __IO uint32_t EMCStaticWaitPage0;
+ __IO uint32_t EMCStaticWaitWr0;
+ __IO uint32_t EMCStaticWaitTurn0;
+ uint32_t RESERVED9;
+ __IO uint32_t EMCStaticConfig1;
+ __IO uint32_t EMCStaticWaitWen1;
+ __IO uint32_t EMCStaticWaitOen1;
+ __IO uint32_t EMCStaticWaitRd1;
+ __IO uint32_t EMCStaticWaitPage1;
+ __IO uint32_t EMCStaticWaitWr1;
+ __IO uint32_t EMCStaticWaitTurn1;
+ uint32_t RESERVED10;
+ __IO uint32_t EMCStaticConfig2;
+ __IO uint32_t EMCStaticWaitWen2;
+ __IO uint32_t EMCStaticWaitOen2;
+ __IO uint32_t EMCStaticWaitRd2;
+ __IO uint32_t EMCStaticWaitPage2;
+ __IO uint32_t EMCStaticWaitWr2;
+ __IO uint32_t EMCStaticWaitTurn2;
+ uint32_t RESERVED11;
+ __IO uint32_t EMCStaticConfig3;
+ __IO uint32_t EMCStaticWaitWen3;
+ __IO uint32_t EMCStaticWaitOen3;
+ __IO uint32_t EMCStaticWaitRd3;
+ __IO uint32_t EMCStaticWaitPage3;
+ __IO uint32_t EMCStaticWaitWr3;
+ __IO uint32_t EMCStaticWaitTurn3;
+} LPC_EMC_TypeDef;
+#if defined ( __CC_ARM )
+ #pragma no_anon_unions
+#endif
+
+/******************************************************************************/
+/* Peripheral memory map */
+/******************************************************************************/
+/* Base addresses */
+
+/* AHB Peripheral # 0 */
+
+/*
+#define FLASH_BASE (0x00000000UL)
+#define RAM_BASE (0x10000000UL)
+#define GPIO_BASE (0x2009C000UL)
+#define APB0_BASE (0x40000000UL)
+#define APB1_BASE (0x40080000UL)
+#define AHB_BASE (0x50000000UL)
+#define CM3_BASE (0xE0000000UL)
+*/
+
+// TODO - #define VIC_BASE_ADDR 0xFFFFF000
+
+#define LPC_WDT_BASE (0xE0000000)
+#define LPC_TIM0_BASE (0xE0004000)
+#define LPC_TIM1_BASE (0xE0008000)
+#define LPC_UART0_BASE (0xE000C000)
+#define LPC_UART1_BASE (0xE0010000)
+#define LPC_PWM1_BASE (0xE0018000)
+#define LPC_I2C0_BASE (0xE001C000)
+#define LPC_SPI_BASE (0xE0020000)
+#define LPC_RTC_BASE (0xE0024000)
+#define LPC_GPIOINT_BASE (0xE0028080)
+#define LPC_PINCON_BASE (0xE002C000)
+#define LPC_SSP1_BASE (0xE0030000)
+#define LPC_ADC_BASE (0xE0034000)
+#define LPC_CANAF_RAM_BASE (0xE0038000)
+#define LPC_CANAF_BASE (0xE003C000)
+#define LPC_CANCR_BASE (0xE0040000)
+#define LPC_CAN1_BASE (0xE0044000)
+#define LPC_CAN2_BASE (0xE0048000)
+#define LPC_I2C1_BASE (0xE005C000)
+#define LPC_SSP0_BASE (0xE0068000)
+#define LPC_DAC_BASE (0xE006C000)
+#define LPC_TIM2_BASE (0xE0070000)
+#define LPC_TIM3_BASE (0xE0074000)
+#define LPC_UART2_BASE (0xE0078000)
+#define LPC_UART3_BASE (0xE007C000)
+#define LPC_I2C2_BASE (0xE0080000)
+#define LPC_I2S_BASE (0xE0088000)
+#define LPC_MCI_BASE (0xE008C000)
+#define LPC_SC_BASE (0xE01FC000)
+#define LPC_EMAC_BASE (0xFFE00000)
+#define LPC_GPDMA_BASE (0xFFE04000)
+#define LPC_GPDMACH0_BASE (0xFFE04100)
+#define LPC_GPDMACH1_BASE (0xFFE04120)
+#define LPC_EMC_BASE (0xFFE08000)
+#define LPC_USB_BASE (0xFFE0C000)
+#define LPC_VIC_BASE (0xFFFFF000)
+
+/* GPIOs */
+#define LPC_GPIO0_BASE (0x3FFFC000)
+#define LPC_GPIO1_BASE (0x3FFFC020)
+#define LPC_GPIO2_BASE (0x3FFFC040)
+#define LPC_GPIO3_BASE (0x3FFFC060)
+#define LPC_GPIO4_BASE (0x3FFFC080)
+
+
+/******************************************************************************/
+/* Peripheral declaration */
+/******************************************************************************/
+#define LPC_SC (( LPC_SC_TypeDef *) LPC_SC_BASE)
+#define LPC_GPIO0 (( LPC_GPIO_TypeDef *) LPC_GPIO0_BASE)
+#define LPC_GPIO1 (( LPC_GPIO_TypeDef *) LPC_GPIO1_BASE)
+#define LPC_GPIO2 (( LPC_GPIO_TypeDef *) LPC_GPIO2_BASE)
+#define LPC_GPIO3 (( LPC_GPIO_TypeDef *) LPC_GPIO3_BASE)
+#define LPC_GPIO4 (( LPC_GPIO_TypeDef *) LPC_GPIO4_BASE)
+#define LPC_WDT (( LPC_WDT_TypeDef *) LPC_WDT_BASE)
+#define LPC_TIM0 (( LPC_TIM_TypeDef *) LPC_TIM0_BASE)
+#define LPC_TIM1 (( LPC_TIM_TypeDef *) LPC_TIM1_BASE)
+#define LPC_TIM2 (( LPC_TIM_TypeDef *) LPC_TIM2_BASE)
+#define LPC_TIM3 (( LPC_TIM_TypeDef *) LPC_TIM3_BASE)
+#define LPC_UART0 (( LPC_UART_TypeDef *) LPC_UART0_BASE)
+#define LPC_UART1 (( LPC_UART1_TypeDef *) LPC_UART1_BASE)
+#define LPC_UART2 (( LPC_UART_TypeDef *) LPC_UART2_BASE)
+#define LPC_UART3 (( LPC_UART_TypeDef *) LPC_UART3_BASE)
+#define LPC_PWM1 (( LPC_PWM_TypeDef *) LPC_PWM1_BASE)
+#define LPC_I2C0 (( LPC_I2C_TypeDef *) LPC_I2C0_BASE)
+#define LPC_I2C1 (( LPC_I2C_TypeDef *) LPC_I2C1_BASE)
+#define LPC_I2C2 (( LPC_I2C_TypeDef *) LPC_I2C2_BASE)
+#define LPC_I2S (( LPC_I2S_TypeDef *) LPC_I2S_BASE)
+#define LPC_SPI (( LPC_SPI_TypeDef *) LPC_SPI_BASE)
+#define LPC_RTC (( LPC_RTC_TypeDef *) LPC_RTC_BASE)
+#define LPC_GPIOINT (( LPC_GPIOINT_TypeDef *) LPC_GPIOINT_BASE)
+#define LPC_PINCON (( LPC_PINCON_TypeDef *) LPC_PINCON_BASE)
+#define LPC_SSP0 (( LPC_SSP_TypeDef *) LPC_SSP0_BASE)
+#define LPC_SSP1 (( LPC_SSP_TypeDef *) LPC_SSP1_BASE)
+#define LPC_ADC (( LPC_ADC_TypeDef *) LPC_ADC_BASE)
+#define LPC_DAC (( LPC_DAC_TypeDef *) LPC_DAC_BASE)
+#define LPC_CANAF_RAM ((LPC_CANAF_RAM_TypeDef *) LPC_CANAF_RAM_BASE)
+#define LPC_CANAF (( LPC_CANAF_TypeDef *) LPC_CANAF_BASE)
+#define LPC_CANCR (( LPC_CANCR_TypeDef *) LPC_CANCR_BASE)
+#define LPC_CAN1 (( LPC_CAN_TypeDef *) LPC_CAN1_BASE)
+#define LPC_CAN2 (( LPC_CAN_TypeDef *) LPC_CAN2_BASE)
+#define LPC_MCI (( LPC_MCI_TypeDef *) LPC_MCI_BASE)
+#define LPC_EMAC (( LPC_EMAC_TypeDef *) LPC_EMAC_BASE)
+#define LPC_GPDMA (( LPC_GPDMA_TypeDef *) LPC_GPDMA_BASE)
+#define LPC_GPDMACH0 (( LPC_GPDMACH_TypeDef *) LPC_GPDMACH0_BASE)
+#define LPC_GPDMACH1 (( LPC_GPDMACH_TypeDef *) LPC_GPDMACH1_BASE)
+#define LPC_USB (( LPC_USB_TypeDef *) LPC_USB_BASE)
+#define LPC_VIC (( LPC_VIC_TypeDef *) LPC_VIC_BASE)
+#define LPC_EMC (( LPC_EMC_TypeDef *) LPC_EMC_BASE)
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // __LPC24xx_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/TOOLCHAIN_GCC_ARM/LPC2460.ld Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,210 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(vectors)
+
+/* Memory Definitions: */
+MEMORY
+{
+ Flash (rx) : ORIGIN = 0xA0001000, LENGTH = 512k
+ Ram (rwx) : ORIGIN = 0x40000040, LENGTH = 64k - 0x40
+ UsbRam (rw) : ORIGIN = 0x7FD00000, LENGTH = 8k
+ EthRam (rw) : ORIGIN = 0x7FE00000, LENGTH = 16k
+ CanRam (rw) : ORIGIN = 0xE0038000, LENGTH = 2k
+ BatRam (rw) : ORIGIN = 0xE0084000, LENGTH = 2k
+}
+
+/* Stack sizes: */
+UND_Stack_Size = 64;
+SVC_Stack_Size = 64;
+ABT_Stack_Size = 64;
+FIQ_Stack_Size = 64;
+IRQ_Stack_Size = 64;
+User_Stack_Size = 4096;
+Stack_Size_Total = UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size + User_Stack_Size;
+
+/* Stack tops for each mode: */
+__und_stack_top__ = __stacks_top__;
+__abt_stack_top__ = __und_stack_top__ - UND_Stack_Size ;
+__fiq_stack_top__ = __abt_stack_top__ - ABT_Stack_Size ;
+__irq_stack_top__ = __fiq_stack_top__ - FIQ_Stack_Size ;
+__svc_stack_top__ = __irq_stack_top__ - IRQ_Stack_Size ;
+__usr_stack_top__ = __svc_stack_top__ - User_Stack_Size ;
+
+/* C-accessible symbols for memory address ranges: */
+__FLASH_segment_start__ = ORIGIN( Flash );
+__FLASH_segment_end__ = ORIGIN( Flash ) + LENGTH( Flash );
+__SRAM_segment_start__ = ORIGIN( Ram );
+__SRAM_segment_end__ = ORIGIN( Ram ) + LENGTH( Ram );
+
+/* Stacks (full descending) at top of RAM, grows downward:
+ *
+ * __stack_min__ is used by the malloc implementation to ensure heap never collides
+ * with stack (assuming stack never grows beyond Stack_Size_Total in length) */
+__stacks_top__ = __SRAM_segment_end__;
+__stacks_min__ = __SRAM_segment_end__ - Stack_Size_Total;
+
+SECTIONS
+{
+ /* first section is .text which is used for code */
+ __text_start__ = . ;
+ .text : {
+ __privileged_code_start__ = . ;
+ KEEP( *( .vectors ) )
+ *( .privileged_code )
+
+ __privileged_code_end__ = .;
+
+ *( .text .text.* .gnu.linkonce.t.* )
+ *( .plt )
+ *( .gnu.warning )
+ *( .glue_7t ) *( .glue_7 ) *( .vfp11_veneer )
+
+ *( .rodata .rodata.* .gnu.linkonce.r.* )
+
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ . = ALIGN( 4 ) ;
+ KEEP( *( .init ) )
+ . = ALIGN( 4 ) ;
+ __preinit_array_start = . ;
+ KEEP( *( .preinit_array ) )
+ __preinit_array_end = . ;
+ . = ALIGN( 4 ) ;
+ __init_array_start = . ;
+ KEEP( *( SORT( .init_array.* ) ) )
+ KEEP( *( .init_array ) )
+ __init_array_end = . ;
+
+ . = ALIGN( 4 ) ;
+ KEEP( *crtbegin.o( .ctors ) )
+ KEEP( *( EXCLUDE_FILE( *crtend.o ) .ctors ) )
+ KEEP( *( SORT( .ctors.* ) ) )
+ KEEP( *crtend.o( .ctors ) )
+
+ . = ALIGN( 4 ) ;
+ KEEP( *( .fini ) )
+ . = ALIGN( 4 ) ;
+ __fini_array_start = . ;
+ KEEP( *( .fini_array ) )
+ KEEP( *( SORT( .fini_array.* ) ) )
+ __fini_array_end = . ;
+
+ KEEP( *crtbegin.o( .dtors ) )
+ KEEP( *( EXCLUDE_FILE( *crtend.o ) .dtors ) )
+ KEEP( *( SORT( .dtors.* ) ) )
+ KEEP( *crtend.o( .dtors ) )
+
+ } >Flash
+
+ __exidx_start = . ;
+ .ARM.exidx : {
+ *( .ARM.exidx* .gnu.linkonce.armexidx.* )
+ } >Flash
+ __exidx_end = . ;
+
+ .text.align : { . = ALIGN( 8 ) ; } >Flash /* Alignment schenanigans */
+ __text_end__ = . ;
+
+ /* .bss section -- used for uninitialized data */
+ /* Located at the start of RAM */
+ .bss (NOLOAD) : {
+ __bss_start__ = . ;
+ *crt0.o( .ram_vectors )
+
+ __user_bss_start__ = . ;
+ *( .user_bss )
+ __user_bss_end__ = . ;
+
+ *( .shbss )
+ *( .bss .bss.* .gnu.linkonce.b.* )
+ *( COMMON )
+ *( .ram.b )
+ . = ALIGN( 8 ) ;
+
+ __bss_end__ = . ;
+ } >Ram AT>Flash
+
+ /* .data section -- used for initialized data */
+ .data : {
+ __data_start__ = . ;
+ KEEP( *( .jcr ) )
+ *( .got.plt ) *( .got )
+ *( .shdata )
+ *( .data .data.* .gnu.linkonce.d.* )
+ *( .ram )
+ . = ALIGN( 8 ) ;
+ __data_end__ = . ;
+ } >Ram AT>Flash
+
+ __data_init_start__ = LOADADDR( .data ) ;
+
+ /* Heap starts here and grows up in memory */
+ . = ALIGN( 8 ) ;
+ __heap_start__ = . ;
+ end = . ;
+ __end__ = . ;
+
+ .stab 0 (NOLOAD) : { *(.stab) }
+ .stabstr 0 (NOLOAD) : { *(.stabstr) }
+ /* DWARF debug sections. */
+ /* Symbols in the DWARF debugging sections are relative to the */
+ /* beginning of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+
+ .note.gnu.arm.ident 0 : { KEEP( *( .note.gnu.arm.ident ) ) }
+ .ARM.attributes 0 : {
+ KEEP( *( .ARM.attributes ) )
+ KEEP( *( .gnu.attributes ) )
+ }
+ /DISCARD/ : { *( .note.GNU-stack ) }
+
+ /* C data can be defined as being in special purpose RAMs using
+ * __attribute__ ((section ("ethram"))) for example. */
+ .usbram (NOLOAD):
+ {
+ *( .usbram )
+ *( .usbram.* )
+ } > UsbRam
+ .ethram (NOLOAD):
+ {
+ *( .ethram )
+ *( .ethram.* )
+ } > EthRam
+ .canram (NOLOAD):
+ {
+ *( .canram )
+ *( .canram.* )
+ } > CanRam
+ .batram (NOLOAD):
+ {
+ *( .batram )
+ *( .batram.* )
+ } > BatRam
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/TOOLCHAIN_GCC_ARM/vector_functions.s Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,195 @@
+/* .include "vector_defns.h" */
+
+
+
+.section .privileged_code, "ax"
+.arm
+
+
+.weak __mbed_fiq
+.weak __mbed_undef
+.weak __mbed_prefetch_abort
+.weak __mbed_data_abort
+.weak __mbed_irq
+.weak __mbed_swi
+.weak __mbed_dcc_irq
+.weak __mbed_reset
+.global __mbed_init_realmonitor
+.weak SVC_Handler
+.weak IRQ_Handler
+/* .global __mbed_init */
+
+
+
+
+__mbed_fiq:
+ B __mbed_fiq
+__mbed_undef:
+ LDR PC, =0x7fffffa0
+__mbed_prefetch_abort:
+ LDR PC, =0x7fffffb0
+__mbed_data_abort:
+ LDR PC, =0x7fffffc0
+__mbed_irq:
+/*
+ If RTOS is enabled then goto RTOS IRQ handler
+*/
+ PUSH {R0}
+ LDR R0, =IRQ_Handler
+ CMP R0, #0
+ POP {R0}
+ BNE IRQ_Handler
+/*
+ else use CMSIS IRQ handler
+*/
+ MSR CPSR_c, #0x1F|0x80|0x40
+
+ STMDB sp!, {r0-r3,r12,lr}
+
+ MOV r0, #0xFFFFFF00
+ LDR r0, [r0]
+
+ MOV lr, pc
+ BX r0
+
+ MOV r0, #0xFFFFFF00
+ STR r0, [r0]
+
+ LDMFD sp!,{r0-r3,r12,lr}
+
+ MSR CPSR_c, #0x12|0x80|0x40
+
+ SUBS pc, lr, #4
+
+__mbed_swi:
+/*
+ If RTOS is enabled then goto RTOS SVC handler
+*/
+ PUSH {R0}
+ LDR R0, =SVC_Handler
+ CMP R0, #0
+ POP {R0}
+ BNE SVC_Handler
+/*
+ else use CMSIS SVC handler
+*/
+ STMFD sp!, {a4, r4, ip, lr}
+
+ LDR r4, =0x40000040
+
+ LDR a4, =0x00940000
+ LDR PC, =0x7ffff820
+
+__mbed_dcc_irq:
+ LDMFD sp!,{r0-r3,r12,lr}
+
+ MSR CPSR_c, #0x12|0x80|0x40
+
+ SUB lr, lr, #4
+ STMFD sp!, {ip,lr}
+
+ LDR LR, =0xfffff000
+ STR LR, [LR, #0xf00]
+
+ LDR PC, =0x7fffffe0
+/*
+ __mbed_reset is called after reset
+ we setup the stacks and realmonitor, then call Reset_Handler like on M3
+*/
+
+.section .text, "ax"
+.arm
+.global Reset_handler
+Reset_Handler:
+ .extern __libc_init_array
+ .extern SystemInit
+ .weak software_init_hook
+ LDR R0, =SystemInit
+ MOV LR, PC
+ BX R0
+
+/* if (software_init_hook) // give control to the RTOS
+ software_init_hook(); // this will also call __libc_init_array
+*/
+ LDR R0, =software_init_hook
+ CMP R0, #0
+ BEQ nortos
+ ORR R0,R0,#1 /* set thumb address */
+ BX R0
+/* else */
+nortos:
+ LDR R0, =__libc_init_array
+ MOV LR, PC
+ BX R0
+
+ MSR CPSR_c, #0x1F /* enable irq */
+
+ LDR R0, =main
+ BX R0
+
+__mbed_reset:
+ LDR R0, =( __SRAM_segment_end__ )
+
+ MSR CPSR_c, #0x1B|0x80|0x40
+ MOV SP, R0
+ SUB R0, R0, #0x00000040
+
+ MSR CPSR_c, #0x17|0x80|0x40
+ MOV SP, R0
+ SUB R0, R0, #0x00000040
+
+ MSR CPSR_c, #0x11|0x80|0x40
+ MOV SP, R0
+ SUB R0, R0, #0x00000040
+
+ MSR CPSR_c, #0x12|0x80|0x40
+ MOV SP, R0
+ SUB R0, R0, #0x00000040
+
+ MSR CPSR_c, #0x13|0x80|0x40
+ MOV SP, R0
+ SUB R0, R0, #0x00000040
+
+/*
+ MSR CPSR_c, #0x10|0x80|0x40
+ MOV SP, R0
+*/
+ MSR CPSR_c, #0x1F|0x80|0x40
+ MOV SP, R0
+
+ MSR CPSR_c, #0x13|0x80|0x40 /* execute in Supervisor mode */
+
+/* Relocate .data section (Copy from ROM to RAM) */
+ LDR R1, =__text_end__ /* _etext */
+ LDR R2, =__data_start__ /* _data */
+ LDR R3, =__data_end__ /* _edata */
+ CMP R2, R3
+ BEQ DataIsEmpty
+LoopRel: CMP R2, R3
+ LDRLO R0, [R1], #4
+ STRLO R0, [R2], #4
+ BLO LoopRel
+DataIsEmpty:
+
+/* Clear .bss section (Zero init) */
+ MOV R0, #0
+ LDR R1, =__bss_start__
+ LDR R2, =__bss_end__
+ CMP R1,R2
+ BEQ BSSIsEmpty
+LoopZI: CMP R1, R2
+ STRLO R0, [R1], #4
+ BLO LoopZI
+BSSIsEmpty:
+
+
+/* Init realmonitor */
+/*
+ LDR R0, =__mbed_init_realmonitor
+ MOV LR, PC
+ BX R0
+*/
+
+/* Go to Reset_Handler */
+ LDR R0, =Reset_Handler
+ BX R0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/TOOLCHAIN_GCC_ARM/vector_table.s Mon Jun 01 11:00:11 2015 +0100 @@ -0,0 +1,45 @@ +# 1 "vector_table.s" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "vector_table.s" +; + + + + +# 1 "vector_defns.h" 1 +# 7 "vector_table.s" 2 + +; + + + + + + + + .section .vectors, "ax" + .arm + + + .global __main + .global __mbed_reset + .global __mbed_undef + .global __mbed_swi + .global __mbed_prefetch_abort + .global __mbed_data_abort + .global __mbed_irq + .global __mbed_fiq + +; + + +_start: + LDR PC, =__mbed_reset + LDR PC, =__mbed_undef + LDR PC, =__mbed_swi + LDR PC, =__mbed_prefetch_abort + LDR PC, =__mbed_data_abort + NOP ; + LDR PC, =__mbed_irq + LDR PC, =__mbed_fiq
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/cmsis.h Mon Jun 01 11:00:11 2015 +0100 @@ -0,0 +1,13 @@ +/* mbed Microcontroller Library - CMSIS + * Copyright (C) 2009-2015 ARM Limited. All rights reserved. + * + * A generic CMSIS include header, pulling in LPC2368 specifics + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "LPC24xx.h" +#include "cmsis_nvic.h" + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/cmsis_nvic.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,40 @@
+/* mbed Microcontroller Library
+ * CMSIS-style functionality to support dynamic vectors
+ *******************************************************************************
+ * Copyright (c) 2011-2015 ARM Limited. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of ARM Limited nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *******************************************************************************
+ */
+#include "cmsis_nvic.h"
+
+void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
+ LPC_VIC->VectAddr[(int)IRQn] = vector;
+}
+
+uint32_t NVIC_GetVector(IRQn_Type IRQn) {
+ return LPC_VIC->VectAddr[(int)IRQn];
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/cmsis_nvic.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,51 @@
+/* mbed Microcontroller Library
+ * CMSIS-style functionality to support dynamic vectors
+ *******************************************************************************
+ * Copyright (c) 2011-2015 ARM Limited. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of ARM Limited nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *******************************************************************************
+ */
+
+#ifndef MBED_CMSIS_NVIC_H
+#define MBED_CMSIS_NVIC_H
+
+#define NVIC_NUM_VECTORS 32
+#define NVIC_USER_IRQ_OFFSET 0
+
+#include "cmsis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
+uint32_t NVIC_GetVector(IRQn_Type IRQn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/core_arm7.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,44 @@
+/* mbed Microcontroller Library
+ * Copyright (C) 2008-2015 ARM Limited. All rights reserved.
+ *
+ * ARM7 version of CMSIS-like functionality - not advised for use outside mbed!
+ * based on core_cm3.h, V1.20
+ */
+
+#include <stdint.h>
+
+
+/* define compiler specific symbols */
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for armcc */
+ #define __INLINE __inline /*!< inline keyword for armcc */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for iarcc */
+ #define __INLINE inline /*!< inline keyword for iarcc. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for gcc */
+ #define __INLINE inline /*!< inline keyword for gcc */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+#if defined ( __CC_ARM )
+/**
+ * @brief Return the Main Stack Pointer (return current ARM7 stack)
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+uint32_t __get_MSP(void)
+{
+ return __current_sp();
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/core_arm7.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,343 @@
+/* mbed Microcontroller Library
+ * Copyright (C) 2008-2015 ARM Limited. All rights reserved.
+ *
+ * ARM7 version of CMSIS-like functionality - not advised for use outside mbed!
+ * based on core_cm3.h, V1.20
+ */
+
+#ifndef __ARM7_CORE_H__
+#define __ARM7_CORE_H__
+
+#include "vector_defns.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+//#include "cmsis_nvic.h"
+
+#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00) /*!< Cortex core */
+
+/**
+ * Lint configuration \n
+ * ----------------------- \n
+ *
+ * The following Lint messages will be suppressed and not shown: \n
+ * \n
+ * --- Error 10: --- \n
+ * register uint32_t __regBasePri __asm("basepri"); \n
+ * Error 10: Expecting ';' \n
+ * \n
+ * --- Error 530: --- \n
+ * return(__regBasePri); \n
+ * Warning 530: Symbol '__regBasePri' (line 264) not initialized \n
+ * \n
+ * --- Error 550: --- \n
+ * __regBasePri = (basePri & 0x1ff); \n
+ * } \n
+ * Warning 550: Symbol '__regBasePri' (line 271) not accessed \n
+ * \n
+ * --- Error 754: --- \n
+ * uint32_t RESERVED0[24]; \n
+ * Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 750: --- \n
+ * #define __CM3_CORE_H__ \n
+ * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 528: --- \n
+ * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n
+ * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 751: --- \n
+ * } InterruptType_Type; \n
+ * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n
+ * \n
+ * \n
+ * Note: To re-enable a Message, insert a space before 'lint' * \n
+ *
+ */
+
+/*lint -save */
+/*lint -e10 */
+/*lint -e530 */
+/*lint -e550 */
+/*lint -e754 */
+/*lint -e750 */
+/*lint -e528 */
+/*lint -e751 */
+
+#include <stdint.h> /* Include standard types */
+
+#if defined ( __CC_ARM )
+/**
+ * @brief Return the Main Stack Pointer (current ARM7 stack)
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+#endif
+
+
+#if defined (__ICCARM__)
+ #include <intrinsics.h> /* IAR Intrinsics */
+#endif
+
+
+#ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */
+#endif
+
+typedef struct
+{
+ uint32_t IRQStatus;
+ uint32_t FIQStatus;
+ uint32_t RawIntr;
+ uint32_t IntSelect;
+ uint32_t IntEnable;
+ uint32_t IntEnClr;
+ uint32_t SoftInt;
+ uint32_t SoftIntClr;
+ uint32_t Protection;
+ uint32_t SWPriorityMask;
+ uint32_t RESERVED0[54];
+ uint32_t VectAddr[32];
+ uint32_t RESERVED1[32];
+ uint32_t VectPriority[32];
+ uint32_t RESERVED2[800];
+ uint32_t Address;
+} NVIC_TypeDef;
+
+#define NVIC_BASE (0xFFFFF000)
+#define NVIC (( NVIC_TypeDef *) NVIC_BASE)
+
+
+
+/**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#ifdef __cplusplus
+#define __I volatile /*!< defines 'read only' permissions */
+#else
+#define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+
+
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#define __enable_fault_irq __enable_fiq
+#define __disable_fault_irq __disable_fiq
+
+#define __NOP __nop
+//#define __WFI __wfi
+//#define __WFE __wfe
+//#define __SEV __sev
+//#define __ISB() __isb(0)
+//#define __DSB() __dsb(0)
+//#define __DMB() __dmb(0)
+//#define __REV __rev
+//#define __RBIT __rbit
+#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))
+#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))
+#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))
+#define __STREXB(value, ptr) __strex(value, ptr)
+#define __STREXH(value, ptr) __strex(value, ptr)
+#define __STREXW(value, ptr) __strex(value, ptr)
+
+#define __disable_irq() unsigned tmp_IntEnable = LPC_VIC->IntEnable; \
+ LPC_VIC->IntEnClr = 0xffffffff
+
+#define __enable_irq() LPC_VIC->IntEnable = tmp_IntEnable
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+
+#define __enable_irq __enable_interrupt /*!< global Interrupt enable */
+#define __disable_irq __disable_interrupt /*!< global Interrupt disable */
+#define __NOP __no_operation() /*!< no operation intrinsic in IAR Compiler */
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+
+static __INLINE void __enable_irq() {
+ unsigned long temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "bic %0, %0, #0x80\n"
+ "msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory");
+}
+
+static __INLINE uint32_t __disable_irq() {
+ unsigned long old,temp;
+ __asm__ __volatile__("mrs %0, cpsr\n"
+ "orr %1, %0, #0xc0\n"
+ "msr cpsr_c, %1"
+ : "=r" (old), "=r" (temp)
+ :
+ : "memory");
+ return (old & 0x80) == 0;
+}
+
+static __INLINE void __NOP() { __ASM volatile ("nop"); }
+
+/** \brief Get Control Bits of Status Register
+
+ This function returns the content of the Control Bits from the Program Status Register.
+
+ \return Control Bits value
+ */
+__attribute__( ( always_inline ) ) static inline uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __asm__ __volatile__ ("MRS %0, CPSR \n"
+ "AND %0,%0,#31" : "=r" (result) );
+ return(result);
+}
+#define MODE_USER 0x10
+#define MODE_FIQ 0x11
+#define MODE_IRQ 0x12
+#define MODE_SUPERVISOR 0x13
+#define MODE_ABORT 0x17
+#define MODE_UNDEFINED 0x1B
+#define MODE_SYSTEM 0x1F
+
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+
+/**
+ * @brief Enable Interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn_Type IRQn specifies the interrupt number
+ * @return none
+ *
+ * Enable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_EnableIRQ(uint32_t IRQn)
+{
+ NVIC->IntEnable = 1 << (uint32_t)IRQn;
+}
+
+
+/**
+ * @brief Disable the interrupt line for external interrupt specified
+ *
+ * @param IRQn_Type IRQn is the positive number of the external interrupt
+ * @return none
+ *
+ * Disable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_DisableIRQ(uint32_t IRQn)
+{
+ NVIC->IntEnClr = 1 << (uint32_t)IRQn;
+}
+
+/**
+ * @brief Pend Interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn_Type IRQn specifies the interrupt number
+ * @return none
+ *
+ * Force software a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_PendIRQ(uint32_t IRQn)
+{
+ NVIC->SoftInt = 1 << (uint32_t)IRQn;
+}
+
+
+/**
+ * @brief Unpend the interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn_Type IRQn is the positive number of the external interrupt
+ * @return none
+ *
+ * Clear software device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_UnpendIRQ(uint32_t IRQn)
+{
+ NVIC->SoftIntClr = 1 << (uint32_t)IRQn;
+}
+
+/**
+ * @brief Is IRQ pending
+ *
+ * @param IRQn_Type IRQn is the positive number of the external interrupt
+ * @return 0 if IRQ is not pending
+ * 1 if IRQ is pending
+ *
+ * Returns software device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE uint32_t NVIC_Pending(uint32_t IRQn)
+{
+ return (NVIC->SoftInt & (1 << (uint32_t)IRQn)) != 0;
+}
+
+static __INLINE uint32_t __get_IPSR(void)
+{
+ unsigned i;
+
+ for(i = 0; i < 32; i ++)
+ if(NVIC->Address == NVIC->VectAddr[i])
+ return i;
+ return 1; // 1 is an invalid entry in the interrupt table on LPC2460
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ARM7_CORE_H__ */
+
+/*lint -restore */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/system_LPC24xx.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,164 @@
+/* mbed Microcontroller Library
+ * Copyright (C) 2008-2015 ARM Limited. All rights reserved.
+ *
+ * ARM7 version of CMSIS-like functionality - not advised for use outside mbed!
+ */
+
+#include <stdint.h>
+#include "LPC24xx.h"
+
+#define CLOCK_SETUP 1
+#define SCS_Val ((1<<4) | (1 << 5))
+#define CLKSRCSEL_Val 0x00000001
+
+#define PLL0_SETUP 1
+#define PLL0CFG_Val 0x0000000B
+#define CCLKCFG_Val 0x00000003
+#define USBCLKCFG_Val 0x00000005
+#define PCLKSEL0_Val 0x00000000
+#define PCLKSEL1_Val 0x00000000
+#define PCONP_Val (1 << PCEMC)
+#define CLKOUTCFG_Val 0x00000000
+#define MAMCR_Val 0x00000002
+#define MAMTIM_Val 0x00000004
+
+/*----------------------------------------------------------------------------
+ DEFINES
+ *----------------------------------------------------------------------------*/
+
+#define XTAL (12000000UL) /* Oscillator frequency */
+#define OSC_CLK ( XTAL) /* Main oscillator frequency */
+#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */
+#define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */
+
+/* F_cco0 = (2 * M * F_in) / N */
+#define __M (((PLL0CFG_Val ) & 0x7FFF) + 1)
+#define __N (((PLL0CFG_Val >> 16) & 0x00FF) + 1)
+#define __FCCO(__F_IN) ((2 * __M * __F_IN) / __N)
+#define __CCLK_DIV (((CCLKCFG_Val ) & 0x00FF) + 1)
+
+/* Determine core clock frequency according to settings */
+ #if (PLL0_SETUP)
+ #if ((CLKSRCSEL_Val & 0x03) == 1)
+ #define __CORE_CLK (__FCCO(OSC_CLK) / __CCLK_DIV)
+ #elif ((CLKSRCSEL_Val & 0x03) == 2)
+ #define __CORE_CLK (__FCCO(RTC_CLK) / __CCLK_DIV)
+ #else
+ #define __CORE_CLK (__FCCO(IRC_OSC) / __CCLK_DIV)
+ #endif
+ #endif
+
+
+/*----------------------------------------------------------------------------
+ Clock Variable definitions
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
+
+/*----------------------------------------------------------------------------
+ Clock functions
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
+{
+ /* Determine clock frequency according to clock register values */
+ if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) { /* If PLL0 enabled and connected */
+ switch (LPC_SC->CLKSRCSEL & 0x03) {
+ case 0: /* Int. RC oscillator => PLL0 */
+ case 3: /* Reserved, default to Int. RC */
+ SystemCoreClock = (IRC_OSC *
+ (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
+ (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1)) /
+ ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+ break;
+ case 1: /* Main oscillator => PLL0 */
+ SystemCoreClock = (OSC_CLK *
+ (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
+ (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1)) /
+ ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+ break;
+ case 2: /* RTC oscillator => PLL0 */
+ SystemCoreClock = (RTC_CLK *
+ (((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
+ (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1)) /
+ ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+ break;
+ }
+ } else {
+ switch (LPC_SC->CLKSRCSEL & 0x03) {
+ case 0: /* Int. RC oscillator => PLL0 */
+ case 3: /* Reserved, default to Int. RC */
+ SystemCoreClock = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+ break;
+ case 1: /* Main oscillator => PLL0 */
+ SystemCoreClock = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+ break;
+ case 2: /* RTC oscillator => PLL0 */
+ SystemCoreClock = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+ break;
+ }
+ }
+}
+
+void vectorRemap()
+{
+ #define ARM_VECTOR_REBASE (0x40000000)
+ extern unsigned long __privileged_code_start__; /* Startup code address from linker */
+ int i;
+
+ /* Copy ARM vector table into internal RAM */
+ for (i = 0; i <= 56; i+=2)
+ {
+ *(unsigned short *)(ARM_VECTOR_REBASE + i) = *(unsigned short *)((unsigned long)(&__privileged_code_start__) + i);
+ }
+
+// *(unsigned long *)(ARM_VECTOR_REBASE) = (unsigned long)armUnexpReset;
+ /* Remap the interrupt vectors to RAM */
+ LPC_SC->MEMMAP = 2;
+}
+
+/**
+ * Initialize the system
+ *
+ * @param none
+ * @return none
+ *
+ * @brief Setup the microcontroller system.
+ * Initialize the System and update the SystemFrequency variable.
+ */
+void SystemInit (void)
+{
+ LPC_WDT->WDMOD = 0; /* Disable internal watchdog */
+#if (CLOCK_SETUP) /* Clock Setup */
+ LPC_SC->SCS = SCS_Val;
+ if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */
+ while ((LPC_SC->SCS & (1 << 6)) == 0); /* Wait for Oscillator to be ready */
+ }
+
+ LPC_SC->CCLKCFG = CCLKCFG_Val; /* Setup Clock Divider */
+
+#if (PLL0_SETUP)
+ LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for PLL0 */
+ LPC_SC->PLL0CFG = PLL0CFG_Val;
+ LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
+ LPC_SC->PLL0FEED = 0xAA;
+ LPC_SC->PLL0FEED = 0x55;
+ while (!(LPC_SC->PLL0STAT & (1 << 26))); /* Wait for PLOCK0 */
+
+ LPC_SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */
+ LPC_SC->PLL0FEED = 0xAA;
+ LPC_SC->PLL0FEED = 0x55;
+#endif
+
+ LPC_SC->USBCLKCFG = USBCLKCFG_Val; /* Setup USB Clock Divider */
+#endif
+
+ LPC_SC->PCLKSEL0 = PCLKSEL0_Val; /* Peripheral Clock Selection */
+ LPC_SC->PCLKSEL1 = PCLKSEL1_Val;
+
+ LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */
+
+ // Setup MAM
+ LPC_SC->MAMTIM = MAMTIM_Val;
+ LPC_SC->MAMCR = MAMCR_Val;
+ vectorRemap();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/system_LPC24xx.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,44 @@
+/* mbed Microcontroller Library
+ * Copyright (C) 2008-2015 ARM Limited. All rights reserved.
+ *
+ * ARM7 version of CMSIS-like functionality - not advised for use outside mbed!
+ * based on cmsis system_LPC17xx.h
+ */
+
+#ifndef __SYSTEM_LPC24xx_H
+#define __SYSTEM_LPC24xx_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/vector_defns.h Mon Jun 01 11:00:11 2015 +0100 @@ -0,0 +1,77 @@ +/* mbed Microcontroller Library - Vectors + * Copyright (c) 2006-2015 ARM Limited. All rights reserved. + */ + +#ifndef MBED_VECTOR_DEFNS_H +#define MBED_VECTOR_DEFNS_H + +// Assember Macros +#ifdef __ARMCC_VERSION +#define EXPORT(x) EXPORT x +#define WEAK_EXPORT(x) EXPORT x [WEAK] +#define IMPORT(x) IMPORT x +#define LABEL(x) x +#else +#define EXPORT(x) .global x +#define WEAK_EXPORT(x) .weak x +#define IMPORT(x) .global x +#define LABEL(x) x: +#endif + +// RealMonitor +// Requires RAM (0x40000040-0x4000011F) to be allocated by the linker + +// RealMonitor entry points +#define rm_init_entry 0x7fffff91 +#define rm_undef_handler 0x7fffffa0 +#define rm_prefetchabort_handler 0x7fffffb0 +#define rm_dataabort_handler 0x7fffffc0 +#define rm_irqhandler2 0x7fffffe0 +//#define rm_RunningToStopped 0x7ffff808 // ARM - MBED64 +#define rm_RunningToStopped 0x7ffff820 // ARM - PHAT40 + +// Unofficial RealMonitor entry points and variables +#define RM_MSG_SWI 0x00940000 +#define StateP 0x40000040 + +// VIC register addresses +#define VIC_Base 0xfffff000 +#define VICAddress_Offset 0xf00 +#define VICVectAddr0_Offset 0x100 +#define VICVectAddr2_Offset 0x108 +#define VICVectAddr3_Offset 0x10c +#define VICVectAddr31_Offset 0x17c +#define VICIntEnClr_Offset 0x014 +#define VICIntEnClr (*(volatile unsigned long *)(VIC_Base + 0x014)) +#define VICVectAddr2 (*(volatile unsigned long *)(VIC_Base + 0x108)) +#define VICVectAddr3 (*(volatile unsigned long *)(VIC_Base + 0x10C)) + +// ARM Mode bits and Interrupt flags in PSRs +#define Mode_USR 0x10 +#define Mode_FIQ 0x11 +#define Mode_IRQ 0x12 +#define Mode_SVC 0x13 +#define Mode_ABT 0x17 +#define Mode_UND 0x1B +#define Mode_SYS 0x1F +#define I_Bit 0x80 // when I bit is set, IRQ is disabled +#define F_Bit 0x40 // when F bit is set, FIQ is disabled + +// MCU RAM +#define LPC2460_RAM_ADDRESS 0x40000000 // RAM Base +#define LPC2460_RAM_SIZE 0x10000 // 64KB + +// ISR Stack Allocation +#define UND_stack_size 0x00000040 +#define SVC_stack_size 0x00000040 +#define ABT_stack_size 0x00000040 +#define FIQ_stack_size 0x00000000 +#define IRQ_stack_size 0x00000040 + +#define ISR_stack_size (UND_stack_size + SVC_stack_size + ABT_stack_size + FIQ_stack_size + IRQ_stack_size) + +// Full Descending Stack, so top-most stack points to just above the top of RAM +#define LPC2460_STACK_TOP (LPC2460_RAM_ADDRESS + LPC2460_RAM_SIZE) +#define USR_STACK_TOP (LPC2460_STACK_TOP - ISR_stack_size) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC2460/vector_realmonitor.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,22 @@
+/* mbed Microcontroller Library - RealMonitor
+ * Copyright (c) 2006-2015 ARM Limited. All rights reserved.
+ */
+#include "vector_defns.h"
+
+extern void __mbed_dcc_irq(void);
+
+/* Function: __mbed_init_realmonitor
+ * Setup the RealMonitor DCC Interrupt Handlers
+ */
+void __mbed_init_realmonitor(void) __attribute__((weak));
+void __mbed_init_realmonitor() {
+ // Disable all interrupts
+ VICIntEnClr = 0xffffffff;
+
+ // Set DCC interrupt vector addresses
+ VICVectAddr2 = (unsigned)&__mbed_dcc_irq;
+ VICVectAddr3 = (unsigned)&__mbed_dcc_irq;
+
+ // Initialise RealMonitor
+ ((void (*)(void))rm_init_entry)();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/PeripheralNames.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,120 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_PERIPHERALNAMES_H
+#define MBED_PERIPHERALNAMES_H
+
+#include "cmsis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ UART_0 = (int)LPC_UART0_BASE,
+ UART_1 = (int)LPC_UART1_BASE,
+ UART_2 = (int)LPC_UART2_BASE,
+ UART_3 = (int)LPC_UART3_BASE
+} UARTName;
+
+typedef enum {
+ ADC0_0 = 0,
+ ADC0_1,
+ ADC0_2,
+ ADC0_3,
+ ADC0_4,
+ ADC0_5,
+ ADC0_6,
+ ADC0_7
+} ADCName;
+
+typedef enum {
+ DAC_0 = 0
+} DACName;
+
+typedef enum {
+ SPI_0 = (int)LPC_SSP0_BASE,
+ SPI_1 = (int)LPC_SSP1_BASE
+} SPIName;
+
+typedef enum {
+ I2C_0 = (int)LPC_I2C0_BASE,
+ I2C_1 = (int)LPC_I2C1_BASE,
+ I2C_2 = (int)LPC_I2C2_BASE
+} I2CName;
+
+typedef enum {
+ PWM_1 = 1,
+ PWM_2,
+ PWM_3,
+ PWM_4,
+ PWM_5,
+ PWM_6
+} PWMName;
+
+typedef enum {
+ CAN_1 = (int)LPC_CAN1_BASE,
+ CAN_2 = (int)LPC_CAN2_BASE
+} CANName;
+
+#define STDIO_UART_TX USBTX
+#define STDIO_UART_RX USBRX
+#define STDIO_UART UART_2
+
+// Default peripherals
+#define MBED_SPI0 p5, p6, p7, p8
+//#define MBED_SPI1 p11, p12, p13, p14
+
+#define MBED_UART0 p9, p10
+#define MBED_UART1 p13, p14
+#define MBED_UART2 p15, p16
+#define MBED_UARTUSB USBTX, USBRX
+
+#define MBED_I2C0 p17, p18
+//#define MBED_I2C1 p9, p10
+
+#define MBED_CAN0 p19, p20
+
+#define MBED_ANALOGOUT0 p21
+
+#define MBED_ANALOGIN0 p22
+#define MBED_ANALOGIN1 p23
+//#define MBED_ANALOGIN2 p17
+//#define MBED_ANALOGIN3 p18
+//#define MBED_ANALOGIN4 p19
+//#define MBED_ANALOGIN5 p20
+
+#define MBED_PWMOUT0 p24
+#define MBED_PWMOUT1 p25
+#define MBED_PWMOUT2 p26
+#define MBED_PWMOUT3 p27
+//#define MBED_PWMOUT4 p22
+//#define MBED_PWMOUT5 p21
+
+#define MBED_USB_D_PLUS p28
+#define MBED_USB_D_MINUS p29
+
+#define MBED_MCICLK p30
+#define MBED_MCICMD p31
+#define MBED_MCIDAT0 p32
+#define MBED_MCIDAT1 p33
+#define MBED_MCIDAT2 p34
+#define MBED_MCIDAT3 p35
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/PinNames.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,112 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBED_PINNAMES_H
+#define MBED_PINNAMES_H
+
+#include "cmsis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ PIN_INPUT,
+ PIN_OUTPUT
+} PinDirection;
+
+#define PORT_SHIFT 5
+
+typedef enum {
+ // LPC Pin Names
+ P0_0 = LPC_GPIO0_BASE,
+ P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31,
+ P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31,
+ P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31,
+ P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31,
+ P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31,
+
+ // mbed DIP Pin Names
+ p5 = P0_18,
+ p6 = P0_17,
+ p7 = P0_15,
+ p8 = P0_16,
+
+ p9 = P0_2,
+ p10 = P0_3,
+ p11 = P0_18,
+ p12 = P0_17,
+ p13 = P2_0,
+ p14 = P2_1,
+ p15 = P4_28,
+ p16 = P4_29,
+ p17 = P2_30,
+ p18 = P2_31,
+ p19 = P0_0,
+ p20 = P0_1,
+ p21 = P0_26,
+ p22 = P0_12,
+ p23 = P0_13,
+ p24 = P1_20,
+ p25 = P1_21,
+ p26 = P1_23,
+ p27 = P1_24,
+ p28 = P0_29,
+ p29 = P0_30,
+ p30 = P1_2,
+ p31 = P1_3,
+ p32 = P1_6,
+ p33 = P1_7,
+ p34 = P1_11,
+ p35 = P1_12,
+
+ // Other mbed Pin Names
+ LED1 = P1_19,
+ LED2 = P2_26,
+ LED3 = P2_27,
+ LED4 = P2_27,
+
+ USBTX = P2_8,
+ USBRX = P2_9,
+
+ EXT_WDT = P0_10,
+
+ // Not connected
+ NC = (int)0xFFFFFFFF
+} PinName;
+
+typedef enum {
+ PullUp = 0,
+ PullDown = 3,
+ PullNone = 2,
+ OpenDrain = 4,
+ PullDefault = PullDown
+} PinMode;
+
+// version of PINCON_TypeDef using register arrays
+typedef struct {
+ __IO uint32_t PINSEL[11];
+ uint32_t RESERVED0[5];
+ __IO uint32_t PINMODE[10];
+} PINCONARRAY_TypeDef;
+
+#define PINCONARRAY ((PINCONARRAY_TypeDef *)LPC_PINCON_BASE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/PortNames.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,38 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_PORTNAMES_H
+#define MBED_PORTNAMES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ Port0 = 0,
+ Port1 = 1,
+ Port2 = 2,
+ Port3 = 3,
+ Port4 = 4
+} PortName;
+
+#define PORT_0 Port0
+#define PORT_1 Port1
+#define PORT_2 Port2
+#define PORT_3 Port3
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/analogin_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,125 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "analogin_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+
+#define ANALOGIN_MEDIAN_FILTER 1
+
+#define ADC_10BIT_RANGE 0x3FF
+#define ADC_12BIT_RANGE 0xFFF
+
+static inline int div_round_up(int x, int y) {
+ return (x + (y - 1)) / y;
+}
+
+static const PinMap PinMap_ADC[] = {
+ {P0_23, ADC0_0, 1},
+ {P0_24, ADC0_1, 1},
+ {P0_25, ADC0_2, 1},
+ {P0_26, ADC0_3, 1},
+ {P1_30, ADC0_4, 3},
+ {P1_31, ADC0_5, 3},
+ {P0_12, ADC0_6, 3},
+ {P0_13, ADC0_7, 3},
+ {NC, NC, 0}
+};
+
+#define ADC_RANGE ADC_10BIT_RANGE
+
+
+void analogin_init(analogin_t *obj, PinName pin) {
+ obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
+ MBED_ASSERT(obj->adc != (ADCName)NC);
+
+ // ensure power is turned on
+ LPC_SC->PCONP |= (1 << PCADC);
+
+ // set PCLK of ADC to /1
+ LPC_SC->PCLKSEL0 &= ~(0x3 << 24);
+ LPC_SC->PCLKSEL0 |= (0x1 << 24);
+ uint32_t PCLK = SystemCoreClock;
+
+ // calculate minimum clock divider
+ // clkdiv = divider - 1
+ uint32_t MAX_ADC_CLK = 4500000;
+ uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
+
+ // Set the generic software-controlled ADC settings
+ LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected
+ | (clkdiv << 8) // CLKDIV: PCLK max ~= 25MHz, /25 to give safe 1MHz at fastest
+ | (0 << 16) // BURST: 0 = software control
+ | (0 << 17) // CLKS: not applicable
+ | (1 << 21) // PDN: 1 = operational
+ | (0 << 24) // START: 0 = no start
+ | (0 << 27); // EDGE: not applicable
+
+ pinmap_pinout(pin, PinMap_ADC);
+}
+
+static inline uint32_t adc_read(analogin_t *obj) {
+ // Select the appropriate channel and start conversion
+ LPC_ADC->ADCR &= ~0xFF;
+ LPC_ADC->ADCR |= 1 << (int)obj->adc;
+ LPC_ADC->ADCR |= 1 << 24;
+
+ // Repeatedly get the sample data until DONE bit
+ unsigned int data;
+ do {
+ data = LPC_ADC->ADGDR;
+ } while ((data & ((unsigned int)1 << 31)) == 0);
+
+ // Stop conversion
+ LPC_ADC->ADCR &= ~(1 << 24);
+
+ return (data >> 6) & ADC_RANGE; // 10 bit
+}
+
+static inline void order(uint32_t *a, uint32_t *b) {
+ if (*a > *b) {
+ uint32_t t = *a;
+ *a = *b;
+ *b = t;
+ }
+}
+
+static inline uint32_t adc_read_u32(analogin_t *obj) {
+ uint32_t value;
+#if ANALOGIN_MEDIAN_FILTER
+ uint32_t v1 = adc_read(obj);
+ uint32_t v2 = adc_read(obj);
+ uint32_t v3 = adc_read(obj);
+ order(&v1, &v2);
+ order(&v2, &v3);
+ order(&v1, &v2);
+ value = v2;
+#else
+ value = adc_read(obj);
+#endif
+ return value;
+}
+
+uint16_t analogin_read_u16(analogin_t *obj) {
+ uint32_t value = adc_read_u32(obj);
+
+ return (value << 6) | ((value >> 4) & 0x003F); // 10 bit
+}
+
+float analogin_read(analogin_t *obj) {
+ uint32_t value = adc_read_u32(obj);
+ return (float)value * (1.0f / (float)ADC_RANGE);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/analogout_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,75 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "analogout_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+
+static const PinMap PinMap_DAC[] = {
+ {P0_26, DAC_0, 2},
+ {NC , NC , 0}
+};
+
+void analogout_init(dac_t *obj, PinName pin) {
+ obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
+ MBED_ASSERT(obj->dac != (DACName)NC);
+
+ // power is on by default, set DAC clk divider is /4
+ LPC_SC->PCLKSEL0 &= ~(0x3 << 22);
+
+ // map out (must be done before accessing registers)
+ pinmap_pinout(pin, PinMap_DAC);
+
+ analogout_write_u16(obj, 0);
+}
+
+void analogout_free(dac_t *obj) {}
+
+static inline void dac_write(int value) {
+ value &= 0x3FF; // 10-bit
+
+ // Set the DAC output
+ LPC_DAC->DACR = (0 << 16) // bias = 0
+ | (value << 6);
+}
+
+static inline int dac_read() {
+ return (LPC_DAC->DACR >> 6) & 0x3FF;
+}
+
+void analogout_write(dac_t *obj, float value) {
+ if (value < 0.0f) {
+ dac_write(0);
+ } else if (value > 1.0f) {
+ dac_write(0x3FF);
+ } else {
+ dac_write(value * (float)0x3FF);
+ }
+}
+
+void analogout_write_u16(dac_t *obj, uint16_t value) {
+ dac_write(value >> 6); // 10-bit
+}
+
+float analogout_read(dac_t *obj) {
+ uint32_t value = dac_read();
+ return (float)value * (1.0f / (float)0x3FF);
+}
+
+uint16_t analogout_read_u16(dac_t *obj) {
+ uint32_t value = dac_read(); // 10-bit
+ return (value << 6) | ((value >> 4) & 0x003F);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/can_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,303 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "can_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+
+#include <math.h>
+#include <string.h>
+
+/* Acceptance filter mode in AFMR register */
+#define ACCF_OFF 0x01
+#define ACCF_BYPASS 0x02
+#define ACCF_ON 0x00
+#define ACCF_FULLCAN 0x04
+
+/* There are several bit timing calculators on the internet.
+http://www.port.de/engl/canprod/sv_req_form.html
+http://www.kvaser.com/can/index.htm
+*/
+
+static const PinMap PinMap_CAN_RD[] = {
+ {P0_0 , CAN_1, 1},
+ {P0_4 , CAN_2, 2},
+ {P0_21, CAN_1, 3},
+ {P2_7 , CAN_2, 1},
+ {NC , NC , 0}
+};
+
+static const PinMap PinMap_CAN_TD[] = {
+ {P0_1 , CAN_1, 1},
+ {P0_5 , CAN_2, 2},
+ {P0_22, CAN_1, 3},
+ {P2_8 , CAN_2, 1},
+ {NC , NC , 0}
+};
+
+// Type definition to hold a CAN message
+struct CANMsg {
+ unsigned int reserved1 : 16;
+ unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter
+ unsigned int reserved0 : 10;
+ unsigned int rtr : 1; // Bit 30: Set if this is a RTR message
+ unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message
+ unsigned int id; // CAN Message ID (11-bit or 29-bit)
+ unsigned char data[8]; // CAN Message Data Bytes 0-7
+};
+typedef struct CANMsg CANMsg;
+
+static uint32_t can_disable(can_t *obj) {
+ uint32_t sm = obj->dev->MOD;
+ obj->dev->MOD |= 1;
+ return sm;
+}
+
+static inline void can_enable(can_t *obj) {
+ if (obj->dev->MOD & 1) {
+ obj->dev->MOD &= ~(1);
+ }
+}
+
+int can_mode(can_t *obj, CanMode mode) {
+ return 0; // not implemented
+}
+
+int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
+ return 0; // not implemented
+}
+
+static int can_pclk(can_t *obj) {
+ int value = 0;
+ switch ((int)obj->dev) {
+ case CAN_1: value = (LPC_SC->PCLKSEL0 & (0x3 << 26)) >> 26; break;
+ case CAN_2: value = (LPC_SC->PCLKSEL0 & (0x3 << 28)) >> 28; break;
+ }
+
+ switch (value) {
+ case 1: return 1;
+ case 2: return 2;
+ case 3: return 6;
+ default: return 4;
+ }
+}
+
+// This table has the sampling points as close to 75% as possible. The first
+// value is TSEG1, the second TSEG2.
+static const int timing_pts[23][2] = {
+ {0x0, 0x0}, // 2, 50%
+ {0x1, 0x0}, // 3, 67%
+ {0x2, 0x0}, // 4, 75%
+ {0x3, 0x0}, // 5, 80%
+ {0x3, 0x1}, // 6, 67%
+ {0x4, 0x1}, // 7, 71%
+ {0x5, 0x1}, // 8, 75%
+ {0x6, 0x1}, // 9, 78%
+ {0x6, 0x2}, // 10, 70%
+ {0x7, 0x2}, // 11, 73%
+ {0x8, 0x2}, // 12, 75%
+ {0x9, 0x2}, // 13, 77%
+ {0x9, 0x3}, // 14, 71%
+ {0xA, 0x3}, // 15, 73%
+ {0xB, 0x3}, // 16, 75%
+ {0xC, 0x3}, // 17, 76%
+ {0xD, 0x3}, // 18, 78%
+ {0xD, 0x4}, // 19, 74%
+ {0xE, 0x4}, // 20, 75%
+ {0xF, 0x4}, // 21, 76%
+ {0xF, 0x5}, // 22, 73%
+ {0xF, 0x6}, // 23, 70%
+ {0xF, 0x7}, // 24, 67%
+};
+
+static unsigned int can_speed(unsigned int sclk, unsigned int pclk, unsigned int cclk, unsigned char psjw) {
+ uint32_t btr;
+ uint16_t brp = 0;
+ uint32_t calcbit;
+ uint32_t bitwidth;
+ int hit = 0;
+ int bits;
+
+ bitwidth = sclk / (pclk * cclk);
+
+ brp = bitwidth / 0x18;
+ while ((!hit) && (brp < bitwidth / 4)) {
+ brp++;
+ for (bits = 22; bits > 0; bits--) {
+ calcbit = (bits + 3) * (brp + 1);
+ if (calcbit == bitwidth) {
+ hit = 1;
+ break;
+ }
+ }
+ }
+
+ if (hit) {
+ btr = ((timing_pts[bits][1] << 20) & 0x00700000)
+ | ((timing_pts[bits][0] << 16) & 0x000F0000)
+ | ((psjw << 14) & 0x0000C000)
+ | ((brp << 0) & 0x000003FF);
+ } else {
+ btr = 0xFFFFFFFF;
+ }
+
+ return btr;
+}
+
+void can_init(can_t *obj, PinName rd, PinName td) {
+ CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
+ CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
+ obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td);
+ MBED_ASSERT((int)obj->dev != NC);
+
+ switch ((int)obj->dev) {
+ case CAN_1: LPC_SC->PCONP |= 1 << PCAN1; break;
+ case CAN_2: LPC_SC->PCONP |= 1 << PCAN2; break;
+ }
+
+ pinmap_pinout(rd, PinMap_CAN_RD);
+ pinmap_pinout(td, PinMap_CAN_TD);
+
+ can_reset(obj);
+ obj->dev->IER = 0; // Disable Interrupts
+ can_frequency(obj, 100000);
+
+ LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter
+}
+
+void can_free(can_t *obj) {
+ switch ((int)obj->dev) {
+ case CAN_1: LPC_SC->PCONP &= ~(1 << PCAN1); break;
+ case CAN_2: LPC_SC->PCONP &= ~(1 << PCAN2); break;
+ }
+}
+
+int can_frequency(can_t *obj, int f) {
+ int pclk = can_pclk(obj);
+ int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1);
+
+ if (btr > 0) {
+ uint32_t modmask = can_disable(obj);
+ obj->dev->BTR = btr;
+ obj->dev->MOD = modmask;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int can_write(can_t *obj, CAN_Message msg, int cc) {
+ unsigned int CANStatus;
+ CANMsg m;
+
+ can_enable(obj);
+
+ m.id = msg.id ;
+ m.dlc = msg.len & 0xF;
+ m.rtr = msg.type;
+ m.type = msg.format;
+ memcpy(m.data, msg.data, msg.len);
+ const unsigned int *buf = (const unsigned int *)&m;
+
+ CANStatus = obj->dev->SR;
+ if (CANStatus & 0x00000004) {
+ obj->dev->TFI1 = buf[0] & 0xC00F0000;
+ obj->dev->TID1 = buf[1];
+ obj->dev->TDA1 = buf[2];
+ obj->dev->TDB1 = buf[3];
+ if (cc) {
+ obj->dev->CMR = 0x30;
+ } else {
+ obj->dev->CMR = 0x21;
+ }
+ return 1;
+
+ } else if (CANStatus & 0x00000400) {
+ obj->dev->TFI2 = buf[0] & 0xC00F0000;
+ obj->dev->TID2 = buf[1];
+ obj->dev->TDA2 = buf[2];
+ obj->dev->TDB2 = buf[3];
+ if (cc) {
+ obj->dev->CMR = 0x50;
+ } else {
+ obj->dev->CMR = 0x41;
+ }
+ return 1;
+
+ } else if (CANStatus & 0x00040000) {
+ obj->dev->TFI3 = buf[0] & 0xC00F0000;
+ obj->dev->TID3 = buf[1];
+ obj->dev->TDA3 = buf[2];
+ obj->dev->TDB3 = buf[3];
+ if (cc) {
+ obj->dev->CMR = 0x90;
+ } else {
+ obj->dev->CMR = 0x81;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+int can_read(can_t *obj, CAN_Message *msg, int handle) {
+ CANMsg x;
+ unsigned int *i = (unsigned int *)&x;
+
+ can_enable(obj);
+
+ if (obj->dev->GSR & 0x1) {
+ *i++ = obj->dev->RFS; // Frame
+ *i++ = obj->dev->RID; // ID
+ *i++ = obj->dev->RDA; // Data A
+ *i++ = obj->dev->RDB; // Data B
+ obj->dev->CMR = 0x04; // release receive buffer
+
+ msg->id = x.id;
+ msg->len = x.dlc;
+ msg->format = (x.type)? CANExtended : CANStandard;
+ msg->type = (x.rtr)? CANRemote: CANData;
+ memcpy(msg->data,x.data,x.dlc);
+ return 1;
+ }
+
+ return 0;
+}
+
+void can_reset(can_t *obj) {
+ can_disable(obj);
+ obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset
+}
+
+unsigned char can_rderror(can_t *obj) {
+ return (obj->dev->GSR >> 16) & 0xFF;
+}
+
+unsigned char can_tderror(can_t *obj) {
+ return (obj->dev->GSR >> 24) & 0xFF;
+}
+
+void can_monitor(can_t *obj, int silent) {
+ uint32_t mod_mask = can_disable(obj);
+ if (silent) {
+ obj->dev->MOD |= (1 << 1);
+ } else {
+ obj->dev->MOD &= ~(1 << 1);
+ }
+ if (!(mod_mask & 1)) {
+ can_enable(obj);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/device.h Mon Jun 01 11:00:11 2015 +0100 @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 0 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/ethernet_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,935 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <string.h>
+
+#include "ethernet_api.h"
+#include "cmsis.h"
+#include "mbed_interface.h"
+#include "toolchain.h"
+#include "mbed_error.h"
+
+#define NEW_LOGIC 0
+#define NEW_ETH_BUFFER 0
+
+#if NEW_ETH_BUFFER
+
+#define NUM_RX_FRAG 4 // Number of Rx Fragments (== packets)
+#define NUM_TX_FRAG 3 // Number of Tx Fragments (== packets)
+
+#define ETH_MAX_FLEN 1536 // Maximum Ethernet Frame Size
+#define ETH_FRAG_SIZE ETH_MAX_FLEN // Packet Fragment size (same as packet length)
+
+#else
+
+// Memfree calculation:
+// (16 * 1024) - ((2 * 4 * NUM_RX) + (2 * 4 * NUM_RX) + (0x300 * NUM_RX) +
+// (2 * 4 * NUM_TX) + (1 * 4 * NUM_TX) + (0x300 * NUM_TX)) = 8556
+/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
+#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */
+#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */
+//#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */
+
+//#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */
+#define ETH_FRAG_SIZE 0x300 /* Packet Fragment size 1536/2 Bytes */
+#define ETH_MAX_FLEN 0x300 /* Max. Ethernet Frame Size */
+
+const int ethernet_MTU_SIZE = 0x300;
+
+#endif
+
+#define ETHERNET_ADDR_SIZE 6
+
+PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */
+ unsigned int Packet;
+ unsigned int Ctrl;
+};
+typedef struct RX_DESC_TypeDef RX_DESC_TypeDef;
+
+PACKED struct RX_STAT_TypeDef { /* RX Status struct */
+ unsigned int Info;
+ unsigned int HashCRC;
+};
+typedef struct RX_STAT_TypeDef RX_STAT_TypeDef;
+
+PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */
+ unsigned int Packet;
+ unsigned int Ctrl;
+};
+typedef struct TX_DESC_TypeDef TX_DESC_TypeDef;
+
+PACKED struct TX_STAT_TypeDef { /* TX Status struct */
+ unsigned int Info;
+};
+typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;
+
+/* MAC Configuration Register 1 */
+#define MAC1_REC_EN 0x00000001 /* Receive Enable */
+#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */
+#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */
+#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */
+#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */
+#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */
+#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */
+#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */
+#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */
+#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */
+#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */
+
+/* MAC Configuration Register 2 */
+#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */
+#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */
+#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */
+#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */
+#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */
+#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */
+#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */
+#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */
+#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */
+#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */
+#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */
+#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */
+#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */
+
+/* Back-to-Back Inter-Packet-Gap Register */
+#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */
+#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */
+
+/* Non Back-to-Back Inter-Packet-Gap Register */
+#define IPGR_DEF 0x00000012 /* Recommended value */
+
+/* Collision Window/Retry Register */
+#define CLRT_DEF 0x0000370F /* Default value */
+
+/* PHY Support Register */
+#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */
+//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */
+#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */
+
+/* Test Register */
+#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */
+#define TEST_TST_PAUSE 0x00000002 /* Test Pause */
+#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */
+
+/* MII Management Configuration Register */
+#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */
+#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */
+#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */
+#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */
+
+/* MII Management Command Register */
+#define MCMD_READ 0x00000001 /* MII Read */
+#define MCMD_SCAN 0x00000002 /* MII Scan continuously */
+
+#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */
+#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */
+
+/* MII Management Address Register */
+#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */
+#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */
+
+/* MII Management Indicators Register */
+#define MIND_BUSY 0x00000001 /* MII is Busy */
+#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */
+#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */
+#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */
+
+/* Command Register */
+#define CR_RX_EN 0x00000001 /* Enable Receive */
+#define CR_TX_EN 0x00000002 /* Enable Transmit */
+#define CR_REG_RES 0x00000008 /* Reset Host Registers */
+#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */
+#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */
+#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */
+#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */
+#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */
+#define CR_RMII 0x00000200 /* Reduced MII Interface */
+#define CR_FULL_DUP 0x00000400 /* Full Duplex */
+
+/* Status Register */
+#define SR_RX_EN 0x00000001 /* Enable Receive */
+#define SR_TX_EN 0x00000002 /* Enable Transmit */
+
+/* Transmit Status Vector 0 Register */
+#define TSV0_CRC_ERR 0x00000001 /* CRC error */
+#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */
+#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */
+#define TSV0_DONE 0x00000008 /* Tramsmission Completed */
+#define TSV0_MCAST 0x00000010 /* Multicast Destination */
+#define TSV0_BCAST 0x00000020 /* Broadcast Destination */
+#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */
+#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */
+#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */
+#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */
+#define TSV0_GIANT 0x00000400 /* Giant Frame */
+#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */
+#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */
+#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */
+#define TSV0_PAUSE 0x20000000 /* Pause Frame */
+#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */
+#define TSV0_VLAN 0x80000000 /* VLAN Frame */
+
+/* Transmit Status Vector 1 Register */
+#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */
+#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */
+
+/* Receive Status Vector Register */
+#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */
+#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */
+#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */
+#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */
+#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */
+#define RSV_CRC_ERR 0x00100000 /* CRC Error */
+#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */
+#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */
+#define RSV_REC_OK 0x00800000 /* Frame Received OK */
+#define RSV_MCAST 0x01000000 /* Multicast Frame */
+#define RSV_BCAST 0x02000000 /* Broadcast Frame */
+#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */
+#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */
+#define RSV_PAUSE 0x10000000 /* Pause Frame */
+#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */
+#define RSV_VLAN 0x40000000 /* VLAN Frame */
+
+/* Flow Control Counter Register */
+#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */
+#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */
+
+/* Flow Control Status Register */
+#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */
+
+/* Receive Filter Control Register */
+#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */
+#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */
+#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */
+#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */
+#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/
+#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */
+#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */
+#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */
+
+/* Receive Filter WoL Status/Clear Registers */
+#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */
+#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */
+#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */
+#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */
+#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */
+#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */
+#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */
+#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */
+
+/* Interrupt Status/Enable/Clear/Set Registers */
+#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */
+#define INT_RX_ERR 0x00000002 /* Receive Error */
+#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */
+#define INT_RX_DONE 0x00000008 /* Receive Done */
+#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */
+#define INT_TX_ERR 0x00000020 /* Transmit Error */
+#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */
+#define INT_TX_DONE 0x00000080 /* Transmit Done */
+#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */
+#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */
+
+/* Power Down Register */
+#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */
+
+/* RX Descriptor Control Word */
+#define RCTRL_SIZE 0x000007FF /* Buffer size mask */
+#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */
+
+/* RX Status Hash CRC Word */
+#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */
+#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */
+
+/* RX Status Information Word */
+#define RINFO_SIZE 0x000007FF /* Data size in bytes */
+#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */
+#define RINFO_VLAN 0x00080000 /* VLAN Frame */
+#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */
+#define RINFO_MCAST 0x00200000 /* Multicast Frame */
+#define RINFO_BCAST 0x00400000 /* Broadcast Frame */
+#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */
+#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */
+#define RINFO_LEN_ERR 0x02000000 /* Length Error */
+#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */
+#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */
+#define RINFO_OVERRUN 0x10000000 /* Receive overrun */
+#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */
+#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */
+#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
+
+//#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)
+#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | \
+ RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)
+
+
+/* TX Descriptor Control Word */
+#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */
+#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */
+#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */
+#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */
+#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */
+#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */
+#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */
+
+/* TX Status Information Word */
+#define TINFO_COL_CNT 0x01E00000 /* Collision Count */
+#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */
+#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */
+#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */
+#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */
+#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */
+#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */
+#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
+
+/* ENET Device Revision ID */
+#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */
+
+/* DP83848C PHY Registers */
+#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */
+#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */
+#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */
+#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */
+#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */
+#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */
+#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */
+#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */
+
+/* PHY Extended Registers */
+#define PHY_REG_STS 0x10 /* Status Register */
+#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */
+#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */
+#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */
+#define PHY_REG_RECR 0x15 /* Receive Error Counter */
+#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */
+#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */
+#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */
+#define PHY_REG_PHYCR 0x19 /* PHY Control Register */
+#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */
+#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */
+#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */
+
+#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */
+
+#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */
+#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */
+#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */
+#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */
+#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */
+
+#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */
+#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */
+
+#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */
+
+#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */
+#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */
+#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */
+
+#define PHY_BMCR_RESET 0x8000 /* PHY Reset */
+
+#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */
+
+#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */
+#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */
+
+
+static int phy_read(unsigned int PhyReg);
+static int phy_write(unsigned int PhyReg, unsigned short Data);
+
+static void txdscr_init(void);
+static void rxdscr_init(void);
+
+#if defined (__ICCARM__)
+# define AHBSRAM1
+#elif defined(TOOLCHAIN_GCC_CR)
+# define AHBSRAM1 __attribute__((section(".data.$RamPeriph32")))
+#else
+# define AHBSRAM1 __attribute__((section("AHBSRAM1"),aligned))
+#endif
+
+AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE];
+AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE];
+AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG];
+AHBSRAM1 volatile RX_STAT_TypeDef rxstat[NUM_RX_FRAG];
+AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG];
+AHBSRAM1 volatile TX_STAT_TypeDef txstat[NUM_TX_FRAG];
+
+
+#if NEW_LOGIC
+static int rx_consume_offset = -1;
+static int tx_produce_offset = -1;
+#else
+static int send_doff = 0;
+static int send_idx = -1;
+static int send_size = 0;
+
+static int receive_soff = 0;
+static int receive_idx = -1;
+#endif
+
+static uint32_t phy_id = 0;
+
+static inline int rinc(int idx, int mod) {
+ ++idx;
+ idx %= mod;
+ return idx;
+}
+
+//extern unsigned int SystemFrequency;
+static inline unsigned int clockselect() {
+ if(SystemCoreClock < 10000000) {
+ return 1;
+ } else if(SystemCoreClock < 15000000) {
+ return 2;
+ } else if(SystemCoreClock < 20000000) {
+ return 3;
+ } else if(SystemCoreClock < 25000000) {
+ return 4;
+ } else if(SystemCoreClock < 35000000) {
+ return 5;
+ } else if(SystemCoreClock < 50000000) {
+ return 6;
+ } else if(SystemCoreClock < 70000000) {
+ return 7;
+ } else if(SystemCoreClock < 80000000) {
+ return 8;
+ } else if(SystemCoreClock < 90000000) {
+ return 9;
+ } else if(SystemCoreClock < 100000000) {
+ return 10;
+ } else if(SystemCoreClock < 120000000) {
+ return 11;
+ } else if(SystemCoreClock < 130000000) {
+ return 12;
+ } else if(SystemCoreClock < 140000000) {
+ return 13;
+ } else if(SystemCoreClock < 150000000) {
+ return 15;
+ } else if(SystemCoreClock < 160000000) {
+ return 16;
+ } else {
+ return 0;
+ }
+}
+
+#ifndef min
+#define min(x, y) (((x)<(y))?(x):(y))
+#endif
+
+/*----------------------------------------------------------------------------
+ Ethernet Device initialize
+ *----------------------------------------------------------------------------*/
+int ethernet_init() {
+ int regv, tout;
+ char mac[ETHERNET_ADDR_SIZE];
+ unsigned int clock = clockselect();
+
+ LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */
+
+ LPC_PINCON->PINSEL2 = 0x50150105; /* Enable P1 Ethernet Pins. */
+ LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
+
+ /* Reset all EMAC internal modules. */
+ LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX |
+ MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
+ LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;
+
+ for(tout = 100; tout; tout--) __NOP(); /* A short delay after reset. */
+
+ LPC_EMAC->MAC1 = MAC1_PASS_ALL; /* Initialize MAC control registers. */
+ LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
+ LPC_EMAC->MAXF = ETH_MAX_FLEN;
+ LPC_EMAC->CLRT = CLRT_DEF;
+ LPC_EMAC->IPGR = IPGR_DEF;
+
+ LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; /* Enable Reduced MII interface. */
+
+ LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */
+ LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */
+
+ for(tout = 100; tout; tout--) __NOP(); /* A short delay */
+
+ LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL;
+ LPC_EMAC->MCMD = 0;
+
+ LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */
+
+ for (tout = 100; tout; tout--) __NOP(); /* A short delay */
+
+ LPC_EMAC->SUPP = 0;
+
+ phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */
+ for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */
+ regv = phy_read(PHY_REG_BMCR);
+ if(regv < 0 || tout == 0) {
+ return -1; /* Error */
+ }
+ if(!(regv & PHY_BMCR_RESET)) {
+ break; /* Reset complete. */
+ }
+ }
+
+ phy_id = (phy_read(PHY_REG_IDR1) << 16);
+ phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0);
+
+ if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) {
+ error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id);
+ }
+
+ ethernet_set_link(-1, 0);
+
+ /* Set the Ethernet MAC Address registers */
+ ethernet_address(mac);
+ LPC_EMAC->SA0 = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4];
+ LPC_EMAC->SA1 = ((uint32_t)mac[3] << 8) | (uint32_t)mac[2];
+ LPC_EMAC->SA2 = ((uint32_t)mac[1] << 8) | (uint32_t)mac[0];
+
+ txdscr_init(); /* initialize DMA TX Descriptor */
+ rxdscr_init(); /* initialize DMA RX Descriptor */
+
+ LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
+ /* Receive Broadcast, Perfect Match Packets */
+
+ LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */
+ LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */
+
+
+ LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */
+ LPC_EMAC->MAC1 |= MAC1_REC_EN;
+
+#if NEW_LOGIC
+ rx_consume_offset = -1;
+ tx_produce_offset = -1;
+#else
+ send_doff = 0;
+ send_idx = -1;
+ send_size = 0;
+
+ receive_soff = 0;
+ receive_idx = -1;
+#endif
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ Ethernet Device Uninitialize
+ *----------------------------------------------------------------------------*/
+void ethernet_free() {
+ LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE);
+ LPC_EMAC->IntClear = 0xFFFF;
+
+ LPC_SC->PCONP &= ~0x40000000; /* Power down the EMAC controller. */
+
+ LPC_PINCON->PINSEL2 &= ~0x50150105; /* Disable P1 ethernet pins. */
+ LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000000;
+}
+
+// if(TxProduceIndex == TxConsumeIndex) buffer array is empty
+// if(TxProduceIndex == TxConsumeIndex - 1) buffer is full, should not fill
+// TxProduceIndex - The buffer that will/is being fileld by driver, s/w increment
+// TxConsumeIndex - The buffer that will/is beign sent by hardware
+
+int ethernet_write(const char *data, int slen) {
+
+#if NEW_LOGIC
+
+ if(tx_produce_offset < 0) { // mark as active if not already
+ tx_produce_offset = 0;
+ }
+
+ int index = LPC_EMAC->TxProduceIndex;
+
+ int remaining = ETH_MAX_FLEN - tx_produce_offset - 4; // bytes written plus checksum
+ int requested = slen;
+ int ncopy = min(remaining, requested);
+
+ void *pdst = (void *)(txdesc[index].Packet + tx_produce_offset);
+ void *psrc = (void *)(data);
+
+ if(ncopy > 0 ){
+ if(data != NULL) {
+ memcpy(pdst, psrc, ncopy);
+ } else {
+ memset(pdst, 0, ncopy);
+ }
+ }
+
+ tx_produce_offset += ncopy;
+
+ return ncopy;
+
+#else
+ void *pdst, *psrc;
+ const int dlen = ETH_FRAG_SIZE;
+ int copy = 0;
+ int soff = 0;
+
+ if(send_idx == -1) {
+ send_idx = LPC_EMAC->TxProduceIndex;
+ }
+
+ if(slen + send_doff > ethernet_MTU_SIZE) {
+ return -1;
+ }
+
+ do {
+ copy = min(slen - soff, dlen - send_doff);
+ pdst = (void *)(txdesc[send_idx].Packet + send_doff);
+ psrc = (void *)(data + soff);
+ if(send_doff + copy > ETH_FRAG_SIZE) {
+ txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT);
+ send_idx = rinc(send_idx, NUM_TX_FRAG);
+ send_doff = 0;
+ }
+
+ if(data != NULL) {
+ memcpy(pdst, psrc, copy);
+ } else {
+ memset(pdst, 0, copy);
+ }
+
+ soff += copy;
+ send_doff += copy;
+ send_size += copy;
+ } while(soff != slen);
+
+ return soff;
+#endif
+}
+
+int ethernet_send() {
+
+#if NEW_LOGIC
+ if(tx_produce_offset < 0) { // no buffer active
+ return -1;
+ }
+
+ // ensure there is a link
+ if(!ethernet_link()) {
+ return -2;
+ }
+
+ // we have been writing in to a buffer, so finalise it
+ int size = tx_produce_offset;
+ int index = LPC_EMAC->TxProduceIndex;
+ txdesc[index].Ctrl = (tx_produce_offset-1) | (TCTRL_INT | TCTRL_LAST);
+
+ // Increment ProduceIndex to allow it to be sent
+ // We can only do this if the next slot is free
+ int next = rinc(index, NUM_TX_FRAG);
+ while(next == LPC_EMAC->TxConsumeIndex) {
+ for(int i=0; i<1000; i++) { __NOP(); }
+ }
+
+ LPC_EMAC->TxProduceIndex = next;
+ tx_produce_offset = -1;
+ return size;
+
+#else
+ int s = send_size;
+ txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT | TCTRL_LAST);
+ send_idx = rinc(send_idx, NUM_TX_FRAG);
+ LPC_EMAC->TxProduceIndex = send_idx;
+ send_doff = 0;
+ send_idx = -1;
+ send_size = 0;
+ return s;
+#endif
+}
+
+// RxConsmeIndex - The index of buffer the driver will/is reading from. Driver should inc once read
+// RxProduceIndex - The index of buffer that will/is being filled by MAC. H/w will inc once rxd
+//
+// if(RxConsumeIndex == RxProduceIndex) buffer array is empty
+// if(RxConsumeIndex == RxProduceIndex + 1) buffer array is full
+
+// Recevies an arrived ethernet packet.
+// Receiving an ethernet packet will drop the last received ethernet packet
+// and make a new ethernet packet ready to read.
+// Returns size of packet, else 0 if nothing to receive
+
+// We read from RxConsumeIndex from position rx_consume_offset
+// if rx_consume_offset < 0, then we have not recieved the RxConsumeIndex packet for reading
+// rx_consume_offset = -1 // no frame
+// rx_consume_offset = 0 // start of frame
+// Assumption: A fragment should alway be a whole frame
+
+int ethernet_receive() {
+#if NEW_LOGIC
+
+ // if we are currently reading a valid RxConsume buffer, increment to the next one
+ if(rx_consume_offset >= 0) {
+ LPC_EMAC->RxConsumeIndex = rinc(LPC_EMAC->RxConsumeIndex, NUM_RX_FRAG);
+ }
+
+ // if the buffer is empty, mark it as no valid buffer
+ if(LPC_EMAC->RxConsumeIndex == LPC_EMAC->RxProduceIndex) {
+ rx_consume_offset = -1;
+ return 0;
+ }
+
+ uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info;
+ rx_consume_offset = 0;
+
+ // check if it is not marked as last or for errors
+ if(!(info & RINFO_LAST_FLAG) || (info & RINFO_ERR_MASK)) {
+ return -1;
+ }
+
+ int size = (info & RINFO_SIZE) + 1;
+ return size - 4; // don't include checksum bytes
+
+#else
+ if(receive_idx == -1) {
+ receive_idx = LPC_EMAC->RxConsumeIndex;
+ } else {
+ while(!(rxstat[receive_idx].Info & RINFO_LAST_FLAG) && ((uint32_t)receive_idx != LPC_EMAC->RxProduceIndex)) {
+ receive_idx = rinc(receive_idx, NUM_RX_FRAG);
+ }
+ unsigned int info = rxstat[receive_idx].Info;
+ int slen = (info & RINFO_SIZE) + 1;
+
+ if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) {
+ /* Invalid frame, ignore it and free buffer. */
+ receive_idx = rinc(receive_idx, NUM_RX_FRAG);
+ }
+ receive_idx = rinc(receive_idx, NUM_RX_FRAG);
+ receive_soff = 0;
+
+ LPC_EMAC->RxConsumeIndex = receive_idx;
+ }
+
+ if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex) {
+ receive_idx = -1;
+ return 0;
+ }
+
+ return (rxstat[receive_idx].Info & RINFO_SIZE) - 3;
+#endif
+}
+
+// Read from an recevied ethernet packet.
+// After receive returnd a number bigger than 0 it is
+// possible to read bytes from this packet.
+// Read will write up to size bytes into data.
+// It is possible to use read multible times.
+// Each time read will start reading after the last read byte before.
+
+int ethernet_read(char *data, int dlen) {
+#if NEW_LOGIC
+ // Check we have a valid buffer to read
+ if(rx_consume_offset < 0) {
+ return 0;
+ }
+
+ // Assume 1 fragment block
+ uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info;
+ int size = (info & RINFO_SIZE) + 1 - 4; // exclude checksum
+
+ int remaining = size - rx_consume_offset;
+ int requested = dlen;
+ int ncopy = min(remaining, requested);
+
+ void *psrc = (void *)(rxdesc[LPC_EMAC->RxConsumeIndex].Packet + rx_consume_offset);
+ void *pdst = (void *)(data);
+
+ if(data != NULL && ncopy > 0) {
+ memcpy(pdst, psrc, ncopy);
+ }
+
+ rx_consume_offset += ncopy;
+
+ return ncopy;
+#else
+ int slen;
+ int copy = 0;
+ unsigned int more;
+ unsigned int info;
+ void *pdst, *psrc;
+ int doff = 0;
+
+ if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex || receive_idx == -1) {
+ return 0;
+ }
+
+ do {
+ info = rxstat[receive_idx].Info;
+ more = !(info & RINFO_LAST_FLAG);
+ slen = (info & RINFO_SIZE) + 1;
+
+ if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) {
+ /* Invalid frame, ignore it and free buffer. */
+ receive_idx = rinc(receive_idx, NUM_RX_FRAG);
+ } else {
+
+ copy = min(slen - receive_soff, dlen - doff);
+ psrc = (void *)(rxdesc[receive_idx].Packet + receive_soff);
+ pdst = (void *)(data + doff);
+
+ if(data != NULL) {
+ /* check if Buffer available */
+ memcpy(pdst, psrc, copy);
+ }
+
+ receive_soff += copy;
+ doff += copy;
+
+ if((more && (receive_soff == slen))) {
+ receive_idx = rinc(receive_idx, NUM_RX_FRAG);
+ receive_soff = 0;
+ }
+ }
+ } while(more && !(doff == dlen) && !receive_soff);
+
+ return doff;
+#endif
+}
+
+int ethernet_link(void) {
+ if (phy_id == DP83848C_ID) {
+ return (phy_read(PHY_REG_STS) & PHY_STS_LINK);
+ }
+ else { // LAN8720_ID
+ return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK);
+ }
+}
+
+static int phy_write(unsigned int PhyReg, unsigned short Data) {
+ unsigned int timeOut;
+
+ LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+ LPC_EMAC->MWTD = Data;
+
+ for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */
+ if((LPC_EMAC->MIND & MIND_BUSY) == 0) {
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int phy_read(unsigned int PhyReg) {
+ unsigned int timeOut;
+
+ LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;
+ LPC_EMAC->MCMD = MCMD_READ;
+
+ for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */
+ if((LPC_EMAC->MIND & MIND_BUSY) == 0) {
+ LPC_EMAC->MCMD = 0;
+ return LPC_EMAC->MRDD; /* Return a 16-bit value. */
+ }
+ }
+
+ return -1;
+}
+
+
+static void txdscr_init() {
+ int i;
+
+ for(i = 0; i < NUM_TX_FRAG; i++) {
+ txdesc[i].Packet = (uint32_t)&txbuf[i];
+ txdesc[i].Ctrl = 0;
+ txstat[i].Info = 0;
+ }
+
+ LPC_EMAC->TxDescriptor = (uint32_t)txdesc; /* Set EMAC Transmit Descriptor Registers. */
+ LPC_EMAC->TxStatus = (uint32_t)txstat;
+ LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1;
+
+ LPC_EMAC->TxProduceIndex = 0; /* Tx Descriptors Point to 0 */
+}
+
+static void rxdscr_init() {
+ int i;
+
+ for(i = 0; i < NUM_RX_FRAG; i++) {
+ rxdesc[i].Packet = (uint32_t)&rxbuf[i];
+ rxdesc[i].Ctrl = RCTRL_INT | (ETH_FRAG_SIZE-1);
+ rxstat[i].Info = 0;
+ rxstat[i].HashCRC = 0;
+ }
+
+ LPC_EMAC->RxDescriptor = (uint32_t)rxdesc; /* Set EMAC Receive Descriptor Registers. */
+ LPC_EMAC->RxStatus = (uint32_t)rxstat;
+ LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1;
+
+ LPC_EMAC->RxConsumeIndex = 0; /* Rx Descriptors Point to 0 */
+}
+
+void ethernet_address(char *mac) {
+ mbed_mac_address(mac);
+}
+
+void ethernet_set_link(int speed, int duplex) {
+ unsigned short phy_data;
+ int tout;
+
+ if((speed < 0) || (speed > 1)) {
+ phy_data = PHY_AUTO_NEG;
+ } else {
+ phy_data = (((unsigned short) speed << 13) |
+ ((unsigned short) duplex << 8));
+ }
+
+ phy_write(PHY_REG_BMCR, phy_data);
+
+ for(tout = 100; tout; tout--) { __NOP(); } /* A short delay */
+
+ switch(phy_id) {
+ case DP83848C_ID:
+ phy_data = phy_read(PHY_REG_STS);
+
+ if(phy_data & PHY_STS_DUPLEX) {
+ LPC_EMAC->MAC2 |= MAC2_FULL_DUP;
+ LPC_EMAC->Command |= CR_FULL_DUP;
+ LPC_EMAC->IPGT = IPGT_FULL_DUP;
+ } else {
+ LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP;
+ LPC_EMAC->Command &= ~CR_FULL_DUP;
+ LPC_EMAC->IPGT = IPGT_HALF_DUP;
+ }
+
+ if(phy_data & PHY_STS_SPEED) {
+ LPC_EMAC->SUPP &= ~SUPP_SPEED;
+ } else {
+ LPC_EMAC->SUPP |= SUPP_SPEED;
+ }
+ break;
+
+ case LAN8720_ID:
+ phy_data = phy_read(PHY_REG_SCSR);
+
+ if (phy_data & PHY_SCSR_DUPLEX) {
+ LPC_EMAC->MAC2 |= MAC2_FULL_DUP;
+ LPC_EMAC->Command |= CR_FULL_DUP;
+ LPC_EMAC->IPGT = IPGT_FULL_DUP;
+ } else {
+ LPC_EMAC->Command &= ~CR_FULL_DUP;
+ LPC_EMAC->IPGT = IPGT_HALF_DUP;
+ }
+
+ if(phy_data & PHY_SCSR_100MBIT) {
+ LPC_EMAC->SUPP |= SUPP_SPEED;
+ } else {
+ LPC_EMAC->SUPP &= ~SUPP_SPEED;
+ }
+ break;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/gpio_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,57 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "gpio_api.h"
+#include "pinmap.h"
+
+uint32_t gpio_set(PinName pin) {
+ LPC_SC->SCS |= 1; // High speed GPIO is enabled on ports 0 and 1
+
+ pin_function(pin, 0);
+
+ return (1 << ((int)pin & 0x1F));
+}
+
+void gpio_init(gpio_t *obj, PinName pin) {
+ if (pin == (PinName)NC)
+ return;
+ obj->pin = pin;
+ if (pin == (PinName)NC)
+ return;
+
+ obj->mask = gpio_set(pin);
+
+ LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *) ((int)pin & ~0x1F);
+
+ obj->reg_set = &port_reg->FIOSET;
+ obj->reg_mask = &port_reg->FIOMASK;
+ obj->reg_clr = &port_reg->FIOCLR;
+ obj->reg_in = &port_reg->FIOPIN;
+ obj->reg_dir = &port_reg->FIODIR;
+}
+
+void gpio_mode(gpio_t *obj, PinMode mode) {
+ pin_mode(obj->pin, mode);
+}
+
+void gpio_dir(gpio_t *obj, PinDirection direction) {
+ if (obj->pin == (PinName)NC)
+ return;
+ switch (direction) {
+ case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break;
+ case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/gpio_irq_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,154 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "gpio_irq_api.h"
+#include "mbed_error.h"
+#include <stddef.h>
+#include "cmsis.h"
+
+#define CHANNEL_NUM 48
+
+static uint32_t channel_ids[CHANNEL_NUM] = {0};
+static gpio_irq_handler irq_handler;
+
+static void handle_interrupt_in(void) {
+ // Read in all current interrupt registers. We do this once as the
+ // GPIO interrupt registers are on the APB bus, and this is slow.
+ uint32_t rise0 = LPC_GPIOINT->IO0IntStatR;
+ uint32_t fall0 = LPC_GPIOINT->IO0IntStatF;
+ uint32_t rise2 = LPC_GPIOINT->IO2IntStatR;
+ uint32_t fall2 = LPC_GPIOINT->IO2IntStatF;
+ uint32_t mask0 = 0;
+ uint32_t mask2 = 0;
+ int i;
+
+ // P0.0-0.31
+ for (i = 0; i < 32; i++) {
+ uint32_t pmask = (1 << i);
+ if (rise0 & pmask) {
+ mask0 |= pmask;
+ if (channel_ids[i] != 0)
+ irq_handler(channel_ids[i], IRQ_RISE);
+ }
+ if (fall0 & pmask) {
+ mask0 |= pmask;
+ if (channel_ids[i] != 0)
+ irq_handler(channel_ids[i], IRQ_FALL);
+ }
+ }
+
+ // P2.0-2.15
+ for (i = 0; i < 16; i++) {
+ uint32_t pmask = (1 << i);
+ int channel_index = i + 32;
+ if (rise2 & pmask) {
+ mask2 |= pmask;
+ if (channel_ids[channel_index] != 0)
+ irq_handler(channel_ids[channel_index], IRQ_RISE);
+ }
+ if (fall2 & pmask) {
+ mask2 |= pmask;
+ if (channel_ids[channel_index] != 0)
+ irq_handler(channel_ids[channel_index], IRQ_FALL);
+ }
+ }
+
+ // Clear the interrupts we just handled
+ LPC_GPIOINT->IO0IntClr = mask0;
+ LPC_GPIOINT->IO2IntClr = mask2;
+}
+
+int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
+ if (pin == NC) return -1;
+
+ irq_handler = handler;
+
+ obj->port = (int)pin & ~0x1F;
+ obj->pin = (int)pin & 0x1F;
+
+ // Interrupts available only on GPIO0 and GPIO2
+ if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) {
+ error("pins on this port cannot generate interrupts");
+ }
+
+ // put us in the interrupt table
+ int index = (obj->port == LPC_GPIO0_BASE) ? obj->pin : obj->pin + 32;
+ channel_ids[index] = id;
+ obj->ch = index;
+
+ NVIC_SetVector(EINT3_IRQn, (uint32_t)handle_interrupt_in);
+ NVIC_EnableIRQ(EINT3_IRQn);
+
+ return 0;
+}
+
+void gpio_irq_free(gpio_irq_t *obj) {
+ channel_ids[obj->ch] = 0;
+}
+
+void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
+ // ensure nothing is pending
+ switch (obj->port) {
+ case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break;
+ case LPC_GPIO2_BASE: LPC_GPIOINT->IO2IntClr = 1 << obj->pin; break;
+ }
+
+ // enable the pin interrupt
+ if (event == IRQ_RISE) {
+ switch (obj->port) {
+ case LPC_GPIO0_BASE:
+ if (enable) {
+ LPC_GPIOINT->IO0IntEnR |= 1 << obj->pin;
+ } else {
+ LPC_GPIOINT->IO0IntEnR &= ~(1 << obj->pin);
+ }
+ break;
+ case LPC_GPIO2_BASE:
+ if (enable) {
+ LPC_GPIOINT->IO2IntEnR |= 1 << obj->pin;
+ } else {
+ LPC_GPIOINT->IO2IntEnR &= ~(1 << obj->pin);
+ }
+ break;
+ }
+ } else {
+ switch (obj->port) {
+ case LPC_GPIO0_BASE:
+ if (enable) {
+ LPC_GPIOINT->IO0IntEnF |= 1 << obj->pin;
+ } else {
+ LPC_GPIOINT->IO0IntEnF &= ~(1 << obj->pin);
+ }
+ break;
+
+ case LPC_GPIO2_BASE:
+ if (enable) {
+ LPC_GPIOINT->IO2IntEnF |= 1 << obj->pin;
+ } else {
+ LPC_GPIOINT->IO2IntEnF &= ~(1 << obj->pin);
+ }
+ break;
+ }
+ }
+}
+
+void gpio_irq_enable(gpio_irq_t *obj) {
+ NVIC_EnableIRQ(EINT3_IRQn);
+}
+
+void gpio_irq_disable(gpio_irq_t *obj) {
+ NVIC_DisableIRQ(EINT3_IRQn);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/gpio_object.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,59 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_GPIO_OBJECT_H
+#define MBED_GPIO_OBJECT_H
+
+#include "mbed_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ PinName pin;
+ uint32_t mask;
+
+ __IO uint32_t *reg_dir;
+ __IO uint32_t *reg_mask;
+ __IO uint32_t *reg_set;
+ __IO uint32_t *reg_clr;
+ __I uint32_t *reg_in;
+} gpio_t;
+
+static inline void gpio_write(gpio_t *obj, int value) {
+ MBED_ASSERT(obj->pin != (PinName)NC);
+ *obj->reg_mask &= ~obj->mask;
+ if (value)
+ *obj->reg_set = obj->mask;
+ else
+ *obj->reg_clr = obj->mask;
+}
+
+static inline int gpio_read(gpio_t *obj) {
+ MBED_ASSERT(obj->pin != (PinName)NC);
+ *obj->reg_mask &= ~obj->mask;
+ return ((*obj->reg_in & obj->mask) ? 1 : 0);
+}
+
+static inline int gpio_is_connected(const gpio_t *obj) {
+ return obj->pin != (PinName)NC;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/i2c_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,399 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "i2c_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+
+static const PinMap PinMap_I2C_SDA[] = {
+ {P0_0 , I2C_1, 3},
+ {P0_10, I2C_2, 2},
+ {P0_19, I2C_1, 3},
+ {P0_27, I2C_0, 1},
+ {P2_14, I2C_1, 3},
+ {P2_30, I2C_2, 3},
+ {P4_20, I2C_2, 2},
+ {NC , NC , 0}
+};
+
+static const PinMap PinMap_I2C_SCL[] = {
+ {P0_1 , I2C_1, 3},
+ {P0_11, I2C_2, 2},
+ {P0_20, I2C_1, 3},
+ {P0_28, I2C_0, 1},
+ {P2_15, I2C_1, 3},
+ {P2_31, I2C_2, 3},
+ {P4_21, I2C_2, 2},
+ {NC , NC, 0}
+};
+
+#define I2C_CONSET(x) (x->i2c->I2CONSET)
+#define I2C_CONCLR(x) (x->i2c->I2CONCLR)
+#define I2C_STAT(x) (x->i2c->I2STAT)
+#define I2C_DAT(x) (x->i2c->I2DAT)
+#define I2C_SCLL(x, val) (x->i2c->I2SCLL = val)
+#define I2C_SCLH(x, val) (x->i2c->I2SCLH = val)
+
+static const uint32_t I2C_addr_offset[2][4] = {
+ {0x0C, 0x20, 0x24, 0x28},
+ {0x30, 0x34, 0x38, 0x3C}
+};
+
+static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
+ I2C_CONCLR(obj) = (start << 5)
+ | (stop << 4)
+ | (interrupt << 3)
+ | (acknowledge << 2);
+}
+
+static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
+ I2C_CONSET(obj) = (start << 5)
+ | (stop << 4)
+ | (interrupt << 3)
+ | (acknowledge << 2);
+}
+
+// Clear the Serial Interrupt (SI)
+static inline void i2c_clear_SI(i2c_t *obj) {
+ i2c_conclr(obj, 0, 0, 1, 0);
+}
+
+static inline int i2c_status(i2c_t *obj) {
+ return I2C_STAT(obj);
+}
+
+// Wait until the Serial Interrupt (SI) is set
+static int i2c_wait_SI(i2c_t *obj) {
+ int timeout = 0;
+ while (!(I2C_CONSET(obj) & (1 << 3))) {
+ timeout++;
+ if (timeout > 100000) return -1;
+ }
+ return 0;
+}
+
+static inline void i2c_interface_enable(i2c_t *obj) {
+ I2C_CONSET(obj) = 0x40;
+}
+
+static inline void i2c_power_enable(i2c_t *obj) {
+ switch ((int)obj->i2c) {
+ case I2C_0: LPC_SC->PCONP |= 1 << PCI2C0; break;
+ case I2C_1: LPC_SC->PCONP |= 1 << PCI2C1; break;
+ case I2C_2: LPC_SC->PCONP |= 1 << PCI2C2; break;
+ }
+}
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
+ // determine the SPI to use
+ I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
+ I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
+ obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
+ MBED_ASSERT((int)obj->i2c != NC);
+
+ // enable power
+ i2c_power_enable(obj);
+
+ // set default frequency at 100k
+ i2c_frequency(obj, 100000);
+ i2c_conclr(obj, 1, 1, 1, 1);
+ i2c_interface_enable(obj);
+
+ pinmap_pinout(sda, PinMap_I2C_SDA);
+ pinmap_pinout(scl, PinMap_I2C_SCL);
+}
+
+inline int i2c_start(i2c_t *obj) {
+ int status = 0;
+ // 8.1 Before master mode can be entered, I2CON must be initialised to:
+ // - I2EN STA STO SI AA - -
+ // - 1 0 0 0 x - -
+ // if AA = 0, it can't enter slave mode
+ i2c_conclr(obj, 1, 1, 1, 1);
+
+ // The master mode may now be entered by setting the STA bit
+ // this will generate a start condition when the bus becomes free
+ i2c_conset(obj, 1, 0, 0, 1);
+
+ i2c_wait_SI(obj);
+ status = i2c_status(obj);
+
+ // Clear start bit now transmitted, and interrupt bit
+ i2c_conclr(obj, 1, 0, 0, 0);
+ return status;
+}
+
+inline int i2c_stop(i2c_t *obj) {
+ int timeout = 0;
+
+ // write the stop bit
+ i2c_conset(obj, 0, 1, 0, 0);
+ i2c_clear_SI(obj);
+
+ // wait for STO bit to reset
+ while (I2C_CONSET(obj) & (1 << 4)) {
+ timeout ++;
+ if (timeout > 100000) return 1;
+ }
+
+ return 0;
+}
+
+static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
+ // write the data
+ I2C_DAT(obj) = value;
+
+ // clear SI to init a send
+ i2c_clear_SI(obj);
+
+ // wait and return status
+ i2c_wait_SI(obj);
+ return i2c_status(obj);
+}
+
+static inline int i2c_do_read(i2c_t *obj, int last) {
+ // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack)
+ if (last) {
+ i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK
+ } else {
+ i2c_conset(obj, 0, 0, 0, 1); // send a ACK
+ }
+
+ // accept byte
+ i2c_clear_SI(obj);
+
+ // wait for it to arrive
+ i2c_wait_SI(obj);
+
+ // return the data
+ return (I2C_DAT(obj) & 0xFF);
+}
+
+void i2c_frequency(i2c_t *obj, int hz) {
+ // [TODO] set pclk to /4
+ uint32_t PCLK = SystemCoreClock / 4;
+
+ uint32_t pulse = PCLK / (hz * 2);
+
+ // I2C Rate
+ I2C_SCLL(obj, pulse);
+ I2C_SCLH(obj, pulse);
+}
+
+// The I2C does a read or a write as a whole operation
+// There are two types of error conditions it can encounter
+// 1) it can not obtain the bus
+// 2) it gets error responses at part of the transmission
+//
+// We tackle them as follows:
+// 1) we retry until we get the bus. we could have a "timeout" if we can not get it
+// which basically turns it in to a 2)
+// 2) on error, we use the standard error mechanisms to report/debug
+//
+// Therefore an I2C transaction should always complete. If it doesn't it is usually
+// because something is setup wrong (e.g. wiring), and we don't need to programatically
+// check for that
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
+ int count, status;
+
+ status = i2c_start(obj);
+
+ if ((status != 0x10) && (status != 0x08)) {
+ i2c_stop(obj);
+ return I2C_ERROR_BUS_BUSY;
+ }
+
+ status = i2c_do_write(obj, (address | 0x01), 1);
+ if (status != 0x40) {
+ i2c_stop(obj);
+ return I2C_ERROR_NO_SLAVE;
+ }
+
+ // Read in all except last byte
+ for (count = 0; count < (length - 1); count++) {
+ int value = i2c_do_read(obj, 0);
+ status = i2c_status(obj);
+ if (status != 0x50) {
+ i2c_stop(obj);
+ return count;
+ }
+ data[count] = (char) value;
+ }
+
+ // read in last byte
+ int value = i2c_do_read(obj, 1);
+ status = i2c_status(obj);
+ if (status != 0x58) {
+ i2c_stop(obj);
+ return length - 1;
+ }
+
+ data[count] = (char) value;
+
+ // If not repeated start, send stop.
+ if (stop) {
+ i2c_stop(obj);
+ }
+
+ return length;
+}
+
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
+ int i, status;
+
+ status = i2c_start(obj);
+
+ if ((status != 0x10) && (status != 0x08)) {
+ i2c_stop(obj);
+ return I2C_ERROR_BUS_BUSY;
+ }
+
+ status = i2c_do_write(obj, (address & 0xFE), 1);
+ if (status != 0x18) {
+ i2c_stop(obj);
+ return I2C_ERROR_NO_SLAVE;
+ }
+
+ for (i=0; i<length; i++) {
+ status = i2c_do_write(obj, data[i], 0);
+ if (status != 0x28) {
+ i2c_stop(obj);
+ return i;
+ }
+ }
+
+ // clearing the serial interrupt here might cause an unintended rewrite of the last byte
+ // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1
+ // i2c_clear_SI(obj);
+
+ // If not repeated start, send stop.
+ if (stop) {
+ i2c_stop(obj);
+ }
+
+ return length;
+}
+
+void i2c_reset(i2c_t *obj) {
+ i2c_stop(obj);
+}
+
+int i2c_byte_read(i2c_t *obj, int last) {
+ return (i2c_do_read(obj, last) & 0xFF);
+}
+
+int i2c_byte_write(i2c_t *obj, int data) {
+ int ack;
+ int status = i2c_do_write(obj, (data & 0xFF), 0);
+
+ switch(status) {
+ case 0x18: case 0x28: // Master transmit ACKs
+ ack = 1;
+ break;
+
+ case 0x40: // Master receive address transmitted ACK
+ ack = 1;
+ break;
+
+ case 0xB8: // Slave transmit ACK
+ ack = 1;
+ break;
+
+ default:
+ ack = 0;
+ break;
+ }
+
+ return ack;
+}
+
+void i2c_slave_mode(i2c_t *obj, int enable_slave) {
+ if (enable_slave != 0) {
+ i2c_conclr(obj, 1, 1, 1, 0);
+ i2c_conset(obj, 0, 0, 0, 1);
+ } else {
+ i2c_conclr(obj, 1, 1, 1, 1);
+ }
+}
+
+int i2c_slave_receive(i2c_t *obj) {
+ int status;
+ int retval;
+
+ status = i2c_status(obj);
+ switch(status) {
+ case 0x60: retval = 3; break;
+ case 0x70: retval = 2; break;
+ case 0xA8: retval = 1; break;
+ default : retval = 0; break;
+ }
+
+ return(retval);
+}
+
+int i2c_slave_read(i2c_t *obj, char *data, int length) {
+ int count = 0;
+ int status;
+
+ do {
+ i2c_clear_SI(obj);
+ i2c_wait_SI(obj);
+ status = i2c_status(obj);
+ if((status == 0x80) || (status == 0x90)) {
+ data[count] = I2C_DAT(obj) & 0xFF;
+ }
+ count++;
+ } while (((status == 0x80) || (status == 0x90) ||
+ (status == 0x060) || (status == 0x70)) && (count < length));
+
+ if(status != 0xA0) {
+ i2c_stop(obj);
+ }
+
+ i2c_clear_SI(obj);
+
+ return count;
+}
+
+int i2c_slave_write(i2c_t *obj, const char *data, int length) {
+ int count = 0;
+ int status;
+
+ if(length <= 0) {
+ return(0);
+ }
+
+ do {
+ status = i2c_do_write(obj, data[count], 0);
+ count++;
+ } while ((count < length) && (status == 0xB8));
+
+ if((status != 0xC0) && (status != 0xC8)) {
+ i2c_stop(obj);
+ }
+
+ i2c_clear_SI(obj);
+
+ return(count);
+}
+
+void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
+ uint32_t addr;
+
+ if ((idx >= 0) && (idx <= 3)) {
+ addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx];
+ *((uint32_t *) addr) = address & 0xFF;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/objects.h Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,78 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_OBJECTS_H
+#define MBED_OBJECTS_H
+
+#include "cmsis.h"
+#include "PortNames.h"
+#include "PeripheralNames.h"
+#include "PinNames.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct gpio_irq_s {
+ uint32_t port;
+ uint32_t pin;
+ uint32_t ch;
+};
+
+struct port_s {
+ __IO uint32_t *reg_dir;
+ __IO uint32_t *reg_out;
+ __I uint32_t *reg_in;
+ PortName port;
+ uint32_t mask;
+};
+
+struct pwmout_s {
+ __IO uint32_t *MR;
+ PWMName pwm;
+};
+
+struct serial_s {
+ LPC_UART_TypeDef *uart;
+ int index;
+};
+
+struct analogin_s {
+ ADCName adc;
+};
+
+struct dac_s {
+ DACName dac;
+};
+
+struct can_s {
+ LPC_CAN_TypeDef *dev;
+};
+
+struct i2c_s {
+ LPC_I2C_TypeDef *i2c;
+};
+
+struct spi_s {
+ LPC_SSP_TypeDef *spi;
+};
+
+#include "gpio_object.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/pinmap.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+
+void pin_function(PinName pin, int function) {
+ MBED_ASSERT(pin != (PinName)NC);
+
+ uint32_t pin_number = (uint32_t)pin - (uint32_t)P0_0;
+ int index = pin_number >> 4;
+ int offset = (pin_number & 0xF) << 1;
+
+ PINCONARRAY->PINSEL[index] &= ~(0x3 << offset);
+ PINCONARRAY->PINSEL[index] |= function << offset;
+}
+
+void pin_mode(PinName pin, PinMode mode) {
+ MBED_ASSERT((pin != (PinName)NC) && (mode != OpenDrain));
+
+ uint32_t pin_number = (uint32_t)pin - (uint32_t)P0_0;
+ int index = pin_number >> 5;
+ int offset = pin_number & 0x1F;
+ uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2;
+
+ if (!drain) {
+ index = pin_number >> 4;
+ offset = (pin_number & 0xF) << 1;
+
+ PINCONARRAY->PINMODE[index] &= ~(0x3 << offset);
+ PINCONARRAY->PINMODE[index] |= (uint32_t)mode << offset;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/port_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,71 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "port_api.h"
+#include "pinmap.h"
+#include "gpio_api.h"
+
+PinName port_pin(PortName port, int pin_n) {
+ return (PinName)(LPC_GPIO0_BASE + ((port << PORT_SHIFT) | pin_n));
+}
+
+void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
+ obj->port = port;
+ obj->mask = mask;
+
+ LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + ((int)port * 0x20));
+
+ // Do not use masking, because it prevents the use of the unmasked pins
+ // port_reg->FIOMASK = ~mask;
+
+ obj->reg_out = &port_reg->FIOPIN;
+ obj->reg_in = &port_reg->FIOPIN;
+ obj->reg_dir = &port_reg->FIODIR;
+
+ uint32_t i;
+ // The function is set per pin: reuse gpio logic
+ for (i=0; i<32; i++) {
+ if (obj->mask & (1<<i)) {
+ gpio_set(port_pin(obj->port, i));
+ }
+ }
+
+ port_dir(obj, dir);
+}
+
+void port_mode(port_t *obj, PinMode mode) {
+ uint32_t i;
+ // The mode is set per pin: reuse pinmap logic
+ for (i=0; i<32; i++) {
+ if (obj->mask & (1<<i)) {
+ pin_mode(port_pin(obj->port, i), mode);
+ }
+ }
+}
+
+void port_dir(port_t *obj, PinDirection dir) {
+ switch (dir) {
+ case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break;
+ case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break;
+ }
+}
+
+void port_write(port_t *obj, int value) {
+ *obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask);
+}
+
+int port_read(port_t *obj) {
+ return (*obj->reg_in & obj->mask);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/pwmout_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,175 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include "pwmout_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+
+#define TCR_CNT_EN 0x00000001
+#define TCR_RESET 0x00000002
+
+// PORT ID, PWM ID, Pin function
+static const PinMap PinMap_PWM[] = {
+ {P1_18, PWM_1, 2},
+ {P1_20, PWM_2, 2},
+ {P1_21, PWM_3, 2},
+ {P1_23, PWM_4, 2},
+ {P1_24, PWM_5, 2},
+ {P1_26, PWM_6, 2},
+ {P2_0 , PWM_1, 1},
+ {P2_1 , PWM_2, 1},
+ {P2_2 , PWM_3, 1},
+ {P2_3 , PWM_4, 1},
+ {P2_4 , PWM_5, 1},
+ {P2_5 , PWM_6, 1},
+ {P3_24, PWM_1, 3},
+ {P3_25, PWM_2, 3},
+ {P3_26, PWM_3, 3},
+ {P3_27, PWM_4, 3},
+ {P3_28, PWM_5, 3},
+ {P3_29, PWM_6, 3},
+ {NC, NC, 0}
+};
+
+__IO uint32_t *PWM_MATCH[] = {
+ &(LPC_PWM1->MR0),
+ &(LPC_PWM1->MR1),
+ &(LPC_PWM1->MR2),
+ &(LPC_PWM1->MR3),
+ &(LPC_PWM1->MR4),
+ &(LPC_PWM1->MR5),
+ &(LPC_PWM1->MR6)
+};
+
+#define TCR_PWM_EN 0x00000008
+
+static unsigned int pwm_clock_mhz;
+
+void pwmout_init(pwmout_t* obj, PinName pin) {
+ // determine the channel
+ PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
+ MBED_ASSERT(pwm != (PWMName)NC);
+
+ obj->pwm = pwm;
+ obj->MR = PWM_MATCH[pwm];
+
+ // ensure the power is on
+ LPC_SC->PCONP |= 1 << 6;
+
+ // ensure clock to /4
+ LPC_SC->PCLKSEL0 &= ~(0x3 << 12); // pclk = /4
+ LPC_PWM1->PR = 0; // no pre-scale
+
+ // ensure single PWM mode
+ LPC_PWM1->MCR = 1 << 1; // reset TC on match 0
+
+ // enable the specific PWM output
+ LPC_PWM1->PCR |= 1 << (8 + pwm);
+
+ pwm_clock_mhz = SystemCoreClock / 4000000;
+
+ // default to 20ms: standard for servos, and fine for e.g. brightness control
+ pwmout_period_ms(obj, 20);
+ pwmout_write (obj, 0);
+
+ // Wire pinout
+ pinmap_pinout(pin, PinMap_PWM);
+}
+
+void pwmout_free(pwmout_t* obj) {
+ // [TODO]
+}
+
+void pwmout_write(pwmout_t* obj, float value) {
+ if (value < 0.0f) {
+ value = 0.0;
+ } else if (value > 1.0f) {
+ value = 1.0;
+ }
+
+ // set channel match to percentage
+ uint32_t v = (uint32_t)((float)(LPC_PWM1->MR0) * value);
+
+ // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
+ if (v == LPC_PWM1->MR0) {
+ v++;
+ }
+
+ *obj->MR = v;
+
+ // accept on next period start
+ LPC_PWM1->LER |= 1 << obj->pwm;
+}
+
+float pwmout_read(pwmout_t* obj) {
+ float v = (float)(*obj->MR) / (float)(LPC_PWM1->MR0);
+ return (v > 1.0f) ? (1.0f) : (v);
+}
+
+void pwmout_period(pwmout_t* obj, float seconds) {
+ pwmout_period_us(obj, seconds * 1000000.0f);
+}
+
+void pwmout_period_ms(pwmout_t* obj, int ms) {
+ pwmout_period_us(obj, ms * 1000);
+}
+
+// Set the PWM period, keeping the duty cycle the same.
+void pwmout_period_us(pwmout_t* obj, int us) {
+ // calculate number of ticks
+ uint32_t ticks = pwm_clock_mhz * us;
+
+ // set reset
+ LPC_PWM1->TCR = TCR_RESET;
+
+ // set the global match register
+ LPC_PWM1->MR0 = ticks;
+
+ // Scale the pulse width to preserve the duty ratio
+ if (LPC_PWM1->MR0 > 0) {
+ *obj->MR = (*obj->MR * ticks) / LPC_PWM1->MR0;
+ }
+
+ // set the channel latch to update value at next period start
+ LPC_PWM1->LER |= 1 << 0;
+
+ // enable counter and pwm, clear reset
+ LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN;
+}
+
+void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
+ pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
+}
+
+void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
+ pwmout_pulsewidth_us(obj, ms * 1000);
+}
+
+void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
+ // calculate number of ticks
+ uint32_t v = pwm_clock_mhz * us;
+
+ // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
+ if (v == LPC_PWM1->MR0) {
+ v++;
+ }
+
+ // set the match register value
+ *obj->MR = v;
+
+ // set the channel latch to update value at next period start
+ LPC_PWM1->LER |= 1 << obj->pwm;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/rtc_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,117 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "rtc_api.h"
+
+// ensure rtc is running (unchanged if already running)
+
+/* Setup the RTC based on a time structure, ensuring RTC is enabled
+ *
+ * Can be clocked by a 32.768KHz oscillator or prescale divider based on the APB clock
+ * - We want to use the 32khz clock, allowing for sleep mode
+ *
+ * Most registers are not changed by a Reset
+ * - We must initialize these registers between power-on and setting the RTC into operation
+
+ * Clock Control Register
+ * RTC_CCR[0] : Enable - 0 = Disabled, 1 = Enabled
+ * RTC_CCR[1] : Reset - 0 = Normal, 1 = Reset
+ * RTC_CCR[4] : Clock Source - 0 = Prescaler, 1 = 32k Xtal
+ *
+ * The RTC may already be running, so we should set it up
+ * without impacting if it is the case
+ */
+void rtc_init(void) {
+ LPC_SC->PCONP |= (1 << PCRTC); // Ensure power is on
+ LPC_RTC->CCR = 0x00;
+
+ // clock source on 2368 is special test mode on 1768!
+ LPC_RTC->CCR |= 1 << 4; // Ensure clock source is 32KHz Xtal
+
+ LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled
+}
+
+void rtc_free(void) {
+ // [TODO]
+}
+
+/*
+ * Little check routine to see if the RTC has been enabled
+ *
+ * Clock Control Register
+ * RTC_CCR[0] : 0 = Disabled, 1 = Enabled
+ *
+ */
+
+int rtc_isenabled(void) {
+ return(((LPC_RTC->CCR) & 0x01) != 0);
+}
+
+/*
+ * RTC Registers
+ * RTC_SEC Seconds 0-59
+ * RTC_MIN Minutes 0-59
+ * RTC_HOUR Hour 0-23
+ * RTC_DOM Day of Month 1-28..31
+ * RTC_DOW Day of Week 0-6
+ * RTC_DOY Day of Year 1-365
+ * RTC_MONTH Month 1-12
+ * RTC_YEAR Year 0-4095
+ *
+ * struct tm
+ * tm_sec seconds after the minute 0-61
+ * tm_min minutes after the hour 0-59
+ * tm_hour hours since midnight 0-23
+ * tm_mday day of the month 1-31
+ * tm_mon months since January 0-11
+ * tm_year years since 1900
+ * tm_wday days since Sunday 0-6
+ * tm_yday days since January 1 0-365
+ * tm_isdst Daylight Saving Time flag
+ */
+time_t rtc_read(void) {
+ // Setup a tm structure based on the RTC
+ struct tm timeinfo;
+ timeinfo.tm_sec = LPC_RTC->SEC;
+ timeinfo.tm_min = LPC_RTC->MIN;
+ timeinfo.tm_hour = LPC_RTC->HOUR;
+ timeinfo.tm_mday = LPC_RTC->DOM;
+ timeinfo.tm_mon = LPC_RTC->MONTH - 1;
+ timeinfo.tm_year = LPC_RTC->YEAR - 1900;
+
+ // Convert to timestamp
+ time_t t = mktime(&timeinfo);
+
+ return t;
+}
+
+void rtc_write(time_t t) {
+ // Convert the time in to a tm
+ struct tm *timeinfo = localtime(&t);
+
+ // Pause clock, and clear counter register (clears us count)
+ LPC_RTC->CCR |= 2;
+
+ // Set the RTC
+ LPC_RTC->SEC = timeinfo->tm_sec;
+ LPC_RTC->MIN = timeinfo->tm_min;
+ LPC_RTC->HOUR = timeinfo->tm_hour;
+ LPC_RTC->DOM = timeinfo->tm_mday;
+ LPC_RTC->MONTH = timeinfo->tm_mon + 1;
+ LPC_RTC->YEAR = timeinfo->tm_year + 1900;
+
+ // Restart clock
+ LPC_RTC->CCR &= ~((uint32_t)2);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/serial_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,338 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// math.h required for floating point operations for baud rate calculation
+#include "mbed_assert.h"
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "serial_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+
+/******************************************************************************
+ * INITIALIZATION
+ ******************************************************************************/
+#define UART_NUM 4
+
+static const PinMap PinMap_UART_TX[] = {
+ {P0_0, UART_3, 2},
+ {P0_2, UART_0, 1},
+ {P0_10, UART_2, 1},
+ {P0_15, UART_1, 1},
+ {P0_25, UART_3, 3},
+ {P2_0 , UART_1, 2},
+ {P2_8 , UART_2, 2},
+ {P4_28, UART_3, 3},
+ {NC , NC , 0}
+};
+
+static const PinMap PinMap_UART_RX[] = {
+ {P0_1 , UART_3, 2},
+ {P0_3 , UART_0, 1},
+ {P0_11, UART_2, 1},
+ {P0_16, UART_1, 1},
+ {P0_26, UART_3, 3},
+ {P2_1 , UART_1, 2},
+ {P2_9 , UART_2, 2},
+ {P4_29, UART_3, 3},
+ {NC , NC , 0}
+};
+
+static uint32_t serial_irq_ids[UART_NUM] = {0};
+static uart_irq_handler irq_handler;
+
+int stdio_uart_inited = 0;
+serial_t stdio_uart;
+
+void serial_init(serial_t *obj, PinName tx, PinName rx) {
+ int is_stdio_uart = 0;
+
+ // determine the UART to use
+ UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
+ UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
+ UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
+ MBED_ASSERT((int)uart != NC);
+
+ obj->uart = (LPC_UART_TypeDef *)uart;
+ // enable power
+ switch (uart) {
+ case UART_0: LPC_SC->PCONP |= 1 << 3; break;
+ case UART_1: LPC_SC->PCONP |= 1 << 4; break;
+ case UART_2: LPC_SC->PCONP |= 1 << 24; break;
+ case UART_3: LPC_SC->PCONP |= 1 << 25; break;
+ }
+
+ // enable fifos and default rx trigger level
+ obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
+ | 0 << 1 // Rx Fifo Reset
+ | 0 << 2 // Tx Fifo Reset
+ | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
+
+ // disable irqs
+ obj->uart->IER = 0 << 0 // Rx Data available irq enable
+ | 0 << 1 // Tx Fifo empty irq enable
+ | 0 << 2; // Rx Line Status irq enable
+
+ // set default baud rate and format
+ serial_baud (obj, 9600);
+ serial_format(obj, 8, ParityNone, 1);
+
+ // pinout the chosen uart
+ pinmap_pinout(tx, PinMap_UART_TX);
+ pinmap_pinout(rx, PinMap_UART_RX);
+
+ // set rx/tx pins in PullUp mode
+ if (tx != NC) {
+ pin_mode(tx, PullUp);
+ }
+ if (rx != NC) {
+ pin_mode(rx, PullUp);
+ }
+
+ switch (uart) {
+ case UART_0: obj->index = 0; break;
+ case UART_1: obj->index = 1; break;
+ case UART_2: obj->index = 2; break;
+ case UART_3: obj->index = 3; break;
+ }
+
+ is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
+
+ if (is_stdio_uart) {
+ stdio_uart_inited = 1;
+ memcpy(&stdio_uart, obj, sizeof(serial_t));
+ }
+}
+
+void serial_free(serial_t *obj) {
+ serial_irq_ids[obj->index] = 0;
+}
+
+// serial_baud
+// set the baud rate, taking in to account the current SystemFrequency
+void serial_baud(serial_t *obj, int baudrate) {
+ MBED_ASSERT((int)obj->uart <= UART_3);
+ // The LPC2300 and LPC1700 have a divider and a fractional divider to control the
+ // baud rate. The formula is:
+ //
+ // Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal)
+ // where:
+ // 1 < MulVal <= 15
+ // 0 <= DivAddVal < 14
+ // DivAddVal < MulVal
+ //
+ // set pclk to /1
+ switch ((int)obj->uart) {
+ case UART_0: LPC_SC->PCLKSEL0 &= ~(0x3 << 6); LPC_SC->PCLKSEL0 |= (0x1 << 6); break;
+ case UART_1: LPC_SC->PCLKSEL0 &= ~(0x3 << 8); LPC_SC->PCLKSEL0 |= (0x1 << 8); break;
+ case UART_2: LPC_SC->PCLKSEL1 &= ~(0x3 << 16); LPC_SC->PCLKSEL1 |= (0x1 << 16); break;
+ case UART_3: LPC_SC->PCLKSEL1 &= ~(0x3 << 18); LPC_SC->PCLKSEL1 |= (0x1 << 18); break;
+ default: break;
+ }
+
+ uint32_t PCLK = SystemCoreClock;
+
+ // First we check to see if the basic divide with no DivAddVal/MulVal
+ // ratio gives us an integer result. If it does, we set DivAddVal = 0,
+ // MulVal = 1. Otherwise, we search the valid ratio value range to find
+ // the closest match. This could be more elegant, using search methods
+ // and/or lookup tables, but the brute force method is not that much
+ // slower, and is more maintainable.
+ uint16_t DL = PCLK / (16 * baudrate);
+
+ uint8_t DivAddVal = 0;
+ uint8_t MulVal = 1;
+ int hit = 0;
+ uint16_t dlv;
+ uint8_t mv, dav;
+ if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder
+ int err_best = baudrate, b;
+ for (mv = 1; mv < 16 && !hit; mv++)
+ {
+ for (dav = 0; dav < mv; dav++)
+ {
+ // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul))
+ // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul))
+ // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding
+ // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision
+ // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding
+
+ if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom
+ dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2;
+ else // 2 bits headroom, use more precision
+ dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2;
+
+ // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood
+ if (dlv == 0)
+ dlv = 1;
+
+ // datasheet says if dav > 0 then DL must be >= 2
+ if ((dav > 0) && (dlv < 2))
+ dlv = 2;
+
+ // integer rearrangement of the baudrate equation (with rounding)
+ b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2;
+
+ // check to see how we went
+ b = abs(b - baudrate);
+ if (b < err_best)
+ {
+ err_best = b;
+
+ DL = dlv;
+ MulVal = mv;
+ DivAddVal = dav;
+
+ if (b == baudrate)
+ {
+ hit = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // set LCR[DLAB] to enable writing to divider registers
+ obj->uart->LCR |= (1 << 7);
+
+ // set divider values
+ obj->uart->DLM = (DL >> 8) & 0xFF;
+ obj->uart->DLL = (DL >> 0) & 0xFF;
+ obj->uart->FDR = (uint32_t) DivAddVal << 0
+ | (uint32_t) MulVal << 4;
+
+ // clear LCR[DLAB]
+ obj->uart->LCR &= ~(1 << 7);
+}
+
+void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
+ MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
+ MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits
+ MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
+ (parity == ParityForced1) || (parity == ParityForced0));
+
+ stop_bits -= 1;
+ data_bits -= 5;
+
+ int parity_enable = 0, parity_select = 0;
+ switch (parity) {
+ case ParityNone: parity_enable = 0; parity_select = 0; break;
+ case ParityOdd : parity_enable = 1; parity_select = 0; break;
+ case ParityEven: parity_enable = 1; parity_select = 1; break;
+ case ParityForced1: parity_enable = 1; parity_select = 2; break;
+ case ParityForced0: parity_enable = 1; parity_select = 3; break;
+ default:
+ break;
+ }
+
+ obj->uart->LCR = data_bits << 0
+ | stop_bits << 2
+ | parity_enable << 3
+ | parity_select << 4;
+}
+
+/******************************************************************************
+ * INTERRUPTS HANDLING
+ ******************************************************************************/
+static inline void uart_irq(uint32_t iir, uint32_t index) {
+ // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling
+ SerialIrq irq_type;
+ switch (iir) {
+ case 1: irq_type = TxIrq; break;
+ case 2: irq_type = RxIrq; break;
+ default: return;
+ }
+
+ if (serial_irq_ids[index] != 0){
+ irq_handler(serial_irq_ids[index], irq_type);
+ }
+}
+
+void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);}
+void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);}
+void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);}
+void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);}
+
+void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
+ irq_handler = handler;
+ serial_irq_ids[obj->index] = id;
+}
+
+void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
+ IRQn_Type irq_n = (IRQn_Type)0;
+ uint32_t vector = 0;
+ switch ((int)obj->uart) {
+ case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
+ case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
+ case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
+ case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break;
+ }
+
+ if (enable) {
+ obj->uart->IER |= 1 << irq;
+ NVIC_SetVector(irq_n, vector);
+ NVIC_EnableIRQ(irq_n);
+ } else { // disable
+ int all_disabled = 0;
+ SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
+ obj->uart->IER &= ~(1 << irq);
+ all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
+ if (all_disabled)
+ NVIC_DisableIRQ(irq_n);
+ }
+}
+
+/******************************************************************************
+ * READ/WRITE
+ ******************************************************************************/
+int serial_getc(serial_t *obj) {
+ while (!serial_readable(obj));
+ return obj->uart->RBR;
+}
+
+void serial_putc(serial_t *obj, int c) {
+ while (!serial_writable(obj));
+ obj->uart->THR = c;
+}
+
+int serial_readable(serial_t *obj) {
+ return obj->uart->LSR & 0x01;
+}
+
+int serial_writable(serial_t *obj) {
+ return obj->uart->LSR & 0x20;
+}
+
+void serial_clear(serial_t *obj) {
+ obj->uart->FCR = 1 << 1 // rx FIFO reset
+ | 1 << 2 // tx FIFO reset
+ | 0 << 6; // interrupt depth
+}
+
+void serial_pinout_tx(PinName tx) {
+ pinmap_pinout(tx, PinMap_UART_TX);
+}
+
+void serial_break_set(serial_t *obj) {
+ obj->uart->LCR |= (1 << 6);
+}
+
+void serial_break_clear(serial_t *obj) {
+ obj->uart->LCR &= ~(1 << 6);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/spi_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,219 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "mbed_assert.h"
+#include <math.h>
+
+#include "spi_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+
+static const PinMap PinMap_SPI_SCLK[] = {
+ {P0_7 , SPI_1, 2},
+ {P0_15, SPI_0, 2},
+ {P1_20, SPI_0, 3},
+ {P1_31, SPI_1, 2},
+ {NC , NC , 0}
+};
+
+static const PinMap PinMap_SPI_MOSI[] = {
+ {P0_9 , SPI_1, 2},
+ {P0_13, SPI_1, 2},
+ {P0_18, SPI_0, 2},
+ {P1_24, SPI_0, 3},
+ {NC , NC , 0}
+};
+
+static const PinMap PinMap_SPI_MISO[] = {
+ {P0_8 , SPI_1, 2},
+ {P0_12, SPI_1, 2},
+ {P0_17, SPI_0, 2},
+ {P1_23, SPI_0, 3},
+ {NC , NC , 0}
+};
+
+static const PinMap PinMap_SPI_SSEL[] = {
+ {P0_6 , SPI_1, 2},
+ {P0_14, SPI_1, 3},
+ {P0_16, SPI_0, 2},
+ {P1_21, SPI_0, 3},
+ {NC , NC , 0}
+};
+
+static inline int ssp_disable(spi_t *obj);
+static inline int ssp_enable(spi_t *obj);
+
+void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
+ // determine the SPI to use
+ SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
+ SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
+ SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
+ SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
+ SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
+ SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
+ obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
+ MBED_ASSERT((int)obj->spi != NC);
+
+ // enable power and clocking
+ switch ((int)obj->spi) {
+ case SPI_0: LPC_SC->PCONP |= 1 << PCSSP0; break;
+ case SPI_1: LPC_SC->PCONP |= 1 << PCSSP1; break;
+ }
+
+ // set default format and frequency
+ if (ssel == NC) {
+ spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
+ } else {
+ spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
+ }
+ spi_frequency(obj, 1000000);
+
+ // enable the ssp channel
+ ssp_enable(obj);
+
+ // pin out the spi pins
+ pinmap_pinout(mosi, PinMap_SPI_MOSI);
+ pinmap_pinout(miso, PinMap_SPI_MISO);
+ pinmap_pinout(sclk, PinMap_SPI_SCLK);
+ if (ssel != NC) {
+ pinmap_pinout(ssel, PinMap_SPI_SSEL);
+ }
+}
+
+void spi_free(spi_t *obj) {}
+
+void spi_format(spi_t *obj, int bits, int mode, int slave) {
+ MBED_ASSERT(((bits >= 4) && (bits <= 16)) && ((mode >= 0) && (mode <= 3)));
+ ssp_disable(obj);
+
+ int polarity = (mode & 0x2) ? 1 : 0;
+ int phase = (mode & 0x1) ? 1 : 0;
+
+ // set it up
+ int DSS = bits - 1; // DSS (data select size)
+ int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
+ int SPH = (phase) ? 1 : 0; // SPH - clock out phase
+
+ int FRF = 0; // FRF (frame format) = SPI
+ uint32_t tmp = obj->spi->CR0;
+ tmp &= ~(0xFFFF);
+ tmp |= DSS << 0
+ | FRF << 4
+ | SPO << 6
+ | SPH << 7;
+ obj->spi->CR0 = tmp;
+
+ tmp = obj->spi->CR1;
+ tmp &= ~(0xD);
+ tmp |= 0 << 0 // LBM - loop back mode - off
+ | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave
+ | 0 << 3; // SOD - slave output disable - na
+ obj->spi->CR1 = tmp;
+
+ ssp_enable(obj);
+}
+
+void spi_frequency(spi_t *obj, int hz) {
+ ssp_disable(obj);
+
+ // setup the spi clock diveder to /1
+ switch ((int)obj->spi) {
+ case SPI_0:
+ LPC_SC->PCLKSEL1 &= ~(3 << 10);
+ LPC_SC->PCLKSEL1 |= (1 << 10);
+ break;
+ case SPI_1:
+ LPC_SC->PCLKSEL0 &= ~(3 << 20);
+ LPC_SC->PCLKSEL0 |= (1 << 20);
+ break;
+ }
+
+ uint32_t PCLK = SystemCoreClock;
+
+ int prescaler;
+
+ for (prescaler = 2; prescaler <= 254; prescaler += 2) {
+ int prescale_hz = PCLK / prescaler;
+
+ // calculate the divider
+ int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
+
+ // check we can support the divider
+ if (divider < 256) {
+ // prescaler
+ obj->spi->CPSR = prescaler;
+
+ // divider
+ obj->spi->CR0 &= ~(0xFFFF << 8);
+ obj->spi->CR0 |= (divider - 1) << 8;
+ ssp_enable(obj);
+ return;
+ }
+ }
+ error("Couldn't setup requested SPI frequency");
+}
+
+static inline int ssp_disable(spi_t *obj) {
+ return obj->spi->CR1 &= ~(1 << 1);
+}
+
+static inline int ssp_enable(spi_t *obj) {
+ return obj->spi->CR1 |= (1 << 1);
+}
+
+static inline int ssp_readable(spi_t *obj) {
+ return obj->spi->SR & (1 << 2);
+}
+
+static inline int ssp_writeable(spi_t *obj) {
+ return obj->spi->SR & (1 << 1);
+}
+
+static inline void ssp_write(spi_t *obj, int value) {
+ while (!ssp_writeable(obj));
+ obj->spi->DR = value;
+}
+
+static inline int ssp_read(spi_t *obj) {
+ while (!ssp_readable(obj));
+ return obj->spi->DR;
+}
+
+static inline int ssp_busy(spi_t *obj) {
+ return (obj->spi->SR & (1 << 4)) ? (1) : (0);
+}
+
+int spi_master_write(spi_t *obj, int value) {
+ ssp_write(obj, value);
+ return ssp_read(obj);
+}
+
+int spi_slave_receive(spi_t *obj) {
+ return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
+}
+
+int spi_slave_read(spi_t *obj) {
+ return obj->spi->DR;
+}
+
+void spi_slave_write(spi_t *obj, int value) {
+ while (ssp_writeable(obj) == 0) ;
+ obj->spi->DR = value;
+}
+
+int spi_busy(spi_t *obj) {
+ return ssp_busy(obj);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NXP/TARGET_LPC2460/us_ticker.c Mon Jun 01 11:00:11 2015 +0100
@@ -0,0 +1,64 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stddef.h>
+#include "us_ticker_api.h"
+#include "PeripheralNames.h"
+
+#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE)
+#define US_TICKER_TIMER_IRQn TIMER3_IRQn
+
+int us_ticker_inited = 0;
+
+void us_ticker_init(void) {
+ if (us_ticker_inited) return;
+ us_ticker_inited = 1;
+
+ LPC_SC->PCONP |= 1 << PCTIM3; // Clock TIMER_3
+
+ US_TICKER_TIMER->CTCR = 0x0; // timer mode
+ uint32_t PCLK = SystemCoreClock / 4;
+
+ US_TICKER_TIMER->TCR = 0x2; // reset
+
+ uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks)
+ US_TICKER_TIMER->PR = prescale - 1;
+ US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0
+
+ NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
+ NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
+}
+
+uint32_t us_ticker_read() {
+ if (!us_ticker_inited)
+ us_ticker_init();
+
+ return US_TICKER_TIMER->TC;
+}
+
+void us_ticker_set_interrupt(timestamp_t timestamp) {
+ // set match value
+ US_TICKER_TIMER->MR0 = (uint32_t)timestamp;
+ // enable match interrupt
+ US_TICKER_TIMER->MCR |= 1;
+}
+
+void us_ticker_disable_interrupt(void) {
+ US_TICKER_TIMER->MCR &= ~1;
+}
+
+void us_ticker_clear_interrupt(void) {
+ US_TICKER_TIMER->IR = 1;
+}
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/pwmout_api.c Mon Jun 01 10:30:08 2015 +0100
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/pwmout_api.c Mon Jun 01 11:00:11 2015 +0100
@@ -139,7 +139,7 @@
value = 1;
}
- float pulse_period_in_s = obj->period_cycles / (float) pwm_clockfreq;
+ float pulse_period_in_s = obj->period_cycles / ((float) (pwm_clockfreq >> pwm_prescaler_div));
pwmout_pulsewidth(obj, value * pulse_period_in_s);
}
@@ -192,7 +192,7 @@
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
{
- obj->width_cycles = pwm_clockfreq * seconds;
+ obj->width_cycles = (uint32_t) (((float) (pwm_clockfreq >> pwm_prescaler_div)) * seconds);
TIMER_CompareBufSet(PWM_TIMER, obj->channel, obj->width_cycles);
}
