Add LPC812 target. Update tests. Remove obsolete documentation. Move shared code among targets to target independent layer.

pull/1/head
Emilio Monti 2013-03-14 11:52:38 +00:00
parent 5f09c37d0f
commit 80518c489c
66 changed files with 5071 additions and 390 deletions

View File

@ -66,8 +66,8 @@ typedef struct BDT {
// * 16 bidirectionnal endpt -> 32 physical endpt
// * as there are ODD and EVEN buffer -> 32*2 bdt
__attribute__((__aligned__(512))) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2];
uint8_t endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2][64];
uint8_t endpoint_buffer_iso[2*2][1023];
uint8_t * endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2];
uint8_t * endpoint_buffer_iso[2*2];
static uint8_t set_addr = 0;
static uint8_t addr = 0;
@ -199,15 +199,21 @@ bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flag
if ((flags & ISOCHRONOUS) == 0) {
handshake_flag = USB_ENDPT_EPHSHK_MASK;
if (IN_EP(endpoint))
if (IN_EP(endpoint)) {
endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD )] = (uint8_t *) malloc (64*2);
buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD )][0];
else
} else {
endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD )] = (uint8_t *) malloc (64*2);
buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD )][0];
}
} else {
if (IN_EP(endpoint))
if (IN_EP(endpoint)) {
endpoint_buffer_iso[2] = (uint8_t *) malloc (1023*2);
buf = &endpoint_buffer_iso[2][0];
else
} else {
endpoint_buffer_iso[0] = (uint8_t *) malloc (1023*2);
buf = &endpoint_buffer_iso[0][0];
}
}
// IN endpt -> device to host (TX)

View File

@ -19,22 +19,37 @@
WEAK void mbed_die(void);
WEAK void mbed_die(void) {
#if defined(DEVICE_ERROR_RED)
gpio_t led_red; gpio_init(&led_red, LED_RED, PIN_OUTPUT);
#elif defined(DEVICE_ERROR_PATTERN)
gpio_t led_1; gpio_init(&led_1, LED1, PIN_OUTPUT);
gpio_t led_2; gpio_init(&led_2, LED2, PIN_OUTPUT);
gpio_t led_3; gpio_init(&led_3, LED3, PIN_OUTPUT);
gpio_t led_4; gpio_init(&led_4, LED4, PIN_OUTPUT);
#endif
while (1) {
#if defined(DEVICE_ERROR_RED)
gpio_write(&led_red, 1);
#elif defined(DEVICE_ERROR_PATTERN)
gpio_write(&led_1, 1);
gpio_write(&led_2, 0);
gpio_write(&led_3, 0);
gpio_write(&led_4, 1);
#endif
wait_ms(150);
#if defined(DEVICE_ERROR_RED)
gpio_write(&led_red, 0);
#elif defined(DEVICE_ERROR_PATTERN)
gpio_write(&led_1, 0);
gpio_write(&led_2, 1);
gpio_write(&led_3, 1);
gpio_write(&led_4, 0);
#endif
wait_ms(150);
}
}

View File

@ -22,8 +22,6 @@
extern "C" {
#endif
PinName parse_pins(const char *str);
typedef struct {
PinName pin;
int peripheral;

View File

@ -15,73 +15,19 @@
*/
#include <stddef.h>
#include "us_ticker_api.h"
#include "PeripheralNames.h"
/* PORTING STEP 4:
Implement
* "us_ticker_init", "us_ticker_read"
* "us_ticker_set_interrupt", "us_ticker_disable_interrupt", "us_ticker_clear_interrupt"
*/
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE)
#define US_TICKER_TIMER_IRQn TIMER3_IRQn
#elif defined(TARGET_LPC11U24)
#define US_TICKER_TIMER ((LPC_CTxxBx_Type *)LPC_CT32B1_BASE)
#define US_TICKER_TIMER_IRQn TIMER_32_1_IRQn
#endif
static int us_ticker_running = 0;
static inline void us_ticker_init(void) {
us_ticker_running = 1;
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
LPC_SC->PCONP |= 1 << 23; // Clock TIMER_3
US_TICKER_TIMER->CTCR = 0x0; // timer mode
uint32_t PCLK = SystemCoreClock / 4;
#elif defined(TARGET_LPC11U24)
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock TIMER_1
uint32_t PCLK = SystemCoreClock;
#endif
US_TICKER_TIMER->TCR = 0x2; // reset
uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks)
US_TICKER_TIMER->PR = prescale - 1;
US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0
}
uint32_t us_ticker_read() {
if (!us_ticker_running)
us_ticker_init();
return US_TICKER_TIMER->TC;
}
static inline void us_ticker_set_interrupt(unsigned int timestamp) {
// set match value
US_TICKER_TIMER->MR0 = timestamp;
// enable match interrupt
US_TICKER_TIMER->MCR |= 1;
}
static inline void us_ticker_disable_interrupt(void) {
US_TICKER_TIMER->MCR &= ~1;
}
static inline void us_ticker_clear_interrupt(void) {
US_TICKER_TIMER->IR = 1;
}
static ticker_event_handler event_handler;
static ticker_event_t *head = NULL;
void irq_handler(void) {
us_ticker_clear_interrupt();
void us_ticker_set_handler(ticker_event_handler handler) {
us_ticker_init();
event_handler = handler;
}
void us_ticker_irq_handler(void) {
us_ticker_clear_interrupt();
/* Go through all the pending TimerEvents */
while (1) {
if (head == NULL) {
@ -89,15 +35,15 @@ void irq_handler(void) {
us_ticker_disable_interrupt();
return;
}
if ((int)(head->timestamp - us_ticker_read()) <= 0) {
// This event was in the past:
// point to the following one and execute its handler
ticker_event_t *p = head;
head = head->next;
event_handler(p->id); // NOTE: the handler can set new events
if (event_handler != NULL) {
event_handler(p->id); // NOTE: the handler can set new events
}
} else {
// This event and the following ones in the list are in the future:
// set it as next interrupt and return
@ -107,21 +53,14 @@ void irq_handler(void) {
}
}
void us_ticker_set_handler(ticker_event_handler handler) {
event_handler = handler;
NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)irq_handler);
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
}
void us_ticker_insert_event(ticker_event_t *obj, unsigned int timestamp, uint32_t id) {
/* disable interrupts for the duration of the function */
__disable_irq();
// initialise our data
obj->timestamp = timestamp;
obj->id = id;
/* Go through the list until we either reach the end, or find
an element this should come before (which is possibly the
head). */
@ -144,20 +83,22 @@ void us_ticker_insert_event(ticker_event_t *obj, unsigned int timestamp, uint32_
}
/* if we're at the end p will be NULL, which is correct */
obj->next = p;
__enable_irq();
}
void us_ticker_remove_event(ticker_event_t *obj) {
__disable_irq();
// remove this object from the list
if (head == obj) { // first in the list, so just drop me
if (head == obj) {
// first in the list, so just drop me
head = obj->next;
if (obj->next != NULL) {
us_ticker_set_interrupt(head->timestamp);
}
} else { // find the object before me, then drop me
} else {
// find the object before me, then drop me
ticker_event_t* p = head;
while (p != NULL) {
if (p->next == obj) {
@ -167,6 +108,6 @@ void us_ticker_remove_event(ticker_event_t *obj) {
p = p->next;
}
}
__enable_irq();
}

View File

@ -33,6 +33,12 @@ typedef struct ticker_event_s {
struct ticker_event_s *next;
} ticker_event_t;
void us_ticker_init(void);
void us_ticker_set_interrupt(unsigned int timestamp);
void us_ticker_disable_interrupt(void);
void us_ticker_clear_interrupt(void);
void us_ticker_irq_handler(void);
void us_ticker_insert_event(ticker_event_t *obj, unsigned int timestamp, uint32_t id);
void us_ticker_remove_event(ticker_event_t *obj);

View File

@ -51,6 +51,8 @@
#define DEVICE_STDIO_MESSAGES 1
#define DEVICE_ERROR_RED 1
#include "objects.h"
#endif

View File

@ -1,45 +0,0 @@
/* 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.
*/
#include "port_api.h"
PinName parse_pins(const char *str) {
if (str[0] == 'P' && str[1] == 'T') { // PTx_n
uint32_t port = str[2] - 'A';
uint32_t pin = str[3] - '0'; // PTxn
uint32_t pin2 = str[4] - '0'; // PTxnn
if (pin2 <= 9) {
pin = pin * 10 + pin2;
}
return port_pin((PortName)port, pin);
} else if (str[0] == 'L') { // LEDn
switch (str[3]) {
case '1' : return LED1;
case '2' : return LED2;
case '3' : return LED3;
case '4' : return LED4;
}
} else if (str[0] == 'U') { // USB?X
switch (str[3]) {
case 'T' : return USBTX;
case 'R' : return USBRX;
}
}
return NC;
}

View File

@ -16,8 +16,6 @@
#include "gpio_api.h"
#include "pinmap.h"
/* PORTING STEP 3a: Implement "gpio_init" */
uint32_t gpio_set(PinName pin) {
pin_function(pin, 1);
return 1 << ((pin & 0x7F) >> 2);

View File

@ -16,12 +16,6 @@
#include "pinmap.h"
#include "error.h"
/* PORTING STEP 2:
Implement "pin_function" and "pin_mode" to set:
* the pin functionality (configuring the multiplexing block)
* the pin pullup settings
*/
void pin_function(PinName pin, int function) {
if (pin == (uint32_t)NC) return;

View File

@ -17,6 +17,19 @@
#include "us_ticker_api.h"
#include "PeripheralNames.h"
static void pit_init(void);
static void lptmr_init(void);
static int us_ticker_inited = 0;
void us_ticker_init(void) {
if (us_ticker_inited) return;
us_ticker_inited = 1;
pit_init();
lptmr_init();
}
/******************************************************************************
* Timer for us timing.
*
@ -28,10 +41,7 @@
* the final result by 24.
* NOTE: The PIT is a countdown timer.
******************************************************************************/
static int us_ticker_running = 0;
static void us_ticker_init(void) {
us_ticker_running = 1;
static void pit_init(void) {
SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT
PIT->MCR = 0; // Enable PIT
@ -46,9 +56,9 @@ static void us_ticker_init(void) {
}
uint32_t us_ticker_read() {
if (!us_ticker_running)
if (!us_ticker_inited)
us_ticker_init();
/* To use LTMR64H and LTMR64L, timer 0 and timer 1 need to be chained.
* To obtain the correct value, first read LTMR64H and then LTMR64L.
* LTMR64H will have the value of CVAL1 at the time of the first access,
@ -72,21 +82,8 @@ uint32_t us_ticker_read() {
* power modes.
******************************************************************************/
static void lptmr_isr(void);
static void lptmr_irq_handler(void);
static void us_ticker_set_interrupt(unsigned int timestamp);
static ticker_event_handler event_handler = NULL;
void us_ticker_set_handler(ticker_event_handler handler) {
event_handler = handler;
}
static uint32_t us_ticker_int_counter = 0;
static uint16_t us_ticker_int_remainder = 0;
static int lptmr_inited = 0;
void lptmr_init(void) {
lptmr_inited = 1;
static void lptmr_init(void) {
/* Clock the timer */
SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK;
@ -102,6 +99,17 @@ void lptmr_init(void) {
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(2); // divide by 8
}
void us_ticker_disable_interrupt(void) {
LPTMR0->CSR &= ~LPTMR_CSR_TIE_MASK;
}
void us_ticker_clear_interrupt(void) {
// we already clear interrupt in lptmr_isr
}
static uint32_t us_ticker_int_counter = 0;
static uint16_t us_ticker_int_remainder = 0;
static void lptmr_set(unsigned short count) {
/* Reset */
LPTMR0->CSR = 0;
@ -132,47 +140,16 @@ static void lptmr_isr(void) {
} else {
// This function is going to disable the interrupts if there are
// no other events in the queue
lptmr_irq_handler();
us_ticker_irq_handler();
}
}
}
static ticker_event_t *head = NULL;
static void lptmr_irq_handler(void) {
/* Go through all the pending TimerEvents */
while (1) {
if (head == NULL) {
// There are no more TimerEvents left, so disable matches.
LPTMR0->CSR &= ~LPTMR_CSR_TIE_MASK;
return;
}
if ((int)(head->timestamp - us_ticker_read()) <= 0) {
// This event was in the past:
// point to the following one and execute its handler
ticker_event_t *p = head;
head = head->next;
if (event_handler != NULL) {
event_handler(p->id); // NOTE: the handler can set new events
}
} else {
// This event and the following ones in the list are in the future:
// set it as next interrupt and return
us_ticker_set_interrupt(head->timestamp);
return;
}
}
}
static void us_ticker_set_interrupt(unsigned int timestamp) {
if (!lptmr_inited)
lptmr_init();
void us_ticker_set_interrupt(unsigned int timestamp) {
int delta = (int)(timestamp - us_ticker_read());
if (delta <= 0) {
// This event was in the past:
lptmr_irq_handler();
us_ticker_irq_handler();
return;
}
@ -186,62 +163,3 @@ static void us_ticker_set_interrupt(unsigned int timestamp) {
us_ticker_int_remainder = 0;
}
}
void us_ticker_insert_event(ticker_event_t *obj, unsigned int timestamp, uint32_t id) {
/* disable interrupts for the duration of the function */
__disable_irq();
// initialise our data
obj->timestamp = timestamp;
obj->id = id;
/* Go through the list until we either reach the end, or find
an element this should come before (which is possibly the
head). */
ticker_event_t *prev = NULL, *p = head;
while (p != NULL) {
/* check if we come before p */
if ((int)(timestamp - p->timestamp) <= 0) {
break;
}
/* go to the next element */
prev = p;
p = p->next;
}
/* if prev is NULL we're at the head */
if (prev == NULL) {
head = obj;
us_ticker_set_interrupt(timestamp);
} else {
prev->next = obj;
}
/* if we're at the end p will be NULL, which is correct */
obj->next = p;
__enable_irq();
}
void us_ticker_remove_event(ticker_event_t *obj) {
__disable_irq();
// remove this object from the list
if (head == obj) {
// first in the list, so just drop me
head = obj->next;
if (obj->next != NULL) {
us_ticker_set_interrupt(head->timestamp);
}
} else {
// find the object before me, then drop me
ticker_event_t* p = head;
while (p != NULL) {
if (p->next == obj) {
p->next = obj->next;
break;
}
p = p->next;
}
}
__enable_irq();
}

View File

@ -52,6 +52,8 @@
#define DEVICE_STDIO_MESSAGES 1
#define DEVICE_ERROR_PATTERN 1
#include "objects.h"
#endif

View File

@ -52,6 +52,8 @@
#define DEVICE_STDIO_MESSAGES 1
#define DEVICE_ERROR_PATTERN 1
#include "objects.h"
#endif

View File

@ -52,6 +52,8 @@
#define DEVICE_STDIO_MESSAGES 1
#define DEVICE_ERROR_PATTERN 1
#include "objects.h"
#endif

View File

@ -13,20 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gpio_api.h"
#include "wait_api.h"
#include "toolchain.h"
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
WEAK void mbed_die(void);
WEAK void mbed_die(void) {
gpio_t led_red;
gpio_init(&led_red, LED_RED, PIN_OUTPUT);
while (1) {
gpio_write(&led_red, 1);
wait_ms(150);
gpio_write(&led_red, 0);
wait_ms(150);
}
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,81 @@
/* 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;
typedef enum {
P0_0 = 0,
P0_1 = 1,
P0_2 = 2,
P0_3 = 3,
P0_4 = 4,
P0_5 = 5,
P0_6 = 6,
P0_7 = 7,
P0_8 = 8,
P0_9 = 9,
P0_10 = 10,
P0_11 = 11,
P0_12 = 12,
P0_13 = 13,
P0_14 = 14,
P0_15 = 15,
P0_16 = 16,
P0_17 = 17,
// LPC800-MAX board
LED_RED = P0_7,
LED_GREEN = P0_17,
LED_BLUE = P0_16,
// mbed original LED naming
LED1 = LED_BLUE,
LED2 = LED_GREEN,
LED3 = LED_RED,
LED4 = LED_RED,
// Serial to USB pins
USBTX = P0_6,
USBRX = P0_1,
// Not connected
NC = (int)0xFFFFFFFF,
} PinName;
typedef enum {
PullUp = 2,
PullDown = 1,
PullNone = 0,
Repeater = 3,
OpenDrain = 4
} PinMode;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,30 @@
/* 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,
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,57 @@
/* 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 0
#define DEVICE_PORTOUT 0
#define DEVICE_PORTINOUT 0
#define DEVICE_INTERRUPTIN 0
#define DEVICE_ANALOGIN 0
#define DEVICE_ANALOGOUT 0
#define DEVICE_SERIAL 0
#define DEVICE_I2C 0
#define DEVICE_I2CSLAVE 0
#define DEVICE_SPI 0
#define DEVICE_SPISLAVE 0
#define DEVICE_CAN 0
#define DEVICE_RTC 0
#define DEVICE_ETHERNET 0
#define DEVICE_PWMOUT 0
#define DEVICE_SEMIHOST 0
#define DEVICE_LOCALFILESYSTEM 0
#define DEVICE_SLEEP 0
#define DEVICE_DEBUG_AWARENESS 0
#define DEVICE_STDIO_MESSAGES 0
#define DEVICE_ERROR_RED 1
#include "objects.h"
#endif

View File

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

View File

@ -0,0 +1,34 @@
/* 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
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,58 +0,0 @@
/* 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.
*/
#include "port_api.h"
PinName parse_pins(const char *str) {
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};
if (str[0] == 'P') { // Pn_n
uint32_t port = str[1] - '0';
uint32_t pin = str[3] - '0'; // Pn_n
uint32_t pin2 = str[4] - '0'; // Pn_nn
if (pin2 <= 9) {
pin = pin * 10 + pin2;
}
return port_pin((PortName)port, pin);
} else if (str[0] == 'p') { // pn
uint32_t pin = str[1] - '0'; // pn
uint32_t pin2 = str[2] - '0'; // pnn
if (pin2 <= 9) {
pin = pin * 10 + pin2;
}
if (pin < 5 || pin > 30) {
return NC;
}
return pin_names[pin - 5];
} else if (str[0] == 'L') { // LEDn
switch (str[3]) {
case '1' : return LED1;
case '2' : return LED2;
case '3' : return LED3;
case '4' : return LED4;
}
} else if (str[0] == 'U') { // USB?X
switch (str[3]) {
case 'T' : return USBTX;
case 'R' : return USBRX;
}
}
return NC;
}

View File

@ -16,22 +16,37 @@
#include "gpio_api.h"
#include "pinmap.h"
/* PORTING STEP 3a: Implement "gpio_init" */
static int gpio_enabled = 0;
static void gpio_enable(void) {
gpio_enabled = 1;
#if defined(TARGET_LPC2368)
LPC_SC->SCS |= 1; // High speed GPIO is enabled on ports 0 and 1
#elif defined(TARGET_LPC812)
/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
/* Peripheral reset control to GPIO and GPIO INT, a "1" bring it out of reset. */
LPC_SYSCON->PRESETCTRL &= ~(0x1<<10);
LPC_SYSCON->PRESETCTRL |= (0x1<<10);
#endif
}
uint32_t gpio_set(PinName pin) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#ifdef TARGET_LPC2368
LPC_SC->SCS |= 1; // High speed GPIO is enabled on ports 0 and 1
int f = 0;
if (!gpio_enabled)
gpio_enable();
#if defined(TARGET_LPC11U24)
f = ((pin == P0_11) ||
(pin == P0_12) ||
(pin == P0_13) ||
(pin == P0_14)) ? (1) : (0);
#endif
pin_function(pin, 0);
#elif defined(TARGET_LPC11U24)
int f = ((pin == P0_11) ||
(pin == P0_12) ||
(pin == P0_13) ||
(pin == P0_14)) ? (1) : (0);
pin_function(pin, f);
#endif
return (1 << ((int)pin & 0x1F));
}
@ -56,6 +71,12 @@ void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
obj->reg_clr = &LPC_GPIO->CLR[port];
obj->reg_in = &LPC_GPIO->PIN[port];
obj->reg_dir = &LPC_GPIO->DIR[port];
#elif defined(TARGET_LPC812)
obj->reg_set = &LPC_GPIO_PORT->SET0;
obj->reg_clr = &LPC_GPIO_PORT->CLR0;
obj->reg_in = &LPC_GPIO_PORT->PIN0;
obj->reg_dir = &LPC_GPIO_PORT->DIR0;
#endif
gpio_dir(obj, direction);

View File

@ -16,15 +16,19 @@
#include "pinmap.h"
#include "error.h"
/* PORTING STEP 2:
Implement "pin_function" and "pin_mode" to set:
* the pin functionality (configuring the multiplexing block)
* the pin pullup settings
*/
#if defined(TARGET_LPC11U24)
#define LPC_IOCON0_BASE (LPC_IOCON_BASE)
#define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60)
#elif defined(TARGET_LPC812)
__IO uint32_t* IOCON_REGISTERS[18] = {
&LPC_IOCON->PIO0_0 , &LPC_IOCON->PIO0_1 , &LPC_IOCON->PIO0_2 ,
&LPC_IOCON->PIO0_3 , &LPC_IOCON->PIO0_4 , &LPC_IOCON->PIO0_5 ,
&LPC_IOCON->PIO0_6 , &LPC_IOCON->PIO0_7 , &LPC_IOCON->PIO0_8 ,
&LPC_IOCON->PIO0_9 , &LPC_IOCON->PIO0_10, &LPC_IOCON->PIO0_11,
&LPC_IOCON->PIO0_12, &LPC_IOCON->PIO0_13, &LPC_IOCON->PIO0_14,
&LPC_IOCON->PIO0_15, &LPC_IOCON->PIO0_16, &LPC_IOCON->PIO0_17,
};
#endif
void pin_function(PinName pin, int function) {
@ -79,7 +83,6 @@ void pin_mode(PinName pin, PinMode mode) {
uint32_t pin_number = (uint32_t)pin;
uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2;
// Open drain mode is not available on LPC2368
__IO uint32_t *reg = (pin_number < 32) ?
(__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) :
(__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32));
@ -94,5 +97,22 @@ void pin_mode(PinName pin, PinMode mode) {
tmp |= drain << 10;
*reg = tmp;
#elif defined(TARGET_LPC812)
if ((pin == 10) || (pin == 11)) {
// True open-drain pins can be configured for different I2C-bus speeds
return;
}
__IO uint32_t *reg = IOCON_REGISTERS[pin];
if (mode == OpenDrain) {
*reg |= (1 << 10);
} else {
uint32_t tmp = *reg;
tmp &= ~(0x3 << 3);
tmp |= (mode & 0x3) << 3;
*reg = tmp;
}
#endif
}

View File

@ -0,0 +1,119 @@
/* 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.
*/
#include <stddef.h>
#include "us_ticker_api.h"
#include "PeripheralNames.h"
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE)
#define US_TICKER_TIMER_IRQn TIMER3_IRQn
#elif defined(TARGET_LPC11U24)
#define US_TICKER_TIMER ((LPC_CTxxBx_Type *)LPC_CT32B1_BASE)
#define US_TICKER_TIMER_IRQn TIMER_32_1_IRQn
#elif defined(TARGET_LPC812)
#define US_TICKER_TIMER_IRQn SCT_IRQn
#endif
int us_ticker_inited = 0;
void us_ticker_init(void) {
if (us_ticker_inited) return;
us_ticker_inited = 1;
#ifdef TARGET_LPC812
// Enable the SCT clock
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
// Clear peripheral reset the SCT:
LPC_SYSCON->PRESETCTRL |= ( 1<< 8);
// Unified counter
LPC_SCT->CONFIG = 1;
// System Clock (12)MHz -> us_ticker (1)MHz
LPC_SCT->CTRL_L |= ((12) << 5);
// unhalt it: - clearing bit 2 of the CTRL register
LPC_SCT->CTRL_L &= ~(1 << 2);
#else
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
LPC_SC->PCONP |= 1 << 23; // Clock TIMER_3
US_TICKER_TIMER->CTCR = 0x0; // timer mode
uint32_t PCLK = SystemCoreClock / 4;
#elif defined(TARGET_LPC11U24)
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock TIMER_1
uint32_t PCLK = SystemCoreClock;
#endif
US_TICKER_TIMER->TCR = 0x2; // reset
uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks)
US_TICKER_TIMER->PR = prescale - 1;
US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0
NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
#endif
}
uint32_t us_ticker_read() {
if (!us_ticker_inited)
us_ticker_init();
#ifdef TARGET_LPC812
return LPC_SCT->COUNT_U;
#else
return US_TICKER_TIMER->TC;
#endif
}
void us_ticker_set_interrupt(unsigned int timestamp) {
#ifdef TARGET_LPC812
LPC_SCT->MATCH[0].U = timestamp;
// [TODO] define the event: LPC_SCT->EVENT[0].CTRL
LPC_SCT->EVEN |= 1;
#else
// set match value
US_TICKER_TIMER->MR0 = timestamp;
// enable match interrupt
US_TICKER_TIMER->MCR |= 1;
#endif
}
void us_ticker_disable_interrupt(void) {
#ifdef TARGET_LPC812
LPC_SCT->EVEN &= ~1;
#else
US_TICKER_TIMER->MCR &= ~1;
#endif
}
void us_ticker_clear_interrupt(void) {
#ifdef TARGET_LPC812
LPC_SCT->EVFLAG = 1;
#else
US_TICKER_TIMER->IR = 1;
#endif
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,279 @@
/**************************************************************************//**
* @file core_cm0.c
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Source File
* @version V2.00
* @date 10. September 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/* ########################## Core Instruction Access ######################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \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
*/
#if (__ARMCC_VERSION < 400677)
__ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \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
*/
#if (__ARMCC_VERSION < 400677)
__ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __CLREX(void)
{
clrex
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif
/* ########################### Core Function Access ########################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_CONTROL(void)
{
mrs r0, control
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_CONTROL(uint32_t control)
{
msr control, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_IPSR(void)
{
mrs r0, ipsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_APSR(void)
{
mrs r0, apsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_xPSR(void)
{
mrs r0, xpsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PSP(void)
{
mrs r0, psp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \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
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PSP(uint32_t topOfProcStack)
{
msr psp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_MSP(void)
{
mrs r0, msp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \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
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PRIMASK(uint32_t priMask)
{
msr primask, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif

View File

@ -0,0 +1,778 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V3.02
* @date 05. November 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.
*
******************************************************************************/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_H_GENERIC
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex-M0+
@{
*/
/* CMSIS CM0P definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
__CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#endif
/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0
#warning "__VTOR_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*@} end of group Cortex-M0+ */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
#else
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
#endif
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
#else
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
#endif
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/** \brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/*@} end of group CMSIS_CORE */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1)
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
#if (__VTOR_PRESENT == 1)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1)
/** \ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/** \brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register */
#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register */
#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register */
#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register */
#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0+ Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \brief Enable External Interrupt
The function enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Disable External Interrupt
The function disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Get Pending Interrupt
The function reads the pending register in the NVIC and returns the pending bit
for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/** \brief Set Pending Interrupt
The function sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Clear Pending Interrupt
The function clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \brief Set Interrupt Priority
The function sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \brief Get Interrupt Priority
The function reads the priority of an interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority. Value is aligned automatically to the implemented
priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \brief System Reset
The function initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0)
/** \brief System Tick Configuration
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
#ifdef __cplusplus
}
#endif

View File

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

View File

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

View File

@ -0,0 +1,367 @@
/******************************************************************************
* @file: system_LPC8xx.c
* @purpose: CMSIS Cortex-M0+ Device Peripheral Access Layer Source File
* for the NXP LPC8xx Device Series
* @version: V1.0
* @date: 16. Aug. 2012
*----------------------------------------------------------------------------
*
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M0+
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
#include "LPC8xx.h"
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
/*--------------------- Clock Configuration ----------------------------------
//
// <e> Clock Configuration
// <h> System Oscillator Control Register (SYSOSCCTRL)
// <o1.0> BYPASS: System Oscillator Bypass Enable
// <i> If enabled then PLL input (sys_osc_clk) is fed
// <i> directly from XTALIN and XTALOUT pins.
// <o1.9> FREQRANGE: System Oscillator Frequency Range
// <i> Determines frequency range for Low-power oscillator.
// <0=> 1 - 20 MHz
// <1=> 15 - 25 MHz
// </h>
//
// <h> Watchdog Oscillator Control Register (WDTOSCCTRL)
// <o2.0..4> DIVSEL: Select Divider for Fclkana
// <i> wdt_osc_clk = Fclkana/ (2 × (1 + DIVSEL))
// <0-31>
// <o2.5..8> FREQSEL: Select Watchdog Oscillator Analog Output Frequency (Fclkana)
// <0=> Undefined
// <1=> 0.5 MHz
// <2=> 0.8 MHz
// <3=> 1.1 MHz
// <4=> 1.4 MHz
// <5=> 1.6 MHz
// <6=> 1.8 MHz
// <7=> 2.0 MHz
// <8=> 2.2 MHz
// <9=> 2.4 MHz
// <10=> 2.6 MHz
// <11=> 2.7 MHz
// <12=> 2.9 MHz
// <13=> 3.1 MHz
// <14=> 3.2 MHz
// <15=> 3.4 MHz
// </h>
//
// <h> System PLL Control Register (SYSPLLCTRL)
// <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
// <i> F_clkin must be in the range of 10 MHz to 25 MHz
// <i> F_CCO must be in the range of 156 MHz to 320 MHz
// <o3.0..4> MSEL: Feedback Divider Selection
// <i> M = MSEL + 1
// <0-31>
// <o3.5..6> PSEL: Post Divider Selection
// <0=> P = 1
// <1=> P = 2
// <2=> P = 4
// <3=> P = 8
// </h>
//
// <h> System PLL Clock Source Select Register (SYSPLLCLKSEL)
// <o4.0..1> SEL: System PLL Clock Source
// <0=> IRC Oscillator
// <1=> System Oscillator
// <2=> Reserved
// <3=> CLKIN pin
// </h>
//
// <h> Main Clock Source Select Register (MAINCLKSEL)
// <o5.0..1> SEL: Clock Source for Main Clock
// <0=> IRC Oscillator
// <1=> Input Clock to System PLL
// <2=> WDT Oscillator
// <3=> System PLL Clock Out
// </h>
//
// <h> System AHB Clock Divider Register (SYSAHBCLKDIV)
// <o6.0..7> DIV: System AHB Clock Divider
// <i> Divides main clock to provide system clock to core, memories, and peripherals.
// <i> 0 = is disabled
// <0-255>
// </h>
// </e>
*/
#define CLOCK_SETUP 1
#define SYSOSCCTRL_Val 0x00000000 // Reset: 0x000
#define WDTOSCCTRL_Val 0x00000000 // Reset: 0x000
#define SYSPLLCTRL_Val 0x00000041 // Reset: 0x000
#define SYSPLLCLKSEL_Val 0x00000000 // Reset: 0x000
#define MAINCLKSEL_Val 0x00000000 // Reset: 0x000
#define SYSAHBCLKDIV_Val 0x00000001 // Reset: 0x001
/*
//-------- <<< end of configuration section >>> ------------------------------
*/
/*----------------------------------------------------------------------------
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((SYSOSCCTRL_Val), ~0x00000003))
#error "SYSOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF))
#error "WDTOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 3))
#error "SYSPLLCLKSEL: Value out of range!"
#endif
#if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF))
#error "SYSPLLCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003))
#error "MAINCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
#error "SYSAHBCLKDIV: Value out of range!"
#endif
/*----------------------------------------------------------------------------
DEFINES
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define __XTAL (12000000UL) /* Oscillator frequency */
#define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */
#define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */
#define __CLKIN_CLK (12000000UL) /* CLKIN pin frequency */
#define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F)
#define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
#if (CLOCK_SETUP) /* Clock Setup */
#if (__FREQSEL == 0)
#define __WDT_OSC_CLK ( 0) /* undefined */
#elif (__FREQSEL == 1)
#define __WDT_OSC_CLK ( 500000 / __DIVSEL)
#elif (__FREQSEL == 2)
#define __WDT_OSC_CLK ( 800000 / __DIVSEL)
#elif (__FREQSEL == 3)
#define __WDT_OSC_CLK (1100000 / __DIVSEL)
#elif (__FREQSEL == 4)
#define __WDT_OSC_CLK (1400000 / __DIVSEL)
#elif (__FREQSEL == 5)
#define __WDT_OSC_CLK (1600000 / __DIVSEL)
#elif (__FREQSEL == 6)
#define __WDT_OSC_CLK (1800000 / __DIVSEL)
#elif (__FREQSEL == 7)
#define __WDT_OSC_CLK (2000000 / __DIVSEL)
#elif (__FREQSEL == 8)
#define __WDT_OSC_CLK (2200000 / __DIVSEL)
#elif (__FREQSEL == 9)
#define __WDT_OSC_CLK (2400000 / __DIVSEL)
#elif (__FREQSEL == 10)
#define __WDT_OSC_CLK (2600000 / __DIVSEL)
#elif (__FREQSEL == 11)
#define __WDT_OSC_CLK (2700000 / __DIVSEL)
#elif (__FREQSEL == 12)
#define __WDT_OSC_CLK (2900000 / __DIVSEL)
#elif (__FREQSEL == 13)
#define __WDT_OSC_CLK (3100000 / __DIVSEL)
#elif (__FREQSEL == 14)
#define __WDT_OSC_CLK (3200000 / __DIVSEL)
#else
#define __WDT_OSC_CLK (3400000 / __DIVSEL)
#endif
/* sys_pllclkin calculation */
#if ((SYSPLLCLKSEL_Val & 0x03) == 0)
#define __SYS_PLLCLKIN (__IRC_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
#define __SYS_PLLCLKIN (__SYS_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 3)
#define __SYS_PLLCLKIN (__CLKIN_CLK)
#else
#define __SYS_PLLCLKIN (0)
#endif
#define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
/* main clock calculation */
#if ((MAINCLKSEL_Val & 0x03) == 0)
#define __MAIN_CLOCK (__IRC_OSC_CLK)
#elif ((MAINCLKSEL_Val & 0x03) == 1)
#define __MAIN_CLOCK (__SYS_PLLCLKIN)
#elif ((MAINCLKSEL_Val & 0x03) == 2)
#if (__FREQSEL == 0)
#error "MAINCLKSEL: WDT Oscillator selected but FREQSEL is undefined!"
#else
#define __MAIN_CLOCK (__WDT_OSC_CLK)
#endif
#elif ((MAINCLKSEL_Val & 0x03) == 3)
#define __MAIN_CLOCK (__SYS_PLLCLKOUT)
#else
#define __MAIN_CLOCK (0)
#endif
#define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val)
#else
#define __SYSTEM_CLOCK (__IRC_OSC_CLK)
#endif // CLOCK_SETUP
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
uint32_t wdt_osc = 0;
/* Determine clock frequency according to clock register values */
switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
case 0: wdt_osc = 0; break;
case 1: wdt_osc = 500000; break;
case 2: wdt_osc = 800000; break;
case 3: wdt_osc = 1100000; break;
case 4: wdt_osc = 1400000; break;
case 5: wdt_osc = 1600000; break;
case 6: wdt_osc = 1800000; break;
case 7: wdt_osc = 2000000; break;
case 8: wdt_osc = 2200000; break;
case 9: wdt_osc = 2400000; break;
case 10: wdt_osc = 2600000; break;
case 11: wdt_osc = 2700000; break;
case 12: wdt_osc = 2900000; break;
case 13: wdt_osc = 3100000; break;
case 14: wdt_osc = 3200000; break;
case 15: wdt_osc = 3400000; break;
}
wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* Input Clock to System PLL */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* System oscillator */
SystemCoreClock = __SYS_OSC_CLK;
break;
case 2: /* Reserved */
SystemCoreClock = 0;
break;
case 3: /* CLKIN pin */
SystemCoreClock = __CLKIN_CLK;
break;
}
break;
case 2: /* WDT Oscillator */
SystemCoreClock = wdt_osc;
break;
case 3: /* System PLL Clock Out */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
break;
case 1: /* System oscillator */
SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
break;
case 2: /* Reserved */
SystemCoreClock = 0;
break;
case 3: /* CLKIN pin */
SystemCoreClock = __CLKIN_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
break;
}
break;
}
SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;
}
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void) {
volatile uint32_t i;
/* System clock to the IOCON & the SWM need to be enabled or
most of the I/O related peripherals won't work. */
LPC_SYSCON->SYSAHBCLKCTRL |= ( (0x1 << 7) | (0x1 << 18) );
#if (CLOCK_SETUP) /* Clock Setup */
#if ((SYSPLLCLKSEL_Val & 0x03) == 1)
LPC_IOCON->PIO0_8 &= ~(0x3 << 3);
LPC_IOCON->PIO0_9 &= ~(0x3 << 3);
LPC_SWM->PINENABLE0 &= ~(0x3 << 4);
LPC_SYSCON->PDRUNCFG &= ~(0x1 << 5); /* Power-up System Osc */
LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
for (i = 0; i < 200; i++) __NOP();
#endif
#if ((SYSPLLCLKSEL_Val & 0x03) == 3)
LPC_IOCON->PIO0_1 &= ~(0x3 << 3);
LPC_SWM->PINENABLE0 &= ~(0x1 << 7);
for (i = 0; i < 200; i++) __NOP();
#endif
LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
#if ((MAINCLKSEL_Val & 0x03) == 3) /* Main Clock is PLL Out */
LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(0x1 << 7); /* Power-up SYSPLL */
while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
#endif
#if (((MAINCLKSEL_Val & 0x03) == 2) )
LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(0x1 << 6); /* Power-up WDT Clock */
for (i = 0; i < 200; i++) __NOP();
#endif
LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */
LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
#endif
}

View File

@ -0,0 +1,62 @@
/******************************************************************************
* @file: system_LPC8xx.h
* @purpose: CMSIS Cortex-M0+ Device Peripheral Access Layer Header File
* for the NXP LPC8xx Device Series
* @version: V1.0
* @date: 16. Aug. 2012
*----------------------------------------------------------------------------
*
* Copyright (C) 2012 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M0+
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC8xx_H
#define __SYSTEM_LPC8xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC8xx_H */

View File

@ -0,0 +1,14 @@
LR_IROM1 0x00000000 0x4000 { ; load region size_region (32k)
ER_IROM1 0x00000000 0x4000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
; 8KB - 0xC0 = 0xF40
RW_IRAM1 0x100000C0 0xF40 {
.ANY (+RW +ZI)
}
}

View File

@ -0,0 +1,211 @@
;/*****************************************************************************
; * @file: startup_LPC8xx.s
; * @purpose: CMSIS Cortex-M0+ Core Device Startup File
; * for the NXP LPC8xx Device Series
; * @version: V1.0
; * @date: 16. Aug. 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-M0+
; * processor based microcontrollers. This file can be freely distributed
; * within development tools that are supporting such ARM based processors.
; *
; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
; *
; *****************************************************************************/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x00000200
AREA STACK, NOINIT, READWRITE, ALIGN=3
EXPORT __initial_sp
Stack_Mem SPACE Stack_Size
__initial_sp EQU 0x10001000
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
EXPORT __heap_base
EXPORT __heap_limit
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
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 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD SPI0_IRQHandler ; SPI0 controller
DCD SPI1_IRQHandler ; SPI1 controller
DCD 0 ; Reserved
DCD UART0_IRQHandler ; UART0
DCD UART1_IRQHandler ; UART1
DCD UART2_IRQHandler ; UART2
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD I2C_IRQHandler ; I2C controller
DCD SCT_IRQHandler ; Smart Counter Timer
DCD MRT_IRQHandler ; Multi-Rate Timer
DCD CMP_IRQHandler ; Comparator
DCD WDT_IRQHandler ; PIO1 (0:11)
DCD BOD_IRQHandler ; Brown Out Detect
DCD 0 ; Reserved
DCD WKT_IRQHandler ; Wakeup timer
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PININT0_IRQHandler ; PIO INT0
DCD PININT1_IRQHandler ; PIO INT1
DCD PININT2_IRQHandler ; PIO INT2
DCD PININT3_IRQHandler ; PIO INT3
DCD PININT4_IRQHandler ; PIO INT4
DCD PININT5_IRQHandler ; PIO INT5
DCD PININT6_IRQHandler ; PIO INT6
DCD PININT7_IRQHandler ; PIO INT7
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)
; now, under COMMON lpc8xx_nmi.c and lpc8xx_nmi.h, a real NMI handler is created if NMI is enabled
; for particular peripheral.
;NMI_Handler PROC
; EXPORT NMI_Handler [WEAK]
; B .
; ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_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 NMI_Handler [WEAK]
EXPORT SPI0_IRQHandler [WEAK]
EXPORT SPI1_IRQHandler [WEAK]
EXPORT UART0_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT UART2_IRQHandler [WEAK]
EXPORT I2C_IRQHandler [WEAK]
EXPORT SCT_IRQHandler [WEAK]
EXPORT MRT_IRQHandler [WEAK]
EXPORT CMP_IRQHandler [WEAK]
EXPORT WDT_IRQHandler [WEAK]
EXPORT BOD_IRQHandler [WEAK]
EXPORT WKT_IRQHandler [WEAK]
EXPORT PININT0_IRQHandler [WEAK]
EXPORT PININT1_IRQHandler [WEAK]
EXPORT PININT2_IRQHandler [WEAK]
EXPORT PININT3_IRQHandler [WEAK]
EXPORT PININT4_IRQHandler [WEAK]
EXPORT PININT5_IRQHandler [WEAK]
EXPORT PININT6_IRQHandler [WEAK]
EXPORT PININT7_IRQHandler [WEAK]
NMI_Handler
SPI0_IRQHandler
SPI1_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
I2C_IRQHandler
SCT_IRQHandler
MRT_IRQHandler
CMP_IRQHandler
WDT_IRQHandler
BOD_IRQHandler
WKT_IRQHandler
PININT0_IRQHandler
PININT1_IRQHandler
PININT2_IRQHandler
PININT3_IRQHandler
PININT4_IRQHandler
PININT5_IRQHandler
PININT6_IRQHandler
PININT7_IRQHandler
B .
ENDP
ALIGN
END

View File

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

View File

@ -13,9 +13,11 @@
"system_LPC23xx.o",
"system_LPC11Uxx.o",
"system_LPC17xx.o",
"system_LPC8xx.o",
"startup_LPC11xx.o",
"startup_LPC17xx.o",
"startup_LPC8xx.o",
"vector_functions.o",
"vector_realmonitor.o",

View File

@ -59,8 +59,8 @@ int UDPSocket::join_multicast_group(const char* address) {
return set_option(IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
}
int UDPSocket::set_broadcasting(void) {
int option = 1;
int UDPSocket::set_broadcasting(bool broadcast) {
int option = (broadcast) ? (1) : (0);
return set_option(SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
}

View File

@ -54,7 +54,7 @@ public:
/** Set the socket in broadcasting mode
\return 0 on success, -1 on failure.
*/
int set_broadcasting(void);
int set_broadcasting(bool broadcast=true);
/** Send a packet to a remote endpoint
\param remote The remote endpoint

View File

@ -0,0 +1,48 @@
#include "mbed.h"
volatile unsigned int ticks = 0;
DigitalOut led(LED_BLUE);
extern "C" void lptmr_isr(void) {
// write 1 to TCF to clear the LPT timer compare flag
LPTMR0->CSR |= LPTMR_CSR_TCF_MASK;
ticks++;
}
int main() {
/* Clock the timer */
SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK;
/* Reset */
LPTMR0->CSR = 0;
/* Compare value */
LPTMR0->CMR = 1000;
/* Enable interrupt */
LPTMR0->CSR |= LPTMR_CSR_TIE_MASK;
/* Set interrupt handler */
NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr);
NVIC_EnableIRQ(LPTimer_IRQn);
/* select LPO for RTC and LPTMR */
LPTMR0->PSR = LPTMR_PSR_PCS(3); // ERCLK32K -> 8MHz
LPTMR0->PSR |= LPTMR_PSR_PRESCALE(2); // divide by 8
/* Start the timer */
LPTMR0->CSR |= LPTMR_CSR_TEN_MASK;
led = 0;
while (true) {
wait(1);
led = 1;
printf("%d\n", ticks);
wait(1);
led = 0;
printf("%d\n", ticks);
}
}

View File

@ -0,0 +1,48 @@
#include "mbed.h"
extern "C" {
volatile uint32_t msTicks;
void SysTick_Handler(void) {
msTicks++;
}
void Delay(uint32_t dlyTicks) {
uint32_t curTicks;
curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}
}
int main() {
SysTick_Config(SystemCoreClock / 1000);
SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT
PIT->MCR = 0; // Enable PIT
// Timer 1
PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF;
PIT->CHANNEL[1].TCTRL = 0x0; // Disable Interrupts
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_CHN_MASK; // Chain to timer 0
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1
// Timer 2
PIT->CHANNEL[0].LDVAL = 0xFFFFFFFF;
PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // Start timer 0, disable interrupts
DigitalOut led(LED_BLUE);
while (true) {
Delay(1000);
led = !led;
uint64_t ticks = (uint64_t)PIT->LTMR64H << 32;
ticks |= (uint64_t)PIT->LTMR64L;
printf("ticks: 0x%x%x\n", (uint32_t)(ticks>>32), (uint32_t)(ticks & 0xFFFFFFFF));
ticks = (~ticks) / 24;
uint32_t us = (uint32_t)(0xFFFFFFFF & ticks);
printf("us : 0x%x\n", us);
}
}

View File

@ -0,0 +1,72 @@
#include "mbed.h"
DigitalOut status_led(LED_BLUE);
DigitalOut error_led(LED_RED);
extern "C" void RTC_IRQHandler(void) {
error_led = 0;
}
extern "C" void RTC_Seconds_IRQHandler(void) {
error_led = 0;
}
extern "C" void HardFault_Handler(void) {
error_led = 0;
}
extern "C" void NMI_Handler_Handler(void) {
error_led = 0;
}
void rtc_init(void) {
// enable the clock to SRTC module register space
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
SIM->SOPT1 = (SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(0);
// disable interrupts
NVIC_DisableIRQ(RTC_Seconds_IRQn);
NVIC_DisableIRQ(RTC_IRQn);
// Reset
RTC->CR = RTC_CR_SWR_MASK;
RTC->CR &= ~RTC_CR_SWR_MASK;
// Allow write
RTC->CR = RTC_CR_UM_MASK | RTC_CR_SUP_MASK;
NVIC_EnableIRQ(RTC_Seconds_IRQn);
NVIC_EnableIRQ(RTC_Seconds_IRQn);
printf("LR: 0x%x\n", RTC->LR);
printf("CR: 0x%x\n", RTC->CR);
wait(1);
if (RTC->SR & RTC_SR_TIF_MASK){
RTC->TSR = 0;
}
RTC->TCR = 0;
// After setting this bit, wait the oscillator startup time before enabling
// the time counter to allow the clock time to stabilize
RTC->CR |= RTC_CR_OSCE_MASK;
for (volatile int i=0; i<0x600000; i++);
//enable seconds interrupts
RTC->IER |= RTC_IER_TSIE_MASK;
// enable time counter
RTC->SR |= RTC_SR_TCE_MASK;
}
int main() {
error_led = 1;
rtc_init();
while (true) {
wait(1);
status_led = !status_led;
printf("%u\n", RTC->TSR);
}
}

View File

@ -0,0 +1,15 @@
#include "mbed.h"
DigitalOut out(p5);
AnalogIn in(p19);
volatile float w, x, y, z;
int main() {
while(1) {
z = x * y / w;
printf("Hello World %d %f\n", out.read(), z);
if(in > 0.5) {
out = !out;
}
}
}

View File

@ -0,0 +1,8 @@
#include "mbed.h"
volatile int x, y, z;
int main() {
while(1) {
z = x * y;
}
}

View File

@ -0,0 +1,8 @@
#include "mbed.h"
volatile float w, x, y, z;
int main() {
while (1) {
z = x * y / w;
}
}

View File

@ -0,0 +1,12 @@
#include "mbed.h"
DigitalOut out(p5);
AnalogIn in(p19);
int main() {
while(1) {
if(in > 0.5) {
out = !out;
}
}
}

View File

@ -0,0 +1,5 @@
#include "mbed.h"
int main() {
printf("Hello World!");
}

View File

@ -0,0 +1,43 @@
/* mbed Microcontroller Library - SPIHalfDuplex
* Copyright (c) 2010-2011 ARM Limited. All rights reserved.
*/
#include "SPIHalfDuplex.h"
#if DEVICE_SPI
#include "spi_api.h"
#include "pinmap.h"
#define GPIO_MODE 0
#define SPI_MODE 2
namespace mbed {
SPIHalfDuplex::SPIHalfDuplex(PinName mosi, PinName miso, PinName sclk) : SPI(mosi, miso, sclk) {
_mosi = mosi;
_miso = miso;
_sbits = _bits;
}
void SPIHalfDuplex::slave_format(int sbits) {
_sbits = sbits;
}
int SPIHalfDuplex::write(int value) {
int t_bits = _bits;
pin_function(_mosi, SPI_MODE);
int ret_val = SPI::write(value);
if (ret_val != value) {
return -1;
}
format(_sbits, _mode);
pin_function(_mosi, GPIO_MODE);
ret_val = SPI::write(0x55);
format(t_bits, _mode);
pin_function(_mosi, SPI_MODE);
return ret_val;
}
} // end namespace mbed
#endif

View File

@ -0,0 +1,85 @@
/* mbed Microcontroller Library - SPIHalfDuplex
* Copyright (c) 2010-2011 ARM Limited. All rights reserved.
*/
#ifndef MBED_SPIHALFDUPLEX_H
#define MBED_SPIHALFDUPLEX_H
#include "platform.h"
#if DEVICE_SPI
#include "SPI.h"
namespace mbed {
/** A SPI half-duplex master, used for communicating with SPI slave devices
* over a shared data line.
*
* The default format is set to 8-bits for both master and slave, and a
* clock frequency of 1MHz
*
* Most SPI devies will also require Chip Select and Reset signals. These
* can be controlled using <DigitalOut> pins.
*
* Although this is for a shared data line, both MISO and MOSI are defined,
* and should be tied together externally to the mbed. This class handles
* the tri-stating of the MOSI pin.
*
* Example:
* @code
* // Send a byte to a SPI half-duplex slave, and record the response
*
* #include "mbed.h"
*
* SPIHalfDuplex device(p5, p6, p7) // mosi, miso, sclk
*
* int main() {
* int respone = device.write(0xAA);
* }
* @endcode
*/
class SPIHalfDuplex : public SPI {
public:
/** Create a SPI half-duplex master connected to the specified pins
*
* Pin Options:
* (5, 6, 7) or (11, 12, 13)
*
* mosi or miso can be specfied as NC if not used
*
* @param mosi SPI Master Out, Slave In pin
* @param miso SPI Master In, Slave Out pin
* @param sclk SPI Clock pin
* @param name (optional) A string to identify the object
*/
SPIHalfDuplex(PinName mosi, PinName miso, PinName sclk);
/** Write to the SPI Slave and return the response
*
* @param value Data to be sent to the SPI slave
*
* @returns
* Response from the SPI slave
*/
virtual int write(int value);
/** Set the number of databits expected from the slave, from 4-16
*
* @param sbits Number of expected bits in the slave response
*/
void slave_format(int sbits);
protected:
PinName _mosi;
PinName _miso;
int _sbits;
}; // End of class
} // End of namespace mbed
#endif
#endif

View File

@ -0,0 +1,52 @@
/* mbed Microcontroller Library - SerialHalfDuplex
* Copyright (c) 2010-2011 ARM Limited. All rights reserved.
*/
#include "SerialHalfDuplex.h"
#if DEVICE_SERIAL
#include "pinmap.h"
#include "serial_api.h"
namespace mbed {
SerialHalfDuplex::SerialHalfDuplex(PinName tx, PinName rx)
: Serial(tx, rx) {
gpio_init(&gpio, tx, PIN_INPUT);
gpio_mode(&gpio, PullNone); // no pull
}
// To transmit a byte in half duplex mode:
// 1. Disable interrupts, so we don't trigger on loopback byte
// 2. Set tx pin to UART out
// 3. Transmit byte as normal
// 4. Read back byte from looped back tx pin - this both confirms that the
// transmit has occurred, and also clears the byte from the buffer.
// 5. Return pin to input mode
// 6. Re-enable interrupts
int SerialHalfDuplex::_putc(int c) {
int retc;
// TODO: We should not disable all interrupts
__disable_irq();
serial_pinout_tx(gpio.pin);
Serial::_putc(c);
retc = Serial::getc(); // reading also clears any interrupt
pin_function(gpio.pin, 0);
__enable_irq();
return retc;
}
int SerialHalfDuplex::_getc(void) {
return Serial::_getc();
}
} // End namespace
#endif

View File

@ -0,0 +1,82 @@
/* mbed Microcontroller Library - SerialHalfDuplex
* Copyright (c) 2010-2011 ARM Limited. All rights reserved.
*/
#ifndef MBED_SERIALHALFDUPLEX_H
#define MBED_SERIALHALFDUPLEX_H
#include "platform.h"
#if DEVICE_SERIAL
#include "Serial.h"
#include "gpio_api.h"
namespace mbed {
/** A serial port (UART) for communication with other devices using
* Half-Duplex, allowing transmit and receive on a single
* shared transmit and receive line. Only one end should be transmitting
* at a time.
*
* Both the tx and rx pin should be defined, and wired together.
* This is in addition to them being wired to the other serial
* device to allow both read and write functions to operate.
*
* For Simplex and Full-Duplex Serial communication, see Serial()
*
* Example:
* @code
* // Send a byte to a second HalfDuplex device, and read the response
*
* #include "mbed.h"
*
* // p9 and p10 should be wired together to form "a"
* // p28 and p27 should be wired together to form "b"
* // p9/p10 should be wired to p28/p27 as the Half Duplex connection
*
* SerialHalfDuplex a(p9, p10);
* SerialHalfDuplex b(p28, p27);
*
* void b_rx() { // second device response
* b.putc(b.getc() + 4);
* }
*
* int main() {
* b.attach(&b_rx);
* for (int c = 'A'; c < 'Z'; c++) {
* a.putc(c);
* printf("sent [%c]\n", c);
* wait(0.5); // b should respond
* if (a.readable()) {
* printf("received [%c]\n", a.getc());
* }
* }
* }
* @endcode
*/
class SerialHalfDuplex : public Serial {
public:
/** Create a half-duplex serial port, connected to the specified transmit
* and receive pins.
*
* These pins should be wired together, as well as to the target device
*
* @param tx Transmit pin
* @param rx Receive pin
*/
SerialHalfDuplex(PinName tx, PinName rx);
protected:
gpio_object gpio;
virtual int _putc(int c);
virtual int _getc(void);
}; // End class SerialHalfDuplex
} // End namespace
#endif
#endif

View File

@ -0,0 +1,32 @@
#include "mbed.h"
#include "rtos.h"
#include "SDFileSystem.h"
#define FILE_LOC "/sd/test.txt"
Serial pc(USBTX, USBRX);
Serial gps(p28, p27);
Serial test(p9,p10);
SDFileSystem sd(p11, p12, p13, p14, "sd");
DigitalOut myled(LED1);
DigitalOut sdled(LED2);
void sd_thread(void const *argument) {
while (true) {
sdled = !sdled;
FILE *fp = NULL;
fp = fopen(FILE_LOC, "w");
if( fp != NULL ) fclose(fp);
Thread::wait(1000);
}
}
int main() {
Thread sdTask(sd_thread, NULL, osPriorityNormal, DEFAULT_STACK_SIZE * 2.25);
while (true) {
myled = !myled;
Thread::wait(1000);
}
}

View File

@ -0,0 +1,20 @@
#include "mbed.h"
DigitalOut led(LED1);
#ifdef TARGET_KL25Z
DigitalOut out(PTA1);
#else
DigitalOut out(p5);
#endif
Ticker tick;
void togglePin (void) {
out = !out;
led = !led;
}
int main() {
tick.attach_us(togglePin, 10000);
}

View File

@ -0,0 +1,19 @@
#include "mbed.h"
#ifdef TARGET_KL25Z
DigitalOut out(PTA1);
#else
DigitalOut out(p5);
#endif
DigitalOut myled(LED1);
int main() {
printf("Hello World\n");
while (true) {
wait_us(10000);
out = !out;
myled = !myled;
}
}

View File

@ -0,0 +1,33 @@
#include "mbed.h"
DigitalOut led(LED1);
#ifdef TARGET_KL25Z
DigitalOut out(PTA1);
#elif defined(TARGET_LPC812)
DigitalOut out(P0_12);
#else
DigitalOut out(p5);
#endif
Timeout timer;
void toggleOff (void);
void toggleOn (void) {
out = 1;
led = 1;
timer.attach_us(toggleOff, 10000);
}
void toggleOff(void) {
out = 0;
led = 0;
timer.attach_us(toggleOn, 30000);
}
int main() {
toggleOn();
}

View File

@ -18,8 +18,8 @@ int main() {
int rc = 0;
EthernetInterface eth;
// rc = eth.init(); //Use DHCP
rc = eth.init(LOCAL_IP_ADDRESS, NETWORK_MASK, GATEWAY);
rc = eth.init(); //Use DHCP
// rc = eth.init(LOCAL_IP_ADDRESS, NETWORK_MASK, GATEWAY);
CHECK(rc, "eth init");
rc = eth.connect();

View File

@ -11,7 +11,7 @@ ROOT = abspath(join(dirname(__file__), ".."))
sys.path.append(ROOT)
from workspace_tools.toolchains import TARGETS, TOOLCHAINS
from workspace_tools.options import get_default_options_parser, TARGET_OPTIONS
from workspace_tools.options import get_default_options_parser
from workspace_tools.build_api import build_mbed_libs, build_lib
@ -45,7 +45,7 @@ if __name__ == '__main__':
# Get target list
if options.mcu:
targets = [TARGET_OPTIONS[options.mcu]]
targets = [options.mcu]
else:
targets = TARGETS

View File

@ -141,11 +141,13 @@ CHIP_VENDOR = {
"LPC2368" : "nxp",
"LPC1768" : "nxp",
"LPC11U24": "nxp",
"LPC812" : "nxp",
"KL25Z" : "freescale",
}
def build_mbed_libs(target, toolchain, verbose=False):
vendor = CHIP_VENDOR[target]
for lib_name in ["%s_cmsis"%vendor, "%s_mbed"%vendor]:
build_lib(lib_name, target, toolchain, verbose=verbose)

View File

@ -6,6 +6,7 @@ DEFAULT_SUPPORT = {
"LPC11U24": ALL_TOOLCHAINS,
"LPC2368": ARM_TOOLCHAINS,
"KL25Z": ALL_TOOLCHAINS,
"LPC812" : ALL_TOOLCHAINS,
}
CORTEX_SUPPORT = {
"LPC1768": ALL_TOOLCHAINS,
@ -15,7 +16,8 @@ CORTEX_SUPPORT = {
CORTEX_ARM_SUPPORT = {
"LPC1768": ARM_TOOLCHAINS,
"LPC11U24": ARM_TOOLCHAINS,
"KL25Z": ALL_TOOLCHAINS,
"KL25Z" : ARM_TOOLCHAINS,
"LPC812" : ARM_TOOLCHAINS,
}
LPC11U24_SUPPORT = {
"LPC11U24": ALL_TOOLCHAINS,

View File

@ -1,6 +1,6 @@
import socket
ECHO_SERVER_ADDRESS = "10.2.131.195"
ECHO_SERVER_ADDRESS = "10.2.200.41"
ECHO_PORT = 7
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

View File

@ -1,6 +1,6 @@
import socket
ECHO_SERVER_ADDRESS = '10.2.131.195'
ECHO_SERVER_ADDRESS = '10.2.200.41'
ECHO_PORT = 7
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

View File

@ -12,7 +12,7 @@ from serial import Serial
ROOT = abspath(join(dirname(__file__), ".."))
sys.path.append(ROOT)
from workspace_tools.options import get_default_options_parser, TARGET_OPTIONS
from workspace_tools.options import get_default_options_parser
from workspace_tools.build_api import build_project
from workspace_tools.tests import TESTS, Test, TEST_MAP
from workspace_tools.paths import BUILD_DIR, RTOS_LIBRARIES
@ -59,7 +59,7 @@ if __name__ == '__main__':
# Target
if options.mcu is None :
args_error(parser, "[ERROR] You should specify an MCU")
mcu = TARGET_OPTIONS[options.mcu]
mcu = options.mcu
# Toolchain
if options.tool is None:
@ -88,11 +88,11 @@ if __name__ == '__main__':
copy(bin, options.disk)
if options.serial:
if options.mcu == "M0+":
# In the Freedom Board we do not have a flash disk where to store
# the image, we write it directly on the target chip, therefore
# we need to disconnect the interface: wait for the device to
# enumerate again
if options.mcu in ["M0+", "LPC812"]:
# We do not have a flash disk where to store the image, we write
# it directly on the target chip, therefore we need to
# disconnect the interface: wait for the device to enumerate
# again
copy_time = 4
else:
copy_time = 1.5

View File

@ -4,19 +4,19 @@ from workspace_tools.toolchains import *
# Targets and Toolchains
TARGET_OPTIONS = {
"ARM7": "LPC2368",
"M3": "LPC1768",
"M0": "LPC11U24",
"M0+": "KL25Z",
}
TARGETS = TARGET_OPTIONS.values()
TARGETS = (
"LPC2368",
"LPC1768",
"LPC11U24",
"KL25Z",
"LPC812"
)
def get_default_options_parser():
parser = OptionParser()
parser.add_option("-m", "--mcu", dest="mcu",
help="build for the given MCU (%s)" % ', '.join(TARGET_OPTIONS.keys()),
help="build for the given MCU (%s)" % ', '.join(TARGETS),
metavar="MCU")
parser.add_option("-t", "--tool", dest="tool",

105
workspace_tools/size.py Normal file
View File

@ -0,0 +1,105 @@
import sys
from os.path import join, abspath, dirname, exists, splitext
from subprocess import Popen, PIPE
import csv
from collections import defaultdict
ROOT = abspath(join(dirname(__file__), ".."))
sys.path.append(ROOT)
from workspace_tools.paths import BUILD_DIR, TOOLS_DATA
from workspace_tools.settings import GCC_ARM_PATH
from workspace_tools.tests import TEST_MAP
from workspace_tools.build_api import build_mbed_libs, build_project
SIZE = join(GCC_ARM_PATH, 'arm-none-eabi-size')
def get_size(path):
out = Popen([SIZE, path], stdout=PIPE).communicate()[0]
return map(int, out.splitlines()[1].split()[:4])
def get_percentage(before, after):
if before == 0:
return 0 if after == 0 else 100.0
return float(after - before) / float(before) * 100.0
def human_size(val):
if val>1024:
return "%.0fKb" % (float(val)/1024.0)
return "%d" % val
def print_diff(name, before, after):
print "%s: (%s -> %s) %.2f%%" % (name, human_size(before) , human_size(after) , get_percentage(before , after))
BENCHMARKS = [
("BENCHMARK_1", "CENV"),
("BENCHMARK_2", "PRINTF"),
("BENCHMARK_3", "FP"),
("BENCHMARK_4", "MBED"),
("BENCHMARK_5", "ALL"),
]
BENCHMARK_DATA_PATH = join(TOOLS_DATA, 'benchmarks.csv')
def benchmarks():
# CSV Data
csv_data = csv.writer(open(BENCHMARK_DATA_PATH, 'wb'))
csv_data.writerow(['Toolchain', "Target", "Benchmark", "code", "data", "bss", "flash"])
# Build
for toolchain in ['ARM', 'uARM', 'GCC_CR', 'GCC_CS', 'GCC_ARM']:
for mcu in ["LPC1768", "LPC11U24"]:
# Build Libraries
build_mbed_libs(mcu, toolchain)
# Build benchmarks
build_dir = join(BUILD_DIR, "benchmarks", mcu, toolchain)
for test_id, title in BENCHMARKS:
# Build Benchmark
try:
test = TEST_MAP[test_id]
path = build_project(test.source_dir, join(build_dir, test_id),
mcu, toolchain, test.dependencies)
base, ext = splitext(path)
# Check Size
code, data, bss, flash = get_size(base+'.elf')
csv_data.writerow([toolchain, mcu, title, code, data, bss, flash])
except Exception, e:
print "Unable to build %s for toolchain %s targeting %s" % (test_id, toolchain, mcu)
print e
def compare(t1, t2, target):
if not exists(BENCHMARK_DATA_PATH):
benchmarks()
else:
print "Loading: %s" % BENCHMARK_DATA_PATH
data = csv.reader(open(BENCHMARK_DATA_PATH, 'rb'))
benchmarks_data = defaultdict(dict)
for (toolchain, mcu, name, code, data, bss, flash) in data:
if target == mcu:
for t in [t1, t2]:
if toolchain == t:
benchmarks_data[name][t] = map(int, (code, data, bss, flash))
print "%s vs %s for %s" % (t1, t2, target)
for name, data in benchmarks_data.iteritems():
try:
# Check Size
code_a, data_a, bss_a, flash_a = data[t1]
code_u, data_u, bss_u, flash_u = data[t2]
print "\n=== %s ===" % name
print_diff("code", code_a , code_u)
print_diff("data", data_a , data_u)
print_diff("bss", bss_a , bss_u)
print_diff("flash", flash_a , flash_u)
except Exception, e:
print "No data for benchmark %s" % (name)
print e
if __name__ == '__main__':
compare("GCC_CR", "GCC_CS", "LPC1768")

View File

@ -135,6 +135,33 @@ TESTS = [
"automated": True,
"peripherals": ["MMA7660"]
},
# Size benchmarks
{
"id": "BENCHMARK_1", "description": "Benchmark: Size (c environment)",
"source_dir": join(BENCHMARKS_DIR, "cenv"),
"dependencies": [MBED_LIBRARIES]
},
{
"id": "BENCHMARK_2", "description": "Benchmark: Size (float math)",
"source_dir": join(BENCHMARKS_DIR, "float_math"),
"dependencies": [MBED_LIBRARIES]
},
{
"id": "BENCHMARK_3", "description": "Benchmark: Size (printf)",
"source_dir": join(BENCHMARKS_DIR, "printf"),
"dependencies": [MBED_LIBRARIES]
},
{
"id": "BENCHMARK_4", "description": "Benchmark: Size (mbed libs)",
"source_dir": join(BENCHMARKS_DIR, "mbed"),
"dependencies": [MBED_LIBRARIES]
},
{
"id": "BENCHMARK_5", "description": "Benchmark: Size (all)",
"source_dir": join(BENCHMARKS_DIR, "all"),
"dependencies": [MBED_LIBRARIES]
},
# Not automated MBED tests
{
@ -224,41 +251,51 @@ TESTS = [
"dependencies": [MBED_LIBRARIES],
},
{
"id": "MBED_17", "description": "MBED: MODSERIAL",
"source_dir": join(TEST_DIR, "mbed", "modserial"),
"dependencies": [MBED_LIBRARIES, join(TEST_DIR, "MODSERIAL")],
},
{
"id": "MBED_18", "description": "MBED: Serial Interrupt 2",
"id": "MBED_17", "description": "MBED: Serial Interrupt 2",
"source_dir": join(TEST_DIR, "mbed", "serial_interrupt_2"),
"dependencies": [MBED_LIBRARIES],
},
{
"id": "MBED_19", "description": "MBED: Local FS Directory",
"id": "MBED_18", "description": "MBED: Local FS Directory",
"source_dir": join(TEST_DIR, "mbed", "dir"),
"dependencies": [MBED_LIBRARIES],
},
{
"id": "MBED_20", "description": "MBED: SD FS Directory",
"id": "MBED_19", "description": "MBED: SD FS Directory",
"source_dir": join(TEST_DIR, "mbed", "dir_sd"),
"dependencies": [MBED_LIBRARIES, SD_FS, FAT_FS],
"peripherals": ["SD"]
},
{
"id": "MBED_21", "description": "MBED: InterruptIn 2",
"id": "MBED_20", "description": "MBED: InterruptIn 2",
"source_dir": join(TEST_DIR, "mbed", "interruptin_2"),
"dependencies": [MBED_LIBRARIES],
},
{
"id": "MBED_22", "description": "MBED: freopen Stream",
"id": "MBED_21", "description": "MBED: freopen Stream",
"source_dir": join(TEST_DIR, "mbed", "freopen"),
"dependencies": [MBED_LIBRARIES],
},
{
"id": "MBED_23", "description": "MBED: Semihost",
"id": "MBED_22", "description": "MBED: Semihost",
"source_dir": join(TEST_DIR, "mbed", "semihost"),
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
},
{
"id": "MBED_23", "description": "MBED: Ticker 2",
"source_dir": join(TEST_DIR, "mbed", "ticker_2"),
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
},
{
"id": "MBED_24", "description": "MBED: Timeout",
"source_dir": join(TEST_DIR, "mbed", "timeout"),
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
},
{
"id": "MBED_25", "description": "MBED: Time us",
"source_dir": join(TEST_DIR, "mbed", "time_us"),
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
},
# CMSIS RTOS tests
{
"id": "CMSIS_RTOS_1", "description": "CMSIS RTOS: Basic",
@ -541,6 +578,11 @@ TESTS = [
"source_dir": join(TEST_DIR, "mbed", "dev_null"),
"dependencies": [MBED_LIBRARIES],
},
{
"id": "EXAMPLE_2", "description": "FS + RTOS",
"source_dir": join(TEST_DIR, "mbed", "fs"),
"dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, TEST_MBED_LIB, SD_FS, FAT_FS],
}
]
class Test:

View File

@ -24,7 +24,7 @@ type directory, because it would get confused with the legacy "ARM" toolchain.
* ARM -> ARM_STD
* uARM -> ARM_MICRO
"""
TARGETS = set(['LPC1768', 'LPC11U24', 'LPC2368', 'KL25Z'])
TARGETS = set(['LPC1768', 'LPC11U24', 'LPC2368', 'KL25Z', 'LPC812'])
TOOLCHAINS = set(['ARM', 'uARM', 'GCC_ARM', 'GCC_CS', 'GCC_CR', 'GCC', 'IAR'])
TYPES = set(['GCC'])
@ -129,6 +129,7 @@ class mbedToolchain:
"LPC1768" : ["__CORTEX_M3", "ARM_MATH_CM3"],
"LPC11U24": ["__CORTEX_M0", "ARM_MATH_CM0"],
"KL25Z" : ["__CORTEX_M0", "ARM_MATH_CM0"],
"LPC812" : ["__CORTEX_M0", "ARM_MATH_CM0"],
}
def __init__(self, target, notify=None):
@ -171,7 +172,7 @@ class mbedToolchain:
for d in dependencies:
# Some objects are not provided with full path and here we do not have
# information about the library paths. Safe option: assume an update
if not exists(d):
if not d or not exists(d):
return True
if stat(d).st_mtime >= target_mod_time:
@ -358,12 +359,11 @@ class mbedToolchain:
self.link(elf, objects, r.libraries, r.lib_dirs, r.linker_script)
if self.need_update(bin, [elf]):
self.debug("elf to bin: %s" % (name + '.bin'))
self.progress("elf2bin", name)
self.binary(elf, bin)
if self.target in ['LPC1768', 'LPC11U24', 'LPC2368']:
self.debug("patching bin: %s" % (name + '.bin'))
if self.target in ['LPC1768', 'LPC11U24', 'LPC2368', 'LPC812']:
self.progress("LPC Patch", (name + '.bin'))
patch(bin)
self.var("compile_succeded", True)
@ -411,6 +411,7 @@ class ARM(mbedToolchain):
"LPC2368" : "ARM7TDMI-S",
"LPC11U24": "Cortex-M0",
"KL25Z" : "Cortex-M0",
"LPC812" : "Cortex-M0",
}
STD_LIB_NAME = "%s.ar"
@ -494,6 +495,7 @@ class ARM_MICRO(ARM):
ARM.__init__(self, target, notify)
# Compiler
self.asm += ["-D__MICROLIB"]
self.cc += ["--library_type=microlib", "-D__MICROLIB"]
self.cppc += ["--library_type=microlib", "-D__MICROLIB"]
@ -506,7 +508,7 @@ class ARM_MICRO(ARM):
if target == "LPC1768":
self.sys_libs.extend([join(ARM_CPPLIB, lib+".l") for lib in ["cpp_ws", "cpprt_w"]])
elif target in ["LPC11U24", "KL25Z"]:
elif target in ["LPC11U24", "KL25Z", "LPC812"]:
self.sys_libs.extend([join(ARM_CPPLIB, lib+".l") for lib in ["cpp_ps", "cpprt_p"]])
@ -519,6 +521,7 @@ class GCC(mbedToolchain):
"LPC2368": "arm7tdmi-s",
"LPC11U24": "cortex-m0",
"KL25Z": "cortex-m0",
"LPC812" : "cortex-m0",
}
STD_LIB_NAME = "lib%s.a"
@ -529,7 +532,7 @@ class GCC(mbedToolchain):
mbedToolchain.__init__(self, target, notify)
self.IGNORE_DIR.remove('GCC')
cpu = ["-mcpu=%s" % GCC_CS.CPU[target]]
if target in ["LPC1768", "LPC11U24", "KL25Z"]:
if target in ["LPC1768", "LPC11U24", "KL25Z", "LPC812"]:
cpu.append("-mthumb")
# Note: We are using "-O2" instead of "-Os" to avoid this known GCC bug: