Merge pull request #5 from arebert/lpc4088

Add support for NXP LPC4088
pull/6/head
Emilio Monti 2013-05-21 10:14:03 -07:00
commit 6cdbf5512b
66 changed files with 9533 additions and 108 deletions

View File

@ -37,7 +37,7 @@ typedef enum {
} EP_STATUS;
/* Include configuration for specific target */
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#include "USBEndpoints_LPC17_LPC23.h"
#elif defined(TARGET_LPC11U24)
#include "USBEndpoints_LPC11U.h"

View File

@ -0,0 +1,625 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if defined(TARGET_LPC4088)
#include "USBHAL.h"
// Get endpoint direction
#define IN_EP(endpoint) ((endpoint) & 1U ? true : false)
#define OUT_EP(endpoint) ((endpoint) & 1U ? false : true)
// Convert physical endpoint number to register bit
#define EP(endpoint) (1UL<<endpoint)
// Power Control for Peripherals register
#define PCUSB (1UL<<31)
// USB Clock Control register
#define DEV_CLK_EN (1UL<<1)
#define AHB_CLK_EN (1UL<<4)
// USB Clock Status register
#define DEV_CLK_ON (1UL<<1)
#define AHB_CLK_ON (1UL<<4)
// USB Device Interupt registers
#define FRAME (1UL<<0)
#define EP_FAST (1UL<<1)
#define EP_SLOW (1UL<<2)
#define DEV_STAT (1UL<<3)
#define CCEMPTY (1UL<<4)
#define CDFULL (1UL<<5)
#define RxENDPKT (1UL<<6)
#define TxENDPKT (1UL<<7)
#define EP_RLZED (1UL<<8)
#define ERR_INT (1UL<<9)
// USB Control register
#define RD_EN (1<<0)
#define WR_EN (1<<1)
#define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2)
// USB Receive Packet Length register
#define DV (1UL<<10)
#define PKT_RDY (1UL<<11)
#define PKT_LNGTH_MASK (0x3ff)
// Serial Interface Engine (SIE)
#define SIE_WRITE (0x01)
#define SIE_READ (0x02)
#define SIE_COMMAND (0x05)
#define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16))
// SIE Command codes
#define SIE_CMD_SET_ADDRESS (0xD0)
#define SIE_CMD_CONFIGURE_DEVICE (0xD8)
#define SIE_CMD_SET_MODE (0xF3)
#define SIE_CMD_READ_FRAME_NUMBER (0xF5)
#define SIE_CMD_READ_TEST_REGISTER (0xFD)
#define SIE_CMD_SET_DEVICE_STATUS (0xFE)
#define SIE_CMD_GET_DEVICE_STATUS (0xFE)
#define SIE_CMD_GET_ERROR_CODE (0xFF)
#define SIE_CMD_READ_ERROR_STATUS (0xFB)
#define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint)
#define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint)
#define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint)
#define SIE_CMD_CLEAR_BUFFER (0xF2)
#define SIE_CMD_VALIDATE_BUFFER (0xFA)
// SIE Device Status register
#define SIE_DS_CON (1<<0)
#define SIE_DS_CON_CH (1<<1)
#define SIE_DS_SUS (1<<2)
#define SIE_DS_SUS_CH (1<<3)
#define SIE_DS_RST (1<<4)
// SIE Device Set Address register
#define SIE_DSA_DEV_EN (1<<7)
// SIE Configue Device register
#define SIE_CONF_DEVICE (1<<0)
// Select Endpoint register
#define SIE_SE_FE (1<<0)
#define SIE_SE_ST (1<<1)
#define SIE_SE_STP (1<<2)
#define SIE_SE_PO (1<<3)
#define SIE_SE_EPN (1<<4)
#define SIE_SE_B_1_FULL (1<<5)
#define SIE_SE_B_2_FULL (1<<6)
// Set Endpoint Status command
#define SIE_SES_ST (1<<0)
#define SIE_SES_DA (1<<5)
#define SIE_SES_RF_MO (1<<6)
#define SIE_SES_CND_ST (1<<7)
USBHAL * USBHAL::instance;
static volatile int epComplete;
static uint32_t endpointStallState;
static void SIECommand(uint32_t command) {
// The command phase of a SIE transaction
LPC_USB->DevIntClr = CCEMPTY;
LPC_USB->CmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
while (!(LPC_USB->DevIntSt & CCEMPTY));
}
static void SIEWriteData(uint8_t data) {
// The data write phase of a SIE transaction
LPC_USB->DevIntClr = CCEMPTY;
LPC_USB->CmdCode = SIE_CMD_CODE(SIE_WRITE, data);
while (!(LPC_USB->DevIntSt & CCEMPTY));
}
static uint8_t SIEReadData(uint32_t command) {
// The data read phase of a SIE transaction
LPC_USB->DevIntClr = CDFULL;
LPC_USB->CmdCode = SIE_CMD_CODE(SIE_READ, command);
while (!(LPC_USB->DevIntSt & CDFULL));
return (uint8_t)LPC_USB->CmdData;
}
static void SIEsetDeviceStatus(uint8_t status) {
// Write SIE device status register
SIECommand(SIE_CMD_SET_DEVICE_STATUS);
SIEWriteData(status);
}
static uint8_t SIEgetDeviceStatus(void) {
// Read SIE device status register
SIECommand(SIE_CMD_GET_DEVICE_STATUS);
return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
}
void SIEsetAddress(uint8_t address) {
// Write SIE device address register
SIECommand(SIE_CMD_SET_ADDRESS);
SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
}
static uint8_t SIEselectEndpoint(uint8_t endpoint) {
// SIE select endpoint command
SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
}
static uint8_t SIEclearBuffer(void) {
// SIE clear buffer command
SIECommand(SIE_CMD_CLEAR_BUFFER);
return SIEReadData(SIE_CMD_CLEAR_BUFFER);
}
static void SIEvalidateBuffer(void) {
// SIE validate buffer command
SIECommand(SIE_CMD_VALIDATE_BUFFER);
}
static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) {
// SIE set endpoint status command
SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
SIEWriteData(status);
}
static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused));
static uint16_t SIEgetFrameNumber(void) {
// Read current frame number
uint16_t lowByte;
uint16_t highByte;
SIECommand(SIE_CMD_READ_FRAME_NUMBER);
lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
return (highByte << 8) | lowByte;
}
static void SIEconfigureDevice(void) {
// SIE Configure device command
SIECommand(SIE_CMD_CONFIGURE_DEVICE);
SIEWriteData(SIE_CONF_DEVICE);
}
static void SIEunconfigureDevice(void) {
// SIE Configure device command
SIECommand(SIE_CMD_CONFIGURE_DEVICE);
SIEWriteData(0);
}
static void SIEconnect(void) {
// Connect USB device
uint8_t status = SIEgetDeviceStatus();
SIEsetDeviceStatus(status | SIE_DS_CON);
}
static void SIEdisconnect(void) {
// Disconnect USB device
uint8_t status = SIEgetDeviceStatus();
SIEsetDeviceStatus(status & ~SIE_DS_CON);
}
static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) {
// Implemented using using EP_INT_CLR.
LPC_USB->EpIntClr = EP(endpoint);
while (!(LPC_USB->DevIntSt & CDFULL));
return (uint8_t)LPC_USB->CmdData;
}
static void enableEndpointEvent(uint8_t endpoint) {
// Enable an endpoint interrupt
LPC_USB->EpIntEn |= EP(endpoint);
}
static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
static void disableEndpointEvent(uint8_t endpoint) {
// Disable an endpoint interrupt
LPC_USB->EpIntEn &= ~EP(endpoint);
}
static volatile uint32_t __attribute__((used)) dummyRead;
uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
// Read from an OUT endpoint
uint32_t size;
uint32_t i;
uint32_t data = 0;
uint8_t offset;
LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | RD_EN;
while (!(LPC_USB->RxPLen & PKT_RDY));
size = LPC_USB->RxPLen & PKT_LNGTH_MASK;
offset = 0;
if (size > 0) {
for (i=0; i<size; i++) {
if (offset==0) {
// Fetch up to four bytes of data as a word
data = LPC_USB->RxData;
}
// extract a byte
*buffer = (data>>offset) & 0xff;
buffer++;
// move on to the next byte
offset = (offset + 8) % 32;
}
} else {
dummyRead = LPC_USB->RxData;
}
LPC_USB->Ctrl = 0;
if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
SIEselectEndpoint(endpoint);
SIEclearBuffer();
}
return size;
}
static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) {
// Write to an IN endpoint
uint32_t temp, data;
uint8_t offset;
LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | WR_EN;
LPC_USB->TxPLen = size;
offset = 0;
data = 0;
if (size>0) {
do {
// Fetch next data byte into a word-sized temporary variable
temp = *buffer++;
// Add to current data word
temp = temp << offset;
data = data | temp;
// move on to the next byte
offset = (offset + 8) % 32;
size--;
if ((offset==0) || (size==0)) {
// Write the word to the endpoint
LPC_USB->TxData = data;
data = 0;
}
} while (size>0);
} else {
LPC_USB->TxData = 0;
}
// Clear WR_EN to cover zero length packet case
LPC_USB->Ctrl=0;
SIEselectEndpoint(endpoint);
SIEvalidateBuffer();
}
USBHAL::USBHAL(void) {
// Disable IRQ
NVIC_DisableIRQ(USB_IRQn);
// fill in callback array
epCallback[0] = &USBHAL::EP1_OUT_callback;
epCallback[1] = &USBHAL::EP1_IN_callback;
epCallback[2] = &USBHAL::EP2_OUT_callback;
epCallback[3] = &USBHAL::EP2_IN_callback;
epCallback[4] = &USBHAL::EP3_OUT_callback;
epCallback[5] = &USBHAL::EP3_IN_callback;
epCallback[6] = &USBHAL::EP4_OUT_callback;
epCallback[7] = &USBHAL::EP4_IN_callback;
epCallback[8] = &USBHAL::EP5_OUT_callback;
epCallback[9] = &USBHAL::EP5_IN_callback;
epCallback[10] = &USBHAL::EP6_OUT_callback;
epCallback[11] = &USBHAL::EP6_IN_callback;
epCallback[12] = &USBHAL::EP7_OUT_callback;
epCallback[13] = &USBHAL::EP7_IN_callback;
epCallback[14] = &USBHAL::EP8_OUT_callback;
epCallback[15] = &USBHAL::EP8_IN_callback;
epCallback[16] = &USBHAL::EP9_OUT_callback;
epCallback[17] = &USBHAL::EP9_IN_callback;
epCallback[18] = &USBHAL::EP10_OUT_callback;
epCallback[19] = &USBHAL::EP10_IN_callback;
epCallback[20] = &USBHAL::EP11_OUT_callback;
epCallback[21] = &USBHAL::EP11_IN_callback;
epCallback[22] = &USBHAL::EP12_OUT_callback;
epCallback[23] = &USBHAL::EP12_IN_callback;
epCallback[24] = &USBHAL::EP13_OUT_callback;
epCallback[25] = &USBHAL::EP13_IN_callback;
epCallback[26] = &USBHAL::EP14_OUT_callback;
epCallback[27] = &USBHAL::EP14_IN_callback;
epCallback[28] = &USBHAL::EP15_OUT_callback;
epCallback[29] = &USBHAL::EP15_IN_callback;
// Enable power to USB device controller
LPC_SC->PCONP |= PCUSB;
// Enable USB clocks
LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON));
// Configure pins P0.29 and P0.30 to be USB D+ and USB D-
LPC_IOCON->P0_29 &= ~0x07;
LPC_IOCON->P0_29 |= 0x01;
LPC_IOCON->P0_30 &= ~0x07;
LPC_IOCON->P0_30 |= 0x01;
// Disconnect USB device
SIEdisconnect();
// Configure pin P2.9 to be Connect
LPC_IOCON->P2_9 &= ~0x07;
LPC_IOCON->P2_9 |= 0x01;
// Connect must be low for at least 2.5uS
wait(0.3);
// Set the maximum packet size for the control endpoints
realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
// Attach IRQ
instance = this;
NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
// Enable interrupts for device events and EP0
LPC_USB->DevIntEn = EP_SLOW | DEV_STAT | FRAME;
enableEndpointEvent(EP0IN);
enableEndpointEvent(EP0OUT);
}
USBHAL::~USBHAL(void) {
// Ensure device disconnected
SIEdisconnect();
// Disable USB interrupts
NVIC_DisableIRQ(USB_IRQn);
}
void USBHAL::connect(void) {
NVIC_EnableIRQ(USB_IRQn);
// Connect USB device
SIEconnect();
}
void USBHAL::disconnect(void) {
NVIC_DisableIRQ(USB_IRQn);
// Disconnect USB device
SIEdisconnect();
}
void USBHAL::configureDevice(void) {
SIEconfigureDevice();
}
void USBHAL::unconfigureDevice(void) {
SIEunconfigureDevice();
}
void USBHAL::setAddress(uint8_t address) {
SIEsetAddress(address);
}
void USBHAL::EP0setup(uint8_t *buffer) {
endpointReadcore(EP0OUT, buffer);
}
void USBHAL::EP0read(void) {
// Not required
}
void USBHAL::EP0readStage(void) {
// Not required
}
uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
return endpointReadcore(EP0OUT, buffer);
}
void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
endpointWritecore(EP0IN, buffer, size);
}
void USBHAL::EP0getWriteResult(void) {
// Not required
}
void USBHAL::EP0stall(void) {
// This will stall both control endpoints
stallEndpoint(EP0OUT);
}
EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
return EP_PENDING;
}
EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
//for isochronous endpoint, we don't wait an interrupt
if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
if (!(epComplete & EP(endpoint)))
return EP_PENDING;
}
*bytesRead = endpointReadcore(endpoint, buffer);
epComplete &= ~EP(endpoint);
return EP_COMPLETED;
}
EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
if (getEndpointStallState(endpoint)) {
return EP_STALLED;
}
epComplete &= ~EP(endpoint);
endpointWritecore(endpoint, data, size);
return EP_PENDING;
}
EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
if (epComplete & EP(endpoint)) {
epComplete &= ~EP(endpoint);
return EP_COMPLETED;
}
return EP_PENDING;
}
bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
// Realise an endpoint
LPC_USB->DevIntClr = EP_RLZED;
LPC_USB->ReEp |= EP(endpoint);
LPC_USB->EpInd = endpoint;
LPC_USB->MaxPSize = maxPacket;
while (!(LPC_USB->DevIntSt & EP_RLZED));
LPC_USB->DevIntClr = EP_RLZED;
// Clear stall state
endpointStallState &= ~EP(endpoint);
enableEndpointEvent(endpoint);
return true;
}
void USBHAL::stallEndpoint(uint8_t endpoint) {
// Stall an endpoint
if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) {
// Conditionally stall both control endpoints
SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST);
} else {
SIEsetEndpointStatus(endpoint, SIE_SES_ST);
// Update stall state
endpointStallState |= EP(endpoint);
}
}
void USBHAL::unstallEndpoint(uint8_t endpoint) {
// Unstall an endpoint. The endpoint will also be reinitialised
SIEsetEndpointStatus(endpoint, 0);
// Update stall state
endpointStallState &= ~EP(endpoint);
}
bool USBHAL::getEndpointStallState(uint8_t endpoint) {
// Returns true if endpoint stalled
return endpointStallState & EP(endpoint);
}
void USBHAL::remoteWakeup(void) {
// Remote wakeup
uint8_t status;
// Enable USB clocks
LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
status = SIEgetDeviceStatus();
SIEsetDeviceStatus(status & ~SIE_DS_SUS);
}
void USBHAL::_usbisr(void) {
instance->usbisr();
}
void USBHAL::usbisr(void) {
uint8_t devStat;
if (LPC_USB->DevIntSt & FRAME) {
// Start of frame event
SOF(SIEgetFrameNumber());
// Clear interrupt status flag
LPC_USB->DevIntClr = FRAME;
}
if (LPC_USB->DevIntSt & DEV_STAT) {
// Device Status interrupt
// Must clear the interrupt status flag before reading the device status from the SIE
LPC_USB->DevIntClr = DEV_STAT;
// Read device status from SIE
devStat = SIEgetDeviceStatus();
//printf("devStat: %d\r\n", devStat);
if (devStat & SIE_DS_SUS_CH) {
// Suspend status changed
if((devStat & SIE_DS_SUS) != 0) {
suspendStateChanged(0);
}
}
if (devStat & SIE_DS_RST) {
// Bus reset
if((devStat & SIE_DS_SUS) == 0) {
suspendStateChanged(1);
}
busReset();
}
}
if (LPC_USB->DevIntSt & EP_SLOW) {
// (Slow) Endpoint Interrupt
// Process each endpoint interrupt
if (LPC_USB->EpIntSt & EP(EP0OUT)) {
if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) {
// this is a setup packet
EP0setupCallback();
} else {
EP0out();
}
LPC_USB->DevIntClr = EP_SLOW;
}
if (LPC_USB->EpIntSt & EP(EP0IN)) {
selectEndpointClearInterrupt(EP0IN);
LPC_USB->DevIntClr = EP_SLOW;
EP0in();
}
for (uint8_t num = 2; num < 16*2; num++) {
if (LPC_USB->EpIntSt & EP(num)) {
selectEndpointClearInterrupt(num);
epComplete |= EP(num);
LPC_USB->DevIntClr = EP_SLOW;
if ((instance->*(epCallback[num - 2]))()) {
epComplete &= ~EP(num);
}
}
}
}
}
#endif

View File

@ -17,7 +17,7 @@
#include "us_ticker_api.h"
void wait(float s) {
wait_us(s * 1000000.0);
wait_us(s * 1000000.0f);
}
void wait_ms(int ms) {

View File

@ -37,7 +37,7 @@ int Timer::read_us() {
}
float Timer::read() {
return (float)read_us() / 1000000.0;
return (float)read_us() / 1000000.0f;
}
int Timer::read_ms() {

View File

@ -18,13 +18,13 @@
namespace mbed {
PinName parse_pins(const char *str) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
static const PinName pin_names[] = {p5, p6, p7, p8, p9, p10, p11, p12, p13, p14
, p15, p16, p17, p18, p19, p20, p21, p22, p23
, p24, p25, p26, p27, p28, p29, p30};
#endif
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC812)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC812) || defined(TARGET_LPC4088)
if (str[0] == 'P') { // Pn_n
uint32_t port = str[1] - '0';
uint32_t pin = str[3] - '0'; // Pn_n
@ -46,7 +46,7 @@ PinName parse_pins(const char *str) {
return port_pin((PortName)port, pin);
#endif
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
} else if (str[0] == 'p') { // pn
uint32_t pin = str[1] - '0'; // pn
uint32_t pin2 = str[2] - '0'; // pnn

View File

@ -0,0 +1,88 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
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,
UART_4 = (int)LPC_UART4_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,
SPI_2 = (int)LPC_SSP2_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 {
PWM0_1 = 1,
PWM0_2,
PWM0_3,
PWM0_4,
PWM0_5,
PWM0_6,
PWM1_1,
PWM1_2,
PWM1_3,
PWM1_4,
PWM1_5,
PWM1_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_0
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,96 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
#define PORT_SHIFT 5
typedef enum {
// LPC Pin Names
P0_0 = /*LPC_GPIO0_BASE*/0,
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,
P5_0, P5_1, P5_2, P5_3, P5_4,
// mbed DIP Pin Names
p5 = P0_9,
p6 = P0_8,
p7 = P0_7,
p8 = P0_6,
p9 = P0_0,
p10 = P0_1,
p11 = P0_18,
p12 = P0_17,
p13 = P0_15,
p14 = P0_16,
p15 = P0_23,
p16 = P0_24,
p17 = P0_25,
p18 = P0_26,
p19 = P1_30,
p20 = P1_31,
p21 = P2_5,
p22 = P2_4,
p23 = P2_3,
p24 = P2_2,
p25 = P2_1,
p26 = P2_0,
p27 = P0_11,
p28 = P0_10,
p29 = P0_5,
p30 = P0_4,
// Other mbed Pin Names
LED1 = P2_27,
LED2 = P2_26,
LED3 = P2_26,
LED4 = P2_26,
USBTX = P0_2,
USBRX = P0_3,
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
typedef enum {
PullUp = 0,
PullDown = 3,
PullNone = 2,
OpenDrain = 4
} PinMode;
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

@ -0,0 +1,59 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H
#define DEVICE_PORTIN 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 // Need HW?
#define DEVICE_LOCALFILESYSTEM 0 // Need HW?
#define DEVICE_ID_LENGTH 32
#define DEVICE_MAC_OFFSET 20
#define DEVICE_SLEEP 1
#define DEVICE_DEBUG_AWARENESS 1
#define DEVICE_STDIO_MESSAGES 1
#define DEVICE_ERROR_PATTERN 1
#include "objects.h"
#endif

View File

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

View File

@ -0,0 +1,79 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gpio_irq_s {
uint32_t 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;
LPC_PWM_TypeDef *pwm;
uint32_t channel;
};
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

View File

@ -68,6 +68,22 @@ static const PinMap PinMap_ADC[] = {
#define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60)
#define ADC_RANGE ADC_10BIT_RANGE
#elif defined(TARGET_LPC4088)
static const PinMap PinMap_ADC[] = {
{P0_23, ADC0_0, 0x01},
{P0_24, ADC0_1, 0x01},
{P0_25, ADC0_2, 0x01},
{P0_26, ADC0_3, 0x01},
{P1_30, ADC0_4, 0x03},
{P1_31, ADC0_5, 0x03},
{P0_12, ADC0_6, 0x03},
{P0_13, ADC0_7, 0x03},
{NC , NC , 0 }
};
#define ADC_RANGE ADC_12BIT_RANGE
#endif
void analogin_init(analogin_t *obj, PinName pin) {
@ -118,6 +134,31 @@ void analogin_init(analogin_t *obj, PinName pin) {
| (clkdiv << 8) // max of 4.5MHz
| (0 << 16) // BURST = 0, software controlled
| ( 0 << 17 ); // CLKS = 0, not applicable
#elif defined(TARGET_LPC4088)
// ensure power is turned on
LPC_SC->PCONP |= (1 << 12);
uint32_t PCLK = PeripheralClock;
// calculate minimum clock divider
// clkdiv = divider - 1
uint32_t MAX_ADC_CLK = 12400000;
uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
// Set the generic software-controlled ADC settings
LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected
| (clkdiv << 8) // CLKDIV:
| (0 << 16) // BURST: 0 = software control
| (1 << 21) // PDN: 1 = operational
| (0 << 24) // START: 0 = no start
| (0 << 27); // EDGE: not applicable
// must enable analog mode (ADMODE = 0)
__IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
*reg &= ~(1 << 7);
#endif
pinmap_pinout(pin, PinMap_ADC);
}
@ -138,7 +179,7 @@ static inline uint32_t adc_read(analogin_t *obj) {
// Stop conversion
LPC_ADC->ADCR &= ~(1 << 24);
#elif defined(TARGET_LPC11U24)
#elif defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// Select the appropriate channel and start conversion
LPC_ADC->CR &= ~0xFF;
LPC_ADC->CR |= 1 << (int)obj->adc;
@ -154,7 +195,7 @@ static inline uint32_t adc_read(analogin_t *obj) {
LPC_ADC->CR &= ~(1 << 24);
#endif
#if defined(TARGET_LPC1768)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC4088)
return (data >> 4) & ADC_RANGE; // 12 bit
#elif defined(TARGET_LPC2368) || defined (TARGET_LPC11U24)
return (data >> 6) & ADC_RANGE; // 10 bit
@ -188,7 +229,7 @@ static inline uint32_t adc_read_u32(analogin_t *obj) {
uint16_t analogin_read_u16(analogin_t *obj) {
uint32_t value = adc_read_u32(obj);
#if defined(TARGET_LPC1768)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC4088)
return (value << 4) | ((value >> 8) & 0x000F); // 12 bit
#elif defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
return (value << 6) | ((value >> 4) & 0x003F); // 10 bit

View File

@ -32,9 +32,16 @@ void analogout_init(dac_t *obj, PinName pin) {
error("DAC pin mapping failed");
}
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
// power is on by default, set DAC clk divider is /4
LPC_SC->PCLKSEL0 &= ~(0x3 << 22);
#elif defined(TARGET_LPC4088)
// DAC enable bit must be set
LPC_IOCON->P0_26 |= (1 << 16); // DACEN
#endif
// map out (must be done before accessing registers)
pinmap_pinout(pin, PinMap_DAC);
@ -46,19 +53,32 @@ void analogout_free(dac_t *obj) {}
static inline void dac_write(int value) {
value &= 0x3FF; // 10-bit
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
// Set the DAC output
LPC_DAC->DACR = (0 << 16) // bias = 0
| (value << 6);
#elif defined(TARGET_LPC4088)
// Set the DAC output
LPC_DAC->CR = (0 << 16) // bias = 0
| (value << 6);
#endif
}
static inline int dac_read() {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
return (LPC_DAC->DACR >> 6) & 0x3FF;
#elif defined(TARGET_LPC4088)
return (LPC_DAC->CR >> 6) & 0x3FF;
#endif
}
void analogout_write(dac_t *obj, float value) {
if (value < 0.0) {
if (value < 0.0f) {
dac_write(0);
} else if (value > 1.0) {
} else if (value > 1.0f) {
dac_write(0x3FF);
} else {
dac_write(value * (float)0x3FF);

View File

@ -39,7 +39,11 @@ http://www.kvaser.com/can/index.htm
static const PinMap PinMap_CAN_RD[] = {
{P0_0 , CAN_1, 1},
{P0_4 , CAN_2, 2},
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
{P0_21, CAN_1, 3},
#elif defined(TARGET_LPC4088)
{P0_21, CAN_1, 4},
#endif
{P2_7 , CAN_2, 1},
{NC , NC , 0}
};
@ -47,7 +51,11 @@ static const PinMap PinMap_CAN_RD[] = {
static const PinMap PinMap_CAN_TD[] = {
{P0_1 , CAN_1, 1},
{P0_5 , CAN_2, 2},
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
{P0_22, CAN_1, 3},
#elif defined(TARGET_LPC4088)
{P0_22, CAN_1, 4},
#endif
{P2_8 , CAN_2, 1},
{NC , NC , 0}
};
@ -76,6 +84,7 @@ static inline void can_enable(can_t *obj) {
}
}
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
static int can_pclk(can_t *obj) {
int value = 0;
switch ((int)obj->dev) {
@ -90,6 +99,7 @@ static int can_pclk(can_t *obj) {
default: return 4;
}
}
#endif
// This table has the sampling points as close to 75% as possible. The first
// value is TSEG1, the second TSEG2.
@ -185,7 +195,11 @@ void can_free(can_t *obj) {
}
int can_frequency(can_t *obj, int f) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
int pclk = can_pclk(obj);
#elif defined(TARGET_LPC4088)
int pclk = PeripheralClock;
#endif
int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1);
if (btr > 0) {

View File

@ -21,6 +21,7 @@
#include "cmsis.h"
#include "mbed_interface.h"
#include "toolchain.h"
#include "error.h"
#define NEW_LOGIC 0
#define NEW_ETH_BUFFER 0
@ -127,7 +128,7 @@ typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;
/* MII Management Configuration Register */
#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */
#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */
#define MCFG_CLK_SEL 0x0000001C /* Clock Select Mask */
#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */
#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */
/* MII Management Command Register */
@ -322,6 +323,8 @@ typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;
#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 */
@ -329,7 +332,9 @@ typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;
#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */
#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */
#define DP83848C_ID 0x20005C90 /* PHY Identifier */
#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 */
@ -337,6 +342,12 @@ typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;
#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);
@ -345,6 +356,8 @@ 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
@ -369,6 +382,8 @@ 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;
@ -426,9 +441,31 @@ int ethernet_init() {
LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
LPC_PINCON->PINSEL2 = 0x50150105; /* Enable P1 Ethernet Pins. */
LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
#elif defined(TARGET_LPC4088)
LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */
LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */
LPC_IOCON->P1_1 &= ~0x07;
LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */
LPC_IOCON->P1_4 &= ~0x07;
LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */
LPC_IOCON->P1_8 &= ~0x07;
LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */
LPC_IOCON->P1_9 &= ~0x07;
LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */
LPC_IOCON->P1_10 &= ~0x07;
LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */
LPC_IOCON->P1_14 &= ~0x07;
LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */
LPC_IOCON->P1_15 &= ~0x07;
LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */
LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */
LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */
LPC_IOCON->P1_17 &= ~0x07;
LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */
#endif
/* Reset all EMAC internal modules. */
LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX |
@ -470,6 +507,13 @@ int ethernet_init() {
}
}
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 */
@ -515,8 +559,22 @@ void ethernet_free() {
LPC_EMAC->IntClear = 0xFFFF;
LPC_SC->PCONP &= ~0x40000000; /* Power down the EMAC controller. */
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
LPC_PINCON->PINSEL2 &= ~0x50150105; /* Disable P1 ethernet pins. */
LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000000;
#elif defined(TARGET_LPC4088)
LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */
LPC_IOCON->P1_1 &= ~0x07;
LPC_IOCON->P1_4 &= ~0x07;
LPC_IOCON->P1_8 &= ~0x07;
LPC_IOCON->P1_9 &= ~0x07;
LPC_IOCON->P1_10 &= ~0x07;
LPC_IOCON->P1_14 &= ~0x07;
LPC_IOCON->P1_15 &= ~0x07;
LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */
LPC_IOCON->P1_17 &= ~0x07;
#endif
}
// if(TxProduceIndex == TxConsumeIndex) buffer array is empty
@ -781,7 +839,13 @@ int ethernet_read(char *data, int dlen) {
}
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) {
@ -873,6 +937,9 @@ void ethernet_set_link(int speed, int duplex) {
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) {
@ -890,6 +957,33 @@ void ethernet_set_link(int speed, int duplex) {
} 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;
}
}
#endif

View File

@ -77,6 +77,15 @@ void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
obj->reg_clr = &LPC_GPIO_PORT->CLR0;
obj->reg_in = &LPC_GPIO_PORT->PIN0;
obj->reg_dir = &LPC_GPIO_PORT->DIR0;
#elif defined(TARGET_LPC4088)
LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *) ((int)(LPC_GPIO0_BASE+pin) & ~0x1F);
obj->reg_set = &port_reg->SET;
obj->reg_clr = &port_reg->CLR;
obj->reg_in = &port_reg->PIN;
obj->reg_dir = &port_reg->DIR;
#endif
gpio_dir(obj, direction);

View File

@ -33,12 +33,15 @@
#define CHANNEL_NUM 8
#define LPC_GPIO_X LPC_PIN_INT
#define PININT_IRQ PININT0_IRQn
#elif defined(TARGET_LPC4088)
#define CHANNEL_NUM 64
#endif
static uint32_t channel_ids[CHANNEL_NUM] = {0};
static gpio_irq_handler irq_handler;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
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.
@ -65,8 +68,13 @@ static void handle_interrupt_in(void) {
}
}
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
// P2.0-2.15
for (i = 0; i < 16; i++) {
#elif defined(TARGET_LPC4088)
// P2.0-2.31
for (i = 0; i < 32; i++) {
#endif
uint32_t pmask = (1 << i);
int channel_index = i + 32;
if (rise2 & pmask) {
@ -123,9 +131,15 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
irq_handler = handler;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
obj->port = (int)pin & ~0x1F;
obj->pin = (int)pin & 0x1F;
#elif defined(TARGET_LPC4088)
obj->port = ((int)(LPC_GPIO0_BASE+pin) & ~0x1F);
obj->pin = (int)pin % 32;
#endif
// Interrupts available only on GPIO0 and GPIO2
if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) {
@ -137,8 +151,13 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
channel_ids[index] = id;
obj->ch = index;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
NVIC_SetVector(EINT3_IRQn, (uint32_t)handle_interrupt_in);
NVIC_EnableIRQ(EINT3_IRQn);
#elif defined(TARGET_LPC4088)
NVIC_SetVector(GPIO_IRQn, (uint32_t)handle_interrupt_in);
NVIC_EnableIRQ(GPIO_IRQn);
#endif
#elif defined(TARGET_LPC11U24) || defined(TARGET_LPC812)
int found_free_channel = 0;
@ -197,7 +216,7 @@ void gpio_irq_free(gpio_irq_t *obj) {
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
// ensure nothing is pending
switch (obj->port) {
case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break;

View File

@ -77,10 +77,46 @@ static uint8_t repeated_start = 0;
#define I2C_DAT(x) (x->i2c->MSTDAT)
#define I2C_STAT(x) ((x->i2c->STAT >> 1) & (0x07))
#elif defined(TARGET_LPC4088)
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},
{P1_15, I2C_2, 3},
{P1_30, I2C_0, 4},
{P2_14, I2C_1, 2},
{P2_30, I2C_2, 2},
{P4_20, I2C_2, 4},
{P5_2, I2C_0, 5},
{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},
{P1_31, I2C_0, 4},
{P2_15, I2C_1, 2},
{P2_31, I2C_2, 2},
{P4_21, I2C_2, 2},
{P4_29, I2C_2, 4},
{P5_3, I2C_0, 5},
{NC , NC, 0}
};
#define I2C_CONSET(x) (x->i2c->CONSET)
#define I2C_CONCLR(x) (x->i2c->CONCLR)
#define I2C_STAT(x) (x->i2c->STAT)
#define I2C_DAT(x) (x->i2c->DAT)
#define I2C_SCLL(x, val) (x->i2c->SCLL = val)
#define I2C_SCLH(x, val) (x->i2c->SCLH = val)
#endif
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
static const uint32_t I2C_addr_offset[2][4] = {
{0x0C, 0x20, 0x24, 0x28},
{0x30, 0x34, 0x38, 0x3C}
@ -114,7 +150,7 @@ static inline int i2c_status(i2c_t *obj) {
// Wait until the Serial Interrupt (SI) is set
static int i2c_wait_SI(i2c_t *obj) {
int timeout = 0;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
while (!(I2C_CONSET(obj) & (1 << 3))) {
#elif defined(TARGET_LPC812)
while (!(obj->i2c->STAT & (1 << 0))) {
@ -126,7 +162,7 @@ static int i2c_wait_SI(i2c_t *obj) {
}
static inline void i2c_interface_enable(i2c_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
I2C_CONSET(obj) = 0x40;
#elif defined(TARGET_LPC812)
obj->i2c->CFG |= (1 << 0);
@ -134,7 +170,7 @@ static inline void i2c_interface_enable(i2c_t *obj) {
}
static inline void i2c_power_enable(i2c_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
switch ((int)obj->i2c) {
case I2C_0: LPC_SC->PCONP |= 1 << 7; break;
case I2C_1: LPC_SC->PCONP |= 1 << 19; break;
@ -151,11 +187,11 @@ static inline void i2c_power_enable(i2c_t *obj) {
}
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// 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);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
#elif defined(TARGET_LPC11U24)
obj->i2c = (LPC_I2C_Type *)pinmap_merge(i2c_sda, i2c_scl);
@ -201,7 +237,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
inline int i2c_start(i2c_t *obj) {
int status = 0;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// 8.1 Before master mode can be entered, I2CON must be initialised to:
// - I2EN STA STO SI AA - -
// - 1 0 0 0 x - -
@ -229,7 +265,7 @@ inline int i2c_start(i2c_t *obj) {
}
inline void i2c_stop(i2c_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// write the stop bit
i2c_conset(obj, 0, 1, 0, 0);
i2c_clear_SI(obj);
@ -247,7 +283,7 @@ static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
// write the data
I2C_DAT(obj) = value;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// clear SI to init a send
i2c_clear_SI(obj);
#elif defined(TARGET_LPC812)
@ -261,7 +297,7 @@ static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
}
static inline int i2c_do_read(i2c_t *obj, int last) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// 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
@ -292,9 +328,12 @@ void i2c_frequency(i2c_t *obj, int hz) {
#elif defined(TARGET_LPC11U24) || defined(TARGET_LPC812)
// No peripheral clock divider on the M0
uint32_t PCLK = SystemCoreClock;
#elif defined(TARGET_LPC4088)
uint32_t PCLK = PeripheralClock;
#endif
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
uint32_t pulse = PCLK / (hz * 2);
// I2C Rate
@ -327,7 +366,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
status = i2c_start(obj);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
if ((status != 0x10) && (status != 0x08)) {
i2c_stop(obj);
return status;
@ -335,7 +374,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
#endif
status = i2c_do_write(obj, (address | 0x01), 1);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
if (status != 0x40) {
#elif defined(TARGET_LPC812)
if (status != 0x01) {
@ -348,7 +387,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
for (count = 0; count < (length - 1); count++) {
int value = i2c_do_read(obj, 0);
status = i2c_status(obj);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
if (status != 0x50) {
#elif defined(TARGET_LPC812)
if (status != 0x00) {
@ -362,7 +401,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
// read in last byte
int value = i2c_do_read(obj, 1);
status = i2c_status(obj);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
if (status != 0x58) {
#elif defined(TARGET_LPC812)
if (status != 0x01) {
@ -391,7 +430,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
status = i2c_start(obj);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
if ((status != 0x10) && (status != 0x08)) {
i2c_stop(obj);
return status;
@ -399,7 +438,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
#endif
status = i2c_do_write(obj, (address & 0xFE), 1);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
if (status != 0x18) {
#elif defined(TARGET_LPC812)
if (status != 0x02) {
@ -410,7 +449,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
for (i=0; i<length; i++) {
status = i2c_do_write(obj, data[i], 0);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
if(status != 0x28) {
#elif defined(TARGET_LPC812)
if (status != 0x02) {
@ -420,7 +459,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
}
}
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
i2c_clear_SI(obj);
#endif
@ -450,7 +489,7 @@ int i2c_byte_write(i2c_t *obj, int data) {
int status = i2c_do_write(obj, (data & 0xFF), 0);
switch(status) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
case 0x18: case 0x28: // Master transmit ACKs
ack = 1;
break;
@ -550,7 +589,7 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
if ((idx >= 0) && (idx <= 3)) {
addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx];
*((uint32_t *) addr) = address & 0xFF;
#ifdef TARGET_LPC1768
#if defined(TARGET_LPC1768) || defined(TARGET_LPC4088)
addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx];
*((uint32_t *) addr) = mask & 0xFE;
#endif

View File

@ -51,6 +51,12 @@ void pin_function(PinName pin, int function) {
// pin function bits: [2:0] -> 111 = (0x7)
*reg = (*reg & ~0x7) | (function & 0x7);
#elif defined(TARGET_LPC4088)
__IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
// pin function bits: [2:0] -> 111 = (0x7)
*reg = (*reg & ~0x7) | (function & 0x7);
#endif
}
@ -114,5 +120,21 @@ void pin_mode(PinName pin, PinMode mode) {
tmp |= (mode & 0x3) << 3;
*reg = tmp;
}
#elif defined(TARGET_LPC4088)
uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2;
__IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
uint32_t tmp = *reg;
// pin mode bits: [4:3] -> 11000 = (0x3 << 3)
tmp &= ~(0x3 << 3);
tmp |= (mode & 0x3) << 3;
// drain
tmp &= ~(0x1 << 10);
tmp |= drain << 10;
*reg = tmp;
#endif
}

View File

@ -20,7 +20,7 @@
#if DEVICE_PORTIN || DEVICE_PORTOUT
PinName port_pin(PortName port, int pin_n) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
return (PinName)(LPC_GPIO0_BASE + ((port << PORT_SHIFT) | pin_n));
#elif defined(TARGET_LPC11U24)
return (PinName)((port << PORT_SHIFT) | pin_n);
@ -46,6 +46,15 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
obj->reg_mpin = &LPC_GPIO->MPIN[port];
obj->reg_dir = &LPC_GPIO->DIR[port];
#elif defined(TARGET_LPC4088)
LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + ((int)port * 0x20));
port_reg->MASK = ~mask;
obj->reg_out = &port_reg->PIN;
obj->reg_in = &port_reg->PIN;
obj->reg_dir = &port_reg->DIR;
#endif
uint32_t i;
// The function is set per pin: reuse gpio logic
@ -78,7 +87,7 @@ void port_dir(port_t *obj, PinDirection dir) {
void port_write(port_t *obj, int value) {
#if defined(TARGET_LPC11U24)
*obj->reg_mpin = value;
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
*obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask);
#endif
}
@ -86,7 +95,7 @@ void port_write(port_t *obj, int value) {
int port_read(port_t *obj) {
#if defined(TARGET_LPC11U24)
return (*obj->reg_mpin);
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
return (*obj->reg_in & obj->mask);
#endif
}

View File

@ -105,6 +105,50 @@ static LPC_CTxxBx_Type *Timers[4] = {
};
static unsigned int pwm_clock_mhz;
#elif defined(TARGET_LPC4088)
// PORT ID, PWM ID, Pin function
static const PinMap PinMap_PWM[] = {
{P1_2, PWM0_1, 3},
{P1_3, PWM0_2, 3},
{P1_5, PWM0_3, 3},
{P1_6, PWM0_4, 3},
{P1_7, PWM0_5, 3},
{P1_11, PWM0_6, 3},
{P1_18, PWM1_1, 2},
{P1_20, PWM1_2, 2},
{P1_21, PWM1_3, 2},
{P1_23, PWM1_4, 2},
{P1_24, PWM1_5, 2},
{P1_26, PWM1_6, 2},
{P2_0, PWM1_1, 1},
{P2_1, PWM1_2, 1},
{P2_2, PWM1_3, 1},
{P2_3, PWM1_4, 1},
{P2_4, PWM1_5, 1},
{P2_5, PWM1_6, 1},
{P3_16, PWM0_1, 2},
{P3_17, PWM0_2, 2},
{P3_18, PWM0_3, 2},
{P3_19, PWM0_4, 2},
{P3_20, PWM0_5, 2},
{P3_21, PWM0_6, 2},
{P3_24, PWM1_1, 2},
{P3_25, PWM1_2, 2},
{P3_26, PWM1_3, 2},
{P3_27, PWM1_4, 2},
{P3_28, PWM1_5, 2},
{P3_29, PWM1_6, 2},
{NC, NC, 0}
};
static const uint32_t PWM_mr_offset[7] = {
0x18, 0x1C, 0x20, 0x24, 0x40, 0x44, 0x48
};
#define TCR_PWM_EN 0x00000008
static unsigned int pwm_clock_mhz;
#endif
void pwmout_init(pwmout_t* obj, PinName pin) {
@ -152,6 +196,35 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
timer->MCR = 1 << 10;
pwm_clock_mhz = SystemCoreClock / 1000000;
#elif defined(TARGET_LPC4088)
obj->channel = pwm;
obj->pwm = LPC_PWM0;
if (obj->channel > 6) { // PWM1 is used if pwm > 6
obj->channel -= 6;
obj->pwm = LPC_PWM1;
}
obj->MR = (__IO uint32_t *)((uint32_t)obj->pwm + PWM_mr_offset[obj->channel]);
// ensure the power is on
if (obj->pwm == LPC_PWM0) {
LPC_SC->PCONP |= 1 << 5;
} else {
LPC_SC->PCONP |= 1 << 6;
}
obj->pwm->PR = 0; // no pre-scale
// ensure single PWM mode
obj->pwm->MCR = 1 << 1; // reset TC on match 0
// enable the specific PWM output
obj->pwm->PCR |= 1 << (8 + obj->channel);
pwm_clock_mhz = PeripheralClock / 1000000;
#endif
// default to 20ms: standard for servos, and fine for e.g. brightness control
pwmout_period_ms(obj, 20);
@ -166,9 +239,9 @@ void pwmout_free(pwmout_t* obj) {
}
void pwmout_write(pwmout_t* obj, float value) {
if (value < 0.0) {
if (value < 0.0f) {
value = 0.0;
} else if (value > 1.0) {
} else if (value > 1.0f) {
value = 1.0;
}
@ -194,6 +267,21 @@ void pwmout_write(pwmout_t* obj, float value) {
timer->TCR = TCR_RESET;
timer->MR[tid.mr] = t_off;
timer->TCR = TCR_CNT_EN;
#elif defined(TARGET_LPC4088)
// set channel match to percentage
uint32_t v = (uint32_t)((float)(obj->pwm->MR0) * value);
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
if (v == obj->pwm->MR0) {
v++;
}
*obj->MR = v;
// accept on next period start
obj->pwm->LER |= 1 << obj->channel;
#endif
}
@ -207,9 +295,11 @@ float pwmout_read(pwmout_t* obj) {
LPC_CTxxBx_Type *timer = Timers[tid.timer];
v = (float)(timer->MR3 - timer->MR[tid.mr]) / (float)(timer->MR3);
#elif defined(TARGET_LPC4088)
v = (float)(*obj->MR) / (float)(obj->pwm->MR0);
#endif
return (v > 1.0) ? (1.0) : (v);
return (v > 1.0f) ? (1.0f) : (v);
}
void pwmout_period(pwmout_t* obj, float seconds) {
@ -263,6 +353,28 @@ void pwmout_period_us(pwmout_t* obj, int us) {
}
timer->TCR = TCR_CNT_EN;
#elif defined(TARGET_LPC4088)
// calculate number of ticks
uint32_t ticks = pwm_clock_mhz * us;
// set reset
obj->pwm->TCR = TCR_RESET;
// set the global match register
obj->pwm->MR0 = ticks;
// Scale the pulse width to preserve the duty ratio
if (obj->pwm->MR0 > 0) {
*obj->MR = (*obj->MR * ticks) / obj->pwm->MR0;
}
// set the channel latch to update value at next period start
obj->pwm->LER |= 1 << 0;
// enable counter and pwm, clear reset
obj->pwm->TCR = TCR_CNT_EN | TCR_PWM_EN;
#endif
}
@ -303,6 +415,22 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
timer->MR[tid.mr] = t_off;
timer->TCR = TCR_CNT_EN;
#elif defined(TARGET_LPC4088)
// 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 == obj->pwm->MR0) {
v++;
}
// set the match register value
*obj->MR = v;
// set the channel latch to update value at next period start
obj->pwm->LER |= 1 << obj->channel;
#endif
}

View File

@ -114,6 +114,43 @@ static int get_available_uart(void) {
#define TXRDY (0x01<<2)
static uint32_t UARTSysClk;
#elif defined(TARGET_LPC4088)
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},
{P1_29, UART_4, 5},
{P0_25, UART_3, 3},
{P2_0 , UART_1, 2},
{P2_8 , UART_2, 2},
{P3_16, UART_1, 3},
{P4_22, UART_2, 2},
{P4_28, UART_3, 2},
{P5_4, UART_4, 4},
{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},
{P3_17, UART_1, 3},
{P4_23, UART_2, 2},
{P4_29, UART_3, 2},
{P5_3, UART_4, 4},
{NC , NC , 0}
};
#define UART_NUM 5
#endif
static uint32_t serial_irq_ids[UART_NUM] = {0};
@ -204,6 +241,17 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
// disconnect USBTX/RX mapping mux, for case when switching ports
pin_function(USBTX, 0);
pin_function(USBRX, 0);
#elif defined(TARGET_LPC4088)
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;
case UART_4: LPC_SC->PCONP |= 1 << 8; break;
}
#endif
// enable fifos and default rx trigger level
@ -239,6 +287,9 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
#endif
#if (UART_NUM > 3)
case UART_3: obj->index = 3; break;
#endif
#if (UART_NUM > 4)
case UART_4: obj->index = 4; break;
#endif
}
@ -312,6 +363,9 @@ void serial_baud(serial_t *obj, int baudrate) {
#elif defined(TARGET_LPC11U24)
LPC_SYSCON->UARTCLKDIV = 0x1;
uint32_t PCLK = SystemCoreClock;
#elif defined(TARGET_LPC4088)
uint32_t PCLK = PeripheralClock;
#endif
// First we check to see if the basic divide with no DivAddVal/MulVal
@ -333,15 +387,15 @@ void serial_baud(serial_t *obj, int baudrate) {
for ( dlv = (dlmax/2); (dlv <= dlmax) && !hit; dlv++) {
for ( mv = 1; mv <= 15; mv++) {
for ( dav = 1; dav < mv; dav++) {
float ratio = 1.0 + ((float) dav / (float) mv);
float calcbaud = (float)PCLK / (16.0 * (float) dlv * ratio);
float ratio = 1.0f + ((float) dav / (float) mv);
float calcbaud = (float)PCLK / (16.0f * (float) dlv * ratio);
float err = fabs(((float) baudrate - calcbaud) / (float) baudrate);
if (err < err_best) {
DL = dlv;
DivAddVal = dav;
MulVal = mv;
err_best = err;
if (err < 0.001) {
if (err < 0.001f) {
hit = 1;
}
}
@ -447,6 +501,14 @@ void uart0_irq() {uart_irq((LPC_USART0->STAT & (1 << 2)) ? 2 : 1, 0);}
void uart1_irq() {uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 1);}
void uart2_irq() {uart_irq((LPC_USART2->STAT & (1 << 2)) ? 2 : 1, 2);}
#elif defined(TARGET_LPC4088)
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 uart4_irq() {uart_irq((LPC_UART4->IIR >> 1) & 0x7, 4);}
#endif
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
@ -469,11 +531,17 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
case LPC_USART0_BASE: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
case LPC_USART1_BASE: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
case LPC_USART2_BASE: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
#elif defined(TARGET_LPC4088)
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;
case UART_4: irq_n=UART4_IRQn; vector = (uint32_t)&uart4_irq; break;
#endif
}
if (enable) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
obj->uart->IER |= 1 << irq;
#elif defined(TARGET_LPC812)
obj->uart->INTENSET = (1 << ((irq == RxIrq) ? 0 : 2));
@ -483,7 +551,7 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
} else { // disable
int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
obj->uart->IER &= ~(1 << irq);
all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
#elif defined(TARGET_LPC812)
@ -513,6 +581,11 @@ void serial_putc(serial_t *obj, int c) {
obj->uart->TXDATA = c;
#else
obj->uart->THR = c;
uint32_t lsr = obj->uart->LSR;
lsr = lsr;
uint32_t thr = obj->uart->THR;
thr = thr;
#endif
}

View File

@ -29,7 +29,7 @@ void sleep(void) {
// PCON[PD] set to sleep
#if defined(TARGET_LPC11U24)
LPC_PMU->PCON = 0x0;
#elif defined(TARGET_LPC1768)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC4088)
LPC_SC->PCON = 0x0;
#endif
@ -85,7 +85,7 @@ void deepsleep(void) {
// wait for interrupt
__WFI();
#elif defined(TARGET_LPC1768)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC4088)
sleep();
#endif
}

View File

@ -121,13 +121,66 @@ static int get_available_spi(void) {
return -1;
}
#elif defined(TARGET_LPC4088)
static const PinMap PinMap_SPI_SCLK[] = {
{P0_7 , SPI_1, 2},
{P0_15, SPI_0, 2},
{P1_0, SPI_2, 4},
{P1_19, SPI_1, 5},
{P1_20, SPI_0, 5},
{P1_31, SPI_1, 2},
{P2_22, SPI_0, 2},
{P4_20, SPI_1, 3},
{P5_2, SPI_2, 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_1, SPI_2, 4},
{P1_22, SPI_1, 5},
{P1_24, SPI_0, 5},
{P2_27, SPI_0, 2},
{P4_23, SPI_1, 3},
{P5_0, SPI_2, 2},
{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_4, SPI_2, 4},
{P1_18, SPI_1, 5},
{P1_23, SPI_0, 5},
{P2_26, SPI_0, 2},
{P4_22, SPI_1, 3},
{P5_1, SPI_2, 2},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_SSEL[] = {
{P0_6 , SPI_1, 2},
{P0_14, SPI_1, 2},
{P0_16, SPI_0, 2},
{P1_8, SPI_2, 4},
{P1_21, SPI_0, 3},
{P1_26, SPI_1, 5},
{P1_28, SPI_0, 5},
{P2_23, SPI_0, 2},
{P4_21, SPI_1, 3},
{NC , NC , 0}
};
#endif
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) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// 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);
@ -135,7 +188,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
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);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
#elif defined(TARGET_LPC11U24)
obj->spi = (LPC_SSPx_Type*)pinmap_merge(spi_data, spi_cntl);
@ -177,10 +230,13 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
#endif
// enable power and clocking
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
switch ((int)obj->spi) {
case SPI_0: LPC_SC->PCONP |= 1 << 21; break;
case SPI_1: LPC_SC->PCONP |= 1 << 10; break;
#if defined(TARGET_LPC4088)
case SPI_2: LPC_SC->PCONP |= 1 << 20; break;
#endif
}
#elif defined(TARGET_LPC11U24)
switch ((int)obj->spi) {
@ -222,7 +278,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
// enable the ssp channel
ssp_enable(obj);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
// pin out the spi pins
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
@ -238,7 +294,7 @@ void spi_free(spi_t *obj) {}
void spi_format(spi_t *obj, int bits, int mode, int slave) {
ssp_disable(obj);
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
if (!(bits >= 4 && bits <= 16) || !(mode >= 0 && mode <= 3)) {
#elif defined(TARGET_LPC812)
if (!(bits >= 1 && bits <= 16) || !(mode >= 0 && mode <= 3)) {
@ -255,7 +311,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
int SPH = (phase) ? 1 : 0; // SPH - clock out phase
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
int FRF = 0; // FRF (frame format) = SPI
uint32_t tmp = obj->spi->CR0;
tmp &= ~(0xFFFF);
@ -304,16 +360,21 @@ void spi_frequency(spi_t *obj, int hz) {
}
#endif
#if defined(TARGET_LPC4088)
uint32_t PCLK = PeripheralClock;
#else
uint32_t PCLK = SystemCoreClock;
#endif
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
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.5);
int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
// check we can support the divider
if (divider < 256) {
@ -336,7 +397,7 @@ void spi_frequency(spi_t *obj, int hz) {
}
static inline int ssp_disable(spi_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
return obj->spi->CR1 &= ~(1 << 1);
#elif defined(TARGET_LPC812)
return obj->spi->CFG &= ~(1 << 0);
@ -344,7 +405,7 @@ static inline int ssp_disable(spi_t *obj) {
}
static inline int ssp_enable(spi_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
return obj->spi->CR1 |= (1 << 1);
#elif defined(TARGET_LPC812)
return obj->spi->CFG |= (1 << 0);
@ -352,7 +413,7 @@ static inline int ssp_enable(spi_t *obj) {
}
static inline int ssp_readable(spi_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
return obj->spi->SR & (1 << 2);
#elif defined(TARGET_LPC812)
return obj->spi->STAT & (1 << 0);
@ -360,7 +421,7 @@ static inline int ssp_readable(spi_t *obj) {
}
static inline int ssp_writeable(spi_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
return obj->spi->SR & (1 << 1);
#elif defined(TARGET_LPC812)
return obj->spi->STAT & (1 << 1);
@ -369,7 +430,7 @@ static inline int ssp_writeable(spi_t *obj) {
static inline void ssp_write(spi_t *obj, int value) {
while (!ssp_writeable(obj));
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
obj->spi->DR = value;
#elif defined(TARGET_LPC812)
// end of transfer
@ -380,7 +441,7 @@ static inline void ssp_write(spi_t *obj, int value) {
static inline int ssp_read(spi_t *obj) {
while (!ssp_readable(obj));
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
return obj->spi->DR;
#elif defined(TARGET_LPC812)
return obj->spi->RXDAT;
@ -388,7 +449,7 @@ static inline int ssp_read(spi_t *obj) {
}
static inline int ssp_busy(spi_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
return (obj->spi->SR & (1 << 4)) ? (1) : (0);
#elif defined(TARGET_LPC812)
// TODO
@ -406,7 +467,7 @@ int spi_slave_receive(spi_t *obj) {
};
int spi_slave_read(spi_t *obj) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
return obj->spi->DR;
#elif defined(TARGET_LPC812)
return obj->spi->RXDAT;
@ -415,7 +476,7 @@ int spi_slave_read(spi_t *obj) {
void spi_slave_write(spi_t *obj, int value) {
while (ssp_writeable(obj) == 0) ;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
obj->spi->DR = value;
#elif defined(TARGET_LPC812)
obj->spi->TXDAT = value;

View File

@ -17,7 +17,7 @@
#include "us_ticker_api.h"
#include "PeripheralNames.h"
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE)
#define US_TICKER_TIMER_IRQn TIMER3_IRQn
@ -67,6 +67,12 @@ void us_ticker_init(void) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock TIMER_1
uint32_t PCLK = SystemCoreClock;
#elif defined(TARGET_LPC4088)
LPC_SC->PCONP |= 1 << 23; // Clock TIMER_3
US_TICKER_TIMER->CTCR = 0x0; // timer mode
uint32_t PCLK = PeripheralClock;
#endif
US_TICKER_TIMER->TCR = 0x2; // reset

View File

@ -0,0 +1,18 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00000000 0x00080000 { ; load region size_region
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x100000E8 0x0000FF18 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM2 0x20000000 0x00008000 {
.ANY (AHBSRAM1)
}
}

View File

@ -0,0 +1,254 @@
;/*****************************************************************************
; * @file: startup_LPC407x_8x.s
; * @purpose: CMSIS Cortex-M4 Core Device Startup File
; * for the NXP LPC407x_8x Device Series
; * @version: V1.20
; * @date: 16. January 2012
; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
; *
; * Copyright (C) 2012 ARM Limited. All rights reserved.
; * ARM Limited (ARM) is supplying this software for use with Cortex-M4
; * processor based microcontrollers. This file can be freely distributed
; * within development tools that are supporting such ARM based processors.
; *
; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
; *
; *****************************************************************************/
__initial_sp EQU 0x10010000 ; Top of RAM from LPC4088
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
; DCD 0xEFFFF5D6 ; Reserved- vector sum
DCD 0xEFFFF39E ; Reserved- vector sum
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WDT_IRQHandler ; 16: Watchdog Timer
DCD TIMER0_IRQHandler ; 17: Timer0
DCD TIMER1_IRQHandler ; 18: Timer1
DCD TIMER2_IRQHandler ; 19: Timer2
DCD TIMER3_IRQHandler ; 20: Timer3
DCD UART0_IRQHandler ; 21: UART0
DCD UART1_IRQHandler ; 22: UART1
DCD UART2_IRQHandler ; 23: UART2
DCD UART3_IRQHandler ; 24: UART3
DCD PWM1_IRQHandler ; 25: PWM1
DCD I2C0_IRQHandler ; 26: I2C0
DCD I2C1_IRQHandler ; 27: I2C1
DCD I2C2_IRQHandler ; 28: I2C2
DCD 0 ; 29: reserved, not for SPIFI anymore
DCD SSP0_IRQHandler ; 30: SSP0
DCD SSP1_IRQHandler ; 31: SSP1
DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL)
DCD RTC_IRQHandler ; 33: Real Time Clock
DCD EINT0_IRQHandler ; 34: External Interrupt 0
DCD EINT1_IRQHandler ; 35: External Interrupt 1
DCD EINT2_IRQHandler ; 36: External Interrupt 2
DCD EINT3_IRQHandler ; 37: External Interrupt 3
DCD ADC_IRQHandler ; 38: A/D Converter
DCD BOD_IRQHandler ; 39: Brown-Out Detect
DCD USB_IRQHandler ; 40: USB
DCD CAN_IRQHandler ; 41: CAN
DCD DMA_IRQHandler ; 42: General Purpose DMA
DCD I2S_IRQHandler ; 43: I2S
DCD ENET_IRQHandler ; 44: Ethernet
DCD MCI_IRQHandler ; 45: SD/MMC card I/F
DCD MCPWM_IRQHandler ; 46: Motor Control PWM
DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface
DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL)
DCD USBActivity_IRQHandler ; 49: USB Activity interrupt to wakeup
DCD CANActivity_IRQHandler ; 50: CAN Activity interrupt to wakeup
DCD UART4_IRQHandler ; 51: UART4
DCD SSP2_IRQHandler ; 52: SSP2
DCD LCD_IRQHandler ; 53: LCD
DCD GPIO_IRQHandler ; 54: GPIO
DCD PWM0_IRQHandler ; 55: PWM0
DCD EEPROM_IRQHandler ; 56: EEPROM
IF :LNOT::DEF:NO_CRP
AREA |.ARM.__at_0x02FC|, CODE, READONLY
CRP_Key DCD 0xFFFFFFFF
ENDIF
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT WDT_IRQHandler [WEAK]
EXPORT TIMER0_IRQHandler [WEAK]
EXPORT TIMER1_IRQHandler [WEAK]
EXPORT TIMER2_IRQHandler [WEAK]
EXPORT TIMER3_IRQHandler [WEAK]
EXPORT UART0_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT UART2_IRQHandler [WEAK]
EXPORT UART3_IRQHandler [WEAK]
EXPORT PWM1_IRQHandler [WEAK]
EXPORT I2C0_IRQHandler [WEAK]
EXPORT I2C1_IRQHandler [WEAK]
EXPORT I2C2_IRQHandler [WEAK]
;EXPORT SPIFI_IRQHandler [WEAK]
EXPORT SSP0_IRQHandler [WEAK]
EXPORT SSP1_IRQHandler [WEAK]
EXPORT PLL0_IRQHandler [WEAK]
EXPORT RTC_IRQHandler [WEAK]
EXPORT EINT0_IRQHandler [WEAK]
EXPORT EINT1_IRQHandler [WEAK]
EXPORT EINT2_IRQHandler [WEAK]
EXPORT EINT3_IRQHandler [WEAK]
EXPORT ADC_IRQHandler [WEAK]
EXPORT BOD_IRQHandler [WEAK]
EXPORT USB_IRQHandler [WEAK]
EXPORT CAN_IRQHandler [WEAK]
EXPORT DMA_IRQHandler [WEAK]
EXPORT I2S_IRQHandler [WEAK]
EXPORT ENET_IRQHandler [WEAK]
EXPORT MCI_IRQHandler [WEAK]
EXPORT MCPWM_IRQHandler [WEAK]
EXPORT QEI_IRQHandler [WEAK]
EXPORT PLL1_IRQHandler [WEAK]
EXPORT USBActivity_IRQHandler [WEAK]
EXPORT CANActivity_IRQHandler [WEAK]
EXPORT UART4_IRQHandler [WEAK]
EXPORT SSP2_IRQHandler [WEAK]
EXPORT LCD_IRQHandler [WEAK]
EXPORT GPIO_IRQHandler [WEAK]
EXPORT PWM0_IRQHandler [WEAK]
EXPORT EEPROM_IRQHandler [WEAK]
WDT_IRQHandler
TIMER0_IRQHandler
TIMER1_IRQHandler
TIMER2_IRQHandler
TIMER3_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
UART3_IRQHandler
PWM1_IRQHandler
I2C0_IRQHandler
I2C1_IRQHandler
I2C2_IRQHandler
;SPIFI_IRQHandler ;not used
SSP0_IRQHandler
SSP1_IRQHandler
PLL0_IRQHandler
RTC_IRQHandler
EINT0_IRQHandler
EINT1_IRQHandler
EINT2_IRQHandler
EINT3_IRQHandler
ADC_IRQHandler
BOD_IRQHandler
USB_IRQHandler
CAN_IRQHandler
DMA_IRQHandler
I2S_IRQHandler
ENET_IRQHandler
MCI_IRQHandler
MCPWM_IRQHandler
QEI_IRQHandler
PLL1_IRQHandler
USBActivity_IRQHandler
CANActivity_IRQHandler
UART4_IRQHandler
SSP2_IRQHandler
LCD_IRQHandler
GPIO_IRQHandler
PWM0_IRQHandler
EEPROM_IRQHandler
B .
ENDP
ALIGN
END

View File

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

View File

@ -0,0 +1,180 @@
/*
* GENERATED FILE - DO NOT EDIT
* (C) Code Red Technologies Ltd, 2008-2013
* Generated linker script file for LPC4088
* Created from generic_c.ld (vLPCXpresso v5.1 (2 [Build 2065] [2013-02-20] ))
* By LPCXpresso v5.1.2 [Build 2065] [2013-02-20] on Wed Apr 17 14:50:07 CEST 2013
*/
GROUP(libgcc.a libc.a libstdc++.a libm.a libcr_newlib_nohost.a crti.o crtn.o crtbegin.o crtend.o)
MEMORY
{
/* Define each memory region */
MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 512k */
RamLoc64 (rwx) : ORIGIN = 0x100000E8, LENGTH = 0xFF18 /* 64k */
RamPeriph32 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32k */
}
/* Define a symbol for the top of each memory region */
__top_MFlash512 = 0x0 + 0x80000;
__top_RamLoc64 = 0x10000000 + 0x10000;
__top_RamPeriph32 = 0x20000000 + 0x8000;
ENTRY(ResetISR)
SECTIONS
{
/* MAIN TEXT SECTION */
.text : ALIGN(4)
{
FILL(0xff)
KEEP(*(.isr_vector))
/* Global Section Table */
. = ALIGN(4) ;
__section_table_start = .;
__data_section_table = .;
LONG(LOADADDR(.data));
LONG( ADDR(.data)) ;
LONG( SIZEOF(.data));
LONG(LOADADDR(.data_RAM2));
LONG( ADDR(.data_RAM2)) ;
LONG( SIZEOF(.data_RAM2));
__data_section_table_end = .;
__bss_section_table = .;
LONG( ADDR(.bss));
LONG( SIZEOF(.bss));
LONG( ADDR(.bss_RAM2));
LONG( SIZEOF(.bss_RAM2));
__bss_section_table_end = .;
__section_table_end = . ;
/* End of Global Section Table */
*(.after_vectors*)
*(.text*)
*(.rodata .rodata.*)
. = ALIGN(4);
/* C++ constructors etc */
. = 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 = .;
KEEP(*(.fini));
. = ALIGN(4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
/* End C++ */
} > MFlash512
/*
* for exception handling/unwind - some Newlib functions (in common
* with C++ and STDC++) use this.
*/
.ARM.extab : ALIGN(4)
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > MFlash512
__exidx_start = .;
.ARM.exidx : ALIGN(4)
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > MFlash512
__exidx_end = .;
_etext = .;
/* DATA section for RamPeriph32 */
.data_RAM2 : ALIGN(4)
{
FILL(0xff)
*(.data.$RAM2*)
*(.data.$RamPeriph32*)
. = ALIGN(4) ;
} > RamPeriph32 AT>MFlash512
/* MAIN DATA SECTION */
.uninit_RESERVED : ALIGN(4)
{
KEEP(*(.bss.$RESERVED*))
. = ALIGN(4) ;
_end_uninit_RESERVED = .;
} > RamLoc64
.data : ALIGN(4)
{
FILL(0xff)
_data = .;
*(vtable)
*(.data*)
. = ALIGN(4) ;
_edata = .;
} > RamLoc64 AT>MFlash512
/* BSS section for RamPeriph32 */
.bss_RAM2 : ALIGN(4)
{
*(.bss.$RAM2*)
*(.bss.$RamPeriph32*)
. = ALIGN(4) ;
} > RamPeriph32
/* MAIN BSS SECTION */
.bss : ALIGN(4)
{
_bss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4) ;
_ebss = .;
PROVIDE(end = .);
} > RamLoc64
/* NOINIT section for RamPeriph32 */
.noinit_RAM2 (NOLOAD) : ALIGN(4)
{
*(.noinit.$RAM2*)
*(.noinit.$RamPeriph32*)
. = ALIGN(4) ;
} > RamPeriph32
/* DEFAULT NOINIT SECTION */
.noinit (NOLOAD): ALIGN(4)
{
_noinit = .;
*(.noinit*)
. = ALIGN(4) ;
_end_noinit = .;
} > RamLoc64
PROVIDE(_pvHeapStart = .);
PROVIDE(_vStackTop = __top_RamLoc64 - 0);
}

View File

@ -0,0 +1,433 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2012 Code Red Technologies Ltd.
//
// LPC407x_8x Microcontroller Startup code for use with Red Suite
//
// Version : 120624
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
//
//*****************************************************************************
#if defined (__cplusplus)
#ifdef __REDLIB__
#error Redlib does not support C++
#else
//*****************************************************************************
//
// The entry point for the C++ library startup
//
//*****************************************************************************
extern "C" {
extern void __libc_init_array(void);
}
#endif
#endif
#define WEAK __attribute__ ((weak))
#define ALIAS(f) __attribute__ ((weak, alias (#f)))
//#if defined (__USE_CMSIS)
#include "LPC407x_8x_177x_8x.h"
//#endif
//*****************************************************************************
#if defined (__cplusplus)
extern "C" {
#endif
//*****************************************************************************
//
// Forward declaration of the default handlers. These are aliased.
// When the application defines a handler (with the same name), this will
// automatically take precedence over these weak definitions
//
//*****************************************************************************
void ResetISR(void);
WEAK void NMI_Handler(void);
WEAK void HardFault_Handler(void);
WEAK void MemManage_Handler(void);
WEAK void BusFault_Handler(void);
WEAK void UsageFault_Handler(void);
WEAK void SVC_Handler(void);
WEAK void DebugMon_Handler(void);
WEAK void PendSV_Handler(void);
WEAK void SysTick_Handler(void);
WEAK void IntDefaultHandler(void);
//*****************************************************************************
//
// Forward declaration of the specific IRQ handlers. These are aliased
// to the IntDefaultHandler, which is a 'forever' loop. When the application
// defines a handler (with the same name), this will automatically take
// precedence over these weak definitions
//
//*****************************************************************************
void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);
void PWM1_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);
void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);
void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);
void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);
void PLL0_IRQHandler(void) ALIAS(IntDefaultHandler);
void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT2_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT3_IRQHandler(void) ALIAS(IntDefaultHandler);
void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);
void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
void USB_IRQHandler(void) ALIAS(IntDefaultHandler);
void CAN_IRQHandler(void) ALIAS(IntDefaultHandler);
void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2S_IRQHandler(void) ALIAS(IntDefaultHandler);
void ENET_IRQHandler(void) ALIAS(IntDefaultHandler);
void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);
void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);
void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);
void PLL1_IRQHandler(void) ALIAS(IntDefaultHandler);
void USBActivity_IRQHandler(void) ALIAS(IntDefaultHandler);
void CANActivity_IRQHandler(void) ALIAS(IntDefaultHandler);
void MCI_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART4_IRQHandler(void) ALIAS(IntDefaultHandler);
void SSP2_IRQHandler(void) ALIAS(IntDefaultHandler);
void LCD_IRQHandler(void) ALIAS(IntDefaultHandler);
void GPIO_IRQHandler(void) ALIAS(IntDefaultHandler);
void PWM0_IRQHandler(void) ALIAS(IntDefaultHandler);
void EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler);
//*****************************************************************************
//
// The entry point for the application.
// __main() is the entry point for Redlib based applications
// main() is the entry point for Newlib based applications
//
//*****************************************************************************
#if defined (__REDLIB__)
extern void __main(void);
#endif
extern int main(void);
//*****************************************************************************
//
// External declaration for the pointer to the stack top from the Linker Script
//
//*****************************************************************************
extern void _vStackTop(void);
//*****************************************************************************
#if defined (__cplusplus)
} // extern "C"
#endif
//*****************************************************************************
//
// The vector table.
// This relies on the linker script to place at correct location in memory.
//
//*****************************************************************************
extern void (* const g_pfnVectors[])(void);
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
// Core Level - CM3
&_vStackTop, // The initial stack pointer
ResetISR, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
SVC_Handler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
0, // Reserved
PendSV_Handler, // The PendSV handler
SysTick_Handler, // The SysTick handler
// Chip Level - LPC17
WDT_IRQHandler, // 16, 0x40 - WDT
TIMER0_IRQHandler, // 17, 0x44 - TIMER0
TIMER1_IRQHandler, // 18, 0x48 - TIMER1
TIMER2_IRQHandler, // 19, 0x4c - TIMER2
TIMER3_IRQHandler, // 20, 0x50 - TIMER3
UART0_IRQHandler, // 21, 0x54 - UART0
UART1_IRQHandler, // 22, 0x58 - UART1
UART2_IRQHandler, // 23, 0x5c - UART2
UART3_IRQHandler, // 24, 0x60 - UART3
PWM1_IRQHandler, // 25, 0x64 - PWM1
I2C0_IRQHandler, // 26, 0x68 - I2C0
I2C1_IRQHandler, // 27, 0x6c - I2C1
I2C2_IRQHandler, // 28, 0x70 - I2C2
IntDefaultHandler, // 29, Not used
SSP0_IRQHandler, // 30, 0x78 - SSP0
SSP1_IRQHandler, // 31, 0x7c - SSP1
PLL0_IRQHandler, // 32, 0x80 - PLL0 (Main PLL)
RTC_IRQHandler, // 33, 0x84 - RTC
EINT0_IRQHandler, // 34, 0x88 - EINT0
EINT1_IRQHandler, // 35, 0x8c - EINT1
EINT2_IRQHandler, // 36, 0x90 - EINT2
EINT3_IRQHandler, // 37, 0x94 - EINT3
ADC_IRQHandler, // 38, 0x98 - ADC
BOD_IRQHandler, // 39, 0x9c - BOD
USB_IRQHandler, // 40, 0xA0 - USB
CAN_IRQHandler, // 41, 0xa4 - CAN
DMA_IRQHandler, // 42, 0xa8 - GP DMA
I2S_IRQHandler, // 43, 0xac - I2S
ENET_IRQHandler, // 44, 0xb0 - Ethernet
MCI_IRQHandler, // 45, 0xb4 - SD/MMC card I/F
MCPWM_IRQHandler, // 46, 0xb8 - Motor Control PWM
QEI_IRQHandler, // 47, 0xbc - Quadrature Encoder
PLL1_IRQHandler, // 48, 0xc0 - PLL1 (USB PLL)
USBActivity_IRQHandler, // 49, 0xc4 - USB Activity interrupt to wakeup
CANActivity_IRQHandler, // 50, 0xc8 - CAN Activity interrupt to wakeup
UART4_IRQHandler, // 51, 0xcc - UART4
SSP2_IRQHandler, // 52, 0xd0 - SSP2
LCD_IRQHandler, // 53, 0xd4 - LCD
GPIO_IRQHandler, // 54, 0xd8 - GPIO
PWM0_IRQHandler, // 55, 0xdc - PWM0
EEPROM_IRQHandler, // 56, 0xe0 - EEPROM
};
//*****************************************************************************
// Functions to carry out the initialization of RW and BSS data sections. These
// are written as separate functions rather than being inlined within the
// ResetISR() function in order to cope with MCUs with multiple banks of
// memory.
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
unsigned int *pulDest = (unsigned int*) start;
unsigned int *pulSrc = (unsigned int*) romstart;
unsigned int loop;
for (loop = 0; loop < len; loop = loop + 4)
*pulDest++ = *pulSrc++;
}
__attribute__ ((section(".after_vectors")))
void bss_init(unsigned int start, unsigned int len) {
unsigned int *pulDest = (unsigned int*) start;
unsigned int loop;
for (loop = 0; loop < len; loop = loop + 4)
*pulDest++ = 0;
}
//*****************************************************************************
// The following symbols are constructs generated by the linker, indicating
// the location of various points in the "Global Section Table". This table is
// created by the linker via the Code Red managed linker script mechanism. It
// contains the load address, execution address and length of each RW data
// section and the execution and length of each BSS (zero initialized) section.
//*****************************************************************************
extern unsigned int __data_section_table;
extern unsigned int __data_section_table_end;
extern unsigned int __bss_section_table;
extern unsigned int __bss_section_table_end;
//*****************************************************************************
// Reset entry point for your code.
// Sets up a simple runtime environment and initializes the C/C++
// library.
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void
ResetISR(void) {
//
// Copy the data sections from flash to SRAM.
//
unsigned int LoadAddr, ExeAddr, SectionLen;
unsigned int *SectionTableAddr;
// Load base address of Global Section Table
SectionTableAddr = &__data_section_table;
// Copy the data sections from flash to SRAM.
while (SectionTableAddr < &__data_section_table_end) {
LoadAddr = *SectionTableAddr++;
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
data_init(LoadAddr, ExeAddr, SectionLen);
}
// At this point, SectionTableAddr = &__bss_section_table;
// Zero fill the bss segment
while (SectionTableAddr < &__bss_section_table_end) {
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
bss_init(ExeAddr, SectionLen);
}
#if defined (__VFP_FP__) && !defined (__SOFTFP__)
/*
* Code to enable the Cortex-M4 FPU only included
* if appropriate build options have been selected.
* Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C)
*/
// Read CPACR (located at address 0xE000ED88)
// Set bits 20-23 to enable CP10 and CP11 coprocessors
// Write back the modified value to the CPACR
asm volatile ("LDR.W R0, =0xE000ED88\n\t"
"LDR R1, [R0]\n\t"
"ORR R1, R1, #(0xF << 20)\n\t"
"STR R1, [R0]");
#endif // (__VFP_FP__) && !(__SOFTFP__)
// Check to see if we are running the code from a non-zero
// address (eg RAM, external flash), in which case we need
// to modify the VTOR register to tell the CPU that the
// vector table is located at a non-0x0 address.
// Note that we do not use the CMSIS register access mechanism,
// as there is no guarantee that the project has been configured
// to use CMSIS.
unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) {
// CMSIS : SCB->VTOR = <address of vector table>
*pSCB_VTOR = (unsigned int)g_pfnVectors;
}
//#ifdef __USE_CMSIS
SystemInit();
//#endif
#if defined (__cplusplus)
//
// Call C++ library initialisation
//
__libc_init_array();
#endif
#if defined (__REDLIB__)
// Call the Redlib library, which in turn calls main()
__main() ;
#else
main();
#endif
//
// main() shouldn't return, but if it does, we'll just enter an infinite loop
//
while (1) {
;
}
}
//*****************************************************************************
// Default exception handlers. Override the ones here by defining your own
// handler routines in your application code.
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void NMI_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void HardFault_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void MemManage_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void BusFault_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void UsageFault_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void SVC_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void DebugMon_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void PendSV_Handler(void)
{
while(1)
{
}
}
__attribute__ ((section(".after_vectors")))
void SysTick_Handler(void)
{
while(1)
{
}
}
//*****************************************************************************
//
// Processor ends up here if an unexpected interrupt occurs or a specific
// handler is not present in the application code.
//
//*****************************************************************************
__attribute__ ((section(".after_vectors")))
void IntDefaultHandler(void)
{
while(1)
{
}
}
#include <stdlib.h>
void *operator new(size_t size) {return malloc(size);}
void *operator new[](size_t size){return malloc(size);}
void operator delete(void *p) {free(p);}
void operator delete[](void *p) {free(p);}

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,30 @@
/* mbed Microcontroller Library - cmsis_nvic for LCP407x_8x
* Copyright (c) 2009-2011 ARM Limited. All rights reserved.
*
* CMSIS-style functionality to support dynamic vectors
*/
#include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 41) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
int i;
// Copy and switch to dynamic vectors if first time called
if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) {
uint32_t *old_vectors = (uint32_t*)SCB->VTOR;
for (i=0; i<NVIC_NUM_VECTORS; i++) {
vectors[i] = old_vectors[i];
}
SCB->VTOR = (uint32_t)vectors;
}
vectors[IRQn + 16] = vector;
}
uint32_t NVIC_GetVector(IRQn_Type IRQn) {
uint32_t *vectors = (uint32_t*)SCB->VTOR;
return vectors[IRQn + 16];
}

View File

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

View File

@ -0,0 +1,53 @@
/**************************************************************************//**
* @file core_cm4.c
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
/* ################### Compiler specific Intrinsics ########################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/* ARM armcc specific functions */
#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
#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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,649 @@
/**************************************************************************//**
* @file core_cm4_simd.h
* @brief CMSIS Cortex-M4 SIMD Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM4_SIMD_H
#define __CORE_CM4_SIMD_H
/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#include <cmsis_iar.h>
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#include <cmsis_ccs.h>
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SSAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
#define __USAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SMLALD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
#define __SMLALDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SMLSLD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
#define __SMLSLDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
#define __PKHTB(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
if (ARG3 == 0) \
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
else \
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
/* not yet supported */
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CORE_CM4_SIMD_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,616 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.02
* @date 24. May 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#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
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@ -0,0 +1,643 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.03
* @date 29. August 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
return(op1);
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#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 intrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@ -0,0 +1,576 @@
/**********************************************************************
* $Id$ system_LPC407x_8x_177x_8x.c 2012-01-16
*//**
* @file system_LPC407x_8x_177x_8x.c
* @brief CMSIS Cortex-M3, M4 Device Peripheral Access Layer Source File
* for the NXP LPC407x_8x_177x_8x Device Series
*
* ARM Limited (ARM) is supplying this software for use with
* Cortex-M processor based microcontrollers. This file can be
* freely distributed within development tools that are supporting
* such ARM based processors.
*
* @version 1.2
* @date 20. June. 2012
* @author NXP MCU SW Application Team
*
* Copyright(C) 2012, NXP Semiconductor
* All rights reserved.
*
***********************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
**********************************************************************/
#include <stdint.h>
#include "LPC407x_8x_177x_8x.h"
#include "system_LPC407x_8x_177x_8x.h"
#define __CLK_DIV(x,y) (((y) == 0) ? 0: (x)/(y))
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
/*--------------------- Clock Configuration ----------------------------------
//
// <e> Clock Configuration
// <h> System Controls and Status Register (SCS - address 0x400F C1A0)
// <o1.0> EMC Shift Control Bit
// <i> Controls how addresses are output on the EMC address pins for static memories
// <0=> Static CS addresses match bus width; AD[1] = 0 for 32 bit, AD[0] = 0 for 16+32 bit (Bit 0 is 0)
// <1=> Static CS addresses start at LSB 0 regardless of memory width (Bit 0 is 1)
//
// <o1.1> EMC Reset Disable Bit
// <i> If 0 (zero), all registers and functions of the EMC are initialized upon any reset condition
// <i> If 1, EMC is still retained its state through a warm reset
// <0=> Both EMC resets are asserted when any type of chip reset event occurs (Bit 1 is 0)
// <1=> Portions of EMC will only be reset by POR or BOR event (Bit 1 is 1)
//
// <o1.2> EMC Burst Control
// <i> Set to 1 to prevent multiple sequential accesses to memory via EMC static memory chip selects
// <0=> Burst enabled (Bit 2 is 0)
// <1=> Bust disbled (Bit 2 is 1)
//
// <o1.3> MCIPWR Active Level
// <i> Selects the active level for the SD card interface signal SD_PWR
// <0=> SD_PWR is active low (inverted output of the SD Card interface block) (Bit 3 is 0)
// <1=> SD_PWR is active high (follows the output of the SD Card interface block) (Bit 3 is 1)
//
// <o1.4> Main Oscillator Range Select
// <0=> In Range 1 MHz to 20 MHz (Bit 4 is 0)
// <1=> In Range 15 MHz to 25 MHz (Bit 4 is 1)
//
// <o1.5> Main Oscillator enable
// <i> 0 (zero) means disabled, 1 means enable
//
// <o1.6> Main Oscillator status (Read-Only)
// </h>
//
// <h> Clock Source Select Register (CLKSRCSEL - address 0x400F C10C)
// <o2.0> CLKSRC: Select the clock source for sysclk to PLL0 clock
// <0=> Internal RC oscillator (Bit 0 is 0)
// <1=> Main oscillator (Bit 0 is 1)
// </h>
//
// <e3>PLL0 Configuration (Main PLL PLL0CFG - address 0x400F C084)
// <i> F_in is in the range of 1 MHz to 25 MHz
// <i> F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz
// <i> PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz
//
// <o4.0..4> MSEL: PLL Multiplier Value
// <i> M Value
// <1-32><#-1>
//
// <o4.5..6> PSEL: PLL Divider Value
// <i> P Value
// <0=> 1
// <1=> 2
// <2=> 4
// <3=> 8
// </e>
//
// <e5>PLL1 Configuration (Alt PLL PLL1CFG - address 0x400F C0A4)
// <i> F_in is in the range of 1 MHz to 25 MHz
// <i> F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz
// <i> PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz
//
// <o6.0..4> MSEL: PLL Multiplier Value
// <i> M Value
// <1-32><#-1>
//
// <o6.5..6> PSEL: PLL Divider Value
// <i> P Value
// <0=> 1
// <1=> 2
// <2=> 4
// <3=> 8
// </e>
//
// <h> CPU Clock Selection Register (CCLKSEL - address 0x400F C104)
// <o7.0..4> CCLKDIV: Select the value for divider of CPU clock (CCLK)
// <i> 0: The divider is turned off. No clock will be provided to the CPU
// <i> n: The input clock is divided by n to produce the CPU clock
// <0-31>
//
// <o7.8> CCLKSEL: Select the input to the divider of CPU clock
// <0=> sysclk clock is used
// <1=> Main PLL0 clock is used
// </h>
//
// <h> USB Clock Selection Register (USBCLKSEL - 0x400F C108)
// <o8.0..4> USBDIV: USB clock (source PLL0) divider selection
// <0=> Divider is off and no clock provides to USB subsystem
// <4=> Divider value is 4 (The source clock is divided by 4)
// <6=> Divider value is 6 (The source clock is divided by 6)
//
// <o8.8..9> USBSEL: Select the source for USB clock divider
// <i> When CPU clock is selected, the USB can be accessed
// <i> by software but cannot perform USB functions
// <0=> sysclk clock (the clock input to PLL0)
// <1=> The clock output from PLL0
// <2=> The clock output from PLL1
// </h>
//
// <h> EMC Clock Selection Register (EMCCLKSEL - address 0x400F C100)
// <o9.0> EMCDIV: Set the divider for EMC clock
// <0=> Divider value is 1
// <1=> Divider value is 2 (EMC clock is equal a half of input clock)
// </h>
//
// <h> Peripheral Clock Selection Register (PCLKSEL - address 0x400F C1A8)
// <o10.0..4> PCLKDIV: APB Peripheral clock divider
// <i> 0: The divider is turned off. No clock will be provided to APB peripherals
// <i> n: The input clock is divided by n to produce the APB peripheral clock
// <0-31>
// </h>
//
// <h> SPIFI Clock Selection Register (SPIFICLKSEL - address 0x400F C1B4)
// <o11.0..4> SPIFIDIV: Set the divider for SPIFI clock
// <i> 0: The divider is turned off. No clock will be provided to the SPIFI
// <i> n: The input clock is divided by n to produce the SPIFI clock
// <0-31>
//
// <o11.8..9> SPIFISEL: Select the input clock for SPIFI clock divider
// <0=> sysclk clock (the clock input to PLL0)
// <1=> The clock output from PLL0
// <2=> The clock output from PLL1
// </h>
//
// <h> Power Control for Peripherals Register (PCONP - address 0x400F C1C8)
// <o12.0> PCLCD: LCD controller power/clock enable (bit 0)
// <o12.1> PCTIM0: Timer/Counter 0 power/clock enable (bit 1)
// <o12.2> PCTIM1: Timer/Counter 1 power/clock enable (bit 2)
// <o12.3> PCUART0: UART 0 power/clock enable (bit 3)
// <o12.4> PCUART1: UART 1 power/clock enable (bit 4)
// <o12.5> PCPWM0: PWM0 power/clock enable (bit 5)
// <o12.6> PCPWM1: PWM1 power/clock enable (bit 6)
// <o12.7> PCI2C0: I2C 0 interface power/clock enable (bit 7)
// <o12.8> PCUART4: UART 4 power/clock enable (bit 8)
// <o12.9> PCRTC: RTC and Event Recorder power/clock enable (bit 9)
// <o12.10> PCSSP1: SSP 1 interface power/clock enable (bit 10)
// <o12.11> PCEMC: External Memory Controller power/clock enable (bit 11)
// <o12.12> PCADC: A/D converter power/clock enable (bit 12)
// <o12.13> PCCAN1: CAN controller 1 power/clock enable (bit 13)
// <o12.14> PCCAN2: CAN controller 2 power/clock enable (bit 14)
// <o12.15> PCGPIO: IOCON, GPIO, and GPIO interrupts power/clock enable (bit 15)
// <o12.17> PCMCPWM: Motor Control PWM power/clock enable (bit 17)
// <o12.18> PCQEI: Quadrature encoder interface power/clock enable (bit 18)
// <o12.19> PCI2C1: I2C 1 interface power/clock enable (bit 19)
// <o12.20> PCSSP2: SSP 2 interface power/clock enable (bit 20)
// <o12.21> PCSSP0: SSP 0 interface power/clock enable (bit 21)
// <o12.22> PCTIM2: Timer 2 power/clock enable (bit 22)
// <o12.23> PCTIM3: Timer 3 power/clock enable (bit 23)
// <o12.24> PCUART2: UART 2 power/clock enable (bit 24)
// <o12.25> PCUART3: UART 3 power/clock enable (bit 25)
// <o12.26> PCI2C2: I2C 2 interface power/clock enable (bit 26)
// <o12.27> PCI2S: I2S interface power/clock enable (bit 27)
// <o12.28> PCSDC: SD Card interface power/clock enable (bit 28)
// <o12.29> PCGPDMA: GPDMA function power/clock enable (bit 29)
// <o12.30> PCENET: Ethernet block power/clock enable (bit 30)
// <o12.31> PCUSB: USB interface power/clock enable (bit 31)
// </h>
//
// <h> Clock Output Configuration Register (CLKOUTCFG)
// <o13.0..3> CLKOUTSEL: Clock Source for CLKOUT Selection
// <0=> CPU clock
// <1=> Main Oscillator
// <2=> Internal RC Oscillator
// <3=> USB clock
// <4=> RTC Oscillator
// <5=> unused
// <6=> Watchdog Oscillator
//
// <o13.4..7> CLKOUTDIV: Output Clock Divider
// <1-16><#-1>
//
// <o13.8> CLKOUT_EN: CLKOUT enable
// </h>
//
// </e>
*/
#define CLOCK_SETUP 1
#define SCS_Val 0x00000020
#define CLKSRCSEL_Val 0x00000001
#define PLL0_SETUP 1
#define PLL0CFG_Val 0x00000009
#define PLL1_SETUP 1
#define PLL1CFG_Val 0x00000023
#define CCLKSEL_Val 0x00000101
#define USBCLKSEL_Val 0x00000201
#define EMCCLKSEL_Val 0x00000001
#define PCLKSEL_Val 0x00000002
#define SPIFICLKSEL_Val 0x00000002
#define PCONP_Val 0x042887DE
#define CLKOUTCFG_Val 0x00000100
#ifdef CORE_M4
#define LPC_CPACR 0xE000ED88
#define SCB_MVFR0 0xE000EF40
#define SCB_MVFR0_RESET 0x10110021
#define SCB_MVFR1 0xE000EF44
#define SCB_MVFR1_RESET 0x11000011
#endif
/*--------------------- Flash Accelerator Configuration ----------------------
//
// <e> Flash Accelerator Configuration register (FLASHCFG - address 0x400F C000)
// <o1.12..15> FLASHTIM: Flash Access Time
// <0=> 1 CPU clock (for CPU clock up to 20 MHz)
// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
// <5=> 6 CPU clocks (for any CPU clock)
// </e>
*/
#define FLASH_SETUP 1
#define FLASHCFG_Val 0x00005000
/*----------------------------------------------------------------------------
Check the register settings
*----------------------------------------------------------------------------*/
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
#define CHECK_RSVD(val, mask) (val & mask)
/* Clock Configuration -------------------------------------------------------*/
#if (CHECK_RSVD((SCS_Val), ~0x0000003F))
#error "SCS: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 1))
#error "CLKSRCSEL: Value out of range!"
#endif
#if (CHECK_RSVD((PLL0CFG_Val), ~0x0000007F))
#error "PLL0CFG: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))
#error "PLL1CFG: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((CCLKSEL_Val), ~0x0000011F))
#error "CCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((USBCLKSEL_Val), ~0x0000031F))
#error "USBCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((EMCCLKSEL_Val), ~0x00000001))
#error "EMCCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCLKSEL_Val), ~0x0000001F))
#error "PCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCONP_Val), ~0xFFFEFFFF))
#error "PCONP: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
#error "CLKOUTCFG: Invalid values of reserved bits!"
#endif
/* Flash Accelerator Configuration -------------------------------------------*/
#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F000))
#warning "FLASHCFG: Invalid values of reserved bits!"
#endif
/*----------------------------------------------------------------------------
DEFINES
*----------------------------------------------------------------------------*/
/* pll_out_clk = F_cco / (2 <20> P)
F_cco = pll_in_clk <EFBFBD> M <EFBFBD> 2 <EFBFBD> P */
#define __M ((PLL0CFG_Val & 0x1F) + 1)
#define __PLL0_CLK(__F_IN) (__F_IN * __M)
#define __CCLK_DIV (CCLKSEL_Val & 0x1F)
#define __PCLK_DIV (PCLKSEL_Val & 0x1F)
#define __ECLK_DIV ((EMCCLKSEL_Val & 0x01) + 1)
/* Determine core clock frequency according to settings */
#if (CLOCK_SETUP) /* Clock Setup */
#if ((CLKSRCSEL_Val & 0x01) == 1) && ((SCS_Val & 0x20)== 0)
#error "Main Oscillator is selected as clock source but is not enabled!"
#endif
#if ((CCLKSEL_Val & 0x100) == 0x100) && (PLL0_SETUP == 0)
#error "Main PLL is selected as clock source but is not enabled!"
#endif
#if ((CCLKSEL_Val & 0x100) == 0) /* cclk = sysclk */
#if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */
#define __CORE_CLK (IRC_OSC / __CCLK_DIV)
#define __PER_CLK (IRC_OSC/ __PCLK_DIV)
#define __EMC_CLK (__CORE_CLK/ __ECLK_DIV)
#else /* sysclk = osc_clk */
#define __CORE_CLK (OSC_CLK / __CCLK_DIV)
#define __PER_CLK (OSC_CLK/ __PCLK_DIV)
#define __EMC_CLK (__CORE_CLK/ __ECLK_DIV)
#endif
#else /* cclk = pll_clk */
#if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */
#define __CORE_CLK (__PLL0_CLK(IRC_OSC) / __CCLK_DIV)
#define __PER_CLK (__PLL0_CLK(IRC_OSC) / __PCLK_DIV)
#define __EMC_CLK (__CORE_CLK / __ECLK_DIV)
#else /* sysclk = osc_clk */
#define __CORE_CLK (__PLL0_CLK(OSC_CLK) / __CCLK_DIV)
#define __PER_CLK (__PLL0_CLK(OSC_CLK) / __PCLK_DIV)
#define __EMC_CLK (__CORE_CLK / __ECLK_DIV)
#endif
#endif
#else
#define __CORE_CLK (IRC_OSC)
#define __PER_CLK (IRC_OSC)
#define __EMC_CLK (__CORE_CLK)
#endif
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
uint32_t PeripheralClock = __PER_CLK; /*!< Peripheral Clock Frequency (Pclk) */
uint32_t EMCClock = __EMC_CLK; /*!< EMC Clock Frequency */
uint32_t USBClock = (48000000UL); /*!< USB Clock Frequency - this value will
be updated after call SystemCoreClockUpdate, should be 48MHz*/
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
/* Determine clock frequency according to clock register values */
if ((LPC_SC->CCLKSEL &0x100) == 0) { /* cclk = sysclk */
if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */
SystemCoreClock = __CLK_DIV(IRC_OSC , (LPC_SC->CCLKSEL & 0x1F));
PeripheralClock = __CLK_DIV(IRC_OSC , (LPC_SC->PCLKSEL & 0x1F));
EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1));
}
else { /* sysclk = osc_clk */
if ((LPC_SC->SCS & 0x40) == 0) {
SystemCoreClock = 0; /* this should never happen! */
PeripheralClock = 0;
EMCClock = 0;
}
else {
SystemCoreClock = __CLK_DIV(OSC_CLK , (LPC_SC->CCLKSEL & 0x1F));
PeripheralClock = __CLK_DIV(OSC_CLK , (LPC_SC->PCLKSEL & 0x1F));
EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1));
}
}
}
else { /* cclk = pll_clk */
if ((LPC_SC->PLL0STAT & 0x100) == 0) { /* PLL0 not enabled */
SystemCoreClock = 0; /* this should never happen! */
PeripheralClock = 0;
EMCClock = 0;
}
else {
if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */
uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1);
uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F);
uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F);
uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1;
SystemCoreClock = __CLK_DIV(IRC_OSC * mul , cpu_div);
PeripheralClock = __CLK_DIV(IRC_OSC * mul , per_div);
EMCClock = SystemCoreClock / emc_div;
}
else { /* sysclk = osc_clk */
if ((LPC_SC->SCS & 0x40) == 0) {
SystemCoreClock = 0; /* this should never happen! */
PeripheralClock = 0;
EMCClock = 0;
}
else {
uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1);
uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F);
uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F);
uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1;
SystemCoreClock = __CLK_DIV(OSC_CLK * mul , cpu_div);
PeripheralClock = __CLK_DIV(OSC_CLK * mul , per_div);
EMCClock = SystemCoreClock / emc_div;
}
}
}
}
/* ---update USBClock------------------*/
if(LPC_SC->USBCLKSEL & (0x01<<8))//Use PLL0 as the input to the USB clock divider
{
switch (LPC_SC->USBCLKSEL & 0x1F)
{
case 0:
USBClock = 0; //no clock will be provided to the USB subsystem
break;
case 4:
case 6:
{
uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1);
uint8_t usb_div = (LPC_SC->USBCLKSEL & 0x1F);
if(LPC_SC->CLKSRCSEL & 0x01) //pll_clk_in = main_osc
USBClock = OSC_CLK * mul / usb_div;
else //pll_clk_in = irc_clk
USBClock = IRC_OSC * mul / usb_div;
}
break;
default:
USBClock = 0; /* this should never happen! */
}
}
else if(LPC_SC->USBCLKSEL & (0x02<<8))//usb_input_clk = alt_pll (pll1)
{
if(LPC_SC->CLKSRCSEL & 0x01) //pll1_clk_in = main_osc
USBClock = (OSC_CLK * ((LPC_SC->PLL1STAT & 0x1F) + 1));
else //pll1_clk_in = irc_clk
USBClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1));
}
else
USBClock = 0; /* this should never happen! */
}
/* Determine clock frequency according to clock register values */
#ifdef CORE_M4
void fpu_init(void)
{
// from arm trm manual:
// ; CPACR is located at address 0xE000ED88
// LDR.W R0, =0xE000ED88
// ; Read CPACR
// LDR R1, [R0]
// ; Set bits 20-23 to enable CP10 and CP11 coprocessors
// ORR R1, R1, #(0xF << 20)
// ; Write back the modified value to the CPACR
// STR R1, [R0]
volatile uint32_t* regCpacr = (uint32_t*) LPC_CPACR;
volatile uint32_t* regMvfr0 = (uint32_t*) SCB_MVFR0;
volatile uint32_t* regMvfr1 = (uint32_t*) SCB_MVFR1;
volatile uint32_t Cpacr;
volatile uint32_t Mvfr0;
volatile uint32_t Mvfr1;
char vfpPresent = 0;
Mvfr0 = *regMvfr0;
Mvfr1 = *regMvfr1;
vfpPresent = ((SCB_MVFR0_RESET == Mvfr0) && (SCB_MVFR1_RESET == Mvfr1));
if(vfpPresent)
{
Cpacr = *regCpacr;
Cpacr |= (0xF << 20);
*regCpacr = Cpacr; // enable CP10 and CP11 for full access
}
}
#endif
// Make sure we are pulling in the retargeting module at link time
extern int stdio_retargeting_module;
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void)
{
#ifndef __CODE_RED
#ifdef CORE_M4
fpu_init();
#endif
#endif
#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->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for sysclk/PLL0*/
#if (PLL0_SETUP)
LPC_SC->PLL0CFG = PLL0CFG_Val;
LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
while (!(LPC_SC->PLL0STAT & (1<<10)));/* Wait for PLOCK0 */
#endif
#if (PLL1_SETUP)
LPC_SC->PLL1CFG = PLL1CFG_Val;
LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */
#endif
LPC_SC->CCLKSEL = CCLKSEL_Val; /* Setup Clock Divider */
LPC_SC->USBCLKSEL = USBCLKSEL_Val; /* Setup USB Clock Divider */
LPC_SC->EMCCLKSEL = EMCCLKSEL_Val; /* EMC Clock Selection */
LPC_SC->SPIFICLKSEL = SPIFICLKSEL_Val; /* SPIFI Clock Selection */
LPC_SC->PCLKSEL = PCLKSEL_Val; /* Peripheral Clock Selection */
LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */
LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */
#endif
LPC_SC->PBOOST |= 0x03; /* Power Boost control */
#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */
LPC_SC->FLASHCFG = FLASHCFG_Val|0x03A;
#endif
#ifndef __CODE_RED
#ifdef __RAM_MODE__
SCB->VTOR = 0x10000000 & 0x3FFFFF80;
#else
SCB->VTOR = 0x00000000 & 0x3FFFFF80;
#endif
#endif
SystemCoreClockUpdate();
stdio_retargeting_module = 1;
}

View File

@ -0,0 +1,89 @@
/**********************************************************************
* $Id$ system_LPC407x_8x_177x_8x.h 2011-06-02
*//**
* @file system_LPC407x_8x_177x_8x.h
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File
* for the NXP LPC Device Series
* @version 1.0
* @date 02. June. 2011
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, NXP Semiconductor
* All rights reserved.
*
***********************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
**********************************************************************/
#ifndef __SYSTEM_LPC407x_8x_177x_8x_H
#define __SYSTEM_LPC407x_8x_177x_8x_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency (Pclk) */
extern uint32_t EMCClock; /*!< EMC Clock */
extern uint32_t USBClock; /*!< USB Frequency */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define XTAL (12000000UL) /* Oscillator frequency */
#define OSC_CLK ( XTAL) /* Main oscillator frequency */
#define RTC_CLK ( 32768UL) /* RTC oscillator frequency */
#define IRC_OSC (12000000UL) /* Internal RC oscillator frequency */
#define WDT_OSC ( 500000UL) /* Internal WDT oscillator frequency */
/*
//-------- <<< end of configuration section >>> ------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC407x_8x_177x_8x_H */

View File

@ -9,15 +9,18 @@
"core_arm7.o",
"core_cm3.o",
"core_cm0.o",
"core_cm4.o",
"system_LPC23xx.o",
"system_LPC11Uxx.o",
"system_LPC17xx.o",
"system_LPC8xx.o",
"system_LPC407x_8x_177x_8x.o",
"startup_LPC11xx.o",
"startup_LPC17xx.o",
"startup_LPC8xx.o",
"startup_LPC407x_8x_177x_8x.o",
"vector_functions.o",
"vector_realmonitor.o",

View File

@ -20,7 +20,7 @@
#ifndef ETHERNETINTERFACE_H_
#define ETHERNETINTERFACE_H_
#if !defined(TARGET_LPC1768)
#if !defined(TARGET_LPC1768) && !defined(TARGET_LPC4088)
#error The Ethernet Interface library is supported only on the mbed NXP LPC1768
#endif

View File

@ -130,9 +130,21 @@ struct lpc_enetdata {
#endif
};
#if defined(TARGET_LPC4088)
# if defined (__ICCARM__)
# define ETHMEM_SECTION
# elif defined(TOOLCHAIN_GCC_CR)
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
# else
# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
# endif
#else
# define ETHMEM_SECTION ALIGNED(8)
#endif
/** \brief LPC EMAC driver work data
*/
ALIGNED(8) struct lpc_enetdata lpc_enetdata;
ETHMEM_SECTION struct lpc_enetdata lpc_enetdata;
/* Write a value via the MII link (non-blocking) */
void lpc_mii_write_noblock(u32_t PhyReg, u32_t Value)
@ -485,7 +497,11 @@ void lpc_enetif_input(struct netif *netif)
*/
static s32_t lpc_packet_addr_notsafe(void *addr) {
/* Check for legal address ranges */
#if defined(TARGET_LPC1768)
if ((((u32_t) addr >= 0x2007C000) && ((u32_t) addr < 0x20083FFF))) {
#elif defined(TARGET_LPC4088)
if ((((u32_t) addr >= 0x20000000) && ((u32_t) addr < 0x20007FFF))) {
#endif
return 0;
}
return 1;
@ -840,8 +856,31 @@ static err_t low_level_init(struct netif *netif)
/* Enable MII clocking */
LPC_SC->PCONP |= CLKPWR_PCONP_PCENET;
#if defined(TARGET_LPC1768)
LPC_PINCON->PINSEL2 = 0x50150105; /* Enable P1 Ethernet Pins. */
LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
#elif defined(TARGET_LPC4088)
LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */
LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */
LPC_IOCON->P1_1 &= ~0x07;
LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */
LPC_IOCON->P1_4 &= ~0x07;
LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */
LPC_IOCON->P1_8 &= ~0x07;
LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */
LPC_IOCON->P1_9 &= ~0x07;
LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */
LPC_IOCON->P1_10 &= ~0x07;
LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */
LPC_IOCON->P1_14 &= ~0x07;
LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */
LPC_IOCON->P1_15 &= ~0x07;
LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */
LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */
LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */
LPC_IOCON->P1_17 &= ~0x07;
LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */
#endif
/* Reset all MAC logic */
LPC_EMAC->MAC1 = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX |
@ -894,7 +933,7 @@ static err_t low_level_init(struct netif *netif)
/* Enable packet reception */
#if IP_SOF_BROADCAST_RECV
LPC_EMAC->RxFilterCtrl = EMAC_RFC_PERFECT_EN | EMAC_RFC_BCAST_EN;
LPC_EMAC->RxFilterCtrl = EMAC_RFC_PERFECT_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_MCAST_EN;
#else
LPC_EMAC->RxFilterCtrl = EMAC_RFC_PERFECT_EN;
#endif
@ -989,7 +1028,7 @@ err_t lpc_enetif_init(struct netif *netif)
netif->mtu = 1500;
/* device capabilities */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
/* Initialize the hardware */
netif->state = &lpc_enetdata;

View File

@ -34,7 +34,7 @@
#define LPC17XX_EMAC_H_
/* Includes ------------------------------------------------------------------- */
#include "LPC17xx.h"
#include "cmsis.h"
#ifdef __cplusplus
extern "C"

View File

@ -44,6 +44,8 @@
/** \brief DP83848 PHY register offsets */
#define DP8_BMCR_REG 0x0 /**< Basic Mode Control Register */
#define DP8_BMSR_REG 0x1 /**< Basic Mode Status Reg */
#define DP8_IDR1_REG 0x2 /**< Basic Mode Status Reg */
#define DP8_IDR2_REG 0x3 /**< Basic Mode Status Reg */
#define DP8_ANADV_REG 0x4 /**< Auto_Neg Advt Reg */
#define DP8_ANLPA_REG 0x5 /**< Auto_neg Link Partner Ability Reg */
#define DP8_ANEEXP_REG 0x6 /**< Auto-neg Expansion Reg */
@ -52,6 +54,8 @@
#define DP8_PHY_RBR_REG 0x17 /**< PHY RMII and Bypass Register */
#define DP8_PHY_STS_REG 0x19 /**< PHY Status Register */
#define DP8_PHY_SCSR_REG 0x1f /**< PHY Special Control/Status Register (LAN8720) */
/** \brief DP83848 Control register definitions */
#define DP8_RESET (1 << 15) /**< 1= S/W Reset */
#define DP8_LOOPBACK (1 << 14) /**< 1=loopback Enabled */
@ -90,6 +94,19 @@
#define DP8_PHYID1_OUI 0x2000 /**< Expected PHY ID1 */
#define DP8_PHYID2_OUI 0x5c90 /**< Expected PHY ID2 */
/** \brief LAN8720 PHY Special Control/Status Register */
#define PHY_SCSR_100MBIT 0x0008 /**< Speed: 1=100 MBit, 0=10Mbit */
#define PHY_SCSR_DUPLEX 0x0010 /**< PHY Duplex Mask */
/** \brief Link status bits */
#define LNK_STAT_VALID 0x01
#define LNK_STAT_FULLDUPLEX 0x02
#define LNK_STAT_SPEED10MPS 0x04
/** \brief PHY ID definitions */
#define DP83848C_ID 0x20005C90 /**< PHY Identifier - DP83848C */
#define LAN8720_ID 0x0007C0F0 /**< PHY Identifier - LAN8720 */
/** \brief PHY status structure used to indicate current status of PHY.
*/
typedef struct {
@ -107,6 +124,12 @@ static PHY_STATUS_TYPE olddphysts;
/** \brief PHY update counter for state machine */
static s32_t phyustate;
/** \brief Holds the PHY ID */
static u32_t phy_id;
/** \brief Temporary holder of link status for LAN7420 */
static u32_t phy_lan7420_sts_tmp;
/** \brief Update PHY status from passed value
*
* This function updates the current PHY status based on the
@ -122,19 +145,19 @@ static s32_t lpc_update_phy_sts(struct netif *netif, u32_t linksts)
s32_t changed = 0;
/* Update link active status */
if (linksts & DP8_VALID_LINK)
if (linksts & LNK_STAT_VALID)
physts.phy_link_active = 1;
else
physts.phy_link_active = 0;
/* Full or half duplex */
if (linksts & DP8_FULLDUPLEX)
if (linksts & LNK_STAT_FULLDUPLEX)
physts.phy_full_duplex = 1;
else
physts.phy_full_duplex = 0;
/* Configure 100MBit/10MBit mode. */
if (linksts & DP8_SPEED10MBPS)
if (linksts & LNK_STAT_SPEED10MPS)
physts.phy_speed_100mbs = 0;
else
physts.phy_speed_100mbs = 1;
@ -229,6 +252,12 @@ err_t lpc_phy_init(struct netif *netif, int rmii)
if (i == 0)
return ERR_TIMEOUT;
// read PHY ID
lpc_mii_read(DP8_IDR1_REG, &tmp);
phy_id = (tmp << 16);
lpc_mii_read(DP8_IDR2_REG, &tmp);
phy_id |= (tmp & 0XFFF0);
/* Setup link based on configuration options */
#if PHY_USE_AUTONEG==1
tmp = DP8_AUTONEG;
@ -257,20 +286,54 @@ err_t lpc_phy_init(struct netif *netif, int rmii)
s32_t lpc_phy_sts_sm(struct netif *netif)
{
s32_t changed = 0;
u32_t data = 0;
u32_t tmp;
switch (phyustate) {
default:
case 0:
/* Read BMSR to clear faults */
if (phy_id == DP83848C_ID) {
lpc_mii_read_noblock(DP8_PHY_STAT_REG);
phyustate = 2;
}
else if (phy_id == LAN8720_ID) {
lpc_mii_read_noblock(DP8_PHY_SCSR_REG);
phyustate = 1;
}
break;
case 1:
if (phy_id == LAN8720_ID) {
tmp = lpc_mii_read_data();
// we get speed and duplex here.
phy_lan7420_sts_tmp = (tmp & PHY_SCSR_DUPLEX) ? LNK_STAT_FULLDUPLEX : 0;
phy_lan7420_sts_tmp |= (tmp & PHY_SCSR_100MBIT) ? 0 : LNK_STAT_SPEED10MPS;
//read the status register to get link status
lpc_mii_read_noblock(DP8_BMSR_REG);
phyustate = 2;
}
break;
case 2:
/* Wait for read status state */
if (!lpc_mii_is_busy()) {
/* Update PHY status */
changed = lpc_update_phy_sts(netif, lpc_mii_read_data());
tmp = lpc_mii_read_data();
if (phy_id == DP83848C_ID) {
// STS register contains all needed status bits
data = (tmp & DP8_VALID_LINK) ? LNK_STAT_VALID : 0;
data |= (tmp & DP8_FULLDUPLEX) ? LNK_STAT_FULLDUPLEX : 0;
data |= (tmp & DP8_SPEED10MBPS) ? LNK_STAT_SPEED10MPS : 0;
}
else if (phy_id == LAN8720_ID) {
// we only get the link status here.
phy_lan7420_sts_tmp |= (tmp & DP8_LINK_STATUS) ? LNK_STAT_VALID : 0;
data = phy_lan7420_sts_tmp;
}
changed = lpc_update_phy_sts(netif, data);
phyustate = 0;
}
break;

View File

@ -177,8 +177,21 @@ struct mem {
* If so, make sure the memory at that location is big enough (see below on
* how that space is calculated). */
#ifndef LWIP_RAM_HEAP_POINTER
#if defined(TARGET_LPC4088)
# if defined (__ICCARM__)
# define ETHMEM_SECTION
# elif defined(TOOLCHAIN_GCC_CR)
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
# else
# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
# endif
#else
# define ETHMEM_SECTION __attribute((section("AHBSRAM0")))
#endif
/** the heap. we need one struct mem at the end and some room for alignment */
u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT]__attribute((section("AHBSRAM0")));
u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT] ETHMEM_SECTION;
#define LWIP_RAM_HEAP_POINTER ram_heap
#endif /* LWIP_RAM_HEAP_POINTER */

View File

@ -166,11 +166,17 @@ static u8_t *const memp_bases[] = {
#else /* MEMP_SEPARATE_POOLS */
#if defined(TARGET_LPC1768)
# define ETHMEM_SECTION __attribute((section("AHBSRAM1")))
#elif defined(TARGET_LPC4088)
# define ETHMEM_SECTION
#endif
/** This is the actual memory used by the pools (all pools in one big block). */
static u8_t memp_memory[MEM_ALIGNMENT - 1
#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
#include "lwip/memp_std.h"
] __attribute((section("AHBSRAM1")));
] ETHMEM_SECTION;
#endif /* MEMP_SEPARATE_POOLS */

View File

@ -0,0 +1,309 @@
/*----------------------------------------------------------------------------
* RL-ARM - RTX
*----------------------------------------------------------------------------
* Name: HAL_CM4.C
* Purpose: Hardware Abstraction Layer for Cortex-M4
* Rev.: V4.70
*----------------------------------------------------------------------------
*
* Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 "rt_TypeDef.h"
#include "RTX_Conf.h"
#include "rt_System.h"
#include "rt_HAL_CM.h"
#include "rt_Task.h"
#include "rt_MemBox.h"
/*----------------------------------------------------------------------------
* Functions
*---------------------------------------------------------------------------*/
/*--------------------------- rt_set_PSP ------------------------------------*/
__asm void rt_set_PSP (U32 stack) {
MSR PSP,R0
BX LR
}
/*--------------------------- rt_get_PSP ------------------------------------*/
__asm U32 rt_get_PSP (void) {
MRS R0,PSP
BX LR
}
/*--------------------------- os_set_env ------------------------------------*/
__asm void os_set_env (void) {
/* Switch to Unprivileged/Privileged Thread mode, use PSP. */
MOV R0,SP ; PSP = MSP
MSR PSP,R0
LDR R0,=__cpp(&os_flags)
LDRB R0,[R0]
LSLS R0,#31
MOVNE R0,#0x02 ; Privileged Thread mode, use PSP
MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP
MSR CONTROL,R0
BX LR
ALIGN
}
/*--------------------------- _alloc_box ------------------------------------*/
__asm void *_alloc_box (void *box_mem) {
/* Function wrapper for Unprivileged/Privileged mode. */
LDR R12,=__cpp(rt_alloc_box)
MRS R3,IPSR
LSLS R3,#24
BXNE R12
MRS R3,CONTROL
LSLS R3,#31
BXEQ R12
SVC 0
BX LR
ALIGN
}
/*--------------------------- _free_box -------------------------------------*/
__asm int _free_box (void *box_mem, void *box) {
/* Function wrapper for Unprivileged/Privileged mode. */
LDR R12,=__cpp(rt_free_box)
MRS R3,IPSR
LSLS R3,#24
BXNE R12
MRS R3,CONTROL
LSLS R3,#31
BXEQ R12
SVC 0
BX LR
ALIGN
}
/*-------------------------- SVC_Handler ------------------------------------*/
__asm void SVC_Handler (void) {
PRESERVE8
IMPORT SVC_Count
IMPORT SVC_Table
IMPORT rt_stk_check
#ifdef IFX_XMC4XXX
EXPORT SVC_Handler_Veneer
SVC_Handler_Veneer
#endif
MRS R0,PSP ; Read PSP
LDR R1,[R0,#24] ; Read Saved PC from Stack
LDRB R1,[R1,#-2] ; Load SVC Number
CBNZ R1,SVC_User
LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack
PUSH {R4,LR} ; Save EXC_RETURN
BLX R12 ; Call SVC Function
POP {R4,LR} ; Restore EXC_RETURN
MRS R12,PSP ; Read PSP
STM R12,{R0-R2} ; Store return values
LDR R3,=__cpp(&os_tsk)
LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new
CMP R1,R2
#ifdef IFX_XMC4XXX
PUSHEQ {LR}
POPEQ {PC}
#else
BXEQ LR ; RETI, no task switch
#endif
CBZ R1,SVC_Next ; Runtask deleted?
TST LR,#0x10 ; is it extended frame?
VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs
MOVEQ R0,#0x01 ; os_tsk->stack_frame val
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val
STMDB R12!,{R4-R11} ; Save Old context
STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack
PUSH {R2,R3}
BL rt_stk_check ; Check for Stack overflow
POP {R2,R3}
SVC_Next
STR R2,[R3] ; os_tsk.run = os_tsk.new
LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack
LDMIA R12!,{R4-R11} ; Restore New Context
LDRB R0,[R2,#TCB_STACKF] ; Stack Frame
CMP R0,#0 ; Basic/Extended Stack Frame
VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers
MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value
MVNEQ LR,#:NOT:0xFFFFFFFD
MSR PSP,R12 ; Write PSP
SVC_Exit
#ifdef IFX_XMC4XXX
PUSH {LR}
POP {PC}
#else
BX LR
#endif
/*------------------- User SVC ------------------------------*/
SVC_User
PUSH {R4,LR} ; Save Registers
LDR R2,=SVC_Count
LDR R2,[R2]
CMP R1,R2
BHI SVC_Done ; Overflow
LDR R4,=SVC_Table-4
LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address
LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack
BLX R4 ; Call SVC Function
MRS R12,PSP
STM R12,{R0-R3} ; Function return values
SVC_Done
POP {R4,PC} ; RETI
ALIGN
}
/*-------------------------- PendSV_Handler ---------------------------------*/
__asm void PendSV_Handler (void) {
PRESERVE8
#ifdef IFX_XMC4XXX
EXPORT PendSV_Handler_Veneer
PendSV_Handler_Veneer
#endif
PUSH {R4,LR} ; Save EXC_RETURN
BL __cpp(rt_pop_req)
Sys_Switch
POP {R4,LR} ; Restore EXC_RETURN
LDR R3,=__cpp(&os_tsk)
LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new
CMP R1,R2
#ifdef IFX_XMC4XXX
PUSHEQ {LR}
POPEQ {PC}
#else
BXEQ LR ; RETI, no task switch
#endif
MRS R12,PSP ; Read PSP
TST LR,#0x10 ; is it extended frame?
VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs
MOVEQ R0,#0x01 ; os_tsk->stack_frame val
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val
STMDB R12!,{R4-R11} ; Save Old context
STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack
PUSH {R2,R3}
BL rt_stk_check ; Check for Stack overflow
POP {R2,R3}
STR R2,[R3] ; os_tsk.run = os_tsk.new
LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack
LDMIA R12!,{R4-R11} ; Restore New Context
LDRB R0,[R2,#TCB_STACKF] ; Stack Frame
CMP R0,#0 ; Basic/Extended Stack Frame
VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs
MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value
MVNEQ LR,#:NOT:0xFFFFFFFD
MSR PSP,R12 ; Write PSP
Sys_Exit
#ifdef IFX_XMC4XXX
PUSH {LR}
POP {PC}
#else
BX LR ; Return to Thread Mode
#endif
ALIGN
}
/*-------------------------- SysTick_Handler --------------------------------*/
__asm void SysTick_Handler (void) {
PRESERVE8
#ifdef IFX_XMC4XXX
EXPORT SysTick_Handler_Veneer
SysTick_Handler_Veneer
#endif
PUSH {R4,LR} ; Save EXC_RETURN
BL __cpp(rt_systick)
B Sys_Switch
ALIGN
}
/*-------------------------- OS_Tick_Handler --------------------------------*/
__asm void OS_Tick_Handler (void) {
PRESERVE8
PUSH {R4,LR} ; Save EXC_RETURN
BL __cpp(os_tick_irqack)
BL __cpp(rt_systick)
B Sys_Switch
ALIGN
}
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,57 @@
;/*----------------------------------------------------------------------------
; * RL-ARM - RTX
; *----------------------------------------------------------------------------
; * Name: SVC_TABLE.S
; * Purpose: Pre-defined SVC Table for Cortex-M
; * Rev.: V4.70
; *----------------------------------------------------------------------------
; *
; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
; * All rights reserved.
; * Redistribution and use in source and binary forms, with or without
; * modification, are permitted provided that the following conditions are met:
; * - Redistributions of source code must retain the above copyright
; * notice, this list of conditions and the following disclaimer.
; * - 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.
; * - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
; *---------------------------------------------------------------------------*/
AREA SVC_TABLE, CODE, READONLY
EXPORT SVC_Count
SVC_Cnt EQU (SVC_End-SVC_Table)/4
SVC_Count DCD SVC_Cnt
; Import user SVC functions here.
; IMPORT __SVC_1
EXPORT SVC_Table
SVC_Table
; Insert user SVC functions here. SVC 0 used by RTL Kernel.
; DCD __SVC_1 ; user SVC function
SVC_End
END
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,389 @@
/*----------------------------------------------------------------------------
* RL-ARM - RTX
*----------------------------------------------------------------------------
* Name: HAL_CM4.S
* Purpose: Hardware Abstraction Layer for Cortex-M4
* Rev.: V4.70
*----------------------------------------------------------------------------
*
* Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
*---------------------------------------------------------------------------*/
.file "HAL_CM4.S"
.syntax unified
.equ TCB_STACKF, 32
.equ TCB_TSTACK, 36
/*----------------------------------------------------------------------------
* Functions
*---------------------------------------------------------------------------*/
.thumb
.section ".text"
.align 2
/*--------------------------- rt_set_PSP ------------------------------------*/
# void rt_set_PSP (U32 stack);
.thumb_func
.type rt_set_PSP, %function
.global rt_set_PSP
rt_set_PSP:
.fnstart
.cantunwind
MSR PSP,R0
BX LR
.fnend
.size rt_set_PSP, .-rt_set_PSP
/*--------------------------- rt_get_PSP ------------------------------------*/
# U32 rt_get_PSP (void);
.thumb_func
.type rt_get_PSP, %function
.global rt_get_PSP
rt_get_PSP:
.fnstart
.cantunwind
MRS R0,PSP
BX LR
.fnend
.size rt_get_PSP, .-rt_get_PSP
/*--------------------------- os_set_env ------------------------------------*/
# void os_set_env (void);
/* Switch to Unprivileged/Privileged Thread mode, use PSP. */
.thumb_func
.type os_set_env, %function
.global os_set_env
os_set_env:
.fnstart
.cantunwind
MOV R0,SP /* PSP = MSP */
MSR PSP,R0
LDR R0,=os_flags
LDRB R0,[R0]
LSLS R0,#31
ITE NE
MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */
MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */
MSR CONTROL,R0
BX LR
.fnend
.size os_set_env, .-os_set_env
/*--------------------------- _alloc_box ------------------------------------*/
# void *_alloc_box (void *box_mem);
/* Function wrapper for Unprivileged/Privileged mode. */
.thumb_func
.type _alloc_box, %function
.global _alloc_box
_alloc_box:
.fnstart
.cantunwind
LDR R12,=rt_alloc_box
MRS R3,IPSR
LSLS R3,#24
IT NE
BXNE R12
MRS R3,CONTROL
LSLS R3,#31
IT EQ
BXEQ R12
SVC 0
BX LR
.fnend
.size _alloc_box, .-_alloc_box
/*--------------------------- _free_box -------------------------------------*/
# int _free_box (void *box_mem, void *box);
/* Function wrapper for Unprivileged/Privileged mode. */
.thumb_func
.type _free_box, %function
.global _free_box
_free_box:
.fnstart
.cantunwind
LDR R12,=rt_free_box
MRS R3,IPSR
LSLS R3,#24
IT NE
BXNE R12
MRS R3,CONTROL
LSLS R3,#31
IT EQ
BXEQ R12
SVC 0
BX LR
.fnend
.size _free_box, .-_free_box
/*-------------------------- SVC_Handler ------------------------------------*/
# void SVC_Handler (void);
.thumb_func
.type SVC_Handler, %function
.global SVC_Handler
SVC_Handler:
.ifdef IFX_XMC4XXX
.global SVC_Handler_Veneer
SVC_Handler_Veneer:
.endif
.fnstart
.cantunwind
MRS R0,PSP /* Read PSP */
LDR R1,[R0,#24] /* Read Saved PC from Stack */
LDRB R1,[R1,#-2] /* Load SVC Number */
CBNZ R1,SVC_User
LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */
PUSH {R4,LR} /* Save EXC_RETURN */
BLX R12 /* Call SVC Function */
POP {R4,LR} /* Restore EXC_RETURN */
MRS R12,PSP /* Read PSP */
STM R12,{R0-R2} /* Store return values */
LDR R3,=os_tsk
LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */
CMP R1,R2
.ifdef IFX_XMC4XXX
ITT EQ
PUSHEQ {LR}
POPEQ {PC}
.else
IT EQ
BXEQ LR /* RETI, no task switch */
.endif
CBZ R1,SVC_Next /* Runtask deleted? */
TST LR,#0x10 /* is it extended frame? */
ITTE EQ
VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */
MOVEQ R0,#0x01 /* os_tsk->stack_frame val */
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */
STMDB R12!,{R4-R11} /* Save Old context */
STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */
PUSH {R2,R3}
BL rt_stk_check /* Check for Stack overflow */
POP {R2,R3}
SVC_Next:
STR R2,[R3] /* os_tsk.run = os_tsk.new */
LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */
LDMIA R12!,{R4-R11} /* Restore New Context */
LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */
CMP R0,#0 /* Basic/Extended Stack Frame */
ITTE NE
VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */
MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */
MVNEQ LR,#~0xFFFFFFFD
MSR PSP,R12 /* Write PSP */
SVC_Exit:
.ifdef IFX_XMC4XXX
PUSH {LR}
POP {PC}
.else
BX LR
.endif
/*------------------- User SVC ------------------------------*/
SVC_User:
PUSH {R4,LR} /* Save Registers */
LDR R2,=SVC_Count
LDR R2,[R2]
CMP R1,R2
BHI SVC_Done /* Overflow */
LDR R4,=SVC_Table-4
LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */
LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */
BLX R4 /* Call SVC Function */
MRS R12,PSP
STM R12,{R0-R3} /* Function return values */
SVC_Done:
POP {R4,PC} /* RETI */
.fnend
.size SVC_Handler, .-SVC_Handler
/*-------------------------- PendSV_Handler ---------------------------------*/
# void PendSV_Handler (void);
.thumb_func
.type PendSV_Handler, %function
.global PendSV_Handler
.global Sys_Switch
PendSV_Handler:
.ifdef IFX_XMC4XXX
.global PendSV_Handler_Veneer
PendSV_Handler_Veneer:
.endif
.fnstart
.cantunwind
PUSH {R4,LR} /* Save EXC_RETURN */
BL rt_pop_req
Sys_Switch:
POP {R4,LR} /* Restore EXC_RETURN */
LDR R3,=os_tsk
LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */
CMP R1,R2
.ifdef IFX_XMC4XXX
ITT EQ
PUSHEQ {LR}
POPEQ {PC}
.else
IT EQ
BXEQ LR /* RETI, no task switch */
.endif
MRS R12,PSP /* Read PSP */
TST LR,#0x10 /* is it extended frame? */
ITTE EQ
VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */
MOVEQ R0,#0x01 /* os_tsk->stack_frame val */
MOVNE R0,#0x00
STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */
STMDB R12!,{R4-R11} /* Save Old context */
STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */
PUSH {R2,R3}
BL rt_stk_check /* Check for Stack overflow */
POP {R2,R3}
STR R2,[R3] /* os_tsk.run = os_tsk.new */
LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */
LDMIA R12!,{R4-R11} /* Restore New Context */
LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */
CMP R0,#0 /* Basic/Extended Stack Frame */
ITTE NE
VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */
MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */
MVNEQ LR,#~0xFFFFFFFD
MSR PSP,R12 /* Write PSP */
Sys_Exit:
.ifdef IFX_XMC4XXX
PUSH {LR}
POP {PC}
.else
BX LR /* Return to Thread Mode */
.endif
.fnend
.size PendSV_Handler, .-PendSV_Handler
/*-------------------------- SysTick_Handler --------------------------------*/
# void SysTick_Handler (void);
.thumb_func
.type SysTick_Handler, %function
.global SysTick_Handler
SysTick_Handler:
.ifdef IFX_XMC4XXX
.global SysTick_Handler_Veneer
SysTick_Handler_Veneer:
.endif
.fnstart
.cantunwind
PUSH {R4,LR} /* Save EXC_RETURN */
BL rt_systick
B Sys_Switch
.fnend
.size SysTick_Handler, .-SysTick_Handler
/*-------------------------- OS_Tick_Handler --------------------------------*/
# void OS_Tick_Handler (void);
.thumb_func
.type OS_Tick_Handler, %function
.global OS_Tick_Handler
OS_Tick_Handler:
.fnstart
.cantunwind
PUSH {R4,LR} /* Save EXC_RETURN */
BL os_tick_irqack
BL rt_systick
B Sys_Switch
.fnend
.size OS_Tick_Handler, .-OS_Tick_Handler
.end
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,56 @@
;/*----------------------------------------------------------------------------
; * RL-ARM - RTX
; *----------------------------------------------------------------------------
; * Name: SVC_TABLE.S
; * Purpose: Pre-defined SVC Table for Cortex-M
; * Rev.: V4.70
; *----------------------------------------------------------------------------
; *
; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
; * All rights reserved.
; * Redistribution and use in source and binary forms, with or without
; * modification, are permitted provided that the following conditions are met:
; * - Redistributions of source code must retain the above copyright
; * notice, this list of conditions and the following disclaimer.
; * - 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.
; * - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
; *---------------------------------------------------------------------------*/
.file "SVC_Table.S"
.section ".svc_table"
.global SVC_Table
SVC_Table:
/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */
# .long __SVC_1 /* user SVC function */
SVC_End:
.global SVC_Count
SVC_Count:
.long (SVC_End-SVC_Table)/4
.end
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -210,6 +210,9 @@ osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL}
#elif TARGET_KL25Z
#define INITIAL_SP (0x20003000UL)
#elif TARGET_LPC4088
#define INITIAL_SP (0x10010000UL)
#endif
extern unsigned char Image$$RW_IRAM1$$ZI$$Limit[];

View File

@ -49,7 +49,7 @@
// counting "main", but not counting "osTimerThread"
// <i> Default: 6
#ifndef OS_TASKCNT
# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
# define OS_TASKCNT 14
# elif defined(TARGET_LPC11U24) || defined(TARGET_KL25Z)
# define OS_TASKCNT 6
@ -58,7 +58,7 @@
// <o>Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4>
#ifndef OS_SCHEDULERSTKSIZE
# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
# define OS_SCHEDULERSTKSIZE 256
# elif defined(TARGET_LPC11U24) || defined(TARGET_KL25Z)
# define OS_SCHEDULERSTKSIZE 128
@ -106,6 +106,9 @@
# elif defined(TARGET_LPC11U24) || defined(TARGET_KL25Z)
# define OS_CLOCK 48000000
#
# elif defined(TARGET_LPC4088)
# define OS_CLOCK 120000000
# endif
#endif

View File

@ -115,7 +115,7 @@ used throughout the whole project.
#define CMSIS_OS_RTX
// The stack space occupied is mainly dependent on the underling C standard library
#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_CS_ARM) || defined(TOOLCHAIN_CR_ARM)
#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_CS_ARM) || defined(TOOLCHAIN_CR_ARM) || defined(TOOLCHAIN_GCC_CR)
# define WORDS_STACK_SIZE 512
#elif defined(TOOLCHAIN_ARM)
# define WORDS_STACK_SIZE 512

View File

@ -4,6 +4,10 @@
AnalogIn in(PTC1);
AnalogOut out(PTE30);
#elif defined(TARGET_LPC4088)
AnalogIn in(p15); // p17 (p0.25) is connected to trimpot on OEM base board
AnalogOut out(p18);
#else
AnalogIn in(p17);
AnalogOut out(p18);

View File

@ -9,7 +9,10 @@ static unsigned int iterations = 0;
void report_iterations(void) {
unsigned int tot = (0x100 * iterations)*2;
printf("\nAllocated (%d)Kb in (%u) iterations\n", tot/1024, iterations);
#if !defined(TOOLCHAIN_GCC_CR)
// EA: This causes a crash when compiling with GCC_CR???
printf("%.2f\n", ((float)(tot)/(float)(initial_stack_p - initial_heap_p))*100.);
#endif
#ifdef TOOLCHAIN_ARM
__heapvalid((__heapprt) fprintf, stdout, 1);
#endif

View File

@ -9,7 +9,7 @@
#define P2_2 (1 << 25) // p1.25
#define PORT_2 Port1
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#define P1_1 (1 << 9) // p0.9 -> p5
#define P1_2 (1 << 8) // p0.8 -> p6
#define PORT_1 Port0

View File

@ -1,6 +1,6 @@
#include "mbed.h"
# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
# if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
# define LED1 (1 << 18) // P1.18
# define LED2 (1 << 20) // P1.20
# define LED3 (1 << 21) // P1.21

View File

@ -9,7 +9,7 @@
#define P2_2 (1 << 25) // p1.25
#define PORT_2 Port1
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#define P1_1 (1 << 9) // p0.9 -> p5
#define P1_2 (1 << 8) // p0.8 -> p6
#define PORT_1 Port0

View File

@ -15,7 +15,7 @@ CT32B0/MR2 p10 (P1_26)
*/
int main() {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
PwmOut pwm_p25(p25);
PwmOut pwm_p26(p26);

View File

@ -2,7 +2,11 @@
Serial pc(USBTX, USBRX);
#if defined(TARGET_LPC4088)
Serial uart(P4_22, P4_23);
#else
Serial uart(p9, p10);
#endif
DigitalOut led1(LED1);
DigitalOut led2(LED2);

View File

@ -1,6 +1,10 @@
#include "test_env.h"
#if defined(TARGET_LPC4088)
InterruptIn wkp(P2_10);
#else
InterruptIn wkp(p14);
#endif
void flip() {
printf("button pressed\n");

View File

@ -13,7 +13,7 @@ void flip_1() {
Ticker flipper_2;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
# define LED_NAME LED2
#else
# define LED_NAME PTE31

View File

@ -71,6 +71,16 @@ class LPC812(Target):
self.program_cycle_s = 4
class LPC4088(Target):
def __init__(self):
Target.__init__(self)
self.core = "Cortex-M4"
self.vendor = "NXP"
self.supported_toolchains = ["ARM", "GCC_CR"]
class MBED_MCU(Target):
def __init__(self):
Target.__init__(self)
@ -87,6 +97,7 @@ TARGETS = [
LPC11U24(),
KL25Z(),
LPC812(),
LPC4088(),
MBED_MCU()
]

View File

@ -128,6 +128,7 @@ class mbedToolchain:
"Cortex-M3" : ["__CORTEX_M3", "ARM_MATH_CM3"],
"Cortex-M0" : ["__CORTEX_M0", "ARM_MATH_CM0"],
"Cortex-M0+": ["__CORTEX_M0PLUS", "ARM_MATH_CM0"],
"Cortex-M4" : ["__CORTEX_M4", "ARM_MATH_CM4", "__FPU_PRESENT=1"],
}
def __init__(self, target, notify=None):
@ -430,6 +431,9 @@ class ARM(mbedToolchain):
else:
cpu = target.core
if target.core == "Cortex-M4":
cpu = "Cortex-M4.fp"
common = [join(ARM_BIN, "armcc"), "-c",
"--cpu=%s" % cpu, "--gnu",
"-Ospace", "--split_sections", "--apcs=interwork",
@ -556,6 +560,9 @@ class GCC(mbedToolchain):
if target.core.startswith("Cortex"):
self.cpu.append("-mthumb")
if target.core == "Cortex-M4":
self.cpu.append("-mfpu=vfp")
# Note: We are using "-O2" instead of "-Os" to avoid this known GCC bug:
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46762
common_flags = ["-c", "-O2", "-Wall",