mirror of https://github.com/ARMmbed/mbed-os.git
commit
6cdbf5512b
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -0,0 +1,31 @@
|
|||
/* mbed Microcontroller Library - stackheap
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Setup a fixed single stack/heap memory model,
|
||||
* between the top of the RW/ZI region and the stackpointer
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rt_misc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern char Image$$RW_IRAM1$$ZI$$Limit[];
|
||||
|
||||
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
|
||||
uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
|
||||
uint32_t sp_limit = __current_sp();
|
||||
|
||||
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
|
||||
|
||||
struct __initial_stackheap r;
|
||||
r.heap_base = zi_limit;
|
||||
r.heap_limit = sp_limit;
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,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);
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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];
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#define LPC17XX_EMAC_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "LPC17xx.h"
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
|
@ -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
|
||||
*---------------------------------------------------------------------------*/
|
|
@ -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
|
||||
*---------------------------------------------------------------------------*/
|
|
@ -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
|
||||
*---------------------------------------------------------------------------*/
|
|
@ -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[];
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
]
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue