mirror of https://github.com/ARMmbed/mbed-os.git
Remove LPC4088 based targets
parent
e160bd3602
commit
5dcfe57c41
|
@ -49,15 +49,7 @@ char s_trace_buffer[100] = MEM_MNGR_TRACE;
|
|||
/* For LPC boards define the heap memory bank ourselves to give us section placement
|
||||
control */
|
||||
#ifndef ETHMEM_SECTION
|
||||
#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
# if defined (__ICCARM__)
|
||||
# define ETHMEM_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||
# else
|
||||
# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
|
||||
# endif
|
||||
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC1769)
|
||||
#if defined(TARGET_LPC1768) || defined(TARGET_LPC1769)
|
||||
# if defined (__ICCARM__)
|
||||
# define ETHMEM_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
|
|
|
@ -38,15 +38,7 @@ using namespace utest::v1;
|
|||
/* For LPC boards define the memory bank ourselves to give us section placement
|
||||
control */
|
||||
#ifndef ETHMEM_SECTION
|
||||
#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
# if defined (__ICCARM__)
|
||||
# define ETHMEM_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||
# else
|
||||
# define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned))
|
||||
# endif
|
||||
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC1769)
|
||||
#if defined(TARGET_LPC1768) || defined(TARGET_LPC1769)
|
||||
# if defined (__ICCARM__)
|
||||
# define ETHMEM_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
|
|
|
@ -126,15 +126,7 @@ void trace_to_ascii_hex_dump(char* prefix, int len, char *data);
|
|||
|
||||
/* Define the memory area for the lwip's memory pools */
|
||||
#ifndef MEMP_SECTION
|
||||
#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
# if defined (__ICCARM__)
|
||||
# define MEMP_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
# define MEMP_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||
# else
|
||||
# define MEMP_SECTION __attribute__((section("AHBSRAM0"),aligned))
|
||||
# endif
|
||||
#elif defined(TARGET_LPC1768)
|
||||
#if defined(TARGET_LPC1768)
|
||||
# if defined (__ICCARM__)
|
||||
# define MEMP_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
|
|
|
@ -31,15 +31,7 @@
|
|||
|
||||
/* Define the heap ourselves to give us section placement control */
|
||||
#ifndef ETHMEM_SECTION
|
||||
#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
# if defined (__ICCARM__)
|
||||
# define ETHMEM_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||
# else
|
||||
# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
|
||||
# endif
|
||||
#elif defined(TARGET_LPC1768)
|
||||
#if defined(TARGET_LPC1768)
|
||||
# if defined (__ICCARM__)
|
||||
# define ETHMEM_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
|
|
|
@ -165,12 +165,6 @@
|
|||
"LPC1768": {
|
||||
"mem-size": 16362
|
||||
},
|
||||
"LPC4088": {
|
||||
"mem-size": 15360
|
||||
},
|
||||
"LPC4088_DM": {
|
||||
"mem-size": 15360
|
||||
},
|
||||
"UBLOX_C027": {
|
||||
"mem-size": 16362
|
||||
},
|
||||
|
|
|
@ -125,15 +125,7 @@ struct lpc_enetdata {
|
|||
#define TARGET_LPC17XX
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
# if defined (__ICCARM__)
|
||||
# define ETHMEM_SECTION
|
||||
# elif defined(TOOLCHAIN_GCC_CR)
|
||||
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32"), aligned))
|
||||
# else
|
||||
# define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned))
|
||||
# endif
|
||||
#elif defined(TARGET_LPC17XX)
|
||||
#if defined(TARGET_LPC17XX)
|
||||
# if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_ARM)
|
||||
# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
|
||||
# endif
|
||||
|
@ -392,8 +384,6 @@ int32_t LPC17_EMAC::lpc_packet_addr_notsafe(void *addr)
|
|||
/* Check for legal address ranges */
|
||||
#if defined(TARGET_LPC17XX)
|
||||
if ((((uint32_t) addr >= 0x2007C000) && ((uint32_t) addr < 0x20083FFF))) {
|
||||
#elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
if ((((uint32_t) addr >= 0x20000000) && ((uint32_t) addr < 0x20007FFF))) {
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -699,27 +689,6 @@ bool LPC17_EMAC::low_level_init()
|
|||
#if defined(TARGET_LPC17XX)
|
||||
LPC_PINCON->PINSEL2 = 0x50150105; /* Enable P1 Ethernet Pins. */
|
||||
LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005;
|
||||
#elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */
|
||||
LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */
|
||||
LPC_IOCON->P1_1 &= ~0x07;
|
||||
LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */
|
||||
LPC_IOCON->P1_4 &= ~0x07;
|
||||
LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */
|
||||
LPC_IOCON->P1_8 &= ~0x07;
|
||||
LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */
|
||||
LPC_IOCON->P1_9 &= ~0x07;
|
||||
LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */
|
||||
LPC_IOCON->P1_10 &= ~0x07;
|
||||
LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */
|
||||
LPC_IOCON->P1_14 &= ~0x07;
|
||||
LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */
|
||||
LPC_IOCON->P1_15 &= ~0x07;
|
||||
LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */
|
||||
LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */
|
||||
LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */
|
||||
LPC_IOCON->P1_17 &= ~0x07;
|
||||
LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */
|
||||
#endif
|
||||
|
||||
/* Reset all MAC logic */
|
||||
|
|
|
@ -1,35 +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.
|
||||
*/
|
||||
#ifndef MBED_PORTNAMES_H
|
||||
#define MBED_PORTNAMES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
Port0 = 0,
|
||||
Port1 = 1,
|
||||
Port2 = 2,
|
||||
Port3 = 3,
|
||||
Port4 = 4,
|
||||
Port5 = 5
|
||||
} PortName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -1,119 +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.
|
||||
*/
|
||||
#ifndef MBED_PERIPHERALNAMES_H
|
||||
#define MBED_PERIPHERALNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UART_0 = (int)LPC_UART0_BASE,
|
||||
UART_1 = (int)LPC_UART1_BASE,
|
||||
UART_2 = (int)LPC_UART2_BASE,
|
||||
UART_3 = (int)LPC_UART3_BASE,
|
||||
UART_4 = (int)LPC_UART4_BASE
|
||||
} UARTName;
|
||||
|
||||
typedef enum {
|
||||
ADC0_0 = 0,
|
||||
ADC0_1,
|
||||
ADC0_2,
|
||||
ADC0_3,
|
||||
ADC0_4,
|
||||
ADC0_5,
|
||||
ADC0_6,
|
||||
ADC0_7
|
||||
} ADCName;
|
||||
|
||||
typedef enum {
|
||||
DAC_0 = 0
|
||||
} DACName;
|
||||
|
||||
typedef enum {
|
||||
SPI_0 = (int)LPC_SSP0_BASE,
|
||||
SPI_1 = (int)LPC_SSP1_BASE,
|
||||
SPI_2 = (int)LPC_SSP2_BASE
|
||||
} SPIName;
|
||||
|
||||
typedef enum {
|
||||
I2C_0 = (int)LPC_I2C0_BASE,
|
||||
I2C_1 = (int)LPC_I2C1_BASE,
|
||||
I2C_2 = (int)LPC_I2C2_BASE
|
||||
} I2CName;
|
||||
|
||||
typedef enum {
|
||||
PWM0_1 = 1,
|
||||
PWM0_2,
|
||||
PWM0_3,
|
||||
PWM0_4,
|
||||
PWM0_5,
|
||||
PWM0_6,
|
||||
PWM1_1,
|
||||
PWM1_2,
|
||||
PWM1_3,
|
||||
PWM1_4,
|
||||
PWM1_5,
|
||||
PWM1_6
|
||||
} PWMName;
|
||||
|
||||
typedef enum {
|
||||
CAN_1 = (int)LPC_CAN1_BASE,
|
||||
CAN_2 = (int)LPC_CAN2_BASE
|
||||
} CANName;
|
||||
|
||||
#define STDIO_UART_TX USBTX
|
||||
#define STDIO_UART_RX USBRX
|
||||
#define STDIO_UART UART_0
|
||||
|
||||
// Default peripherals
|
||||
#define MBED_SPI0 p5, p6, p7
|
||||
#define MBED_SPI1 p11, p12, p13, p14
|
||||
#define MBED_SPI2 p39, p38, p32, p31
|
||||
|
||||
#define MBED_UART3 p9, p10
|
||||
#define MBED_UART4 p37, p31
|
||||
#define MBED_UARTUSB USBTX, USBRX
|
||||
|
||||
#define MBED_I2C0 p32, p31
|
||||
#define MBED_I2C1 p9, p10
|
||||
|
||||
#define MBED_CAN1 p9, p10
|
||||
#define MBED_CAN2 p34, p33
|
||||
|
||||
#define MBED_ANALOGOUT0 p18
|
||||
|
||||
#define MBED_ANALOGIN0 p15
|
||||
#define MBED_ANALOGIN1 p16
|
||||
#define MBED_ANALOGIN2 p17
|
||||
#define MBED_ANALOGIN3 p18
|
||||
#define MBED_ANALOGIN4 p19
|
||||
#define MBED_ANALOGIN5 p20
|
||||
|
||||
#define MBED_PWMOUT0 p30
|
||||
#define MBED_PWMOUT1 p29
|
||||
#define MBED_PWMOUT2 p28
|
||||
#define MBED_PWMOUT3 p27
|
||||
#define MBED_PWMOUT4 p26
|
||||
#define MBED_PWMOUT5 p25
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,130 +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.
|
||||
*/
|
||||
#ifndef MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 5
|
||||
|
||||
typedef enum {
|
||||
// LPC Pin Names
|
||||
P0_0 = /*LPC_GPIO0_BASE*/0,
|
||||
P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31,
|
||||
P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31,
|
||||
P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31,
|
||||
P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31,
|
||||
P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31,
|
||||
P5_0, P5_1, P5_2, P5_3, P5_4,
|
||||
|
||||
// mbed DIP Pin Names
|
||||
p5 = P1_24,
|
||||
p6 = P1_23,
|
||||
p7 = P1_20,
|
||||
p8 = P0_21,
|
||||
p9 = P0_0,
|
||||
p10 = P0_1,
|
||||
p11 = P0_9,
|
||||
p12 = P0_8,
|
||||
p13 = P0_7,
|
||||
p14 = P0_6,
|
||||
p15 = P0_23,
|
||||
p16 = P0_24,
|
||||
p17 = P0_25,
|
||||
p18 = P0_26,
|
||||
p19 = P1_30,
|
||||
p20 = P1_31,
|
||||
|
||||
p23 = P2_10,
|
||||
p24 = P1_12,
|
||||
p25 = P1_11,
|
||||
p26 = P1_7,
|
||||
p27 = P1_6,
|
||||
p28 = P1_5,
|
||||
p29 = P1_3,
|
||||
p30 = P1_2,
|
||||
p31 = P5_3,
|
||||
p32 = P5_2,
|
||||
p33 = P0_5,
|
||||
p34 = P0_4,
|
||||
|
||||
p37 = P5_4,
|
||||
p38 = P5_1,
|
||||
p39 = P5_0,
|
||||
|
||||
// Other mbed Pin Names
|
||||
LED1 = P1_18,
|
||||
LED2 = P0_13,
|
||||
LED3 = P1_13,
|
||||
LED4 = P2_19,
|
||||
|
||||
USBTX = P0_2,
|
||||
USBRX = P0_3,
|
||||
|
||||
// QSB baseboard Arduino shield pins
|
||||
D0 = p10,
|
||||
D1 = p9,
|
||||
D2 = p31,
|
||||
D3 = p32,
|
||||
D4 = p33,
|
||||
D5 = p37,
|
||||
D6 = p38,
|
||||
D7 = p34,
|
||||
D8 = p8,
|
||||
D9 = p39,
|
||||
D10 = p14,
|
||||
D11 = p11,
|
||||
D12 = p12,
|
||||
D13 = p13,
|
||||
D14 = p19,
|
||||
D15 = p20,
|
||||
|
||||
A0 = p15,
|
||||
A1 = p16,
|
||||
A2 = p17,
|
||||
A3 = p18,
|
||||
A4 = p19,
|
||||
A5 = p20,
|
||||
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullUp = 2,
|
||||
PullDown = 1,
|
||||
PullNone = 0,
|
||||
OpenDrain = 4,
|
||||
PullDefault = PullDown
|
||||
} PinMode;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,130 +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 "mbed_assert.h"
|
||||
#include "analogin_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
#define ANALOGIN_MEDIAN_FILTER 1
|
||||
|
||||
#define ADC_10BIT_RANGE 0x3FF
|
||||
#define ADC_12BIT_RANGE 0xFFF
|
||||
|
||||
static inline int div_round_up(int x, int y) {
|
||||
return (x + (y - 1)) / y;
|
||||
}
|
||||
|
||||
static const PinMap PinMap_ADC[] = {
|
||||
{P0_23, ADC0_0, 0x01},
|
||||
{P0_24, ADC0_1, 0x01},
|
||||
{P0_25, ADC0_2, 0x01},
|
||||
{P0_26, ADC0_3, 0x01},
|
||||
{P1_30, ADC0_4, 0x03},
|
||||
{P1_31, ADC0_5, 0x03},
|
||||
{P0_12, ADC0_6, 0x03},
|
||||
{P0_13, ADC0_7, 0x03},
|
||||
{NC , NC , 0 }
|
||||
};
|
||||
|
||||
#define ADC_RANGE ADC_12BIT_RANGE
|
||||
|
||||
void analogin_init(analogin_t *obj, PinName pin) {
|
||||
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
|
||||
MBED_ASSERT(obj->adc != (ADCName)NC);
|
||||
|
||||
// ensure power is turned on
|
||||
LPC_SC->PCONP |= (1 << 12);
|
||||
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
|
||||
// calculate minimum clock divider
|
||||
// clkdiv = divider - 1
|
||||
uint32_t MAX_ADC_CLK = 12400000;
|
||||
uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
|
||||
|
||||
// Set the generic software-controlled ADC settings
|
||||
LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected
|
||||
| (clkdiv << 8) // CLKDIV:
|
||||
| (0 << 16) // BURST: 0 = software control
|
||||
| (1 << 21) // PDN: 1 = operational
|
||||
| (0 << 24) // START: 0 = no start
|
||||
| (0 << 27); // EDGE: not applicable
|
||||
|
||||
// must enable analog mode (ADMODE = 0)
|
||||
__IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
|
||||
*reg &= ~(1 << 7);
|
||||
|
||||
pinmap_pinout(pin, PinMap_ADC);
|
||||
}
|
||||
|
||||
static inline uint32_t adc_read(analogin_t *obj) {
|
||||
// Select the appropriate channel and start conversion
|
||||
LPC_ADC->CR &= ~0xFF;
|
||||
LPC_ADC->CR |= 1 << (int)obj->adc;
|
||||
LPC_ADC->CR |= 1 << 24;
|
||||
|
||||
// Repeatedly get the sample data until DONE bit
|
||||
unsigned int data;
|
||||
do {
|
||||
data = LPC_ADC->GDR;
|
||||
} while ((data & ((unsigned int)1 << 31)) == 0);
|
||||
|
||||
// Stop conversion
|
||||
LPC_ADC->CR &= ~(1 << 24);
|
||||
|
||||
return (data >> 4) & ADC_RANGE; // 12 bit
|
||||
}
|
||||
|
||||
static inline void order(uint32_t *a, uint32_t *b) {
|
||||
if (*a > *b) {
|
||||
uint32_t t = *a;
|
||||
*a = *b;
|
||||
*b = t;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t adc_read_u32(analogin_t *obj) {
|
||||
uint32_t value;
|
||||
#if ANALOGIN_MEDIAN_FILTER
|
||||
uint32_t v1 = adc_read(obj);
|
||||
uint32_t v2 = adc_read(obj);
|
||||
uint32_t v3 = adc_read(obj);
|
||||
order(&v1, &v2);
|
||||
order(&v2, &v3);
|
||||
order(&v1, &v2);
|
||||
value = v2;
|
||||
#else
|
||||
value = adc_read(obj);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t analogin_read_u16(analogin_t *obj) {
|
||||
uint32_t value = adc_read_u32(obj);
|
||||
|
||||
return (value << 4) | ((value >> 8) & 0x000F); // 12 bit
|
||||
}
|
||||
|
||||
float analogin_read(analogin_t *obj) {
|
||||
uint32_t value = adc_read_u32(obj);
|
||||
return (float)value * (1.0f / (float)ADC_RANGE);
|
||||
}
|
||||
|
||||
const PinMap *analogin_pinmap()
|
||||
{
|
||||
return PinMap_ADC;
|
||||
}
|
|
@ -1,405 +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 "can_api.h"
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CAN_NUM 2
|
||||
|
||||
/* Acceptance filter mode in AFMR register */
|
||||
#define ACCF_OFF 0x01
|
||||
#define ACCF_BYPASS 0x02
|
||||
#define ACCF_ON 0x00
|
||||
#define ACCF_FULLCAN 0x04
|
||||
|
||||
/* There are several bit timing calculators on the internet.
|
||||
http://www.port.de/engl/canprod/sv_req_form.html
|
||||
http://www.kvaser.com/can/index.htm
|
||||
*/
|
||||
|
||||
static const PinMap PinMap_CAN_RD[] = {
|
||||
{P0_0 , CAN_1, 1},
|
||||
{P0_4 , CAN_2, 2},
|
||||
{P0_21, CAN_1, 4},
|
||||
{P2_7 , CAN_2, 1},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_CAN_TD[] = {
|
||||
{P0_1 , CAN_1, 1},
|
||||
{P0_5 , CAN_2, 2},
|
||||
{P0_22, CAN_1, 4},
|
||||
{P2_8 , CAN_2, 1},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
// Type definition to hold a CAN message
|
||||
struct CANMsg {
|
||||
unsigned int reserved1 : 16;
|
||||
unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter
|
||||
unsigned int reserved0 : 10;
|
||||
unsigned int rtr : 1; // Bit 30: Set if this is a RTR message
|
||||
unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message
|
||||
unsigned int id; // CAN Message ID (11-bit or 29-bit)
|
||||
unsigned char data[8]; // CAN Message Data Bytes 0-7
|
||||
};
|
||||
typedef struct CANMsg CANMsg;
|
||||
|
||||
static uint32_t can_irq_ids[CAN_NUM] = {0};
|
||||
static can_irq_handler irq_handler;
|
||||
|
||||
static uint32_t can_disable(can_t *obj) {
|
||||
uint32_t sm = obj->dev->MOD;
|
||||
obj->dev->MOD |= 1;
|
||||
return sm;
|
||||
}
|
||||
|
||||
static inline void can_enable(can_t *obj) {
|
||||
if (obj->dev->MOD & 1) {
|
||||
obj->dev->MOD &= ~(1);
|
||||
}
|
||||
}
|
||||
|
||||
int can_mode(can_t *obj, CanMode mode)
|
||||
{
|
||||
return 0; // not implemented
|
||||
}
|
||||
|
||||
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
|
||||
return 0; // not implemented
|
||||
}
|
||||
|
||||
static inline void can_irq(uint32_t icr, uint32_t index) {
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
if((can_irq_ids[index] != 0) && (icr & (1 << i)))
|
||||
{
|
||||
switch (i) {
|
||||
case 0: irq_handler(can_irq_ids[index], IRQ_RX); break;
|
||||
case 1: irq_handler(can_irq_ids[index], IRQ_TX); break;
|
||||
case 2: irq_handler(can_irq_ids[index], IRQ_ERROR); break;
|
||||
case 3: irq_handler(can_irq_ids[index], IRQ_OVERRUN); break;
|
||||
case 4: irq_handler(can_irq_ids[index], IRQ_WAKEUP); break;
|
||||
case 5: irq_handler(can_irq_ids[index], IRQ_PASSIVE); break;
|
||||
case 6: irq_handler(can_irq_ids[index], IRQ_ARB); break;
|
||||
case 7: irq_handler(can_irq_ids[index], IRQ_BUS); break;
|
||||
case 8: irq_handler(can_irq_ids[index], IRQ_READY); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Have to check that the CAN block is active before reading the Interrupt
|
||||
// Control Register, or the mbed hangs
|
||||
void can_irq_n() {
|
||||
uint32_t icr;
|
||||
|
||||
if(LPC_SC->PCONP & (1 << 13)) {
|
||||
icr = LPC_CAN1->ICR & 0x1FF;
|
||||
can_irq(icr, 0);
|
||||
}
|
||||
|
||||
if(LPC_SC->PCONP & (1 << 14)) {
|
||||
icr = LPC_CAN2->ICR & 0x1FF;
|
||||
can_irq(icr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Register CAN object's irq handler
|
||||
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
|
||||
irq_handler = handler;
|
||||
can_irq_ids[obj->index] = id;
|
||||
}
|
||||
|
||||
// Unregister CAN object's irq handler
|
||||
void can_irq_free(can_t *obj) {
|
||||
obj->dev->IER &= ~(1);
|
||||
can_irq_ids[obj->index] = 0;
|
||||
|
||||
if ((can_irq_ids[0] == 0) && (can_irq_ids[1] == 0)) {
|
||||
NVIC_DisableIRQ(CAN_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear or set a irq
|
||||
void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
|
||||
uint32_t ier;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_RX: ier = (1 << 0); break;
|
||||
case IRQ_TX: ier = (1 << 1); break;
|
||||
case IRQ_ERROR: ier = (1 << 2); break;
|
||||
case IRQ_OVERRUN: ier = (1 << 3); break;
|
||||
case IRQ_WAKEUP: ier = (1 << 4); break;
|
||||
case IRQ_PASSIVE: ier = (1 << 5); break;
|
||||
case IRQ_ARB: ier = (1 << 6); break;
|
||||
case IRQ_BUS: ier = (1 << 7); break;
|
||||
case IRQ_READY: ier = (1 << 8); break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
obj->dev->MOD |= 1;
|
||||
if(enable == 0) {
|
||||
obj->dev->IER &= ~ier;
|
||||
}
|
||||
else {
|
||||
obj->dev->IER |= ier;
|
||||
}
|
||||
obj->dev->MOD &= ~(1);
|
||||
|
||||
// Enable NVIC if at least 1 interrupt is active
|
||||
if(((LPC_SC->PCONP & (1 << 13)) && LPC_CAN1->IER) || ((LPC_SC->PCONP & (1 << 14)) && LPC_CAN2->IER)) {
|
||||
NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq_n);
|
||||
NVIC_EnableIRQ(CAN_IRQn);
|
||||
}
|
||||
else {
|
||||
NVIC_DisableIRQ(CAN_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
// This table has the sampling points as close to 75% as possible. The first
|
||||
// value is TSEG1, the second TSEG2.
|
||||
static const int timing_pts[23][2] = {
|
||||
{0x0, 0x0}, // 2, 50%
|
||||
{0x1, 0x0}, // 3, 67%
|
||||
{0x2, 0x0}, // 4, 75%
|
||||
{0x3, 0x0}, // 5, 80%
|
||||
{0x3, 0x1}, // 6, 67%
|
||||
{0x4, 0x1}, // 7, 71%
|
||||
{0x5, 0x1}, // 8, 75%
|
||||
{0x6, 0x1}, // 9, 78%
|
||||
{0x6, 0x2}, // 10, 70%
|
||||
{0x7, 0x2}, // 11, 73%
|
||||
{0x8, 0x2}, // 12, 75%
|
||||
{0x9, 0x2}, // 13, 77%
|
||||
{0x9, 0x3}, // 14, 71%
|
||||
{0xA, 0x3}, // 15, 73%
|
||||
{0xB, 0x3}, // 16, 75%
|
||||
{0xC, 0x3}, // 17, 76%
|
||||
{0xD, 0x3}, // 18, 78%
|
||||
{0xD, 0x4}, // 19, 74%
|
||||
{0xE, 0x4}, // 20, 75%
|
||||
{0xF, 0x4}, // 21, 76%
|
||||
{0xF, 0x5}, // 22, 73%
|
||||
{0xF, 0x6}, // 23, 70%
|
||||
{0xF, 0x7}, // 24, 67%
|
||||
};
|
||||
|
||||
static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) {
|
||||
uint32_t btr;
|
||||
uint16_t brp = 0;
|
||||
uint32_t calcbit;
|
||||
uint32_t bitwidth;
|
||||
int hit = 0;
|
||||
int bits;
|
||||
|
||||
bitwidth = (pclk / cclk);
|
||||
|
||||
brp = bitwidth / 0x18;
|
||||
while ((!hit) && (brp < bitwidth / 4)) {
|
||||
brp++;
|
||||
for (bits = 22; bits > 0; bits--) {
|
||||
calcbit = (bits + 3) * (brp + 1);
|
||||
if (calcbit == bitwidth) {
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
btr = ((timing_pts[bits][1] << 20) & 0x00700000)
|
||||
| ((timing_pts[bits][0] << 16) & 0x000F0000)
|
||||
| ((psjw << 14) & 0x0000C000)
|
||||
| ((brp << 0) & 0x000003FF);
|
||||
} else {
|
||||
btr = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return btr;
|
||||
|
||||
}
|
||||
|
||||
void can_init_freq(can_t *obj, PinName rd, PinName td, int hz) {
|
||||
CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
|
||||
CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
|
||||
obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td);
|
||||
MBED_ASSERT((int)obj->dev != NC);
|
||||
|
||||
switch ((int)obj->dev) {
|
||||
case CAN_1: LPC_SC->PCONP |= 1 << 13; break;
|
||||
case CAN_2: LPC_SC->PCONP |= 1 << 14; break;
|
||||
}
|
||||
|
||||
pinmap_pinout(rd, PinMap_CAN_RD);
|
||||
pinmap_pinout(td, PinMap_CAN_TD);
|
||||
|
||||
switch ((int)obj->dev) {
|
||||
case CAN_1: obj->index = 0; break;
|
||||
case CAN_2: obj->index = 1; break;
|
||||
}
|
||||
|
||||
can_reset(obj);
|
||||
obj->dev->IER = 0; // Disable Interrupts
|
||||
can_frequency(obj, hz);
|
||||
|
||||
LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter
|
||||
}
|
||||
|
||||
void can_init(can_t *obj, PinName rd, PinName td) {
|
||||
can_init_freq(obj, rd, td, 100000);
|
||||
}
|
||||
|
||||
void can_free(can_t *obj) {
|
||||
switch ((int)obj->dev) {
|
||||
case CAN_1: LPC_SC->PCONP &= ~(1 << 13); break;
|
||||
case CAN_2: LPC_SC->PCONP &= ~(1 << 14); break;
|
||||
}
|
||||
}
|
||||
|
||||
int can_frequency(can_t *obj, int f) {
|
||||
int pclk = PeripheralClock;
|
||||
|
||||
int btr = can_speed(pclk, (unsigned int)f, 1);
|
||||
|
||||
if (btr > 0) {
|
||||
uint32_t modmask = can_disable(obj);
|
||||
obj->dev->BTR = btr;
|
||||
obj->dev->MOD = modmask;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int can_write(can_t *obj, CAN_Message msg, int cc) {
|
||||
unsigned int CANStatus;
|
||||
CANMsg m;
|
||||
|
||||
can_enable(obj);
|
||||
|
||||
m.id = msg.id ;
|
||||
m.dlc = msg.len & 0xF;
|
||||
m.rtr = msg.type;
|
||||
m.type = msg.format;
|
||||
memcpy(m.data, msg.data, msg.len);
|
||||
const unsigned int *buf = (const unsigned int *)&m;
|
||||
|
||||
CANStatus = obj->dev->SR;
|
||||
if (CANStatus & 0x00000004) {
|
||||
obj->dev->TFI1 = buf[0] & 0xC00F0000;
|
||||
obj->dev->TID1 = buf[1];
|
||||
obj->dev->TDA1 = buf[2];
|
||||
obj->dev->TDB1 = buf[3];
|
||||
if(cc) {
|
||||
obj->dev->CMR = 0x30;
|
||||
} else {
|
||||
obj->dev->CMR = 0x21;
|
||||
}
|
||||
return 1;
|
||||
|
||||
} else if (CANStatus & 0x00000400) {
|
||||
obj->dev->TFI2 = buf[0] & 0xC00F0000;
|
||||
obj->dev->TID2 = buf[1];
|
||||
obj->dev->TDA2 = buf[2];
|
||||
obj->dev->TDB2 = buf[3];
|
||||
if (cc) {
|
||||
obj->dev->CMR = 0x50;
|
||||
} else {
|
||||
obj->dev->CMR = 0x41;
|
||||
}
|
||||
return 1;
|
||||
|
||||
} else if (CANStatus & 0x00040000) {
|
||||
obj->dev->TFI3 = buf[0] & 0xC00F0000;
|
||||
obj->dev->TID3 = buf[1];
|
||||
obj->dev->TDA3 = buf[2];
|
||||
obj->dev->TDB3 = buf[3];
|
||||
if (cc) {
|
||||
obj->dev->CMR = 0x90;
|
||||
} else {
|
||||
obj->dev->CMR = 0x81;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int can_read(can_t *obj, CAN_Message *msg, int handle) {
|
||||
CANMsg x;
|
||||
unsigned int *i = (unsigned int *)&x;
|
||||
|
||||
can_enable(obj);
|
||||
|
||||
if (obj->dev->GSR & 0x1) {
|
||||
*i++ = obj->dev->RFS; // Frame
|
||||
*i++ = obj->dev->RID; // ID
|
||||
*i++ = obj->dev->RDA; // Data A
|
||||
*i++ = obj->dev->RDB; // Data B
|
||||
obj->dev->CMR = 0x04; // release receive buffer
|
||||
|
||||
msg->id = x.id;
|
||||
msg->len = x.dlc;
|
||||
msg->format = (x.type)? CANExtended : CANStandard;
|
||||
msg->type = (x.rtr)? CANRemote: CANData;
|
||||
memcpy(msg->data,x.data,x.dlc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void can_reset(can_t *obj) {
|
||||
can_disable(obj);
|
||||
obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset
|
||||
}
|
||||
|
||||
unsigned char can_rderror(can_t *obj) {
|
||||
return (obj->dev->GSR >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
unsigned char can_tderror(can_t *obj) {
|
||||
return (obj->dev->GSR >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
void can_monitor(can_t *obj, int silent) {
|
||||
uint32_t mod_mask = can_disable(obj);
|
||||
if (silent) {
|
||||
obj->dev->MOD |= (1 << 1);
|
||||
} else {
|
||||
obj->dev->MOD &= ~(1 << 1);
|
||||
}
|
||||
if (!(mod_mask & 1)) {
|
||||
can_enable(obj);
|
||||
}
|
||||
}
|
||||
|
||||
const PinMap *can_rd_pinmap()
|
||||
{
|
||||
return PinMap_CAN_TD;
|
||||
}
|
||||
|
||||
const PinMap *can_td_pinmap()
|
||||
{
|
||||
return PinMap_CAN_RD;
|
||||
}
|
|
@ -1,447 +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 "mbed_assert.h"
|
||||
#include "i2c_api.h"
|
||||
|
||||
#if DEVICE_I2C
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
static const PinMap PinMap_I2C_SDA[] = {
|
||||
{P0_0 , I2C_1, 3},
|
||||
{P0_10, I2C_2, 2},
|
||||
{P0_19, I2C_1, 3},
|
||||
{P0_27, I2C_0, 1},
|
||||
{P1_15, I2C_2, 3},
|
||||
{P1_30, I2C_0, 4},
|
||||
{P2_14, I2C_1, 2},
|
||||
{P2_30, I2C_2, 2},
|
||||
{P4_20, I2C_2, 4},
|
||||
{P5_2, I2C_0, 5},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_I2C_SCL[] = {
|
||||
{P0_1 , I2C_1, 3},
|
||||
{P0_11, I2C_2, 2},
|
||||
{P0_20, I2C_1, 3},
|
||||
{P0_28, I2C_0, 1},
|
||||
{P1_31, I2C_0, 4},
|
||||
{P2_15, I2C_1, 2},
|
||||
{P2_31, I2C_2, 2},
|
||||
{P4_21, I2C_2, 2},
|
||||
{P4_29, I2C_2, 4},
|
||||
{P5_3, I2C_0, 5},
|
||||
{NC , NC, 0}
|
||||
};
|
||||
|
||||
#define I2C_CONSET(x) (x->i2c->CONSET)
|
||||
#define I2C_CONCLR(x) (x->i2c->CONCLR)
|
||||
#define I2C_STAT(x) (x->i2c->STAT)
|
||||
#define I2C_DAT(x) (x->i2c->DAT)
|
||||
#define I2C_SCLL(x, val) (x->i2c->SCLL = val)
|
||||
#define I2C_SCLH(x, val) (x->i2c->SCLH = val)
|
||||
|
||||
static const uint32_t I2C_addr_offset[2][4] = {
|
||||
{0x0C, 0x20, 0x24, 0x28},
|
||||
{0x30, 0x34, 0x38, 0x3C}
|
||||
};
|
||||
|
||||
static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
|
||||
I2C_CONCLR(obj) = (start << 5)
|
||||
| (stop << 4)
|
||||
| (interrupt << 3)
|
||||
| (acknowledge << 2);
|
||||
}
|
||||
|
||||
static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
|
||||
I2C_CONSET(obj) = (start << 5)
|
||||
| (stop << 4)
|
||||
| (interrupt << 3)
|
||||
| (acknowledge << 2);
|
||||
}
|
||||
|
||||
// Clear the Serial Interrupt (SI)
|
||||
static inline void i2c_clear_SI(i2c_t *obj) {
|
||||
i2c_conclr(obj, 0, 0, 1, 0);
|
||||
}
|
||||
|
||||
static inline int i2c_status(i2c_t *obj) {
|
||||
return I2C_STAT(obj);
|
||||
}
|
||||
|
||||
// Wait until the Serial Interrupt (SI) is set
|
||||
static int i2c_wait_SI(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
while (!(I2C_CONSET(obj) & (1 << 3))) {
|
||||
timeout++;
|
||||
if (timeout > 100000) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void i2c_interface_enable(i2c_t *obj) {
|
||||
I2C_CONSET(obj) = 0x40;
|
||||
}
|
||||
|
||||
static inline void i2c_power_enable(i2c_t *obj) {
|
||||
switch ((int)obj->i2c) {
|
||||
case I2C_0: LPC_SC->PCONP |= 1 << 7; break;
|
||||
case I2C_1: LPC_SC->PCONP |= 1 << 19; break;
|
||||
case I2C_2: LPC_SC->PCONP |= 1 << 26; break;
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||
// determine the SPI to use
|
||||
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
|
||||
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
|
||||
obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
|
||||
MBED_ASSERT((int)obj->i2c != NC);
|
||||
|
||||
// enable power
|
||||
i2c_power_enable(obj);
|
||||
|
||||
// set default frequency at 100k
|
||||
i2c_frequency(obj, 100000);
|
||||
i2c_conclr(obj, 1, 1, 1, 1);
|
||||
i2c_interface_enable(obj);
|
||||
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
|
||||
// OpenDrain must explicitly be enabled for p0.0 and p0.1
|
||||
if (sda == P0_0) {
|
||||
pin_mode(sda, OpenDrain);
|
||||
}
|
||||
if (scl == P0_1) {
|
||||
pin_mode(scl, OpenDrain);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline int i2c_start(i2c_t *obj) {
|
||||
int status = 0;
|
||||
int isInterrupted = I2C_CONSET(obj) & (1 << 3);
|
||||
|
||||
// 8.1 Before master mode can be entered, I2CON must be initialised to:
|
||||
// - I2EN STA STO SI AA - -
|
||||
// - 1 0 0 x x - -
|
||||
// if AA = 0, it can't enter slave mode
|
||||
i2c_conclr(obj, 1, 1, 0, 1);
|
||||
|
||||
// The master mode may now be entered by setting the STA bit
|
||||
// this will generate a start condition when the bus becomes free
|
||||
i2c_conset(obj, 1, 0, 0, 1);
|
||||
// Clearing SI bit when it wasn't set on entry can jump past state
|
||||
// 0x10 or 0x08 and erroneously send uninitialized slave address.
|
||||
if (isInterrupted)
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
i2c_wait_SI(obj);
|
||||
status = i2c_status(obj);
|
||||
|
||||
// Clear start bit now that it's transmitted
|
||||
i2c_conclr(obj, 1, 0, 0, 0);
|
||||
return status;
|
||||
}
|
||||
|
||||
inline int i2c_stop(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
// write the stop bit
|
||||
i2c_conset(obj, 0, 1, 0, 0);
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
// wait for STO bit to reset
|
||||
while(I2C_CONSET(obj) & (1 << 4)) {
|
||||
timeout ++;
|
||||
if (timeout > 100000) return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
|
||||
// write the data
|
||||
I2C_DAT(obj) = value;
|
||||
|
||||
// clear SI to init a send
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
// wait and return status
|
||||
i2c_wait_SI(obj);
|
||||
return i2c_status(obj);
|
||||
}
|
||||
|
||||
static inline int i2c_do_read(i2c_t *obj, int last) {
|
||||
// we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack)
|
||||
if(last) {
|
||||
i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK
|
||||
} else {
|
||||
i2c_conset(obj, 0, 0, 0, 1); // send a ACK
|
||||
}
|
||||
|
||||
// accept byte
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
// wait for it to arrive
|
||||
i2c_wait_SI(obj);
|
||||
|
||||
// return the data
|
||||
return (I2C_DAT(obj) & 0xFF);
|
||||
}
|
||||
|
||||
void i2c_frequency(i2c_t *obj, int hz) {
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
uint32_t pulse = PCLK / (hz * 2);
|
||||
|
||||
// I2C Rate
|
||||
I2C_SCLL(obj, pulse);
|
||||
I2C_SCLH(obj, pulse);
|
||||
}
|
||||
|
||||
// The I2C does a read or a write as a whole operation
|
||||
// There are two types of error conditions it can encounter
|
||||
// 1) it can not obtain the bus
|
||||
// 2) it gets error responses at part of the transmission
|
||||
//
|
||||
// We tackle them as follows:
|
||||
// 1) we retry until we get the bus. we could have a "timeout" if we can not get it
|
||||
// which basically turns it in to a 2)
|
||||
// 2) on error, we use the standard error mechanisms to report/debug
|
||||
//
|
||||
// Therefore an I2C transaction should always complete. If it doesn't it is usually
|
||||
// because something is setup wrong (e.g. wiring), and we don't need to programatically
|
||||
// check for that
|
||||
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
||||
int count, status;
|
||||
|
||||
status = i2c_start(obj);
|
||||
|
||||
if ((status != 0x10) && (status != 0x08)) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
|
||||
status = i2c_do_write(obj, (address | 0x01), 1);
|
||||
if (status != 0x40) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
// Read in all except last byte
|
||||
for (count = 0; count < (length - 1); count++) {
|
||||
int value = i2c_do_read(obj, 0);
|
||||
status = i2c_status(obj);
|
||||
if (status != 0x50) {
|
||||
i2c_stop(obj);
|
||||
return count;
|
||||
}
|
||||
data[count] = (char) value;
|
||||
}
|
||||
|
||||
// read in last byte
|
||||
int value = i2c_do_read(obj, 1);
|
||||
status = i2c_status(obj);
|
||||
if (status != 0x58) {
|
||||
i2c_stop(obj);
|
||||
return length - 1;
|
||||
}
|
||||
|
||||
data[count] = (char) value;
|
||||
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
||||
int i, status;
|
||||
|
||||
status = i2c_start(obj);
|
||||
|
||||
if ((status != 0x10) && (status != 0x08)) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
|
||||
status = i2c_do_write(obj, (address & 0xFE), 1);
|
||||
if (status != 0x18) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
for (i=0; i<length; i++) {
|
||||
status = i2c_do_write(obj, data[i], 0);
|
||||
if (status != 0x28) {
|
||||
i2c_stop(obj);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// clearing the serial interrupt here might cause an unintended rewrite of the last byte
|
||||
// see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1
|
||||
// i2c_clear_SI(obj);
|
||||
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void i2c_reset(i2c_t *obj) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
int i2c_byte_read(i2c_t *obj, int last) {
|
||||
return (i2c_do_read(obj, last) & 0xFF);
|
||||
}
|
||||
|
||||
int i2c_byte_write(i2c_t *obj, int data) {
|
||||
int ack;
|
||||
int status = i2c_do_write(obj, (data & 0xFF), 0);
|
||||
|
||||
switch(status) {
|
||||
case 0x18: case 0x28: // Master transmit ACKs
|
||||
ack = 1;
|
||||
break;
|
||||
|
||||
case 0x40: // Master receive address transmitted ACK
|
||||
ack = 1;
|
||||
break;
|
||||
|
||||
case 0xB8: // Slave transmit ACK
|
||||
ack = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ack = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ack;
|
||||
}
|
||||
|
||||
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
|
||||
if (enable_slave != 0) {
|
||||
i2c_conclr(obj, 1, 1, 1, 0);
|
||||
i2c_conset(obj, 0, 0, 0, 1);
|
||||
} else {
|
||||
i2c_conclr(obj, 1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int i2c_slave_receive(i2c_t *obj) {
|
||||
int status;
|
||||
int retval;
|
||||
|
||||
status = i2c_status(obj);
|
||||
switch(status) {
|
||||
case 0x60: retval = 3; break;
|
||||
case 0x70: retval = 2; break;
|
||||
case 0xA8: retval = 1; break;
|
||||
default : retval = 0; break;
|
||||
}
|
||||
|
||||
return(retval);
|
||||
}
|
||||
|
||||
int i2c_slave_read(i2c_t *obj, char *data, int length) {
|
||||
int count = 0;
|
||||
int status;
|
||||
|
||||
do {
|
||||
i2c_clear_SI(obj);
|
||||
i2c_wait_SI(obj);
|
||||
status = i2c_status(obj);
|
||||
if((status == 0x80) || (status == 0x90)) {
|
||||
data[count] = I2C_DAT(obj) & 0xFF;
|
||||
}
|
||||
count++;
|
||||
} while (((status == 0x80) || (status == 0x90) ||
|
||||
(status == 0x060) || (status == 0x70)) && (count < length));
|
||||
|
||||
if(status != 0xA0) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
|
||||
int count = 0;
|
||||
int status;
|
||||
|
||||
if(length <= 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
do {
|
||||
status = i2c_do_write(obj, data[count], 0);
|
||||
count++;
|
||||
} while ((count < length) && (status == 0xB8));
|
||||
|
||||
if((status != 0xC0) && (status != 0xC8)) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
|
||||
uint32_t addr;
|
||||
|
||||
if ((idx >= 0) && (idx <= 3)) {
|
||||
addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx];
|
||||
*((uint32_t *) addr) = address & 0xFF;
|
||||
addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx];
|
||||
*((uint32_t *) addr) = mask & 0xFE;
|
||||
}
|
||||
}
|
||||
|
||||
const PinMap *i2c_master_sda_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SDA;
|
||||
}
|
||||
|
||||
const PinMap *i2c_master_scl_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SCL;
|
||||
}
|
||||
|
||||
const PinMap *i2c_slave_sda_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SDA;
|
||||
}
|
||||
|
||||
const PinMap *i2c_slave_scl_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SCL;
|
||||
}
|
||||
|
||||
#endif // #if DEVICE_I2C
|
|
@ -1,194 +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 "mbed_assert.h"
|
||||
#include "pwmout_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
#define TCR_CNT_EN 0x00000001
|
||||
#define TCR_RESET 0x00000002
|
||||
|
||||
// PORT ID, PWM ID, Pin function
|
||||
static const PinMap PinMap_PWM[] = {
|
||||
{P1_2, PWM0_1, 3},
|
||||
{P1_3, PWM0_2, 3},
|
||||
{P1_5, PWM0_3, 3},
|
||||
{P1_6, PWM0_4, 3},
|
||||
{P1_7, PWM0_5, 3},
|
||||
{P1_11, PWM0_6, 3},
|
||||
{P1_18, PWM1_1, 2},
|
||||
{P1_20, PWM1_2, 2},
|
||||
{P1_21, PWM1_3, 2},
|
||||
{P1_23, PWM1_4, 2},
|
||||
{P1_24, PWM1_5, 2},
|
||||
{P1_26, PWM1_6, 2},
|
||||
{P2_0, PWM1_1, 1},
|
||||
{P2_1, PWM1_2, 1},
|
||||
{P2_2, PWM1_3, 1},
|
||||
{P2_3, PWM1_4, 1},
|
||||
{P2_4, PWM1_5, 1},
|
||||
{P2_5, PWM1_6, 1},
|
||||
{P3_16, PWM0_1, 2},
|
||||
{P3_17, PWM0_2, 2},
|
||||
{P3_18, PWM0_3, 2},
|
||||
{P3_19, PWM0_4, 2},
|
||||
{P3_20, PWM0_5, 2},
|
||||
{P3_21, PWM0_6, 2},
|
||||
{P3_24, PWM1_1, 2},
|
||||
{P3_25, PWM1_2, 2},
|
||||
{P3_26, PWM1_3, 2},
|
||||
{P3_27, PWM1_4, 2},
|
||||
{P3_28, PWM1_5, 2},
|
||||
{P3_29, PWM1_6, 2},
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
static const uint32_t PWM_mr_offset[7] = {
|
||||
0x18, 0x1C, 0x20, 0x24, 0x40, 0x44, 0x48
|
||||
};
|
||||
|
||||
#define TCR_PWM_EN 0x00000008
|
||||
static unsigned int pwm_clock_mhz;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
||||
obj->channel = pwm;
|
||||
obj->pwm = LPC_PWM0;
|
||||
|
||||
if (obj->channel > 6) { // PWM1 is used if pwm > 6
|
||||
obj->channel -= 6;
|
||||
obj->pwm = LPC_PWM1;
|
||||
}
|
||||
|
||||
obj->MR = (__IO uint32_t *)((uint32_t)obj->pwm + PWM_mr_offset[obj->channel]);
|
||||
|
||||
// ensure the power is on
|
||||
if (obj->pwm == LPC_PWM0) {
|
||||
LPC_SC->PCONP |= 1 << 5;
|
||||
} else {
|
||||
LPC_SC->PCONP |= 1 << 6;
|
||||
}
|
||||
|
||||
obj->pwm->PR = 0; // no pre-scale
|
||||
|
||||
// ensure single PWM mode
|
||||
obj->pwm->MCR = 1 << 1; // reset TC on match 0
|
||||
|
||||
// enable the specific PWM output
|
||||
obj->pwm->PCR |= 1 << (8 + obj->channel);
|
||||
|
||||
pwm_clock_mhz = PeripheralClock / 1000000;
|
||||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {
|
||||
// [TODO]
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
if (value < 0.0f) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0f) {
|
||||
value = 1.0;
|
||||
}
|
||||
|
||||
// set channel match to percentage
|
||||
uint32_t v = (uint32_t)((float)(obj->pwm->MR0) * value);
|
||||
|
||||
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
|
||||
if (v == obj->pwm->MR0) {
|
||||
v++;
|
||||
}
|
||||
|
||||
*obj->MR = v;
|
||||
|
||||
// accept on next period start
|
||||
obj->pwm->LER |= 1 << obj->channel;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
float v = (float)(*obj->MR) / (float)(obj->pwm->MR0);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
// calculate number of ticks
|
||||
uint32_t ticks = pwm_clock_mhz * us;
|
||||
|
||||
// set reset
|
||||
obj->pwm->TCR = TCR_RESET;
|
||||
|
||||
// set the global match register
|
||||
obj->pwm->MR0 = ticks;
|
||||
|
||||
// Scale the pulse width to preserve the duty ratio
|
||||
if (obj->pwm->MR0 > 0) {
|
||||
*obj->MR = (*obj->MR * ticks) / obj->pwm->MR0;
|
||||
}
|
||||
|
||||
// set the channel latch to update value at next period start
|
||||
obj->pwm->LER |= 1 << 0;
|
||||
|
||||
// enable counter and pwm, clear reset
|
||||
obj->pwm->TCR = TCR_CNT_EN | TCR_PWM_EN;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
// calculate number of ticks
|
||||
uint32_t v = pwm_clock_mhz * us;
|
||||
|
||||
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
|
||||
if (v == obj->pwm->MR0) {
|
||||
v++;
|
||||
}
|
||||
|
||||
// set the match register value
|
||||
*obj->MR = v;
|
||||
|
||||
// set the channel latch to update value at next period start
|
||||
obj->pwm->LER |= 1 << obj->channel;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
}
|
|
@ -1,362 +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.
|
||||
*/
|
||||
// math.h required for floating point operations for baud rate calculation
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "serial_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
/******************************************************************************
|
||||
* INITIALIZATION
|
||||
******************************************************************************/
|
||||
static const PinMap PinMap_UART_TX[] = {
|
||||
{P0_0, UART_3, 2},
|
||||
{P0_2, UART_0, 1},
|
||||
{P0_10, UART_2, 1},
|
||||
{P0_15, UART_1, 1},
|
||||
{P1_29, UART_4, 5},
|
||||
{P0_25, UART_3, 3},
|
||||
{P2_0 , UART_1, 2},
|
||||
{P2_8 , UART_2, 2},
|
||||
{P3_16, UART_1, 3},
|
||||
{P4_22, UART_2, 2},
|
||||
{P4_28, UART_3, 2},
|
||||
{P5_4, UART_4, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_RX[] = {
|
||||
{P0_1 , UART_3, 2},
|
||||
{P0_3 , UART_0, 1},
|
||||
{P0_11, UART_2, 1},
|
||||
{P0_16, UART_1, 1},
|
||||
{P0_26, UART_3, 3},
|
||||
{P2_1 , UART_1, 2},
|
||||
{P2_9 , UART_2, 2},
|
||||
{P3_17, UART_1, 3},
|
||||
{P4_23, UART_2, 2},
|
||||
{P4_29, UART_3, 2},
|
||||
{P5_3, UART_4, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
#define UART_NUM 5
|
||||
|
||||
static uint32_t serial_irq_ids[UART_NUM] = {0};
|
||||
static uart_irq_handler irq_handler;
|
||||
|
||||
int stdio_uart_inited = 0;
|
||||
serial_t stdio_uart;
|
||||
|
||||
void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
||||
int is_stdio_uart = 0;
|
||||
|
||||
// determine the UART to use
|
||||
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
|
||||
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
|
||||
UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
|
||||
MBED_ASSERT((int)uart != NC);
|
||||
|
||||
obj->uart = (LPC_UART_TypeDef *)uart;
|
||||
// enable power
|
||||
switch (uart) {
|
||||
case UART_0: LPC_SC->PCONP |= 1 << 3; break;
|
||||
case UART_1: LPC_SC->PCONP |= 1 << 4; break;
|
||||
case UART_2: LPC_SC->PCONP |= 1 << 24; break;
|
||||
case UART_3: LPC_SC->PCONP |= 1 << 25; break;
|
||||
case UART_4: LPC_SC->PCONP |= 1 << 8; break;
|
||||
}
|
||||
|
||||
// enable fifos and default rx trigger level
|
||||
obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
|
||||
| 0 << 1 // Rx Fifo Reset
|
||||
| 0 << 2 // Tx Fifo Reset
|
||||
| 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
|
||||
|
||||
// disable irqs
|
||||
obj->uart->IER = 0 << 0 // Rx Data available irq enable
|
||||
| 0 << 1 // Tx Fifo empty irq enable
|
||||
| 0 << 2; // Rx Line Status irq enable
|
||||
|
||||
// set default baud rate and format
|
||||
serial_baud (obj, 9600);
|
||||
serial_format(obj, 8, ParityNone, 1);
|
||||
|
||||
// pinout the chosen uart
|
||||
pinmap_pinout(tx, PinMap_UART_TX);
|
||||
pinmap_pinout(rx, PinMap_UART_RX);
|
||||
|
||||
// set rx/tx pins in PullUp mode
|
||||
if (tx != NC) {
|
||||
pin_mode(tx, PullUp);
|
||||
}
|
||||
if (rx != NC) {
|
||||
pin_mode(rx, PullUp);
|
||||
}
|
||||
|
||||
switch (uart) {
|
||||
case UART_0: obj->index = 0; break;
|
||||
case UART_1: obj->index = 1; break;
|
||||
case UART_2: obj->index = 2; break;
|
||||
case UART_3: obj->index = 3; break;
|
||||
case UART_4: obj->index = 4; break;
|
||||
}
|
||||
|
||||
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
|
||||
|
||||
if (is_stdio_uart) {
|
||||
stdio_uart_inited = 1;
|
||||
memcpy(&stdio_uart, obj, sizeof(serial_t));
|
||||
}
|
||||
}
|
||||
|
||||
void serial_free(serial_t *obj) {
|
||||
serial_irq_ids[obj->index] = 0;
|
||||
}
|
||||
|
||||
// serial_baud
|
||||
// set the baud rate, taking in to account the current SystemFrequency
|
||||
void serial_baud(serial_t *obj, int baudrate) {
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
|
||||
// First we check to see if the basic divide with no DivAddVal/MulVal
|
||||
// ratio gives us an integer result. If it does, we set DivAddVal = 0,
|
||||
// MulVal = 1. Otherwise, we search the valid ratio value range to find
|
||||
// the closest match. This could be more elegant, using search methods
|
||||
// and/or lookup tables, but the brute force method is not that much
|
||||
// slower, and is more maintainable.
|
||||
uint16_t DL = PCLK / (16 * baudrate);
|
||||
|
||||
uint8_t DivAddVal = 0;
|
||||
uint8_t MulVal = 1;
|
||||
int hit = 0;
|
||||
uint16_t dlv;
|
||||
uint8_t mv, dav;
|
||||
if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder
|
||||
int err_best = baudrate, b;
|
||||
for (mv = 1; mv < 16 && !hit; mv++)
|
||||
{
|
||||
for (dav = 0; dav < mv; dav++)
|
||||
{
|
||||
// baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul))
|
||||
// solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul))
|
||||
// mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding
|
||||
// for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision
|
||||
// note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding
|
||||
|
||||
if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom
|
||||
dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2;
|
||||
else // 2 bits headroom, use more precision
|
||||
dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2;
|
||||
|
||||
// datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood
|
||||
if (dlv == 0)
|
||||
dlv = 1;
|
||||
|
||||
// datasheet says if dav > 0 then DL must be >= 2
|
||||
if ((dav > 0) && (dlv < 2))
|
||||
dlv = 2;
|
||||
|
||||
// integer rearrangement of the baudrate equation (with rounding)
|
||||
b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2;
|
||||
|
||||
// check to see how we went
|
||||
b = abs(b - baudrate);
|
||||
if (b < err_best)
|
||||
{
|
||||
err_best = b;
|
||||
|
||||
DL = dlv;
|
||||
MulVal = mv;
|
||||
DivAddVal = dav;
|
||||
|
||||
if (b == baudrate)
|
||||
{
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set LCR[DLAB] to enable writing to divider registers
|
||||
obj->uart->LCR |= (1 << 7);
|
||||
|
||||
// set divider values
|
||||
obj->uart->DLM = (DL >> 8) & 0xFF;
|
||||
obj->uart->DLL = (DL >> 0) & 0xFF;
|
||||
obj->uart->FDR = (uint32_t) DivAddVal << 0
|
||||
| (uint32_t) MulVal << 4;
|
||||
|
||||
// clear LCR[DLAB]
|
||||
obj->uart->LCR &= ~(1 << 7);
|
||||
}
|
||||
|
||||
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
|
||||
MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
|
||||
MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits
|
||||
MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
|
||||
(parity == ParityForced1) || (parity == ParityForced0));
|
||||
|
||||
stop_bits -= 1;
|
||||
data_bits -= 5;
|
||||
|
||||
int parity_enable = 0, parity_select = 0;
|
||||
switch (parity) {
|
||||
case ParityNone: parity_enable = 0; parity_select = 0; break;
|
||||
case ParityOdd : parity_enable = 1; parity_select = 0; break;
|
||||
case ParityEven: parity_enable = 1; parity_select = 1; break;
|
||||
case ParityForced1: parity_enable = 1; parity_select = 2; break;
|
||||
case ParityForced0: parity_enable = 1; parity_select = 3; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
obj->uart->LCR = data_bits << 0
|
||||
| stop_bits << 2
|
||||
| parity_enable << 3
|
||||
| parity_select << 4;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* INTERRUPTS HANDLING
|
||||
******************************************************************************/
|
||||
static inline void uart_irq(uint32_t iir, uint32_t index) {
|
||||
// [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling
|
||||
SerialIrq irq_type;
|
||||
switch (iir) {
|
||||
case 1: irq_type = TxIrq; break;
|
||||
case 2: irq_type = RxIrq; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (serial_irq_ids[index] != 0)
|
||||
irq_handler(serial_irq_ids[index], irq_type);
|
||||
}
|
||||
|
||||
void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);}
|
||||
void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);}
|
||||
void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);}
|
||||
void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);}
|
||||
void uart4_irq() {uart_irq((LPC_UART4->IIR >> 1) & 0x7, 4);}
|
||||
|
||||
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
|
||||
irq_handler = handler;
|
||||
serial_irq_ids[obj->index] = id;
|
||||
}
|
||||
|
||||
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
||||
IRQn_Type irq_n = (IRQn_Type)0;
|
||||
uint32_t vector = 0;
|
||||
switch ((int)obj->uart) {
|
||||
case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
|
||||
case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
|
||||
case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
|
||||
case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break;
|
||||
case UART_4: irq_n=UART4_IRQn; vector = (uint32_t)&uart4_irq; break;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
obj->uart->IER |= 1 << irq;
|
||||
NVIC_SetVector(irq_n, vector);
|
||||
NVIC_EnableIRQ(irq_n);
|
||||
} else { // disable
|
||||
int all_disabled = 0;
|
||||
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
|
||||
obj->uart->IER &= ~(1 << irq);
|
||||
all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
|
||||
if (all_disabled)
|
||||
NVIC_DisableIRQ(irq_n);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* READ/WRITE
|
||||
******************************************************************************/
|
||||
int serial_getc(serial_t *obj) {
|
||||
while (!serial_readable(obj));
|
||||
return obj->uart->RBR;
|
||||
}
|
||||
|
||||
void serial_putc(serial_t *obj, int c) {
|
||||
while (!serial_writable(obj));
|
||||
obj->uart->THR = c;
|
||||
}
|
||||
|
||||
int serial_readable(serial_t *obj) {
|
||||
return obj->uart->LSR & 0x01;
|
||||
}
|
||||
|
||||
int serial_writable(serial_t *obj) {
|
||||
return obj->uart->LSR & 0x20;
|
||||
}
|
||||
|
||||
void serial_clear(serial_t *obj) {
|
||||
obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
|
||||
| 1 << 1 // rx FIFO reset
|
||||
| 1 << 2 // tx FIFO reset
|
||||
| 0 << 6; // interrupt depth
|
||||
}
|
||||
|
||||
void serial_pinout_tx(PinName tx) {
|
||||
pinmap_pinout(tx, PinMap_UART_TX);
|
||||
}
|
||||
|
||||
void serial_break_set(serial_t *obj) {
|
||||
obj->uart->LCR |= (1 << 6);
|
||||
}
|
||||
|
||||
void serial_break_clear(serial_t *obj) {
|
||||
obj->uart->LCR &= ~(1 << 6);
|
||||
}
|
||||
|
||||
const PinMap *serial_tx_pinmap()
|
||||
{
|
||||
return PinMap_UART_TX;
|
||||
}
|
||||
|
||||
const PinMap *serial_rx_pinmap()
|
||||
{
|
||||
return PinMap_UART_RX;
|
||||
}
|
||||
|
||||
const PinMap *serial_cts_pinmap()
|
||||
{
|
||||
#if !DEVICE_SERIAL_FC
|
||||
static const PinMap PinMap_UART_CTS[] = {
|
||||
{NC, NC, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
return PinMap_UART_CTS;
|
||||
}
|
||||
|
||||
const PinMap *serial_rts_pinmap()
|
||||
{
|
||||
#if !DEVICE_SERIAL_FC
|
||||
static const PinMap PinMap_UART_RTS[] = {
|
||||
{NC, NC, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
return PinMap_UART_RTS;
|
||||
}
|
||||
|
|
@ -1,271 +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 <math.h>
|
||||
|
||||
#include "spi_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
static const PinMap PinMap_SPI_SCLK[] = {
|
||||
{P0_7 , SPI_1, 2},
|
||||
{P0_15, SPI_0, 2},
|
||||
{P1_0, SPI_2, 4},
|
||||
{P1_19, SPI_1, 5},
|
||||
{P1_20, SPI_0, 5},
|
||||
{P1_31, SPI_1, 2},
|
||||
{P2_22, SPI_0, 2},
|
||||
{P4_20, SPI_1, 3},
|
||||
{P5_2, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MOSI[] = {
|
||||
{P0_9 , SPI_1, 2},
|
||||
{P0_13, SPI_1, 2},
|
||||
{P0_18, SPI_0, 2},
|
||||
{P1_1, SPI_2, 4},
|
||||
{P1_22, SPI_1, 5},
|
||||
{P1_24, SPI_0, 5},
|
||||
{P2_27, SPI_0, 2},
|
||||
{P4_23, SPI_1, 3},
|
||||
{P5_0, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MISO[] = {
|
||||
{P0_8 , SPI_1, 2},
|
||||
{P0_12, SPI_1, 2},
|
||||
{P0_17, SPI_0, 2},
|
||||
{P1_4, SPI_2, 4},
|
||||
{P1_18, SPI_1, 5},
|
||||
{P1_23, SPI_0, 5},
|
||||
{P2_26, SPI_0, 2},
|
||||
{P4_22, SPI_1, 3},
|
||||
{P5_1, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_SSEL[] = {
|
||||
{P0_6 , SPI_1, 2},
|
||||
{P0_14, SPI_1, 2},
|
||||
{P0_16, SPI_0, 2},
|
||||
{P1_8, SPI_2, 4},
|
||||
{P1_21, SPI_0, 3},
|
||||
{P1_26, SPI_1, 5},
|
||||
{P1_28, SPI_0, 5},
|
||||
{P2_23, SPI_0, 2},
|
||||
{P4_21, SPI_1, 3},
|
||||
{P5_3, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static inline int ssp_disable(spi_t *obj);
|
||||
static inline int ssp_enable(spi_t *obj);
|
||||
|
||||
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
|
||||
// determine the SPI to use
|
||||
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
|
||||
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
|
||||
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
|
||||
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
|
||||
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
|
||||
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
|
||||
obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
|
||||
MBED_ASSERT((int)obj->spi != NC);
|
||||
|
||||
// enable power and clocking
|
||||
switch ((int)obj->spi) {
|
||||
case SPI_0: LPC_SC->PCONP |= 1 << 21; break;
|
||||
case SPI_1: LPC_SC->PCONP |= 1 << 10; break;
|
||||
case SPI_2: LPC_SC->PCONP |= 1 << 20; break;
|
||||
}
|
||||
|
||||
// pin out the spi pins
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
pinmap_pinout(miso, PinMap_SPI_MISO);
|
||||
pinmap_pinout(sclk, PinMap_SPI_SCLK);
|
||||
if (ssel != NC) {
|
||||
pinmap_pinout(ssel, PinMap_SPI_SSEL);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_free(spi_t *obj) {}
|
||||
|
||||
void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
||||
MBED_ASSERT(((bits >= 4) && (bits <= 16)) && ((mode >= 0) && (mode <= 3)));
|
||||
ssp_disable(obj);
|
||||
|
||||
int polarity = (mode & 0x2) ? 1 : 0;
|
||||
int phase = (mode & 0x1) ? 1 : 0;
|
||||
|
||||
// set it up
|
||||
int DSS = bits - 1; // DSS (data select size)
|
||||
int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
|
||||
int SPH = (phase) ? 1 : 0; // SPH - clock out phase
|
||||
|
||||
int FRF = 0; // FRF (frame format) = SPI
|
||||
uint32_t tmp = obj->spi->CR0;
|
||||
tmp &= ~(0x00FF); // Clear DSS, FRF, CPOL and CPHA [7:0]
|
||||
tmp |= DSS << 0
|
||||
| FRF << 4
|
||||
| SPO << 6
|
||||
| SPH << 7;
|
||||
obj->spi->CR0 = tmp;
|
||||
|
||||
tmp = obj->spi->CR1;
|
||||
tmp &= ~(0xD);
|
||||
tmp |= 0 << 0 // LBM - loop back mode - off
|
||||
| ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave
|
||||
| 0 << 3; // SOD - slave output disable - na
|
||||
obj->spi->CR1 = tmp;
|
||||
ssp_enable(obj);
|
||||
}
|
||||
|
||||
void spi_frequency(spi_t *obj, int hz) {
|
||||
ssp_disable(obj);
|
||||
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
|
||||
int prescaler;
|
||||
|
||||
for (prescaler = 2; prescaler <= 254; prescaler += 2) {
|
||||
int prescale_hz = PCLK / prescaler;
|
||||
|
||||
// calculate the divider
|
||||
int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
|
||||
|
||||
// check we can support the divider
|
||||
if (divider < 256) {
|
||||
// prescaler
|
||||
obj->spi->CPSR = prescaler;
|
||||
|
||||
// divider
|
||||
obj->spi->CR0 &= ~(0xFF00); // Clear SCR: Serial clock rate [15:8]
|
||||
obj->spi->CR0 |= (divider - 1) << 8;
|
||||
ssp_enable(obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
error("Couldn't setup requested SPI frequency");
|
||||
}
|
||||
|
||||
static inline int ssp_disable(spi_t *obj) {
|
||||
return obj->spi->CR1 &= ~(1 << 1);
|
||||
}
|
||||
|
||||
static inline int ssp_enable(spi_t *obj) {
|
||||
return obj->spi->CR1 |= (1 << 1);
|
||||
}
|
||||
|
||||
static inline int ssp_readable(spi_t *obj) {
|
||||
return obj->spi->SR & (1 << 2);
|
||||
}
|
||||
|
||||
static inline int ssp_writeable(spi_t *obj) {
|
||||
return obj->spi->SR & (1 << 1);
|
||||
}
|
||||
|
||||
static inline void ssp_write(spi_t *obj, int value) {
|
||||
while (!ssp_writeable(obj));
|
||||
obj->spi->DR = value;
|
||||
}
|
||||
|
||||
static inline int ssp_read(spi_t *obj) {
|
||||
while (!ssp_readable(obj));
|
||||
return obj->spi->DR;
|
||||
}
|
||||
|
||||
static inline int ssp_busy(spi_t *obj) {
|
||||
return (obj->spi->SR & (1 << 4)) ? (1) : (0);
|
||||
}
|
||||
|
||||
int spi_master_write(spi_t *obj, int value) {
|
||||
ssp_write(obj, value);
|
||||
return ssp_read(obj);
|
||||
}
|
||||
|
||||
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
|
||||
char *rx_buffer, int rx_length, char write_fill) {
|
||||
int total = (tx_length > rx_length) ? tx_length : rx_length;
|
||||
|
||||
for (int i = 0; i < total; i++) {
|
||||
char out = (i < tx_length) ? tx_buffer[i] : write_fill;
|
||||
char in = spi_master_write(obj, out);
|
||||
if (i < rx_length) {
|
||||
rx_buffer[i] = in;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int spi_slave_receive(spi_t *obj) {
|
||||
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
|
||||
}
|
||||
|
||||
int spi_slave_read(spi_t *obj) {
|
||||
return obj->spi->DR;
|
||||
}
|
||||
|
||||
void spi_slave_write(spi_t *obj, int value) {
|
||||
while (ssp_writeable(obj) == 0) ;
|
||||
obj->spi->DR = value;
|
||||
}
|
||||
|
||||
int spi_busy(spi_t *obj) {
|
||||
return ssp_busy(obj);
|
||||
}
|
||||
|
||||
const PinMap *spi_master_mosi_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MOSI;
|
||||
}
|
||||
|
||||
const PinMap *spi_master_miso_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MISO;
|
||||
}
|
||||
|
||||
const PinMap *spi_master_clk_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SCLK;
|
||||
}
|
||||
|
||||
const PinMap *spi_master_cs_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SSEL;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_mosi_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MOSI;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_miso_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MISO;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_clk_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SCLK;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_cs_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SSEL;
|
||||
}
|
|
@ -1,111 +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.
|
||||
*/
|
||||
#ifndef MBED_PERIPHERALNAMES_H
|
||||
#define MBED_PERIPHERALNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UART_0 = (int)LPC_UART0_BASE,
|
||||
UART_1 = (int)LPC_UART1_BASE,
|
||||
UART_2 = (int)LPC_UART2_BASE,
|
||||
UART_3 = (int)LPC_UART3_BASE,
|
||||
UART_4 = (int)LPC_UART4_BASE
|
||||
} UARTName;
|
||||
|
||||
typedef enum {
|
||||
ADC0_0 = 0,
|
||||
ADC0_1,
|
||||
ADC0_2,
|
||||
ADC0_3,
|
||||
ADC0_4,
|
||||
ADC0_5,
|
||||
ADC0_6,
|
||||
ADC0_7
|
||||
} ADCName;
|
||||
|
||||
typedef enum {
|
||||
DAC_0 = 0
|
||||
} DACName;
|
||||
|
||||
typedef enum {
|
||||
SPI_0 = (int)LPC_SSP0_BASE,
|
||||
SPI_1 = (int)LPC_SSP1_BASE,
|
||||
SPI_2 = (int)LPC_SSP2_BASE
|
||||
} SPIName;
|
||||
|
||||
typedef enum {
|
||||
I2C_0 = (int)LPC_I2C0_BASE,
|
||||
I2C_1 = (int)LPC_I2C1_BASE,
|
||||
I2C_2 = (int)LPC_I2C2_BASE
|
||||
} I2CName;
|
||||
|
||||
typedef enum {
|
||||
PWM0_1 = 1,
|
||||
PWM0_2,
|
||||
PWM0_3,
|
||||
PWM0_4,
|
||||
PWM0_5,
|
||||
PWM0_6,
|
||||
PWM1_1,
|
||||
PWM1_2,
|
||||
PWM1_3,
|
||||
PWM1_4,
|
||||
PWM1_5,
|
||||
PWM1_6
|
||||
} PWMName;
|
||||
|
||||
typedef enum {
|
||||
CAN_1 = (int)LPC_CAN1_BASE,
|
||||
CAN_2 = (int)LPC_CAN2_BASE
|
||||
} CANName;
|
||||
|
||||
#define STDIO_UART_TX USBTX
|
||||
#define STDIO_UART_RX USBRX
|
||||
#define STDIO_UART UART_0
|
||||
|
||||
// Default peripherals
|
||||
#define MBED_SPI0 p7, p8, p9
|
||||
#define MBED_SPI1 p46, p44, p42, p45
|
||||
#define MBED_SPI2 p15, p16, p17, p18
|
||||
|
||||
#define MBED_UART3 p29, p30
|
||||
#define MBED_UART4 p19, p18
|
||||
#define MBED_UARTUSB USBTX, USBRX
|
||||
|
||||
#define MBED_I2C1 p12, p13
|
||||
|
||||
#define MBED_CAN1 p12, p13
|
||||
#define MBED_CAN2 p41, p43
|
||||
|
||||
#define MBED_ANALOGOUT0 p30
|
||||
|
||||
#define MBED_ANALOGIN2 p29
|
||||
#define MBED_ANALOGIN3 p30
|
||||
|
||||
#define MBED_PWMOUT0 p9
|
||||
#define MBED_PWMOUT1 p8
|
||||
#define MBED_PWMOUT2 p7
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,106 +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.
|
||||
*/
|
||||
#ifndef MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 5
|
||||
|
||||
typedef enum {
|
||||
// LPC Pin Names
|
||||
P0_0 = /*LPC_GPIO0_BASE*/0,
|
||||
P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31,
|
||||
P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31,
|
||||
P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31,
|
||||
P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31,
|
||||
P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31,
|
||||
P5_0, P5_1, P5_2, P5_3, P5_4,
|
||||
|
||||
// mbed DIP Pin Names
|
||||
p1 = P0_30,
|
||||
p2 = P2_14,
|
||||
p3 = P0_29,
|
||||
p4 = P2_15,
|
||||
|
||||
p7 = P1_24,
|
||||
p8 = P1_23,
|
||||
p9 = P1_20,
|
||||
p10 = P1_19,
|
||||
p11 = P0_21,
|
||||
p12 = P0_0,
|
||||
p13 = P0_1,
|
||||
p14 = P2_10,
|
||||
p15 = P5_0,
|
||||
p16 = P5_1,
|
||||
p17 = P5_2,
|
||||
p18 = P5_3,
|
||||
p19 = P5_4,
|
||||
p20 = P2_22,
|
||||
p21 = P2_23,
|
||||
p22 = P2_25,
|
||||
p23 = P2_26,
|
||||
p24 = P2_27,
|
||||
p25 = P0_2,
|
||||
p26 = P0_3,
|
||||
|
||||
p29 = P0_25,
|
||||
p30 = P0_26,
|
||||
|
||||
p41 = P0_4,
|
||||
p42 = P0_7,
|
||||
p43 = P0_5,
|
||||
p44 = P0_8,
|
||||
p45 = P0_6,
|
||||
p46 = P0_9,
|
||||
|
||||
// Other mbed Pin Names
|
||||
LED1 = P1_18,
|
||||
LED2 = P0_13,
|
||||
LED3 = P1_13,
|
||||
LED4 = P2_19,
|
||||
|
||||
USBTX = P0_2,
|
||||
USBRX = P0_3,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullUp = 2,
|
||||
PullDown = 1,
|
||||
PullNone = 0,
|
||||
OpenDrain = 4,
|
||||
PullDefault = PullDown
|
||||
} PinMode;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,124 +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 "mbed_assert.h"
|
||||
#include "analogin_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
#define ANALOGIN_MEDIAN_FILTER 1
|
||||
|
||||
#define ADC_10BIT_RANGE 0x3FF
|
||||
#define ADC_12BIT_RANGE 0xFFF
|
||||
|
||||
static inline int div_round_up(int x, int y) {
|
||||
return (x + (y - 1)) / y;
|
||||
}
|
||||
|
||||
static const PinMap PinMap_ADC[] = {
|
||||
{P0_25, ADC0_2, 0x01},
|
||||
{P0_26, ADC0_3, 0x01},
|
||||
{NC , NC , 0 }
|
||||
};
|
||||
|
||||
#define ADC_RANGE ADC_12BIT_RANGE
|
||||
|
||||
void analogin_init(analogin_t *obj, PinName pin) {
|
||||
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
|
||||
MBED_ASSERT(obj->adc != (ADCName)NC);
|
||||
|
||||
// ensure power is turned on
|
||||
LPC_SC->PCONP |= (1 << 12);
|
||||
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
|
||||
// calculate minimum clock divider
|
||||
// clkdiv = divider - 1
|
||||
uint32_t MAX_ADC_CLK = 12400000;
|
||||
uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
|
||||
|
||||
// Set the generic software-controlled ADC settings
|
||||
LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected
|
||||
| (clkdiv << 8) // CLKDIV:
|
||||
| (0 << 16) // BURST: 0 = software control
|
||||
| (1 << 21) // PDN: 1 = operational
|
||||
| (0 << 24) // START: 0 = no start
|
||||
| (0 << 27); // EDGE: not applicable
|
||||
|
||||
// must enable analog mode (ADMODE = 0)
|
||||
__IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
|
||||
*reg &= ~(1 << 7);
|
||||
|
||||
pinmap_pinout(pin, PinMap_ADC);
|
||||
}
|
||||
|
||||
static inline uint32_t adc_read(analogin_t *obj) {
|
||||
// Select the appropriate channel and start conversion
|
||||
LPC_ADC->CR &= ~0xFF;
|
||||
LPC_ADC->CR |= 1 << (int)obj->adc;
|
||||
LPC_ADC->CR |= 1 << 24;
|
||||
|
||||
// Repeatedly get the sample data until DONE bit
|
||||
unsigned int data;
|
||||
do {
|
||||
data = LPC_ADC->GDR;
|
||||
} while ((data & ((unsigned int)1 << 31)) == 0);
|
||||
|
||||
// Stop conversion
|
||||
LPC_ADC->CR &= ~(1 << 24);
|
||||
|
||||
return (data >> 4) & ADC_RANGE; // 12 bit
|
||||
}
|
||||
|
||||
static inline void order(uint32_t *a, uint32_t *b) {
|
||||
if (*a > *b) {
|
||||
uint32_t t = *a;
|
||||
*a = *b;
|
||||
*b = t;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t adc_read_u32(analogin_t *obj) {
|
||||
uint32_t value;
|
||||
#if ANALOGIN_MEDIAN_FILTER
|
||||
uint32_t v1 = adc_read(obj);
|
||||
uint32_t v2 = adc_read(obj);
|
||||
uint32_t v3 = adc_read(obj);
|
||||
order(&v1, &v2);
|
||||
order(&v2, &v3);
|
||||
order(&v1, &v2);
|
||||
value = v2;
|
||||
#else
|
||||
value = adc_read(obj);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t analogin_read_u16(analogin_t *obj) {
|
||||
uint32_t value = adc_read_u32(obj);
|
||||
|
||||
return (value << 4) | ((value >> 8) & 0x000F); // 12 bit
|
||||
}
|
||||
|
||||
float analogin_read(analogin_t *obj) {
|
||||
uint32_t value = adc_read_u32(obj);
|
||||
return (float)value * (1.0f / (float)ADC_RANGE);
|
||||
}
|
||||
|
||||
const PinMap *analogin_pinmap()
|
||||
{
|
||||
return PinMap_ADC;
|
||||
}
|
|
@ -1,402 +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 "can_api.h"
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CAN_NUM 2
|
||||
|
||||
/* Acceptance filter mode in AFMR register */
|
||||
#define ACCF_OFF 0x01
|
||||
#define ACCF_BYPASS 0x02
|
||||
#define ACCF_ON 0x00
|
||||
#define ACCF_FULLCAN 0x04
|
||||
|
||||
/* There are several bit timing calculators on the internet.
|
||||
http://www.port.de/engl/canprod/sv_req_form.html
|
||||
http://www.kvaser.com/can/index.htm
|
||||
*/
|
||||
|
||||
static const PinMap PinMap_CAN_RD[] = {
|
||||
{P0_0 , CAN_1, 1},
|
||||
{P0_4 , CAN_2, 2},
|
||||
{P0_21, CAN_1, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_CAN_TD[] = {
|
||||
{P0_1 , CAN_1, 1},
|
||||
{P0_5 , CAN_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
// Type definition to hold a CAN message
|
||||
struct CANMsg {
|
||||
unsigned int reserved1 : 16;
|
||||
unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter
|
||||
unsigned int reserved0 : 10;
|
||||
unsigned int rtr : 1; // Bit 30: Set if this is a RTR message
|
||||
unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message
|
||||
unsigned int id; // CAN Message ID (11-bit or 29-bit)
|
||||
unsigned char data[8]; // CAN Message Data Bytes 0-7
|
||||
};
|
||||
typedef struct CANMsg CANMsg;
|
||||
|
||||
static uint32_t can_irq_ids[CAN_NUM] = {0};
|
||||
static can_irq_handler irq_handler;
|
||||
|
||||
static uint32_t can_disable(can_t *obj) {
|
||||
uint32_t sm = obj->dev->MOD;
|
||||
obj->dev->MOD |= 1;
|
||||
return sm;
|
||||
}
|
||||
|
||||
static inline void can_enable(can_t *obj) {
|
||||
if (obj->dev->MOD & 1) {
|
||||
obj->dev->MOD &= ~(1);
|
||||
}
|
||||
}
|
||||
|
||||
int can_mode(can_t *obj, CanMode mode)
|
||||
{
|
||||
return 0; // not implemented
|
||||
}
|
||||
|
||||
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
|
||||
return 0; // not implemented
|
||||
}
|
||||
|
||||
static inline void can_irq(uint32_t icr, uint32_t index) {
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
if((can_irq_ids[index] != 0) && (icr & (1 << i)))
|
||||
{
|
||||
switch (i) {
|
||||
case 0: irq_handler(can_irq_ids[index], IRQ_RX); break;
|
||||
case 1: irq_handler(can_irq_ids[index], IRQ_TX); break;
|
||||
case 2: irq_handler(can_irq_ids[index], IRQ_ERROR); break;
|
||||
case 3: irq_handler(can_irq_ids[index], IRQ_OVERRUN); break;
|
||||
case 4: irq_handler(can_irq_ids[index], IRQ_WAKEUP); break;
|
||||
case 5: irq_handler(can_irq_ids[index], IRQ_PASSIVE); break;
|
||||
case 6: irq_handler(can_irq_ids[index], IRQ_ARB); break;
|
||||
case 7: irq_handler(can_irq_ids[index], IRQ_BUS); break;
|
||||
case 8: irq_handler(can_irq_ids[index], IRQ_READY); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Have to check that the CAN block is active before reading the Interrupt
|
||||
// Control Register, or the mbed hangs
|
||||
void can_irq_n() {
|
||||
uint32_t icr;
|
||||
|
||||
if(LPC_SC->PCONP & (1 << 13)) {
|
||||
icr = LPC_CAN1->ICR & 0x1FF;
|
||||
can_irq(icr, 0);
|
||||
}
|
||||
|
||||
if(LPC_SC->PCONP & (1 << 14)) {
|
||||
icr = LPC_CAN2->ICR & 0x1FF;
|
||||
can_irq(icr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Register CAN object's irq handler
|
||||
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
|
||||
irq_handler = handler;
|
||||
can_irq_ids[obj->index] = id;
|
||||
}
|
||||
|
||||
// Unregister CAN object's irq handler
|
||||
void can_irq_free(can_t *obj) {
|
||||
obj->dev->IER &= ~(1);
|
||||
can_irq_ids[obj->index] = 0;
|
||||
|
||||
if ((can_irq_ids[0] == 0) && (can_irq_ids[1] == 0)) {
|
||||
NVIC_DisableIRQ(CAN_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear or set a irq
|
||||
void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
|
||||
uint32_t ier;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_RX: ier = (1 << 0); break;
|
||||
case IRQ_TX: ier = (1 << 1); break;
|
||||
case IRQ_ERROR: ier = (1 << 2); break;
|
||||
case IRQ_OVERRUN: ier = (1 << 3); break;
|
||||
case IRQ_WAKEUP: ier = (1 << 4); break;
|
||||
case IRQ_PASSIVE: ier = (1 << 5); break;
|
||||
case IRQ_ARB: ier = (1 << 6); break;
|
||||
case IRQ_BUS: ier = (1 << 7); break;
|
||||
case IRQ_READY: ier = (1 << 8); break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
obj->dev->MOD |= 1;
|
||||
if(enable == 0) {
|
||||
obj->dev->IER &= ~ier;
|
||||
}
|
||||
else {
|
||||
obj->dev->IER |= ier;
|
||||
}
|
||||
obj->dev->MOD &= ~(1);
|
||||
|
||||
// Enable NVIC if at least 1 interrupt is active
|
||||
if(((LPC_SC->PCONP & (1 << 13)) && LPC_CAN1->IER) || ((LPC_SC->PCONP & (1 << 14)) && LPC_CAN2->IER)) {
|
||||
NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq_n);
|
||||
NVIC_EnableIRQ(CAN_IRQn);
|
||||
}
|
||||
else {
|
||||
NVIC_DisableIRQ(CAN_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
// This table has the sampling points as close to 75% as possible. The first
|
||||
// value is TSEG1, the second TSEG2.
|
||||
static const int timing_pts[23][2] = {
|
||||
{0x0, 0x0}, // 2, 50%
|
||||
{0x1, 0x0}, // 3, 67%
|
||||
{0x2, 0x0}, // 4, 75%
|
||||
{0x3, 0x0}, // 5, 80%
|
||||
{0x3, 0x1}, // 6, 67%
|
||||
{0x4, 0x1}, // 7, 71%
|
||||
{0x5, 0x1}, // 8, 75%
|
||||
{0x6, 0x1}, // 9, 78%
|
||||
{0x6, 0x2}, // 10, 70%
|
||||
{0x7, 0x2}, // 11, 73%
|
||||
{0x8, 0x2}, // 12, 75%
|
||||
{0x9, 0x2}, // 13, 77%
|
||||
{0x9, 0x3}, // 14, 71%
|
||||
{0xA, 0x3}, // 15, 73%
|
||||
{0xB, 0x3}, // 16, 75%
|
||||
{0xC, 0x3}, // 17, 76%
|
||||
{0xD, 0x3}, // 18, 78%
|
||||
{0xD, 0x4}, // 19, 74%
|
||||
{0xE, 0x4}, // 20, 75%
|
||||
{0xF, 0x4}, // 21, 76%
|
||||
{0xF, 0x5}, // 22, 73%
|
||||
{0xF, 0x6}, // 23, 70%
|
||||
{0xF, 0x7}, // 24, 67%
|
||||
};
|
||||
|
||||
static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) {
|
||||
uint32_t btr;
|
||||
uint16_t brp = 0;
|
||||
uint32_t calcbit;
|
||||
uint32_t bitwidth;
|
||||
int hit = 0;
|
||||
int bits;
|
||||
|
||||
bitwidth = (pclk / cclk);
|
||||
|
||||
brp = bitwidth / 0x18;
|
||||
while ((!hit) && (brp < bitwidth / 4)) {
|
||||
brp++;
|
||||
for (bits = 22; bits > 0; bits--) {
|
||||
calcbit = (bits + 3) * (brp + 1);
|
||||
if (calcbit == bitwidth) {
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
btr = ((timing_pts[bits][1] << 20) & 0x00700000)
|
||||
| ((timing_pts[bits][0] << 16) & 0x000F0000)
|
||||
| ((psjw << 14) & 0x0000C000)
|
||||
| ((brp << 0) & 0x000003FF);
|
||||
} else {
|
||||
btr = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return btr;
|
||||
|
||||
}
|
||||
|
||||
void can_init_freq(can_t *obj, PinName rd, PinName td, int hz) {
|
||||
CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
|
||||
CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
|
||||
obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td);
|
||||
MBED_ASSERT((int)obj->dev != NC);
|
||||
|
||||
switch ((int)obj->dev) {
|
||||
case CAN_1: LPC_SC->PCONP |= 1 << 13; break;
|
||||
case CAN_2: LPC_SC->PCONP |= 1 << 14; break;
|
||||
}
|
||||
|
||||
pinmap_pinout(rd, PinMap_CAN_RD);
|
||||
pinmap_pinout(td, PinMap_CAN_TD);
|
||||
|
||||
switch ((int)obj->dev) {
|
||||
case CAN_1: obj->index = 0; break;
|
||||
case CAN_2: obj->index = 1; break;
|
||||
}
|
||||
|
||||
can_reset(obj);
|
||||
obj->dev->IER = 0; // Disable Interrupts
|
||||
can_frequency(obj, hz);
|
||||
|
||||
LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter
|
||||
}
|
||||
|
||||
void can_init(can_t *obj, PinName rd, PinName td) {
|
||||
can_init_freq(obj, rd, td, 100000);
|
||||
}
|
||||
|
||||
void can_free(can_t *obj) {
|
||||
switch ((int)obj->dev) {
|
||||
case CAN_1: LPC_SC->PCONP &= ~(1 << 13); break;
|
||||
case CAN_2: LPC_SC->PCONP &= ~(1 << 14); break;
|
||||
}
|
||||
}
|
||||
|
||||
int can_frequency(can_t *obj, int f) {
|
||||
int pclk = PeripheralClock;
|
||||
|
||||
int btr = can_speed(pclk, (unsigned int)f, 1);
|
||||
|
||||
if (btr > 0) {
|
||||
uint32_t modmask = can_disable(obj);
|
||||
obj->dev->BTR = btr;
|
||||
obj->dev->MOD = modmask;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int can_write(can_t *obj, CAN_Message msg, int cc) {
|
||||
unsigned int CANStatus;
|
||||
CANMsg m;
|
||||
|
||||
can_enable(obj);
|
||||
|
||||
m.id = msg.id ;
|
||||
m.dlc = msg.len & 0xF;
|
||||
m.rtr = msg.type;
|
||||
m.type = msg.format;
|
||||
memcpy(m.data, msg.data, msg.len);
|
||||
const unsigned int *buf = (const unsigned int *)&m;
|
||||
|
||||
CANStatus = obj->dev->SR;
|
||||
if (CANStatus & 0x00000004) {
|
||||
obj->dev->TFI1 = buf[0] & 0xC00F0000;
|
||||
obj->dev->TID1 = buf[1];
|
||||
obj->dev->TDA1 = buf[2];
|
||||
obj->dev->TDB1 = buf[3];
|
||||
if(cc) {
|
||||
obj->dev->CMR = 0x30;
|
||||
} else {
|
||||
obj->dev->CMR = 0x21;
|
||||
}
|
||||
return 1;
|
||||
|
||||
} else if (CANStatus & 0x00000400) {
|
||||
obj->dev->TFI2 = buf[0] & 0xC00F0000;
|
||||
obj->dev->TID2 = buf[1];
|
||||
obj->dev->TDA2 = buf[2];
|
||||
obj->dev->TDB2 = buf[3];
|
||||
if (cc) {
|
||||
obj->dev->CMR = 0x50;
|
||||
} else {
|
||||
obj->dev->CMR = 0x41;
|
||||
}
|
||||
return 1;
|
||||
|
||||
} else if (CANStatus & 0x00040000) {
|
||||
obj->dev->TFI3 = buf[0] & 0xC00F0000;
|
||||
obj->dev->TID3 = buf[1];
|
||||
obj->dev->TDA3 = buf[2];
|
||||
obj->dev->TDB3 = buf[3];
|
||||
if (cc) {
|
||||
obj->dev->CMR = 0x90;
|
||||
} else {
|
||||
obj->dev->CMR = 0x81;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int can_read(can_t *obj, CAN_Message *msg, int handle) {
|
||||
CANMsg x;
|
||||
unsigned int *i = (unsigned int *)&x;
|
||||
|
||||
can_enable(obj);
|
||||
|
||||
if (obj->dev->GSR & 0x1) {
|
||||
*i++ = obj->dev->RFS; // Frame
|
||||
*i++ = obj->dev->RID; // ID
|
||||
*i++ = obj->dev->RDA; // Data A
|
||||
*i++ = obj->dev->RDB; // Data B
|
||||
obj->dev->CMR = 0x04; // release receive buffer
|
||||
|
||||
msg->id = x.id;
|
||||
msg->len = x.dlc;
|
||||
msg->format = (x.type)? CANExtended : CANStandard;
|
||||
msg->type = (x.rtr)? CANRemote: CANData;
|
||||
memcpy(msg->data,x.data,x.dlc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void can_reset(can_t *obj) {
|
||||
can_disable(obj);
|
||||
obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset
|
||||
}
|
||||
|
||||
unsigned char can_rderror(can_t *obj) {
|
||||
return (obj->dev->GSR >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
unsigned char can_tderror(can_t *obj) {
|
||||
return (obj->dev->GSR >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
void can_monitor(can_t *obj, int silent) {
|
||||
uint32_t mod_mask = can_disable(obj);
|
||||
if (silent) {
|
||||
obj->dev->MOD |= (1 << 1);
|
||||
} else {
|
||||
obj->dev->MOD &= ~(1 << 1);
|
||||
}
|
||||
if (!(mod_mask & 1)) {
|
||||
can_enable(obj);
|
||||
}
|
||||
}
|
||||
|
||||
const PinMap *can_rd_pinmap()
|
||||
{
|
||||
return PinMap_CAN_TD;
|
||||
}
|
||||
|
||||
const PinMap *can_td_pinmap()
|
||||
{
|
||||
return PinMap_CAN_RD;
|
||||
}
|
|
@ -1,433 +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 "mbed_assert.h"
|
||||
#include "i2c_api.h"
|
||||
|
||||
#if DEVICE_I2C
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
static const PinMap PinMap_I2C_SDA[] = {
|
||||
{P0_0 , I2C_1, 3},
|
||||
{P0_27, I2C_0, 1},
|
||||
{P2_14, I2C_1, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_I2C_SCL[] = {
|
||||
{P0_1 , I2C_1, 3},
|
||||
{P0_28, I2C_0, 1},
|
||||
{P2_15, I2C_1, 2},
|
||||
{NC , NC, 0}
|
||||
};
|
||||
|
||||
#define I2C_CONSET(x) (x->i2c->CONSET)
|
||||
#define I2C_CONCLR(x) (x->i2c->CONCLR)
|
||||
#define I2C_STAT(x) (x->i2c->STAT)
|
||||
#define I2C_DAT(x) (x->i2c->DAT)
|
||||
#define I2C_SCLL(x, val) (x->i2c->SCLL = val)
|
||||
#define I2C_SCLH(x, val) (x->i2c->SCLH = val)
|
||||
|
||||
static const uint32_t I2C_addr_offset[2][4] = {
|
||||
{0x0C, 0x20, 0x24, 0x28},
|
||||
{0x30, 0x34, 0x38, 0x3C}
|
||||
};
|
||||
|
||||
static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
|
||||
I2C_CONCLR(obj) = (start << 5)
|
||||
| (stop << 4)
|
||||
| (interrupt << 3)
|
||||
| (acknowledge << 2);
|
||||
}
|
||||
|
||||
static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
|
||||
I2C_CONSET(obj) = (start << 5)
|
||||
| (stop << 4)
|
||||
| (interrupt << 3)
|
||||
| (acknowledge << 2);
|
||||
}
|
||||
|
||||
// Clear the Serial Interrupt (SI)
|
||||
static inline void i2c_clear_SI(i2c_t *obj) {
|
||||
i2c_conclr(obj, 0, 0, 1, 0);
|
||||
}
|
||||
|
||||
static inline int i2c_status(i2c_t *obj) {
|
||||
return I2C_STAT(obj);
|
||||
}
|
||||
|
||||
// Wait until the Serial Interrupt (SI) is set
|
||||
static int i2c_wait_SI(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
while (!(I2C_CONSET(obj) & (1 << 3))) {
|
||||
timeout++;
|
||||
if (timeout > 100000) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void i2c_interface_enable(i2c_t *obj) {
|
||||
I2C_CONSET(obj) = 0x40;
|
||||
}
|
||||
|
||||
static inline void i2c_power_enable(i2c_t *obj) {
|
||||
switch ((int)obj->i2c) {
|
||||
case I2C_0: LPC_SC->PCONP |= 1 << 7; break;
|
||||
case I2C_1: LPC_SC->PCONP |= 1 << 19; break;
|
||||
case I2C_2: LPC_SC->PCONP |= 1 << 26; break;
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||
// determine the SPI to use
|
||||
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
|
||||
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
|
||||
obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
|
||||
MBED_ASSERT((int)obj->i2c != NC);
|
||||
|
||||
// enable power
|
||||
i2c_power_enable(obj);
|
||||
|
||||
// set default frequency at 100k
|
||||
i2c_frequency(obj, 100000);
|
||||
i2c_conclr(obj, 1, 1, 1, 1);
|
||||
i2c_interface_enable(obj);
|
||||
|
||||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
|
||||
// OpenDrain must explicitly be enabled for p0.0 and p0.1
|
||||
if (sda == P0_0) {
|
||||
pin_mode(sda, OpenDrain);
|
||||
}
|
||||
if (scl == P0_1) {
|
||||
pin_mode(scl, OpenDrain);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline int i2c_start(i2c_t *obj) {
|
||||
int status = 0;
|
||||
int isInterrupted = I2C_CONSET(obj) & (1 << 3);
|
||||
|
||||
// 8.1 Before master mode can be entered, I2CON must be initialised to:
|
||||
// - I2EN STA STO SI AA - -
|
||||
// - 1 0 0 x x - -
|
||||
// if AA = 0, it can't enter slave mode
|
||||
i2c_conclr(obj, 1, 1, 0, 1);
|
||||
|
||||
// The master mode may now be entered by setting the STA bit
|
||||
// this will generate a start condition when the bus becomes free
|
||||
i2c_conset(obj, 1, 0, 0, 1);
|
||||
// Clearing SI bit when it wasn't set on entry can jump past state
|
||||
// 0x10 or 0x08 and erroneously send uninitialized slave address.
|
||||
if (isInterrupted)
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
i2c_wait_SI(obj);
|
||||
status = i2c_status(obj);
|
||||
|
||||
// Clear start bit now that it's transmitted
|
||||
i2c_conclr(obj, 1, 0, 0, 0);
|
||||
return status;
|
||||
}
|
||||
|
||||
inline int i2c_stop(i2c_t *obj) {
|
||||
int timeout = 0;
|
||||
|
||||
// write the stop bit
|
||||
i2c_conset(obj, 0, 1, 0, 0);
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
// wait for STO bit to reset
|
||||
while(I2C_CONSET(obj) & (1 << 4)) {
|
||||
timeout ++;
|
||||
if (timeout > 100000) return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
|
||||
// write the data
|
||||
I2C_DAT(obj) = value;
|
||||
|
||||
// clear SI to init a send
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
// wait and return status
|
||||
i2c_wait_SI(obj);
|
||||
return i2c_status(obj);
|
||||
}
|
||||
|
||||
static inline int i2c_do_read(i2c_t *obj, int last) {
|
||||
// we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack)
|
||||
if(last) {
|
||||
i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK
|
||||
} else {
|
||||
i2c_conset(obj, 0, 0, 0, 1); // send a ACK
|
||||
}
|
||||
|
||||
// accept byte
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
// wait for it to arrive
|
||||
i2c_wait_SI(obj);
|
||||
|
||||
// return the data
|
||||
return (I2C_DAT(obj) & 0xFF);
|
||||
}
|
||||
|
||||
void i2c_frequency(i2c_t *obj, int hz) {
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
uint32_t pulse = PCLK / (hz * 2);
|
||||
|
||||
// I2C Rate
|
||||
I2C_SCLL(obj, pulse);
|
||||
I2C_SCLH(obj, pulse);
|
||||
}
|
||||
|
||||
// The I2C does a read or a write as a whole operation
|
||||
// There are two types of error conditions it can encounter
|
||||
// 1) it can not obtain the bus
|
||||
// 2) it gets error responses at part of the transmission
|
||||
//
|
||||
// We tackle them as follows:
|
||||
// 1) we retry until we get the bus. we could have a "timeout" if we can not get it
|
||||
// which basically turns it in to a 2)
|
||||
// 2) on error, we use the standard error mechanisms to report/debug
|
||||
//
|
||||
// Therefore an I2C transaction should always complete. If it doesn't it is usually
|
||||
// because something is setup wrong (e.g. wiring), and we don't need to programatically
|
||||
// check for that
|
||||
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
||||
int count, status;
|
||||
|
||||
status = i2c_start(obj);
|
||||
|
||||
if ((status != 0x10) && (status != 0x08)) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
|
||||
status = i2c_do_write(obj, (address | 0x01), 1);
|
||||
if (status != 0x40) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
// Read in all except last byte
|
||||
for (count = 0; count < (length - 1); count++) {
|
||||
int value = i2c_do_read(obj, 0);
|
||||
status = i2c_status(obj);
|
||||
if (status != 0x50) {
|
||||
i2c_stop(obj);
|
||||
return count;
|
||||
}
|
||||
data[count] = (char) value;
|
||||
}
|
||||
|
||||
// read in last byte
|
||||
int value = i2c_do_read(obj, 1);
|
||||
status = i2c_status(obj);
|
||||
if (status != 0x58) {
|
||||
i2c_stop(obj);
|
||||
return length - 1;
|
||||
}
|
||||
|
||||
data[count] = (char) value;
|
||||
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
||||
int i, status;
|
||||
|
||||
status = i2c_start(obj);
|
||||
|
||||
if ((status != 0x10) && (status != 0x08)) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
|
||||
status = i2c_do_write(obj, (address & 0xFE), 1);
|
||||
if (status != 0x18) {
|
||||
i2c_stop(obj);
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
|
||||
for (i=0; i<length; i++) {
|
||||
status = i2c_do_write(obj, data[i], 0);
|
||||
if (status != 0x28) {
|
||||
i2c_stop(obj);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// clearing the serial interrupt here might cause an unintended rewrite of the last byte
|
||||
// see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1
|
||||
// i2c_clear_SI(obj);
|
||||
|
||||
// If not repeated start, send stop.
|
||||
if (stop) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void i2c_reset(i2c_t *obj) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
int i2c_byte_read(i2c_t *obj, int last) {
|
||||
return (i2c_do_read(obj, last) & 0xFF);
|
||||
}
|
||||
|
||||
int i2c_byte_write(i2c_t *obj, int data) {
|
||||
int ack;
|
||||
int status = i2c_do_write(obj, (data & 0xFF), 0);
|
||||
|
||||
switch(status) {
|
||||
case 0x18: case 0x28: // Master transmit ACKs
|
||||
ack = 1;
|
||||
break;
|
||||
|
||||
case 0x40: // Master receive address transmitted ACK
|
||||
ack = 1;
|
||||
break;
|
||||
|
||||
case 0xB8: // Slave transmit ACK
|
||||
ack = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ack = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ack;
|
||||
}
|
||||
|
||||
void i2c_slave_mode(i2c_t *obj, int enable_slave) {
|
||||
if (enable_slave != 0) {
|
||||
i2c_conclr(obj, 1, 1, 1, 0);
|
||||
i2c_conset(obj, 0, 0, 0, 1);
|
||||
} else {
|
||||
i2c_conclr(obj, 1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int i2c_slave_receive(i2c_t *obj) {
|
||||
int status;
|
||||
int retval;
|
||||
|
||||
status = i2c_status(obj);
|
||||
switch(status) {
|
||||
case 0x60: retval = 3; break;
|
||||
case 0x70: retval = 2; break;
|
||||
case 0xA8: retval = 1; break;
|
||||
default : retval = 0; break;
|
||||
}
|
||||
|
||||
return(retval);
|
||||
}
|
||||
|
||||
int i2c_slave_read(i2c_t *obj, char *data, int length) {
|
||||
int count = 0;
|
||||
int status;
|
||||
|
||||
do {
|
||||
i2c_clear_SI(obj);
|
||||
i2c_wait_SI(obj);
|
||||
status = i2c_status(obj);
|
||||
if((status == 0x80) || (status == 0x90)) {
|
||||
data[count] = I2C_DAT(obj) & 0xFF;
|
||||
}
|
||||
count++;
|
||||
} while (((status == 0x80) || (status == 0x90) ||
|
||||
(status == 0x060) || (status == 0x70)) && (count < length));
|
||||
|
||||
if(status != 0xA0) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
|
||||
int count = 0;
|
||||
int status;
|
||||
|
||||
if(length <= 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
do {
|
||||
status = i2c_do_write(obj, data[count], 0);
|
||||
count++;
|
||||
} while ((count < length) && (status == 0xB8));
|
||||
|
||||
if((status != 0xC0) && (status != 0xC8)) {
|
||||
i2c_stop(obj);
|
||||
}
|
||||
|
||||
i2c_clear_SI(obj);
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
|
||||
uint32_t addr;
|
||||
|
||||
if ((idx >= 0) && (idx <= 3)) {
|
||||
addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx];
|
||||
*((uint32_t *) addr) = address & 0xFF;
|
||||
addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx];
|
||||
*((uint32_t *) addr) = mask & 0xFE;
|
||||
}
|
||||
}
|
||||
|
||||
const PinMap *i2c_master_sda_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SDA;
|
||||
}
|
||||
|
||||
const PinMap *i2c_master_scl_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SCL;
|
||||
}
|
||||
|
||||
const PinMap *i2c_slave_sda_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SDA;
|
||||
}
|
||||
|
||||
const PinMap *i2c_slave_scl_pinmap()
|
||||
{
|
||||
return PinMap_I2C_SCL;
|
||||
}
|
||||
|
||||
#endif // #if DEVICE_I2C
|
|
@ -1,168 +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 "mbed_assert.h"
|
||||
#include "pwmout_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
#define TCR_CNT_EN 0x00000001
|
||||
#define TCR_RESET 0x00000002
|
||||
|
||||
// PORT ID, PWM ID, Pin function
|
||||
static const PinMap PinMap_PWM[] = {
|
||||
{P1_5, PWM0_3, 3},
|
||||
{P1_20, PWM1_2, 2},
|
||||
{P1_23, PWM1_4, 2},
|
||||
{P1_24, PWM1_5, 2},
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
static const uint32_t PWM_mr_offset[7] = {
|
||||
0x18, 0x1C, 0x20, 0x24, 0x40, 0x44, 0x48
|
||||
};
|
||||
|
||||
#define TCR_PWM_EN 0x00000008
|
||||
static unsigned int pwm_clock_mhz;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
||||
obj->channel = pwm;
|
||||
obj->pwm = LPC_PWM0;
|
||||
|
||||
if (obj->channel > 6) { // PWM1 is used if pwm > 6
|
||||
obj->channel -= 6;
|
||||
obj->pwm = LPC_PWM1;
|
||||
}
|
||||
|
||||
obj->MR = (__IO uint32_t *)((uint32_t)obj->pwm + PWM_mr_offset[obj->channel]);
|
||||
|
||||
// ensure the power is on
|
||||
if (obj->pwm == LPC_PWM0) {
|
||||
LPC_SC->PCONP |= 1 << 5;
|
||||
} else {
|
||||
LPC_SC->PCONP |= 1 << 6;
|
||||
}
|
||||
|
||||
obj->pwm->PR = 0; // no pre-scale
|
||||
|
||||
// ensure single PWM mode
|
||||
obj->pwm->MCR = 1 << 1; // reset TC on match 0
|
||||
|
||||
// enable the specific PWM output
|
||||
obj->pwm->PCR |= 1 << (8 + obj->channel);
|
||||
|
||||
pwm_clock_mhz = PeripheralClock / 1000000;
|
||||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {
|
||||
// [TODO]
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
if (value < 0.0f) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0f) {
|
||||
value = 1.0;
|
||||
}
|
||||
|
||||
// set channel match to percentage
|
||||
uint32_t v = (uint32_t)((float)(obj->pwm->MR0) * value);
|
||||
|
||||
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
|
||||
if (v == obj->pwm->MR0) {
|
||||
v++;
|
||||
}
|
||||
|
||||
*obj->MR = v;
|
||||
|
||||
// accept on next period start
|
||||
obj->pwm->LER |= 1 << obj->channel;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
float v = (float)(*obj->MR) / (float)(obj->pwm->MR0);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
// calculate number of ticks
|
||||
uint32_t ticks = pwm_clock_mhz * us;
|
||||
|
||||
// set reset
|
||||
obj->pwm->TCR = TCR_RESET;
|
||||
|
||||
// set the global match register
|
||||
obj->pwm->MR0 = ticks;
|
||||
|
||||
// Scale the pulse width to preserve the duty ratio
|
||||
if (obj->pwm->MR0 > 0) {
|
||||
*obj->MR = (*obj->MR * ticks) / obj->pwm->MR0;
|
||||
}
|
||||
|
||||
// set the channel latch to update value at next period start
|
||||
obj->pwm->LER |= 1 << 0;
|
||||
|
||||
// enable counter and pwm, clear reset
|
||||
obj->pwm->TCR = TCR_CNT_EN | TCR_PWM_EN;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
// calculate number of ticks
|
||||
uint32_t v = pwm_clock_mhz * us;
|
||||
|
||||
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
|
||||
if (v == obj->pwm->MR0) {
|
||||
v++;
|
||||
}
|
||||
|
||||
// set the match register value
|
||||
*obj->MR = v;
|
||||
|
||||
// set the channel latch to update value at next period start
|
||||
obj->pwm->LER |= 1 << obj->channel;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
}
|
|
@ -1,349 +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.
|
||||
*/
|
||||
// math.h required for floating point operations for baud rate calculation
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "serial_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
/******************************************************************************
|
||||
* INITIALIZATION
|
||||
******************************************************************************/
|
||||
static const PinMap PinMap_UART_TX[] = {
|
||||
{P0_0, UART_3, 2},
|
||||
{P0_2, UART_0, 1},
|
||||
{P0_25, UART_3, 3},
|
||||
{P4_22, UART_2, 2},
|
||||
{P5_4, UART_4, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_UART_RX[] = {
|
||||
{P0_1 , UART_3, 2},
|
||||
{P0_3 , UART_0, 1},
|
||||
{P0_26, UART_3, 3},
|
||||
{P4_23, UART_2, 2},
|
||||
{P5_3, UART_4, 4},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
#define UART_NUM 5
|
||||
|
||||
static uint32_t serial_irq_ids[UART_NUM] = {0};
|
||||
static uart_irq_handler irq_handler;
|
||||
|
||||
int stdio_uart_inited = 0;
|
||||
serial_t stdio_uart;
|
||||
|
||||
void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
||||
int is_stdio_uart = 0;
|
||||
|
||||
// determine the UART to use
|
||||
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
|
||||
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
|
||||
UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
|
||||
MBED_ASSERT((int)uart != NC);
|
||||
|
||||
obj->uart = (LPC_UART_TypeDef *)uart;
|
||||
// enable power
|
||||
switch (uart) {
|
||||
case UART_0: LPC_SC->PCONP |= 1 << 3; break;
|
||||
case UART_1: LPC_SC->PCONP |= 1 << 4; break;
|
||||
case UART_2: LPC_SC->PCONP |= 1 << 24; break;
|
||||
case UART_3: LPC_SC->PCONP |= 1 << 25; break;
|
||||
case UART_4: LPC_SC->PCONP |= 1 << 8; break;
|
||||
}
|
||||
|
||||
// enable fifos and default rx trigger level
|
||||
obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
|
||||
| 0 << 1 // Rx Fifo Reset
|
||||
| 0 << 2 // Tx Fifo Reset
|
||||
| 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
|
||||
|
||||
// disable irqs
|
||||
obj->uart->IER = 0 << 0 // Rx Data available irq enable
|
||||
| 0 << 1 // Tx Fifo empty irq enable
|
||||
| 0 << 2; // Rx Line Status irq enable
|
||||
|
||||
// set default baud rate and format
|
||||
serial_baud (obj, 9600);
|
||||
serial_format(obj, 8, ParityNone, 1);
|
||||
|
||||
// pinout the chosen uart
|
||||
pinmap_pinout(tx, PinMap_UART_TX);
|
||||
pinmap_pinout(rx, PinMap_UART_RX);
|
||||
|
||||
// set rx/tx pins in PullUp mode
|
||||
if (tx != NC) {
|
||||
pin_mode(tx, PullUp);
|
||||
}
|
||||
if (rx != NC) {
|
||||
pin_mode(rx, PullUp);
|
||||
}
|
||||
|
||||
switch (uart) {
|
||||
case UART_0: obj->index = 0; break;
|
||||
case UART_1: obj->index = 1; break;
|
||||
case UART_2: obj->index = 2; break;
|
||||
case UART_3: obj->index = 3; break;
|
||||
case UART_4: obj->index = 4; break;
|
||||
}
|
||||
|
||||
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
|
||||
|
||||
if (is_stdio_uart) {
|
||||
stdio_uart_inited = 1;
|
||||
memcpy(&stdio_uart, obj, sizeof(serial_t));
|
||||
}
|
||||
}
|
||||
|
||||
void serial_free(serial_t *obj) {
|
||||
serial_irq_ids[obj->index] = 0;
|
||||
}
|
||||
|
||||
// serial_baud
|
||||
// set the baud rate, taking in to account the current SystemFrequency
|
||||
void serial_baud(serial_t *obj, int baudrate) {
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
|
||||
// First we check to see if the basic divide with no DivAddVal/MulVal
|
||||
// ratio gives us an integer result. If it does, we set DivAddVal = 0,
|
||||
// MulVal = 1. Otherwise, we search the valid ratio value range to find
|
||||
// the closest match. This could be more elegant, using search methods
|
||||
// and/or lookup tables, but the brute force method is not that much
|
||||
// slower, and is more maintainable.
|
||||
uint16_t DL = PCLK / (16 * baudrate);
|
||||
|
||||
uint8_t DivAddVal = 0;
|
||||
uint8_t MulVal = 1;
|
||||
int hit = 0;
|
||||
uint16_t dlv;
|
||||
uint8_t mv, dav;
|
||||
if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder
|
||||
int err_best = baudrate, b;
|
||||
for (mv = 1; mv < 16 && !hit; mv++)
|
||||
{
|
||||
for (dav = 0; dav < mv; dav++)
|
||||
{
|
||||
// baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul))
|
||||
// solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul))
|
||||
// mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding
|
||||
// for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision
|
||||
// note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding
|
||||
|
||||
if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom
|
||||
dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2;
|
||||
else // 2 bits headroom, use more precision
|
||||
dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2;
|
||||
|
||||
// datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood
|
||||
if (dlv == 0)
|
||||
dlv = 1;
|
||||
|
||||
// datasheet says if dav > 0 then DL must be >= 2
|
||||
if ((dav > 0) && (dlv < 2))
|
||||
dlv = 2;
|
||||
|
||||
// integer rearrangement of the baudrate equation (with rounding)
|
||||
b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2;
|
||||
|
||||
// check to see how we went
|
||||
b = abs(b - baudrate);
|
||||
if (b < err_best)
|
||||
{
|
||||
err_best = b;
|
||||
|
||||
DL = dlv;
|
||||
MulVal = mv;
|
||||
DivAddVal = dav;
|
||||
|
||||
if (b == baudrate)
|
||||
{
|
||||
hit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set LCR[DLAB] to enable writing to divider registers
|
||||
obj->uart->LCR |= (1 << 7);
|
||||
|
||||
// set divider values
|
||||
obj->uart->DLM = (DL >> 8) & 0xFF;
|
||||
obj->uart->DLL = (DL >> 0) & 0xFF;
|
||||
obj->uart->FDR = (uint32_t) DivAddVal << 0
|
||||
| (uint32_t) MulVal << 4;
|
||||
|
||||
// clear LCR[DLAB]
|
||||
obj->uart->LCR &= ~(1 << 7);
|
||||
}
|
||||
|
||||
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
|
||||
MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits
|
||||
MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits
|
||||
MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) ||
|
||||
(parity == ParityForced1) || (parity == ParityForced0));
|
||||
|
||||
stop_bits -= 1;
|
||||
data_bits -= 5;
|
||||
|
||||
int parity_enable = 0, parity_select = 0;
|
||||
switch (parity) {
|
||||
case ParityNone: parity_enable = 0; parity_select = 0; break;
|
||||
case ParityOdd : parity_enable = 1; parity_select = 0; break;
|
||||
case ParityEven: parity_enable = 1; parity_select = 1; break;
|
||||
case ParityForced1: parity_enable = 1; parity_select = 2; break;
|
||||
case ParityForced0: parity_enable = 1; parity_select = 3; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
obj->uart->LCR = data_bits << 0
|
||||
| stop_bits << 2
|
||||
| parity_enable << 3
|
||||
| parity_select << 4;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* INTERRUPTS HANDLING
|
||||
******************************************************************************/
|
||||
static inline void uart_irq(uint32_t iir, uint32_t index) {
|
||||
// [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling
|
||||
SerialIrq irq_type;
|
||||
switch (iir) {
|
||||
case 1: irq_type = TxIrq; break;
|
||||
case 2: irq_type = RxIrq; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (serial_irq_ids[index] != 0)
|
||||
irq_handler(serial_irq_ids[index], irq_type);
|
||||
}
|
||||
|
||||
void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);}
|
||||
void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);}
|
||||
void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);}
|
||||
void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);}
|
||||
void uart4_irq() {uart_irq((LPC_UART4->IIR >> 1) & 0x7, 4);}
|
||||
|
||||
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
|
||||
irq_handler = handler;
|
||||
serial_irq_ids[obj->index] = id;
|
||||
}
|
||||
|
||||
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
||||
IRQn_Type irq_n = (IRQn_Type)0;
|
||||
uint32_t vector = 0;
|
||||
switch ((int)obj->uart) {
|
||||
case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break;
|
||||
case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break;
|
||||
case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break;
|
||||
case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break;
|
||||
case UART_4: irq_n=UART4_IRQn; vector = (uint32_t)&uart4_irq; break;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
obj->uart->IER |= 1 << irq;
|
||||
NVIC_SetVector(irq_n, vector);
|
||||
NVIC_EnableIRQ(irq_n);
|
||||
} else { // disable
|
||||
int all_disabled = 0;
|
||||
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
|
||||
obj->uart->IER &= ~(1 << irq);
|
||||
all_disabled = (obj->uart->IER & (1 << other_irq)) == 0;
|
||||
if (all_disabled)
|
||||
NVIC_DisableIRQ(irq_n);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* READ/WRITE
|
||||
******************************************************************************/
|
||||
int serial_getc(serial_t *obj) {
|
||||
while (!serial_readable(obj));
|
||||
return obj->uart->RBR;
|
||||
}
|
||||
|
||||
void serial_putc(serial_t *obj, int c) {
|
||||
while (!serial_writable(obj));
|
||||
obj->uart->THR = c;
|
||||
}
|
||||
|
||||
int serial_readable(serial_t *obj) {
|
||||
return obj->uart->LSR & 0x01;
|
||||
}
|
||||
|
||||
int serial_writable(serial_t *obj) {
|
||||
return obj->uart->LSR & 0x20;
|
||||
}
|
||||
|
||||
void serial_clear(serial_t *obj) {
|
||||
obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
|
||||
| 1 << 1 // rx FIFO reset
|
||||
| 1 << 2 // tx FIFO reset
|
||||
| 0 << 6; // interrupt depth
|
||||
}
|
||||
|
||||
void serial_pinout_tx(PinName tx) {
|
||||
pinmap_pinout(tx, PinMap_UART_TX);
|
||||
}
|
||||
|
||||
void serial_break_set(serial_t *obj) {
|
||||
obj->uart->LCR |= (1 << 6);
|
||||
}
|
||||
|
||||
void serial_break_clear(serial_t *obj) {
|
||||
obj->uart->LCR &= ~(1 << 6);
|
||||
}
|
||||
|
||||
const PinMap *serial_tx_pinmap()
|
||||
{
|
||||
return PinMap_UART_TX;
|
||||
}
|
||||
|
||||
const PinMap *serial_rx_pinmap()
|
||||
{
|
||||
return PinMap_UART_RX;
|
||||
}
|
||||
|
||||
const PinMap *serial_cts_pinmap()
|
||||
{
|
||||
#if !DEVICE_SERIAL_FC
|
||||
static const PinMap PinMap_UART_CTS[] = {
|
||||
{NC, NC, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
return PinMap_UART_CTS;
|
||||
}
|
||||
|
||||
const PinMap *serial_rts_pinmap()
|
||||
{
|
||||
#if !DEVICE_SERIAL_FC
|
||||
static const PinMap PinMap_UART_RTS[] = {
|
||||
{NC, NC, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
return PinMap_UART_RTS;
|
||||
}
|
||||
|
|
@ -1,250 +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 <math.h>
|
||||
|
||||
#include "spi_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
static const PinMap PinMap_SPI_SCLK[] = {
|
||||
{P0_7 , SPI_1, 2},
|
||||
{P1_19, SPI_1, 5},
|
||||
{P1_20, SPI_0, 5},
|
||||
{P2_22, SPI_0, 2},
|
||||
{P5_2, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MOSI[] = {
|
||||
{P0_9 , SPI_1, 2},
|
||||
{P1_24, SPI_0, 5},
|
||||
{P2_27, SPI_0, 2},
|
||||
{P5_0, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_MISO[] = {
|
||||
{P0_8 , SPI_1, 2},
|
||||
{P1_23, SPI_0, 5},
|
||||
{P2_26, SPI_0, 2},
|
||||
{P5_1, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static const PinMap PinMap_SPI_SSEL[] = {
|
||||
{P0_6 , SPI_1, 2},
|
||||
{P2_23, SPI_0, 2},
|
||||
{P5_3, SPI_2, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
static inline int ssp_disable(spi_t *obj);
|
||||
static inline int ssp_enable(spi_t *obj);
|
||||
|
||||
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
|
||||
// determine the SPI to use
|
||||
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
|
||||
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
|
||||
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
|
||||
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
|
||||
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
|
||||
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
|
||||
obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
|
||||
MBED_ASSERT((int)obj->spi != NC);
|
||||
|
||||
// enable power and clocking
|
||||
switch ((int)obj->spi) {
|
||||
case SPI_0: LPC_SC->PCONP |= 1 << 21; break;
|
||||
case SPI_1: LPC_SC->PCONP |= 1 << 10; break;
|
||||
case SPI_2: LPC_SC->PCONP |= 1 << 20; break;
|
||||
}
|
||||
|
||||
// pin out the spi pins
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
pinmap_pinout(miso, PinMap_SPI_MISO);
|
||||
pinmap_pinout(sclk, PinMap_SPI_SCLK);
|
||||
if (ssel != NC) {
|
||||
pinmap_pinout(ssel, PinMap_SPI_SSEL);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_free(spi_t *obj) {}
|
||||
|
||||
void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
||||
MBED_ASSERT(((bits >= 4) && (bits <= 16)) && ((mode >= 0) && (mode <= 3)));
|
||||
ssp_disable(obj);
|
||||
|
||||
int polarity = (mode & 0x2) ? 1 : 0;
|
||||
int phase = (mode & 0x1) ? 1 : 0;
|
||||
|
||||
// set it up
|
||||
int DSS = bits - 1; // DSS (data select size)
|
||||
int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
|
||||
int SPH = (phase) ? 1 : 0; // SPH - clock out phase
|
||||
|
||||
int FRF = 0; // FRF (frame format) = SPI
|
||||
uint32_t tmp = obj->spi->CR0;
|
||||
tmp &= ~(0x00FF); // Clear DSS, FRF, CPOL and CPHA [7:0]
|
||||
tmp |= DSS << 0
|
||||
| FRF << 4
|
||||
| SPO << 6
|
||||
| SPH << 7;
|
||||
obj->spi->CR0 = tmp;
|
||||
|
||||
tmp = obj->spi->CR1;
|
||||
tmp &= ~(0xD);
|
||||
tmp |= 0 << 0 // LBM - loop back mode - off
|
||||
| ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave
|
||||
| 0 << 3; // SOD - slave output disable - na
|
||||
obj->spi->CR1 = tmp;
|
||||
ssp_enable(obj);
|
||||
}
|
||||
|
||||
void spi_frequency(spi_t *obj, int hz) {
|
||||
ssp_disable(obj);
|
||||
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
|
||||
int prescaler;
|
||||
|
||||
for (prescaler = 2; prescaler <= 254; prescaler += 2) {
|
||||
int prescale_hz = PCLK / prescaler;
|
||||
|
||||
// calculate the divider
|
||||
int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
|
||||
|
||||
// check we can support the divider
|
||||
if (divider < 256) {
|
||||
// prescaler
|
||||
obj->spi->CPSR = prescaler;
|
||||
|
||||
// divider
|
||||
obj->spi->CR0 &= ~(0xFF00); // Clear SCR: Serial clock rate [15:8]
|
||||
obj->spi->CR0 |= (divider - 1) << 8;
|
||||
ssp_enable(obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
error("Couldn't setup requested SPI frequency");
|
||||
}
|
||||
|
||||
static inline int ssp_disable(spi_t *obj) {
|
||||
return obj->spi->CR1 &= ~(1 << 1);
|
||||
}
|
||||
|
||||
static inline int ssp_enable(spi_t *obj) {
|
||||
return obj->spi->CR1 |= (1 << 1);
|
||||
}
|
||||
|
||||
static inline int ssp_readable(spi_t *obj) {
|
||||
return obj->spi->SR & (1 << 2);
|
||||
}
|
||||
|
||||
static inline int ssp_writeable(spi_t *obj) {
|
||||
return obj->spi->SR & (1 << 1);
|
||||
}
|
||||
|
||||
static inline void ssp_write(spi_t *obj, int value) {
|
||||
while (!ssp_writeable(obj));
|
||||
obj->spi->DR = value;
|
||||
}
|
||||
|
||||
static inline int ssp_read(spi_t *obj) {
|
||||
while (!ssp_readable(obj));
|
||||
return obj->spi->DR;
|
||||
}
|
||||
|
||||
static inline int ssp_busy(spi_t *obj) {
|
||||
return (obj->spi->SR & (1 << 4)) ? (1) : (0);
|
||||
}
|
||||
|
||||
int spi_master_write(spi_t *obj, int value) {
|
||||
ssp_write(obj, value);
|
||||
return ssp_read(obj);
|
||||
}
|
||||
|
||||
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
|
||||
char *rx_buffer, int rx_length, char write_fill) {
|
||||
int total = (tx_length > rx_length) ? tx_length : rx_length;
|
||||
|
||||
for (int i = 0; i < total; i++) {
|
||||
char out = (i < tx_length) ? tx_buffer[i] : write_fill;
|
||||
char in = spi_master_write(obj, out);
|
||||
if (i < rx_length) {
|
||||
rx_buffer[i] = in;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int spi_slave_receive(spi_t *obj) {
|
||||
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
|
||||
}
|
||||
|
||||
int spi_slave_read(spi_t *obj) {
|
||||
return obj->spi->DR;
|
||||
}
|
||||
|
||||
void spi_slave_write(spi_t *obj, int value) {
|
||||
while (ssp_writeable(obj) == 0) ;
|
||||
obj->spi->DR = value;
|
||||
}
|
||||
|
||||
int spi_busy(spi_t *obj) {
|
||||
return ssp_busy(obj);
|
||||
}
|
||||
|
||||
const PinMap *spi_master_mosi_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MOSI;
|
||||
}
|
||||
|
||||
const PinMap *spi_master_miso_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MISO;
|
||||
}
|
||||
|
||||
const PinMap *spi_master_clk_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SCLK;
|
||||
}
|
||||
|
||||
const PinMap *spi_master_cs_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SSEL;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_mosi_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MOSI;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_miso_pinmap()
|
||||
{
|
||||
return PinMap_SPI_MISO;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_clk_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SCLK;
|
||||
}
|
||||
|
||||
const PinMap *spi_slave_cs_pinmap()
|
||||
{
|
||||
return PinMap_SPI_SSEL;
|
||||
}
|
|
@ -1,80 +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 "mbed_assert.h"
|
||||
#include "analogout_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
static const PinMap PinMap_DAC[] = {
|
||||
{P0_26, DAC_0, 2},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
void analogout_init(dac_t *obj, PinName pin) {
|
||||
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
|
||||
MBED_ASSERT(obj->dac != (DACName)NC);
|
||||
|
||||
// DAC enable bit must be set
|
||||
LPC_IOCON->P0_26 |= (1 << 16); // DACEN
|
||||
|
||||
// map out (must be done before accessing registers)
|
||||
pinmap_pinout(pin, PinMap_DAC);
|
||||
|
||||
analogout_write_u16(obj, 0);
|
||||
}
|
||||
|
||||
void analogout_free(dac_t *obj) {}
|
||||
|
||||
static inline void dac_write(int value) {
|
||||
value &= 0x3FF; // 10-bit
|
||||
|
||||
// Set the DAC output
|
||||
LPC_DAC->CR = (0 << 16) // bias = 0
|
||||
| (value << 6);
|
||||
}
|
||||
|
||||
static inline int dac_read() {
|
||||
return (LPC_DAC->CR >> 6) & 0x3FF;
|
||||
}
|
||||
|
||||
void analogout_write(dac_t *obj, float value) {
|
||||
if (value < 0.0f) {
|
||||
dac_write(0);
|
||||
} else if (value > 1.0f) {
|
||||
dac_write(0x3FF);
|
||||
} else {
|
||||
dac_write(value * (float)0x3FF);
|
||||
}
|
||||
}
|
||||
|
||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
|
||||
dac_write(value >> 6); // 10-bit
|
||||
}
|
||||
|
||||
float analogout_read(dac_t *obj) {
|
||||
uint32_t value = dac_read();
|
||||
return (float)value * (1.0f / (float)0x3FF);
|
||||
}
|
||||
|
||||
uint16_t analogout_read_u16(dac_t *obj) {
|
||||
uint32_t value = dac_read(); // 10-bit
|
||||
return (value << 6) | ((value >> 4) & 0x003F);
|
||||
}
|
||||
|
||||
const PinMap *analogout_pinmap()
|
||||
{
|
||||
return PinMap_DAC;
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* 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_ID_LENGTH 32
|
||||
#define DEVICE_MAC_OFFSET 20
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,41 +0,0 @@
|
|||
#! armcc -E
|
||||
|
||||
; *************************************************************
|
||||
; *** Scatter-Loading Description File generated by uVision ***
|
||||
; *************************************************************
|
||||
|
||||
#if !defined(MBED_BOOT_STACK_SIZE)
|
||||
#define MBED_BOOT_STACK_SIZE 0x400
|
||||
#endif
|
||||
|
||||
#define Stack_Size MBED_BOOT_STACK_SIZE
|
||||
|
||||
LR_IROM1 0x00000000 0x00080000 { ; load region size_region
|
||||
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
*.o (+RO-CODE) ; prioritizes CODE in IFLASH before SPIFI
|
||||
.ANY2 (+RO-DATA) ; prioritizes DATA in IFLASH before SPIFI
|
||||
.ANY (+RO) ; remaining RO
|
||||
}
|
||||
RW_IRAM1 0x100000E8 0x0000FF18-Stack_Size { ; RW data
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
ARM_LIB_STACK (0x100000E8+0x0000FF18) EMPTY -Stack_Size { ; stack
|
||||
}
|
||||
RW_IRAM2 0x20000000 0x00004000 {
|
||||
.ANY (AHBSRAM0)
|
||||
}
|
||||
RW_IRAM3 0x20004000 0x00004000 {
|
||||
.ANY (AHBSRAM1)
|
||||
}
|
||||
}
|
||||
|
||||
LR_IROM2 0x28000000 0x01000000 {
|
||||
ER_IROM2 0x28000000 0x01000000 { ; load address = execution address
|
||||
.ANY1 (+RO-DATA) ; all DATA not fitting in IFLASH
|
||||
.ANY (SPIFI_MEM) ; DATA tagged as SPIFI_MEM
|
||||
*.o (SPIFI_MEM) ; CODE tagged as SPIFI_MEM
|
||||
}
|
||||
}
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
;/*****************************************************************************
|
||||
; * @file: startup_LPC407x_8x.s
|
||||
; * @purpose: CMSIS Cortex-M4 Core Device Startup File
|
||||
; * for the NXP LPC407x_8x Device Series
|
||||
; * @version: V1.20
|
||||
; * @date: 16. January 2012
|
||||
; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
; *
|
||||
; * Copyright (C) 2012 ARM Limited. All rights reserved.
|
||||
; * ARM Limited (ARM) is supplying this software for use with Cortex-M4
|
||||
; * processor based microcontrollers. This file can be freely distributed
|
||||
; * within development tools that are supporting such ARM based processors.
|
||||
; *
|
||||
; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
; *
|
||||
; *****************************************************************************/
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit|
|
||||
|
||||
__Vectors DCD |Image$$ARM_LIB_STACK$$ZI$$Limit| ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
; DCD 0xEFFFF5D6 ; Reserved- vector sum
|
||||
DCD 0xEFFFF39E ; Reserved- vector sum
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 16: Watchdog Timer
|
||||
DCD TIMER0_IRQHandler ; 17: Timer0
|
||||
DCD TIMER1_IRQHandler ; 18: Timer1
|
||||
DCD TIMER2_IRQHandler ; 19: Timer2
|
||||
DCD TIMER3_IRQHandler ; 20: Timer3
|
||||
DCD UART0_IRQHandler ; 21: UART0
|
||||
DCD UART1_IRQHandler ; 22: UART1
|
||||
DCD UART2_IRQHandler ; 23: UART2
|
||||
DCD UART3_IRQHandler ; 24: UART3
|
||||
DCD PWM1_IRQHandler ; 25: PWM1
|
||||
DCD I2C0_IRQHandler ; 26: I2C0
|
||||
DCD I2C1_IRQHandler ; 27: I2C1
|
||||
DCD I2C2_IRQHandler ; 28: I2C2
|
||||
DCD 0 ; 29: reserved, not for SPIFI anymore
|
||||
DCD SSP0_IRQHandler ; 30: SSP0
|
||||
DCD SSP1_IRQHandler ; 31: SSP1
|
||||
DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL)
|
||||
DCD RTC_IRQHandler ; 33: Real Time Clock
|
||||
DCD EINT0_IRQHandler ; 34: External Interrupt 0
|
||||
DCD EINT1_IRQHandler ; 35: External Interrupt 1
|
||||
DCD EINT2_IRQHandler ; 36: External Interrupt 2
|
||||
DCD EINT3_IRQHandler ; 37: External Interrupt 3
|
||||
DCD ADC_IRQHandler ; 38: A/D Converter
|
||||
DCD BOD_IRQHandler ; 39: Brown-Out Detect
|
||||
DCD USB_IRQHandler ; 40: USB
|
||||
DCD CAN_IRQHandler ; 41: CAN
|
||||
DCD DMA_IRQHandler ; 42: General Purpose DMA
|
||||
DCD I2S_IRQHandler ; 43: I2S
|
||||
DCD ENET_IRQHandler ; 44: Ethernet
|
||||
DCD MCI_IRQHandler ; 45: SD/MMC card I/F
|
||||
DCD MCPWM_IRQHandler ; 46: Motor Control PWM
|
||||
DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface
|
||||
DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL)
|
||||
DCD USBActivity_IRQHandler ; 49: USB Activity interrupt to wakeup
|
||||
DCD CANActivity_IRQHandler ; 50: CAN Activity interrupt to wakeup
|
||||
DCD UART4_IRQHandler ; 51: UART4
|
||||
DCD SSP2_IRQHandler ; 52: SSP2
|
||||
DCD LCD_IRQHandler ; 53: LCD
|
||||
DCD GPIO_IRQHandler ; 54: GPIO
|
||||
DCD PWM0_IRQHandler ; 55: PWM0
|
||||
DCD EEPROM_IRQHandler ; 56: EEPROM
|
||||
|
||||
|
||||
IF :LNOT::DEF:NO_CRP
|
||||
AREA |.ARM.__at_0x02FC|, CODE, READONLY
|
||||
CRP_Key DCD 0xFFFFFFFF
|
||||
ENDIF
|
||||
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT TIMER0_IRQHandler [WEAK]
|
||||
EXPORT TIMER1_IRQHandler [WEAK]
|
||||
EXPORT TIMER2_IRQHandler [WEAK]
|
||||
EXPORT TIMER3_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT PWM1_IRQHandler [WEAK]
|
||||
EXPORT I2C0_IRQHandler [WEAK]
|
||||
EXPORT I2C1_IRQHandler [WEAK]
|
||||
EXPORT I2C2_IRQHandler [WEAK]
|
||||
;EXPORT SPIFI_IRQHandler [WEAK]
|
||||
EXPORT SSP0_IRQHandler [WEAK]
|
||||
EXPORT SSP1_IRQHandler [WEAK]
|
||||
EXPORT PLL0_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT EINT0_IRQHandler [WEAK]
|
||||
EXPORT EINT1_IRQHandler [WEAK]
|
||||
EXPORT EINT2_IRQHandler [WEAK]
|
||||
EXPORT EINT3_IRQHandler [WEAK]
|
||||
EXPORT ADC_IRQHandler [WEAK]
|
||||
EXPORT BOD_IRQHandler [WEAK]
|
||||
EXPORT USB_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT DMA_IRQHandler [WEAK]
|
||||
EXPORT I2S_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT MCI_IRQHandler [WEAK]
|
||||
EXPORT MCPWM_IRQHandler [WEAK]
|
||||
EXPORT QEI_IRQHandler [WEAK]
|
||||
EXPORT PLL1_IRQHandler [WEAK]
|
||||
EXPORT USBActivity_IRQHandler [WEAK]
|
||||
EXPORT CANActivity_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT SSP2_IRQHandler [WEAK]
|
||||
EXPORT LCD_IRQHandler [WEAK]
|
||||
EXPORT GPIO_IRQHandler [WEAK]
|
||||
EXPORT PWM0_IRQHandler [WEAK]
|
||||
EXPORT EEPROM_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
TIMER0_IRQHandler
|
||||
TIMER1_IRQHandler
|
||||
TIMER2_IRQHandler
|
||||
TIMER3_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
PWM1_IRQHandler
|
||||
I2C0_IRQHandler
|
||||
I2C1_IRQHandler
|
||||
I2C2_IRQHandler
|
||||
;SPIFI_IRQHandler ;not used
|
||||
SSP0_IRQHandler
|
||||
SSP1_IRQHandler
|
||||
PLL0_IRQHandler
|
||||
RTC_IRQHandler
|
||||
EINT0_IRQHandler
|
||||
EINT1_IRQHandler
|
||||
EINT2_IRQHandler
|
||||
EINT3_IRQHandler
|
||||
ADC_IRQHandler
|
||||
BOD_IRQHandler
|
||||
USB_IRQHandler
|
||||
CAN_IRQHandler
|
||||
DMA_IRQHandler
|
||||
I2S_IRQHandler
|
||||
ENET_IRQHandler
|
||||
MCI_IRQHandler
|
||||
MCPWM_IRQHandler
|
||||
QEI_IRQHandler
|
||||
PLL1_IRQHandler
|
||||
USBActivity_IRQHandler
|
||||
CANActivity_IRQHandler
|
||||
UART4_IRQHandler
|
||||
SSP2_IRQHandler
|
||||
LCD_IRQHandler
|
||||
GPIO_IRQHandler
|
||||
PWM0_IRQHandler
|
||||
EEPROM_IRQHandler
|
||||
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
END
|
|
@ -1,19 +0,0 @@
|
|||
/* mbed Microcontroller Library - stackheap
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sys_helper.h"
|
||||
|
||||
/* This function specifies the amount of memory of the internal RAM to
|
||||
reserve for the stack. The default implementation will reserve 0 bytes
|
||||
which gives the normal behaviour where the stack and heap share all the
|
||||
internal RAM.
|
||||
|
||||
You can override this function in your code to reserve a number of bytes
|
||||
for the stack.
|
||||
*/
|
||||
extern "C" __attribute__((weak)) uint32_t __reserved_stack_size();
|
||||
extern "C" __attribute__((weak)) uint32_t __reserved_stack_size() {
|
||||
return 0; // return 0 to indicate that nothing is reserved
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef SYS_HELPER_H
|
||||
#define SYS_HELPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t __reserved_stack_size();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,179 +0,0 @@
|
|||
/* Linker script for mbed LPC1768 */
|
||||
|
||||
#if !defined(MBED_BOOT_STACK_SIZE)
|
||||
#define MBED_BOOT_STACK_SIZE 0x400
|
||||
#endif
|
||||
|
||||
STACK_SIZE = MBED_BOOT_STACK_SIZE;
|
||||
|
||||
/* Linker script to configure memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
|
||||
RAM (rwx) : ORIGIN = 0x100000E8, LENGTH = (64K - 0xE8)
|
||||
|
||||
USB_RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 16K
|
||||
ETH_RAM(rwx) : ORIGIN = 0x20004000, LENGTH = 16K
|
||||
}
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with other linker script that defines memory regions FLASH and RAM.
|
||||
* It references following symbols, which must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines following symbols, which code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __end__
|
||||
* end
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.isr_vector))
|
||||
*(.text*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
} > FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} > FLASH
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} > FLASH
|
||||
__exidx_end = .;
|
||||
|
||||
__etext = .;
|
||||
|
||||
.data : AT (__etext)
|
||||
{
|
||||
__data_start__ = .;
|
||||
Image$$RW_IRAM1$$Base = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(8);
|
||||
/* preinit data */
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(8);
|
||||
/* init data */
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
|
||||
|
||||
. = ALIGN(8);
|
||||
/* finit data */
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
|
||||
. = ALIGN(8);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
|
||||
} > RAM
|
||||
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
__bss_end__ = .;
|
||||
Image$$RW_IRAM1$$ZI$$Limit = . ;
|
||||
} > RAM
|
||||
|
||||
|
||||
.heap :
|
||||
{
|
||||
__end__ = .;
|
||||
end = __end__;
|
||||
*(.heap*)
|
||||
. = ORIGIN(RAM) + LENGTH(RAM) - STACK_SIZE;
|
||||
__HeapLimit = .;
|
||||
} > RAM
|
||||
|
||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||
* used for linker to calculate size of stack sections, and assign
|
||||
* values to stack symbols later */
|
||||
.stack_dummy :
|
||||
{
|
||||
*(.stack)
|
||||
} > RAM
|
||||
|
||||
/* Set stack top to end of RAM, and stack limit move down by
|
||||
* size of stack_dummy section */
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
__StackLimit = __StackTop - STACK_SIZE;
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
|
||||
|
||||
/* Code can explicitly ask for data to be
|
||||
placed in these higher RAM banks where
|
||||
they will be left uninitialized.
|
||||
*/
|
||||
.AHBSRAM0 (NOLOAD):
|
||||
{
|
||||
Image$$RW_IRAM2$$Base = . ;
|
||||
*(AHBSRAM0)
|
||||
Image$$RW_IRAM2$$ZI$$Limit = .;
|
||||
} > USB_RAM
|
||||
|
||||
.AHBSRAM1 (NOLOAD):
|
||||
{
|
||||
Image$$RW_IRAM3$$Base = . ;
|
||||
*(AHBSRAM1)
|
||||
Image$$RW_IRAM3$$ZI$$Limit = .;
|
||||
} > ETH_RAM
|
||||
}
|
|
@ -1,235 +0,0 @@
|
|||
/* File: startup_ARMCM3.s
|
||||
* Purpose: startup file for Cortex-M3/M4 devices. Should use with
|
||||
* GNU Tools for ARM Embedded Processors
|
||||
* Version: V1.1
|
||||
* Date: 17 June 2011
|
||||
*
|
||||
* Copyright (C) 2011 ARM Limited. All rights reserved.
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M3/M4
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*/
|
||||
.syntax unified
|
||||
.arch armv7-m
|
||||
|
||||
/* Memory Model
|
||||
The HEAP starts at the end of the DATA section and grows upward.
|
||||
|
||||
The STACK starts at the end of the RAM and grows downward.
|
||||
|
||||
The HEAP and stack STACK are only checked at compile time:
|
||||
(DATA_SIZE + HEAP_SIZE + STACK_SIZE) < RAM_SIZE
|
||||
|
||||
This is just a check for the bare minimum for the Heap+Stack area before
|
||||
aborting compilation, it is not the run time limit:
|
||||
Heap_Size + Stack_Size = 0x80 + 0x80 = 0x100
|
||||
*/
|
||||
.section .stack
|
||||
.align 3
|
||||
#ifdef __STACK_SIZE
|
||||
.equ Stack_Size, __STACK_SIZE
|
||||
#else
|
||||
.equ Stack_Size, 0xc00
|
||||
#endif
|
||||
.globl __StackTop
|
||||
.globl __StackLimit
|
||||
__StackLimit:
|
||||
.space Stack_Size
|
||||
.size __StackLimit, . - __StackLimit
|
||||
__StackTop:
|
||||
.size __StackTop, . - __StackTop
|
||||
|
||||
.section .heap
|
||||
.align 3
|
||||
#ifdef __HEAP_SIZE
|
||||
.equ Heap_Size, __HEAP_SIZE
|
||||
#else
|
||||
.equ Heap_Size, 0x800
|
||||
#endif
|
||||
.globl __HeapBase
|
||||
.globl __HeapLimit
|
||||
__HeapBase:
|
||||
.space Heap_Size
|
||||
.size __HeapBase, . - __HeapBase
|
||||
__HeapLimit:
|
||||
.size __HeapLimit, . - __HeapLimit
|
||||
|
||||
.section .isr_vector
|
||||
.align 2
|
||||
.globl __isr_vector
|
||||
__isr_vector:
|
||||
.long __StackTop /* Top of Stack */
|
||||
.long Reset_Handler /* Reset Handler */
|
||||
.long NMI_Handler /* NMI Handler */
|
||||
.long HardFault_Handler /* Hard Fault Handler */
|
||||
.long MemManage_Handler /* MPU Fault Handler */
|
||||
.long BusFault_Handler /* Bus Fault Handler */
|
||||
.long UsageFault_Handler /* Usage Fault Handler */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long SVC_Handler /* SVCall Handler */
|
||||
.long DebugMon_Handler /* Debug Monitor Handler */
|
||||
.long 0 /* Reserved */
|
||||
.long PendSV_Handler /* PendSV Handler */
|
||||
.long SysTick_Handler /* SysTick Handler */
|
||||
|
||||
/* External interrupts */
|
||||
.long WDT_IRQHandler /* 16: Watchdog Timer */
|
||||
.long TIMER0_IRQHandler /* 17: Timer0 */
|
||||
.long TIMER1_IRQHandler /* 18: Timer1 */
|
||||
.long TIMER2_IRQHandler /* 19: Timer2 */
|
||||
.long TIMER3_IRQHandler /* 20: Timer3 */
|
||||
.long UART0_IRQHandler /* 21: UART0 */
|
||||
.long UART1_IRQHandler /* 22: UART1 */
|
||||
.long UART2_IRQHandler /* 23: UART2 */
|
||||
.long UART3_IRQHandler /* 24: UART3 */
|
||||
.long PWM1_IRQHandler /* 25: PWM1 */
|
||||
.long I2C0_IRQHandler /* 26: I2C0 */
|
||||
.long I2C1_IRQHandler /* 27: I2C1 */
|
||||
.long I2C2_IRQHandler /* 28: I2C2 */
|
||||
.long 0 /* 29: Reserved */
|
||||
.long SSP0_IRQHandler /* 30: SSP0 */
|
||||
.long SSP1_IRQHandler /* 31: SSP1 */
|
||||
.long PLL0_IRQHandler /* 32: PLL0 Lock (Main PLL) */
|
||||
.long RTC_IRQHandler /* 33: Real Time Clock */
|
||||
.long EINT0_IRQHandler /* 34: External Interrupt 0 */
|
||||
.long EINT1_IRQHandler /* 35: External Interrupt 1 */
|
||||
.long EINT2_IRQHandler /* 36: External Interrupt 2 */
|
||||
.long EINT3_IRQHandler /* 37: External Interrupt 3 */
|
||||
.long ADC_IRQHandler /* 38: A/D Converter */
|
||||
.long BOD_IRQHandler /* 39: Brown-Out Detect */
|
||||
.long USB_IRQHandler /* 40: USB */
|
||||
.long CAN_IRQHandler /* 41: CAN */
|
||||
.long DMA_IRQHandler /* 42: General Purpose DMA */
|
||||
.long I2S_IRQHandler /* 43: I2S */
|
||||
.long ENET_IRQHandler /* 44: Ethernet */
|
||||
.long MCI_IRQHandler /* 45: SD/MMC carf I/F */
|
||||
.long MCPWM_IRQHandler /* 46: Motor Control PWM */
|
||||
.long QEI_IRQHandler /* 47: Quadrature Encoder Interface */
|
||||
.long PLL1_IRQHandler /* 48: PLL1 Lock (USB PLL) */
|
||||
.long USBActivity_IRQHandler /* 49: USB Activity */
|
||||
.long CANActivity_IRQHandler /* 50: CAN Activity */
|
||||
.long UART4_IRQHandler /* 51: UART4 */
|
||||
.long SSP2_IRQHandler /* 52: SSP2 */
|
||||
.long LCD_IRQHandler /* 53: LCD */
|
||||
.long GPIO_IRQHandler /* 54: GPIO */
|
||||
.long PWM0_IRQHandler /* 55: PWM0 */
|
||||
.long EEPROM_IRQHandler /* 56: EEPROM */
|
||||
|
||||
.size __isr_vector, . - __isr_vector
|
||||
|
||||
.text
|
||||
.thumb
|
||||
.thumb_func
|
||||
.align 2
|
||||
.globl Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
/* Loop to copy data from read only memory to RAM. The ranges
|
||||
* of copy from/to are specified by following symbols evaluated in
|
||||
* linker script.
|
||||
* _etext: End of code section, i.e., begin of data sections to copy from.
|
||||
* __data_start__/__data_end__: RAM address range that data should be
|
||||
* copied to. Both must be aligned to 4 bytes boundary. */
|
||||
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__data_end__
|
||||
|
||||
.Lflash_to_ram_loop:
|
||||
cmp r2, r3
|
||||
ittt lt
|
||||
ldrlt r0, [r1], #4
|
||||
strlt r0, [r2], #4
|
||||
blt .Lflash_to_ram_loop
|
||||
|
||||
ldr r0, =SystemInit
|
||||
blx r0
|
||||
ldr r0, =_start
|
||||
bx r0
|
||||
.pool
|
||||
.size Reset_Handler, . - Reset_Handler
|
||||
|
||||
.text
|
||||
/* Macro to define default handlers. Default handler
|
||||
* will be weak symbol and just dead loops. They can be
|
||||
* overwritten by other handlers */
|
||||
.macro def_default_handler handler_name
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak \handler_name
|
||||
.type \handler_name, %function
|
||||
\handler_name :
|
||||
b .
|
||||
.size \handler_name, . - \handler_name
|
||||
.endm
|
||||
|
||||
def_default_handler NMI_Handler
|
||||
def_default_handler HardFault_Handler
|
||||
def_default_handler MemManage_Handler
|
||||
def_default_handler BusFault_Handler
|
||||
def_default_handler UsageFault_Handler
|
||||
def_default_handler SVC_Handler
|
||||
def_default_handler DebugMon_Handler
|
||||
def_default_handler PendSV_Handler
|
||||
def_default_handler SysTick_Handler
|
||||
def_default_handler Default_Handler
|
||||
|
||||
.macro def_irq_default_handler handler_name
|
||||
.weak \handler_name
|
||||
.set \handler_name, Default_Handler
|
||||
.endm
|
||||
|
||||
def_irq_default_handler WDT_IRQHandler
|
||||
def_irq_default_handler TIMER0_IRQHandler
|
||||
def_irq_default_handler TIMER1_IRQHandler
|
||||
def_irq_default_handler TIMER2_IRQHandler
|
||||
def_irq_default_handler TIMER3_IRQHandler
|
||||
def_irq_default_handler UART0_IRQHandler
|
||||
def_irq_default_handler UART1_IRQHandler
|
||||
def_irq_default_handler UART2_IRQHandler
|
||||
def_irq_default_handler UART3_IRQHandler
|
||||
def_irq_default_handler PWM1_IRQHandler
|
||||
def_irq_default_handler I2C0_IRQHandler
|
||||
def_irq_default_handler I2C1_IRQHandler
|
||||
def_irq_default_handler I2C2_IRQHandler
|
||||
/* def_irq_default_handler SPI_IRQHandler */
|
||||
def_irq_default_handler SSP0_IRQHandler
|
||||
def_irq_default_handler SSP1_IRQHandler
|
||||
def_irq_default_handler PLL0_IRQHandler
|
||||
def_irq_default_handler RTC_IRQHandler
|
||||
def_irq_default_handler EINT0_IRQHandler
|
||||
def_irq_default_handler EINT1_IRQHandler
|
||||
def_irq_default_handler EINT2_IRQHandler
|
||||
def_irq_default_handler EINT3_IRQHandler
|
||||
def_irq_default_handler ADC_IRQHandler
|
||||
def_irq_default_handler BOD_IRQHandler
|
||||
def_irq_default_handler USB_IRQHandler
|
||||
def_irq_default_handler CAN_IRQHandler
|
||||
def_irq_default_handler DMA_IRQHandler
|
||||
def_irq_default_handler I2S_IRQHandler
|
||||
def_irq_default_handler ENET_IRQHandler
|
||||
def_irq_default_handler MCI_IRQHandler
|
||||
def_irq_default_handler MCPWM_IRQHandler
|
||||
def_irq_default_handler QEI_IRQHandler
|
||||
def_irq_default_handler PLL1_IRQHandler
|
||||
def_irq_default_handler USBActivity_IRQHandler
|
||||
def_irq_default_handler CANActivity_IRQHandler
|
||||
def_irq_default_handler UART4_IRQHandler
|
||||
def_irq_default_handler SSP2_IRQHandler
|
||||
def_irq_default_handler LCD_IRQHandler
|
||||
def_irq_default_handler GPIO_IRQHandler
|
||||
def_irq_default_handler PWM0_IRQHandler
|
||||
def_irq_default_handler EEPROM_IRQHandler
|
||||
def_irq_default_handler DEF_IRQHandler
|
||||
|
||||
.end
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF;
|
||||
define symbol __ICFEDIT_region_NVIC_start__ = 0x10000000;
|
||||
define symbol __ICFEDIT_region_NVIC_end__ = 0x100000E7;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x100000E8;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x1000FFDF;
|
||||
/*-Sizes-*/
|
||||
if (!isdefinedsymbol(MBED_BOOT_STACK_SIZE)) {
|
||||
define symbol MBED_BOOT_STACK_SIZE = 0x400;
|
||||
}
|
||||
|
||||
define symbol __ICFEDIT_size_cstack__ = MBED_BOOT_STACK_SIZE;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x4000;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol __CRP_start__ = 0x000002FC;
|
||||
define symbol __CRP_end__ = 0x000002FF;
|
||||
|
||||
define symbol __RAM1_start__ = 0x20000000;
|
||||
define symbol __RAM1_end__ = 0x20007FFF;
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__] - mem:[from __CRP_start__ to __CRP_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
define region CRP_region = mem:[from __CRP_start__ to __CRP_end__];
|
||||
define region RAM1_region = mem:[from __RAM1_start__ to __RAM1_end__];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
initialize by copy { readwrite };
|
||||
do not initialize { section .noinit };
|
||||
|
||||
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
place in ROM_region { readonly };
|
||||
place in RAM_region { readwrite,
|
||||
block HEAP, block CSTACK };
|
||||
place in CRP_region { section .crp };
|
||||
place in RAM1_region { section .sram };
|
|
@ -1,256 +0,0 @@
|
|||
/**************************************************
|
||||
*
|
||||
* Part one of the system initialization code, contains low-level
|
||||
* initialization, plain thumb variant.
|
||||
*
|
||||
* Copyright 2011 IAR Systems. All rights reserved.
|
||||
*
|
||||
* $Revision: 47876 $
|
||||
*
|
||||
**************************************************/
|
||||
|
||||
;
|
||||
; The modules in this file are included in the libraries, and may be replaced
|
||||
; by any user-defined modules that define the PUBLIC symbol _program_start or
|
||||
; a user defined start symbol.
|
||||
; To override the cstartup defined in the library, simply add your modified
|
||||
; version to the workbench project.
|
||||
;
|
||||
; The vector table is normally located at address 0.
|
||||
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
|
||||
; The name "__vector_table" has special meaning for C-SPY:
|
||||
; it is where the SP start value is found, and the NVIC vector
|
||||
; table register (VTOR) is initialized to this address if != 0.
|
||||
;
|
||||
; Cortex-M version
|
||||
;
|
||||
|
||||
|
||||
MODULE ?cstartup
|
||||
|
||||
;; Forward declaration of sections.
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
|
||||
SECTION .intvec:CODE:NOROOT(2)
|
||||
|
||||
EXTERN __iar_program_start
|
||||
EXTERN SystemInit
|
||||
PUBLIC __vector_table
|
||||
PUBLIC __vector_table_0x1c
|
||||
PUBLIC __Vectors
|
||||
PUBLIC __Vectors_End
|
||||
PUBLIC __Vectors_Size
|
||||
|
||||
DATA
|
||||
|
||||
__vector_table
|
||||
DCD sfe(CSTACK)
|
||||
DCD Reset_Handler
|
||||
DCD NMI_Handler
|
||||
DCD HardFault_Handler
|
||||
DCD MemManage_Handler
|
||||
DCD BusFault_Handler
|
||||
DCD UsageFault_Handler
|
||||
__vector_table_0x1c
|
||||
DCD 0xEFFFF39E ; Reserved- vector sum
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD 0
|
||||
DCD SVC_Handler
|
||||
DCD DebugMon_Handler
|
||||
DCD 0
|
||||
DCD PendSV_Handler
|
||||
DCD SysTick_Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 16: Watchdog Timer
|
||||
DCD TIMER0_IRQHandler ; 17: Timer0
|
||||
DCD TIMER1_IRQHandler ; 18: Timer1
|
||||
DCD TIMER2_IRQHandler ; 19: Timer2
|
||||
DCD TIMER3_IRQHandler ; 20: Timer3
|
||||
DCD UART0_IRQHandler ; 21: UART0
|
||||
DCD UART1_IRQHandler ; 22: UART1
|
||||
DCD UART2_IRQHandler ; 23: UART2
|
||||
DCD UART3_IRQHandler ; 24: UART3
|
||||
DCD PWM1_IRQHandler ; 25: PWM1
|
||||
DCD I2C0_IRQHandler ; 26: I2C0
|
||||
DCD I2C1_IRQHandler ; 27: I2C1
|
||||
DCD I2C2_IRQHandler ; 28: I2C2
|
||||
DCD 0 ; 29: reserved, not for SPIFI anymore
|
||||
DCD SSP0_IRQHandler ; 30: SSP0
|
||||
DCD SSP1_IRQHandler ; 31: SSP1
|
||||
DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL)
|
||||
DCD RTC_IRQHandler ; 33: Real Time Clock
|
||||
DCD EINT0_IRQHandler ; 34: External Interrupt 0
|
||||
DCD EINT1_IRQHandler ; 35: External Interrupt 1
|
||||
DCD EINT2_IRQHandler ; 36: External Interrupt 2
|
||||
DCD EINT3_IRQHandler ; 37: External Interrupt 3
|
||||
DCD ADC_IRQHandler ; 38: A/D Converter
|
||||
DCD BOD_IRQHandler ; 39: Brown-Out Detect
|
||||
DCD USB_IRQHandler ; 40: USB
|
||||
DCD CAN_IRQHandler ; 41: CAN
|
||||
DCD DMA_IRQHandler ; 42: General Purpose DMA
|
||||
DCD I2S_IRQHandler ; 43: I2S
|
||||
DCD ENET_IRQHandler ; 44: Ethernet
|
||||
DCD MCI_IRQHandler ; 45: SD/MMC card I/F
|
||||
DCD MCPWM_IRQHandler ; 46: Motor Control PWM
|
||||
DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface
|
||||
DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL)
|
||||
DCD USBActivity_IRQHandler ; 49: USB Activity interrupt to wakeup
|
||||
DCD CANActivity_IRQHandler ; 50: CAN Activity interrupt to wakeup
|
||||
DCD UART4_IRQHandler ; 51: UART4
|
||||
DCD SSP2_IRQHandler ; 52: SSP2
|
||||
DCD LCD_IRQHandler ; 53: LCD
|
||||
DCD GPIO_IRQHandler ; 54: GPIO
|
||||
DCD PWM0_IRQHandler ; 55: PWM0
|
||||
DCD EEPROM_IRQHandler ; 56: EEPROM
|
||||
__Vectors_End
|
||||
|
||||
__Vectors EQU __vector_table
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Default interrupt handlers.
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
THUMB
|
||||
PUBWEAK Reset_Handler
|
||||
SECTION .text:CODE:NOROOT:REORDER(2)
|
||||
Reset_Handler
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__iar_program_start
|
||||
BX R0
|
||||
|
||||
PUBWEAK NMI_Handler
|
||||
PUBWEAK HardFault_Handler
|
||||
PUBWEAK MemManage_Handler
|
||||
PUBWEAK BusFault_Handler
|
||||
PUBWEAK UsageFault_Handler
|
||||
PUBWEAK SVC_Handler
|
||||
PUBWEAK DebugMon_Handler
|
||||
PUBWEAK PendSV_Handler
|
||||
PUBWEAK SysTick_Handler
|
||||
PUBWEAK WDT_IRQHandler
|
||||
PUBWEAK TIMER0_IRQHandler
|
||||
PUBWEAK TIMER1_IRQHandler
|
||||
PUBWEAK TIMER2_IRQHandler
|
||||
PUBWEAK TIMER3_IRQHandler
|
||||
PUBWEAK UART0_IRQHandler
|
||||
PUBWEAK UART1_IRQHandler
|
||||
PUBWEAK UART2_IRQHandler
|
||||
PUBWEAK UART3_IRQHandler
|
||||
PUBWEAK PWM1_IRQHandler
|
||||
PUBWEAK I2C0_IRQHandler
|
||||
PUBWEAK I2C1_IRQHandler
|
||||
PUBWEAK I2C2_IRQHandler
|
||||
;SPIFI_IRQHandler ;not used
|
||||
PUBWEAK SSP0_IRQHandler
|
||||
PUBWEAK SSP1_IRQHandler
|
||||
PUBWEAK PLL0_IRQHandler
|
||||
PUBWEAK RTC_IRQHandler
|
||||
PUBWEAK EINT0_IRQHandler
|
||||
PUBWEAK EINT1_IRQHandler
|
||||
PUBWEAK EINT2_IRQHandler
|
||||
PUBWEAK EINT3_IRQHandler
|
||||
PUBWEAK ADC_IRQHandler
|
||||
PUBWEAK BOD_IRQHandler
|
||||
PUBWEAK USB_IRQHandler
|
||||
PUBWEAK CAN_IRQHandler
|
||||
PUBWEAK DMA_IRQHandler
|
||||
PUBWEAK I2S_IRQHandler
|
||||
PUBWEAK ENET_IRQHandler
|
||||
PUBWEAK MCI_IRQHandler
|
||||
PUBWEAK MCPWM_IRQHandler
|
||||
PUBWEAK QEI_IRQHandler
|
||||
PUBWEAK PLL1_IRQHandler
|
||||
PUBWEAK USBActivity_IRQHandler
|
||||
PUBWEAK CANActivity_IRQHandler
|
||||
PUBWEAK UART4_IRQHandler
|
||||
PUBWEAK SSP2_IRQHandler
|
||||
PUBWEAK LCD_IRQHandler
|
||||
PUBWEAK GPIO_IRQHandler
|
||||
PUBWEAK PWM0_IRQHandler
|
||||
PUBWEAK EEPROM_IRQHandler
|
||||
|
||||
SECTION .text:CODE:REORDER:NOROOT(1)
|
||||
THUMB
|
||||
NMI_Handler
|
||||
HardFault_Handler
|
||||
MemManage_Handler
|
||||
BusFault_Handler
|
||||
UsageFault_Handler
|
||||
SVC_Handler
|
||||
DebugMon_Handler
|
||||
PendSV_Handler
|
||||
SysTick_Handler
|
||||
WDT_IRQHandler
|
||||
TIMER0_IRQHandler
|
||||
TIMER1_IRQHandler
|
||||
TIMER2_IRQHandler
|
||||
TIMER3_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
PWM1_IRQHandler
|
||||
I2C0_IRQHandler
|
||||
I2C1_IRQHandler
|
||||
I2C2_IRQHandler
|
||||
;SPIFI_IRQHandler ;not used
|
||||
SSP0_IRQHandler
|
||||
SSP1_IRQHandler
|
||||
PLL0_IRQHandler
|
||||
RTC_IRQHandler
|
||||
EINT0_IRQHandler
|
||||
EINT1_IRQHandler
|
||||
EINT2_IRQHandler
|
||||
EINT3_IRQHandler
|
||||
ADC_IRQHandler
|
||||
BOD_IRQHandler
|
||||
USB_IRQHandler
|
||||
CAN_IRQHandler
|
||||
DMA_IRQHandler
|
||||
I2S_IRQHandler
|
||||
ENET_IRQHandler
|
||||
MCI_IRQHandler
|
||||
MCPWM_IRQHandler
|
||||
QEI_IRQHandler
|
||||
PLL1_IRQHandler
|
||||
USBActivity_IRQHandler
|
||||
CANActivity_IRQHandler
|
||||
UART4_IRQHandler
|
||||
SSP2_IRQHandler
|
||||
LCD_IRQHandler
|
||||
GPIO_IRQHandler
|
||||
PWM0_IRQHandler
|
||||
EEPROM_IRQHandler
|
||||
Default_IRQHandler
|
||||
B Default_IRQHandler
|
||||
|
||||
SECTION .crp:CODE:ROOT(2)
|
||||
DATA
|
||||
/* Code Read Protection
|
||||
NO_ISP 0x4E697370 - Prevents sampling of pin PIO0_1 for entering ISP mode
|
||||
CRP1 0x12345678 - Write to RAM command cannot access RAM below 0x10000300.
|
||||
- Copy RAM to flash command can not write to Sector 0.
|
||||
- Erase command can erase Sector 0 only when all sectors
|
||||
are selected for erase.
|
||||
- Compare command is disabled.
|
||||
- Read Memory command is disabled.
|
||||
CRP2 0x87654321 - Read Memory is disabled.
|
||||
- Write to RAM is disabled.
|
||||
- "Go" command is disabled.
|
||||
- Copy RAM to flash is disabled.
|
||||
- Compare is disabled.
|
||||
CRP3 0x43218765 - Access to chip via the SWD pins is disabled. ISP entry
|
||||
by pulling PIO0_1 LOW is disabled if a valid user code is
|
||||
present in flash sector 0.
|
||||
Caution: If CRP3 is selected, no future factory testing can be
|
||||
performed on the device.
|
||||
*/
|
||||
DCD 0xFFFFFFFF
|
||||
|
||||
END
|
|
@ -1,13 +0,0 @@
|
|||
/* mbed Microcontroller Library - CMSIS
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* A generic CMSIS include header, pulling in LPC407x_8x specifics
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_H
|
||||
#define MBED_CMSIS_H
|
||||
|
||||
#include "LPC407x_8x_177x_8x.h"
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2011 ARM Limited. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_NVIC_H
|
||||
#define MBED_CMSIS_NVIC_H
|
||||
|
||||
#define NVIC_NUM_VECTORS (16 + 41) // CORE + MCU Peripherals
|
||||
#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Location of vectors in RAM
|
||||
|
||||
#endif
|
|
@ -1,581 +0,0 @@
|
|||
/**********************************************************************
|
||||
* $Id$ system_LPC407x_8x_177x_8x.c 2012-01-16
|
||||
*//**
|
||||
* @file system_LPC407x_8x_177x_8x.c
|
||||
* @brief CMSIS Cortex-M3, M4 Device Peripheral Access Layer Source File
|
||||
* for the NXP LPC407x_8x_177x_8x Device Series
|
||||
*
|
||||
* ARM Limited (ARM) is supplying this software for use with
|
||||
* Cortex-M processor based microcontrollers. This file can be
|
||||
* freely distributed within development tools that are supporting
|
||||
* such ARM based processors.
|
||||
*
|
||||
* @version 1.2
|
||||
* @date 20. June. 2012
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2012, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
**********************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LPC407x_8x_177x_8x.h"
|
||||
#include "system_LPC407x_8x_177x_8x.h"
|
||||
|
||||
#define __CLK_DIV(x,y) (((y) == 0) ? 0: (x)/(y))
|
||||
|
||||
/*
|
||||
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
*/
|
||||
/*--------------------- Clock Configuration ----------------------------------
|
||||
//
|
||||
// <e> Clock Configuration
|
||||
// <h> System Controls and Status Register (SCS - address 0x400F C1A0)
|
||||
// <o1.0> EMC Shift Control Bit
|
||||
// <i> Controls how addresses are output on the EMC address pins for static memories
|
||||
// <0=> Static CS addresses match bus width; AD[1] = 0 for 32 bit, AD[0] = 0 for 16+32 bit (Bit 0 is 0)
|
||||
// <1=> Static CS addresses start at LSB 0 regardless of memory width (Bit 0 is 1)
|
||||
//
|
||||
// <o1.1> EMC Reset Disable Bit
|
||||
// <i> If 0 (zero), all registers and functions of the EMC are initialized upon any reset condition
|
||||
// <i> If 1, EMC is still retained its state through a warm reset
|
||||
// <0=> Both EMC resets are asserted when any type of chip reset event occurs (Bit 1 is 0)
|
||||
// <1=> Portions of EMC will only be reset by POR or BOR event (Bit 1 is 1)
|
||||
//
|
||||
// <o1.2> EMC Burst Control
|
||||
// <i> Set to 1 to prevent multiple sequential accesses to memory via EMC static memory chip selects
|
||||
// <0=> Burst enabled (Bit 2 is 0)
|
||||
// <1=> Bust disbled (Bit 2 is 1)
|
||||
//
|
||||
// <o1.3> MCIPWR Active Level
|
||||
// <i> Selects the active level for the SD card interface signal SD_PWR
|
||||
// <0=> SD_PWR is active low (inverted output of the SD Card interface block) (Bit 3 is 0)
|
||||
// <1=> SD_PWR is active high (follows the output of the SD Card interface block) (Bit 3 is 1)
|
||||
//
|
||||
// <o1.4> Main Oscillator Range Select
|
||||
// <0=> In Range 1 MHz to 20 MHz (Bit 4 is 0)
|
||||
// <1=> In Range 15 MHz to 25 MHz (Bit 4 is 1)
|
||||
//
|
||||
// <o1.5> Main Oscillator enable
|
||||
// <i> 0 (zero) means disabled, 1 means enable
|
||||
//
|
||||
// <o1.6> Main Oscillator status (Read-Only)
|
||||
// </h>
|
||||
//
|
||||
// <h> Clock Source Select Register (CLKSRCSEL - address 0x400F C10C)
|
||||
// <o2.0> CLKSRC: Select the clock source for sysclk to PLL0 clock
|
||||
// <0=> Internal RC oscillator (Bit 0 is 0)
|
||||
// <1=> Main oscillator (Bit 0 is 1)
|
||||
// </h>
|
||||
//
|
||||
// <e3>PLL0 Configuration (Main PLL PLL0CFG - address 0x400F C084)
|
||||
// <i> F_in is in the range of 1 MHz to 25 MHz
|
||||
// <i> F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz
|
||||
// <i> PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz
|
||||
//
|
||||
// <o4.0..4> MSEL: PLL Multiplier Value
|
||||
// <i> M Value
|
||||
// <1-32><#-1>
|
||||
//
|
||||
// <o4.5..6> PSEL: PLL Divider Value
|
||||
// <i> P Value
|
||||
// <0=> 1
|
||||
// <1=> 2
|
||||
// <2=> 4
|
||||
// <3=> 8
|
||||
// </e>
|
||||
//
|
||||
// <e5>PLL1 Configuration (Alt PLL PLL1CFG - address 0x400F C0A4)
|
||||
// <i> F_in is in the range of 1 MHz to 25 MHz
|
||||
// <i> F_cco = (F_in * M * 2 * P) is in range of 156 MHz to 320 MHz
|
||||
// <i> PLL out clock = (F_cco / (2 * P)) is in rane of 9.75 MHz to 160 MHz
|
||||
//
|
||||
// <o6.0..4> MSEL: PLL Multiplier Value
|
||||
// <i> M Value
|
||||
// <1-32><#-1>
|
||||
//
|
||||
// <o6.5..6> PSEL: PLL Divider Value
|
||||
// <i> P Value
|
||||
// <0=> 1
|
||||
// <1=> 2
|
||||
// <2=> 4
|
||||
// <3=> 8
|
||||
// </e>
|
||||
//
|
||||
// <h> CPU Clock Selection Register (CCLKSEL - address 0x400F C104)
|
||||
// <o7.0..4> CCLKDIV: Select the value for divider of CPU clock (CCLK)
|
||||
// <i> 0: The divider is turned off. No clock will be provided to the CPU
|
||||
// <i> n: The input clock is divided by n to produce the CPU clock
|
||||
// <0-31>
|
||||
//
|
||||
// <o7.8> CCLKSEL: Select the input to the divider of CPU clock
|
||||
// <0=> sysclk clock is used
|
||||
// <1=> Main PLL0 clock is used
|
||||
// </h>
|
||||
//
|
||||
// <h> USB Clock Selection Register (USBCLKSEL - 0x400F C108)
|
||||
// <o8.0..4> USBDIV: USB clock (source PLL0) divider selection
|
||||
// <0=> Divider is off and no clock provides to USB subsystem
|
||||
// <4=> Divider value is 4 (The source clock is divided by 4)
|
||||
// <6=> Divider value is 6 (The source clock is divided by 6)
|
||||
//
|
||||
// <o8.8..9> USBSEL: Select the source for USB clock divider
|
||||
// <i> When CPU clock is selected, the USB can be accessed
|
||||
// <i> by software but cannot perform USB functions
|
||||
// <0=> sysclk clock (the clock input to PLL0)
|
||||
// <1=> The clock output from PLL0
|
||||
// <2=> The clock output from PLL1
|
||||
// </h>
|
||||
//
|
||||
// <h> EMC Clock Selection Register (EMCCLKSEL - address 0x400F C100)
|
||||
// <o9.0> EMCDIV: Set the divider for EMC clock
|
||||
// <0=> Divider value is 1
|
||||
// <1=> Divider value is 2 (EMC clock is equal a half of input clock)
|
||||
// </h>
|
||||
//
|
||||
// <h> Peripheral Clock Selection Register (PCLKSEL - address 0x400F C1A8)
|
||||
// <o10.0..4> PCLKDIV: APB Peripheral clock divider
|
||||
// <i> 0: The divider is turned off. No clock will be provided to APB peripherals
|
||||
// <i> n: The input clock is divided by n to produce the APB peripheral clock
|
||||
// <0-31>
|
||||
// </h>
|
||||
//
|
||||
// <h> SPIFI Clock Selection Register (SPIFICLKSEL - address 0x400F C1B4)
|
||||
// <o11.0..4> SPIFIDIV: Set the divider for SPIFI clock
|
||||
// <i> 0: The divider is turned off. No clock will be provided to the SPIFI
|
||||
// <i> n: The input clock is divided by n to produce the SPIFI clock
|
||||
// <0-31>
|
||||
//
|
||||
// <o11.8..9> SPIFISEL: Select the input clock for SPIFI clock divider
|
||||
// <0=> sysclk clock (the clock input to PLL0)
|
||||
// <1=> The clock output from PLL0
|
||||
// <2=> The clock output from PLL1
|
||||
// </h>
|
||||
//
|
||||
// <h> Power Control for Peripherals Register (PCONP - address 0x400F C1C8)
|
||||
// <o12.0> PCLCD: LCD controller power/clock enable (bit 0)
|
||||
// <o12.1> PCTIM0: Timer/Counter 0 power/clock enable (bit 1)
|
||||
// <o12.2> PCTIM1: Timer/Counter 1 power/clock enable (bit 2)
|
||||
// <o12.3> PCUART0: UART 0 power/clock enable (bit 3)
|
||||
// <o12.4> PCUART1: UART 1 power/clock enable (bit 4)
|
||||
// <o12.5> PCPWM0: PWM0 power/clock enable (bit 5)
|
||||
// <o12.6> PCPWM1: PWM1 power/clock enable (bit 6)
|
||||
// <o12.7> PCI2C0: I2C 0 interface power/clock enable (bit 7)
|
||||
// <o12.8> PCUART4: UART 4 power/clock enable (bit 8)
|
||||
// <o12.9> PCRTC: RTC and Event Recorder power/clock enable (bit 9)
|
||||
// <o12.10> PCSSP1: SSP 1 interface power/clock enable (bit 10)
|
||||
// <o12.11> PCEMC: External Memory Controller power/clock enable (bit 11)
|
||||
// <o12.12> PCADC: A/D converter power/clock enable (bit 12)
|
||||
// <o12.13> PCCAN1: CAN controller 1 power/clock enable (bit 13)
|
||||
// <o12.14> PCCAN2: CAN controller 2 power/clock enable (bit 14)
|
||||
// <o12.15> PCGPIO: IOCON, GPIO, and GPIO interrupts power/clock enable (bit 15)
|
||||
// <o12.17> PCMCPWM: Motor Control PWM power/clock enable (bit 17)
|
||||
// <o12.18> PCQEI: Quadrature encoder interface power/clock enable (bit 18)
|
||||
// <o12.19> PCI2C1: I2C 1 interface power/clock enable (bit 19)
|
||||
// <o12.20> PCSSP2: SSP 2 interface power/clock enable (bit 20)
|
||||
// <o12.21> PCSSP0: SSP 0 interface power/clock enable (bit 21)
|
||||
// <o12.22> PCTIM2: Timer 2 power/clock enable (bit 22)
|
||||
// <o12.23> PCTIM3: Timer 3 power/clock enable (bit 23)
|
||||
// <o12.24> PCUART2: UART 2 power/clock enable (bit 24)
|
||||
// <o12.25> PCUART3: UART 3 power/clock enable (bit 25)
|
||||
// <o12.26> PCI2C2: I2C 2 interface power/clock enable (bit 26)
|
||||
// <o12.27> PCI2S: I2S interface power/clock enable (bit 27)
|
||||
// <o12.28> PCSDC: SD Card interface power/clock enable (bit 28)
|
||||
// <o12.29> PCGPDMA: GPDMA function power/clock enable (bit 29)
|
||||
// <o12.30> PCENET: Ethernet block power/clock enable (bit 30)
|
||||
// <o12.31> PCUSB: USB interface power/clock enable (bit 31)
|
||||
// </h>
|
||||
//
|
||||
// <h> Clock Output Configuration Register (CLKOUTCFG)
|
||||
// <o13.0..3> CLKOUTSEL: Clock Source for CLKOUT Selection
|
||||
// <0=> CPU clock
|
||||
// <1=> Main Oscillator
|
||||
// <2=> Internal RC Oscillator
|
||||
// <3=> USB clock
|
||||
// <4=> RTC Oscillator
|
||||
// <5=> unused
|
||||
// <6=> Watchdog Oscillator
|
||||
//
|
||||
// <o13.4..7> CLKOUTDIV: Output Clock Divider
|
||||
// <1-16><#-1>
|
||||
//
|
||||
// <o13.8> CLKOUT_EN: CLKOUT enable
|
||||
// </h>
|
||||
//
|
||||
// </e>
|
||||
*/
|
||||
|
||||
#define CLOCK_SETUP 1
|
||||
#define SCS_Val 0x00000020
|
||||
#define CLKSRCSEL_Val 0x00000001
|
||||
#define PLL0_SETUP 1
|
||||
#define PLL0CFG_Val 0x00000009
|
||||
#define PLL1_SETUP 1
|
||||
#define PLL1CFG_Val 0x00000023
|
||||
#define CCLKSEL_Val 0x00000101
|
||||
#define USBCLKSEL_Val 0x00000201
|
||||
#define EMCCLKSEL_Val 0x00000001
|
||||
#define PCLKSEL_Val 0x00000002
|
||||
#define SPIFICLKSEL_Val 0x00000002
|
||||
#define PCONP_Val 0x042887DE
|
||||
#define CLKOUTCFG_Val 0x00000100
|
||||
|
||||
#ifdef CORE_M4
|
||||
#define LPC_CPACR 0xE000ED88
|
||||
|
||||
#define SCB_MVFR0 0xE000EF40
|
||||
#define SCB_MVFR0_RESET 0x10110021
|
||||
|
||||
#define SCB_MVFR1 0xE000EF44
|
||||
#define SCB_MVFR1_RESET 0x11000011
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------- Flash Accelerator Configuration ----------------------
|
||||
//
|
||||
// <e> Flash Accelerator Configuration register (FLASHCFG - address 0x400F C000)
|
||||
// <o1.12..15> FLASHTIM: Flash Access Time
|
||||
// <0=> 1 CPU clock (for CPU clock up to 20 MHz)
|
||||
// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
|
||||
// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
|
||||
// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
|
||||
// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
|
||||
// <5=> 6 CPU clocks (for any CPU clock)
|
||||
// </e>
|
||||
*/
|
||||
|
||||
#define FLASH_SETUP 1
|
||||
#define FLASHCFG_Val 0x00005000
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Check the register settings
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
|
||||
#define CHECK_RSVD(val, mask) (val & mask)
|
||||
|
||||
/* Clock Configuration -------------------------------------------------------*/
|
||||
#if (CHECK_RSVD((SCS_Val), ~0x0000003F))
|
||||
#error "SCS: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 1))
|
||||
#error "CLKSRCSEL: Value out of range!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PLL0CFG_Val), ~0x0000007F))
|
||||
#error "PLL0CFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))
|
||||
#error "PLL1CFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((CCLKSEL_Val), ~0x0000011F))
|
||||
#error "CCLKSEL: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((USBCLKSEL_Val), ~0x0000031F))
|
||||
#error "USBCLKSEL: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((EMCCLKSEL_Val), ~0x00000001))
|
||||
#error "EMCCLKSEL: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PCLKSEL_Val), ~0x0000001F))
|
||||
#error "PCLKSEL: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PCONP_Val), ~0xFFFEFFFF))
|
||||
#error "PCONP: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
|
||||
#error "CLKOUTCFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
/* Flash Accelerator Configuration -------------------------------------------*/
|
||||
#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F000))
|
||||
#warning "FLASHCFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
DEFINES
|
||||
*----------------------------------------------------------------------------*/
|
||||
/* pll_out_clk = F_cco / (2 <20> P)
|
||||
F_cco = pll_in_clk <EFBFBD> M <EFBFBD> 2 <EFBFBD> P */
|
||||
#define __M ((PLL0CFG_Val & 0x1F) + 1)
|
||||
#define __PLL0_CLK(__F_IN) (__F_IN * __M)
|
||||
#define __CCLK_DIV (CCLKSEL_Val & 0x1F)
|
||||
#define __PCLK_DIV (PCLKSEL_Val & 0x1F)
|
||||
#define __ECLK_DIV ((EMCCLKSEL_Val & 0x01) + 1)
|
||||
|
||||
/* Determine core clock frequency according to settings */
|
||||
#if (CLOCK_SETUP) /* Clock Setup */
|
||||
|
||||
#if ((CLKSRCSEL_Val & 0x01) == 1) && ((SCS_Val & 0x20)== 0)
|
||||
#error "Main Oscillator is selected as clock source but is not enabled!"
|
||||
#endif
|
||||
|
||||
#if ((CCLKSEL_Val & 0x100) == 0x100) && (PLL0_SETUP == 0)
|
||||
#error "Main PLL is selected as clock source but is not enabled!"
|
||||
#endif
|
||||
|
||||
#if ((CCLKSEL_Val & 0x100) == 0) /* cclk = sysclk */
|
||||
#if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */
|
||||
#define __CORE_CLK (IRC_OSC / __CCLK_DIV)
|
||||
#define __PER_CLK (IRC_OSC/ __PCLK_DIV)
|
||||
#define __EMC_CLK (__CORE_CLK/ __ECLK_DIV)
|
||||
#else /* sysclk = osc_clk */
|
||||
#define __CORE_CLK (OSC_CLK / __CCLK_DIV)
|
||||
#define __PER_CLK (OSC_CLK/ __PCLK_DIV)
|
||||
#define __EMC_CLK (__CORE_CLK/ __ECLK_DIV)
|
||||
#endif
|
||||
#else /* cclk = pll_clk */
|
||||
#if ((CLKSRCSEL_Val & 0x01) == 0) /* sysclk = irc_clk */
|
||||
#define __CORE_CLK (__PLL0_CLK(IRC_OSC) / __CCLK_DIV)
|
||||
#define __PER_CLK (__PLL0_CLK(IRC_OSC) / __PCLK_DIV)
|
||||
#define __EMC_CLK (__CORE_CLK / __ECLK_DIV)
|
||||
#else /* sysclk = osc_clk */
|
||||
#define __CORE_CLK (__PLL0_CLK(OSC_CLK) / __CCLK_DIV)
|
||||
#define __PER_CLK (__PLL0_CLK(OSC_CLK) / __PCLK_DIV)
|
||||
#define __EMC_CLK (__CORE_CLK / __ECLK_DIV)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define __CORE_CLK (IRC_OSC)
|
||||
#define __PER_CLK (IRC_OSC)
|
||||
#define __EMC_CLK (__CORE_CLK)
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock Variable definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
|
||||
uint32_t PeripheralClock = __PER_CLK; /*!< Peripheral Clock Frequency (Pclk) */
|
||||
uint32_t EMCClock = __EMC_CLK; /*!< EMC Clock Frequency */
|
||||
uint32_t USBClock = (48000000UL); /*!< USB Clock Frequency - this value will
|
||||
be updated after call SystemCoreClockUpdate, should be 48MHz*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
|
||||
{
|
||||
/* Determine clock frequency according to clock register values */
|
||||
if ((LPC_SC->CCLKSEL &0x100) == 0) { /* cclk = sysclk */
|
||||
if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */
|
||||
SystemCoreClock = __CLK_DIV(IRC_OSC , (LPC_SC->CCLKSEL & 0x1F));
|
||||
PeripheralClock = __CLK_DIV(IRC_OSC , (LPC_SC->PCLKSEL & 0x1F));
|
||||
EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1));
|
||||
}
|
||||
else { /* sysclk = osc_clk */
|
||||
if ((LPC_SC->SCS & 0x40) == 0) {
|
||||
SystemCoreClock = 0; /* this should never happen! */
|
||||
PeripheralClock = 0;
|
||||
EMCClock = 0;
|
||||
}
|
||||
else {
|
||||
SystemCoreClock = __CLK_DIV(OSC_CLK , (LPC_SC->CCLKSEL & 0x1F));
|
||||
PeripheralClock = __CLK_DIV(OSC_CLK , (LPC_SC->PCLKSEL & 0x1F));
|
||||
EMCClock = (SystemCoreClock / ((LPC_SC->EMCCLKSEL & 0x01)+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* cclk = pll_clk */
|
||||
if ((LPC_SC->PLL0STAT & 0x100) == 0) { /* PLL0 not enabled */
|
||||
SystemCoreClock = 0; /* this should never happen! */
|
||||
PeripheralClock = 0;
|
||||
EMCClock = 0;
|
||||
}
|
||||
else {
|
||||
if ((LPC_SC->CLKSRCSEL & 0x01) == 0) { /* sysclk = irc_clk */
|
||||
uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1);
|
||||
uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F);
|
||||
uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F);
|
||||
uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1;
|
||||
SystemCoreClock = __CLK_DIV(IRC_OSC * mul , cpu_div);
|
||||
PeripheralClock = __CLK_DIV(IRC_OSC * mul , per_div);
|
||||
EMCClock = SystemCoreClock / emc_div;
|
||||
}
|
||||
else { /* sysclk = osc_clk */
|
||||
if ((LPC_SC->SCS & 0x40) == 0) {
|
||||
SystemCoreClock = 0; /* this should never happen! */
|
||||
PeripheralClock = 0;
|
||||
EMCClock = 0;
|
||||
}
|
||||
else {
|
||||
uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1);
|
||||
uint8_t cpu_div = (LPC_SC->CCLKSEL & 0x1F);
|
||||
uint8_t per_div = (LPC_SC->PCLKSEL & 0x1F);
|
||||
uint8_t emc_div = (LPC_SC->EMCCLKSEL & 0x01)+1;
|
||||
SystemCoreClock = __CLK_DIV(OSC_CLK * mul , cpu_div);
|
||||
PeripheralClock = __CLK_DIV(OSC_CLK * mul , per_div);
|
||||
EMCClock = SystemCoreClock / emc_div;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ---update USBClock------------------*/
|
||||
if(LPC_SC->USBCLKSEL & (0x01<<8))//Use PLL0 as the input to the USB clock divider
|
||||
{
|
||||
switch (LPC_SC->USBCLKSEL & 0x1F)
|
||||
{
|
||||
case 0:
|
||||
USBClock = 0; //no clock will be provided to the USB subsystem
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
{
|
||||
uint8_t mul = ((LPC_SC->PLL0STAT & 0x1F) + 1);
|
||||
uint8_t usb_div = (LPC_SC->USBCLKSEL & 0x1F);
|
||||
if(LPC_SC->CLKSRCSEL & 0x01) //pll_clk_in = main_osc
|
||||
USBClock = OSC_CLK * mul / usb_div;
|
||||
else //pll_clk_in = irc_clk
|
||||
USBClock = IRC_OSC * mul / usb_div;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USBClock = 0; /* this should never happen! */
|
||||
}
|
||||
}
|
||||
else if(LPC_SC->USBCLKSEL & (0x02<<8))//usb_input_clk = alt_pll (pll1)
|
||||
{
|
||||
if(LPC_SC->CLKSRCSEL & 0x01) //pll1_clk_in = main_osc
|
||||
USBClock = (OSC_CLK * ((LPC_SC->PLL1STAT & 0x1F) + 1));
|
||||
else //pll1_clk_in = irc_clk
|
||||
USBClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1));
|
||||
}
|
||||
else
|
||||
USBClock = 0; /* this should never happen! */
|
||||
}
|
||||
|
||||
/* Determine clock frequency according to clock register values */
|
||||
|
||||
#ifdef CORE_M4
|
||||
|
||||
void fpu_init(void)
|
||||
{
|
||||
// from arm trm manual:
|
||||
// ; CPACR is located at address 0xE000ED88
|
||||
// LDR.W R0, =0xE000ED88
|
||||
// ; Read CPACR
|
||||
// LDR R1, [R0]
|
||||
// ; Set bits 20-23 to enable CP10 and CP11 coprocessors
|
||||
// ORR R1, R1, #(0xF << 20)
|
||||
// ; Write back the modified value to the CPACR
|
||||
// STR R1, [R0]
|
||||
|
||||
|
||||
volatile uint32_t* regCpacr = (uint32_t*) LPC_CPACR;
|
||||
volatile uint32_t* regMvfr0 = (uint32_t*) SCB_MVFR0;
|
||||
volatile uint32_t* regMvfr1 = (uint32_t*) SCB_MVFR1;
|
||||
volatile uint32_t Cpacr;
|
||||
volatile uint32_t Mvfr0;
|
||||
volatile uint32_t Mvfr1;
|
||||
char vfpPresent = 0;
|
||||
|
||||
Mvfr0 = *regMvfr0;
|
||||
Mvfr1 = *regMvfr1;
|
||||
|
||||
vfpPresent = ((SCB_MVFR0_RESET == Mvfr0) && (SCB_MVFR1_RESET == Mvfr1));
|
||||
|
||||
if(vfpPresent)
|
||||
{
|
||||
Cpacr = *regCpacr;
|
||||
Cpacr |= (0xF << 20);
|
||||
*regCpacr = Cpacr; // enable CP10 and CP11 for full access
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the system
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System.
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
#ifndef __CODE_RED
|
||||
#ifdef CORE_M4
|
||||
fpu_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (CLOCK_SETUP) /* Clock Setup */
|
||||
LPC_SC->SCS = SCS_Val;
|
||||
if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */
|
||||
while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready */
|
||||
}
|
||||
|
||||
LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for sysclk/PLL0*/
|
||||
|
||||
#if (PLL0_SETUP)
|
||||
LPC_SC->PLL0CFG = PLL0CFG_Val;
|
||||
LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
|
||||
LPC_SC->PLL0FEED = 0xAA;
|
||||
LPC_SC->PLL0FEED = 0x55;
|
||||
while (!(LPC_SC->PLL0STAT & (1<<10)));/* Wait for PLOCK0 */
|
||||
#endif
|
||||
|
||||
#if (PLL1_SETUP)
|
||||
LPC_SC->PLL1CFG = PLL1CFG_Val;
|
||||
LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */
|
||||
LPC_SC->PLL1FEED = 0xAA;
|
||||
LPC_SC->PLL1FEED = 0x55;
|
||||
while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */
|
||||
#endif
|
||||
|
||||
LPC_SC->CCLKSEL = CCLKSEL_Val; /* Setup Clock Divider */
|
||||
LPC_SC->USBCLKSEL = USBCLKSEL_Val; /* Setup USB Clock Divider */
|
||||
LPC_SC->EMCCLKSEL = EMCCLKSEL_Val; /* EMC Clock Selection */
|
||||
LPC_SC->SPIFICLKSEL = SPIFICLKSEL_Val; /* SPIFI Clock Selection */
|
||||
LPC_SC->PCLKSEL = PCLKSEL_Val; /* Peripheral Clock Selection */
|
||||
LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */
|
||||
LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */
|
||||
#endif
|
||||
|
||||
LPC_SC->PBOOST |= 0x03; /* Power Boost control */
|
||||
|
||||
#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */
|
||||
LPC_SC->FLASHCFG = FLASHCFG_Val|0x03A;
|
||||
#endif
|
||||
#ifndef __CODE_RED
|
||||
#ifdef __RAM_MODE__
|
||||
SCB->VTOR = 0x10000000 & 0x3FFFFF80;
|
||||
#else
|
||||
SCB->VTOR = 0x00000000 & 0x3FFFFF80;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Must set ROM_LAT bit in the Matrix Arbitration Register otherwise SPIFI
|
||||
* initialization will cause debugging to HardFault */
|
||||
LPC_SC->MATRIXARB |= (1<<16);
|
||||
|
||||
/* Reset LCD Controller to prevent strange behavior when doing a partial
|
||||
* reset (happens when debugging).
|
||||
*/
|
||||
LPC_SC->RSTCON0 = 1;
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/**********************************************************************
|
||||
* $Id$ system_LPC407x_8x_177x_8x.h 2011-06-02
|
||||
*//**
|
||||
* @file system_LPC407x_8x_177x_8x.h
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File
|
||||
* for the NXP LPC Device Series
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors'
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __SYSTEM_LPC407x_8x_177x_8x_H
|
||||
#define __SYSTEM_LPC407x_8x_177x_8x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency (Pclk) */
|
||||
extern uint32_t EMCClock; /*!< EMC Clock */
|
||||
extern uint32_t USBClock; /*!< USB Frequency */
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the system
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System and update the SystemCoreClock variable.
|
||||
*/
|
||||
extern void SystemInit (void);
|
||||
|
||||
/**
|
||||
* Update SystemCoreClock variable
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Updates the SystemCoreClock with current core Clock
|
||||
* retrieved from cpu registers.
|
||||
*/
|
||||
extern void SystemCoreClockUpdate (void);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL (12000000UL) /* Oscillator frequency */
|
||||
#define OSC_CLK ( XTAL) /* Main oscillator frequency */
|
||||
#define RTC_CLK ( 32768UL) /* RTC oscillator frequency */
|
||||
#define IRC_OSC (12000000UL) /* Internal RC oscillator frequency */
|
||||
#define WDT_OSC ( 500000UL) /* Internal WDT oscillator frequency */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//-------- <<< end of configuration section >>> ------------------------------
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_LPC407x_8x_177x_8x_H */
|
|
@ -1,56 +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 "mbed_assert.h"
|
||||
#include "gpio_api.h"
|
||||
#include "pinmap.h"
|
||||
|
||||
uint32_t gpio_set(PinName pin) {
|
||||
MBED_ASSERT(pin != (PinName)NC);
|
||||
pin_function(pin, 0);
|
||||
return (1 << ((int)pin & 0x1F));
|
||||
}
|
||||
|
||||
void gpio_init(gpio_t *obj, PinName pin) {
|
||||
obj->pin = pin;
|
||||
if (pin == (PinName)NC)
|
||||
return;
|
||||
|
||||
obj->mask = gpio_set(pin);
|
||||
|
||||
LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *) ((int)(LPC_GPIO0_BASE+pin) & ~0x1F);
|
||||
|
||||
obj->reg_set = &port_reg->SET;
|
||||
obj->reg_clr = &port_reg->CLR;
|
||||
obj->reg_in = &port_reg->PIN;
|
||||
obj->reg_dir = &port_reg->DIR;
|
||||
}
|
||||
|
||||
void gpio_mode(gpio_t *obj, PinMode mode) {
|
||||
pin_mode(obj->pin, mode);
|
||||
}
|
||||
|
||||
void gpio_dir(gpio_t *obj, PinDirection direction) {
|
||||
MBED_ASSERT(obj->pin != (PinName)NC);
|
||||
|
||||
switch (direction) {
|
||||
case PIN_INPUT :
|
||||
*obj->reg_dir &= ~obj->mask;
|
||||
break;
|
||||
case PIN_OUTPUT:
|
||||
*obj->reg_dir |= obj->mask;
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,174 +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 <stddef.h>
|
||||
#include "gpio_irq_api.h"
|
||||
#include "mbed_error.h"
|
||||
#include "cmsis.h"
|
||||
|
||||
#define CHANNEL_NUM 64
|
||||
|
||||
static uint32_t channel_ids[CHANNEL_NUM] = {0};
|
||||
static gpio_irq_handler irq_handler;
|
||||
|
||||
static void handle_interrupt_in(void) {
|
||||
// Read in all current interrupt registers. We do this once as the
|
||||
// GPIO interrupt registers are on the APB bus, and this is slow.
|
||||
uint32_t rise0 = LPC_GPIOINT->IO0IntStatR;
|
||||
uint32_t fall0 = LPC_GPIOINT->IO0IntStatF;
|
||||
uint32_t rise2 = LPC_GPIOINT->IO2IntStatR;
|
||||
uint32_t fall2 = LPC_GPIOINT->IO2IntStatF;
|
||||
|
||||
uint8_t bitloc;
|
||||
|
||||
// Continue as long as there are interrupts pending
|
||||
while(rise0 > 0) {
|
||||
// CLZ returns number of leading zeros, 31 minus that is location of
|
||||
// first pending interrupt
|
||||
bitloc = 31 - __CLZ(rise0);
|
||||
if (channel_ids[bitloc] != 0)
|
||||
irq_handler(channel_ids[bitloc], IRQ_RISE); //Run that interrupt
|
||||
|
||||
// Both clear the interrupt with clear register, and remove it from
|
||||
// our local copy of the interrupt pending register
|
||||
LPC_GPIOINT->IO0IntClr = 1 << bitloc;
|
||||
rise0 -= 1<<bitloc;
|
||||
}
|
||||
|
||||
// Continue as long as there are interrupts pending
|
||||
while(fall0 > 0) {
|
||||
// CLZ returns number of leading zeros, 31 minus that is location of
|
||||
// first pending interrupt
|
||||
bitloc = 31 - __CLZ(fall0);
|
||||
if (channel_ids[bitloc] != 0)
|
||||
irq_handler(channel_ids[bitloc], IRQ_FALL); //Run that interrupt
|
||||
|
||||
// Both clear the interrupt with clear register, and remove it from
|
||||
// our local copy of the interrupt pending register
|
||||
LPC_GPIOINT->IO0IntClr = 1 << bitloc;
|
||||
fall0 -= 1<<bitloc;
|
||||
}
|
||||
|
||||
// Same for port 2
|
||||
|
||||
// Continue as long as there are interrupts pending
|
||||
while(rise2 > 0) {
|
||||
// CLZ returns number of leading zeros, 31 minus that is location of
|
||||
// first pending interrupt
|
||||
bitloc = 31 - __CLZ(rise2);
|
||||
if (channel_ids[bitloc+32] != 0)
|
||||
irq_handler(channel_ids[bitloc+32], IRQ_RISE); //Run that interrupt
|
||||
|
||||
// Both clear the interrupt with clear register, and remove it from
|
||||
// our local copy of the interrupt pending register
|
||||
LPC_GPIOINT->IO2IntClr = 1 << bitloc;
|
||||
rise2 -= 1<<bitloc;
|
||||
}
|
||||
|
||||
// Continue as long as there are interrupts pending
|
||||
while(fall2 > 0) {
|
||||
// CLZ returns number of leading zeros, 31 minus that is location of
|
||||
// first pending interrupt
|
||||
bitloc = 31 - __CLZ(fall2);
|
||||
if (channel_ids[bitloc+32] != 0)
|
||||
irq_handler(channel_ids[bitloc+32], IRQ_FALL); //Run that interrupt
|
||||
|
||||
// Both clear the interrupt with clear register, and remove it from
|
||||
// our local copy of the interrupt pending register
|
||||
LPC_GPIOINT->IO2IntClr = 1 << bitloc;
|
||||
fall2 -= 1<<bitloc;
|
||||
}
|
||||
}
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
|
||||
if (pin == NC) return -1;
|
||||
|
||||
irq_handler = handler;
|
||||
|
||||
obj->port = ((int)(LPC_GPIO0_BASE+pin) & ~0x1F);
|
||||
obj->pin = (int)pin % 32;
|
||||
|
||||
// Interrupts available only on GPIO0 and GPIO2
|
||||
if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) {
|
||||
error("pins on this port cannot generate interrupts");
|
||||
}
|
||||
|
||||
// put us in the interrupt table
|
||||
int index = (obj->port == LPC_GPIO0_BASE) ? obj->pin : obj->pin + 32;
|
||||
channel_ids[index] = id;
|
||||
obj->ch = index;
|
||||
|
||||
NVIC_SetVector(GPIO_IRQn, (uint32_t)handle_interrupt_in);
|
||||
NVIC_EnableIRQ(GPIO_IRQn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_irq_free(gpio_irq_t *obj) {
|
||||
channel_ids[obj->ch] = 0;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
|
||||
// ensure nothing is pending
|
||||
switch (obj->port) {
|
||||
case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break;
|
||||
case LPC_GPIO2_BASE: LPC_GPIOINT->IO2IntClr = 1 << obj->pin; break;
|
||||
}
|
||||
|
||||
// enable the pin interrupt
|
||||
if (event == IRQ_RISE) {
|
||||
switch (obj->port) {
|
||||
case LPC_GPIO0_BASE:
|
||||
if (enable) {
|
||||
LPC_GPIOINT->IO0IntEnR |= 1 << obj->pin;
|
||||
} else {
|
||||
LPC_GPIOINT->IO0IntEnR &= ~(1 << obj->pin);
|
||||
}
|
||||
break;
|
||||
case LPC_GPIO2_BASE:
|
||||
if (enable) {
|
||||
LPC_GPIOINT->IO2IntEnR |= 1 << obj->pin;
|
||||
} else {
|
||||
LPC_GPIOINT->IO2IntEnR &= ~(1 << obj->pin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (obj->port) {
|
||||
case LPC_GPIO0_BASE:
|
||||
if (enable) {
|
||||
LPC_GPIOINT->IO0IntEnF |= 1 << obj->pin;
|
||||
} else {
|
||||
LPC_GPIOINT->IO0IntEnF &= ~(1 << obj->pin);
|
||||
}
|
||||
break;
|
||||
case LPC_GPIO2_BASE:
|
||||
if (enable) {
|
||||
LPC_GPIOINT->IO2IntEnF |= 1 << obj->pin;
|
||||
} else {
|
||||
LPC_GPIOINT->IO2IntEnF &= ~(1 << obj->pin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj) {
|
||||
NVIC_EnableIRQ(GPIO_IRQn);
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_irq_t *obj) {
|
||||
NVIC_DisableIRQ(GPIO_IRQn);
|
||||
}
|
|
@ -1,56 +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.
|
||||
*/
|
||||
#ifndef MBED_GPIO_OBJECT_H
|
||||
#define MBED_GPIO_OBJECT_H
|
||||
|
||||
#include "mbed_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PinName pin;
|
||||
uint32_t mask;
|
||||
|
||||
__IO uint32_t *reg_dir;
|
||||
__IO uint32_t *reg_set;
|
||||
__IO uint32_t *reg_clr;
|
||||
__I uint32_t *reg_in;
|
||||
} gpio_t;
|
||||
|
||||
static inline void gpio_write(gpio_t *obj, int value) {
|
||||
MBED_ASSERT(obj->pin != (PinName)NC);
|
||||
if (value)
|
||||
*obj->reg_set = obj->mask;
|
||||
else
|
||||
*obj->reg_clr = obj->mask;
|
||||
}
|
||||
|
||||
static inline int gpio_read(gpio_t *obj) {
|
||||
MBED_ASSERT(obj->pin != (PinName)NC);
|
||||
return ((*obj->reg_in & obj->mask) ? 1 : 0);
|
||||
}
|
||||
|
||||
static inline int gpio_is_connected(const gpio_t *obj) {
|
||||
return obj->pin != (PinName)NC;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,80 +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.
|
||||
*/
|
||||
#ifndef MBED_OBJECTS_H
|
||||
#define MBED_OBJECTS_H
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "PortNames.h"
|
||||
#include "PeripheralNames.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct gpio_irq_s {
|
||||
uint32_t port;
|
||||
uint32_t pin;
|
||||
uint32_t ch;
|
||||
};
|
||||
|
||||
struct port_s {
|
||||
__IO uint32_t *reg_dir;
|
||||
__IO uint32_t *reg_out;
|
||||
__I uint32_t *reg_in;
|
||||
PortName port;
|
||||
uint32_t mask;
|
||||
};
|
||||
|
||||
struct pwmout_s {
|
||||
__IO uint32_t *MR;
|
||||
LPC_PWM_TypeDef *pwm;
|
||||
uint32_t channel;
|
||||
};
|
||||
|
||||
struct serial_s {
|
||||
LPC_UART_TypeDef *uart;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct analogin_s {
|
||||
ADCName adc;
|
||||
};
|
||||
|
||||
struct dac_s {
|
||||
DACName dac;
|
||||
};
|
||||
|
||||
struct can_s {
|
||||
LPC_CAN_TypeDef *dev;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct i2c_s {
|
||||
LPC_I2C_TypeDef *i2c;
|
||||
};
|
||||
|
||||
struct spi_s {
|
||||
LPC_SSP_TypeDef *spi;
|
||||
};
|
||||
|
||||
#include "gpio_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -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 "mbed_assert.h"
|
||||
#include "pinmap.h"
|
||||
#include "mbed_error.h"
|
||||
|
||||
void pin_function(PinName pin, int function) {
|
||||
MBED_ASSERT(pin != (PinName)NC);
|
||||
__IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
|
||||
|
||||
// pin function bits: [2:0] -> 111 = (0x7)
|
||||
*reg = (*reg & ~0x7) | (function & 0x7);
|
||||
}
|
||||
|
||||
void pin_mode(PinName pin, PinMode mode) {
|
||||
MBED_ASSERT(pin != (PinName)NC);
|
||||
|
||||
uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2;
|
||||
|
||||
__IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
|
||||
uint32_t tmp = *reg;
|
||||
|
||||
// pin mode bits: [4:3] -> 11000 = (0x3 << 3)
|
||||
tmp &= ~(0x3 << 3);
|
||||
tmp |= (mode & 0x3) << 3;
|
||||
|
||||
// drain
|
||||
tmp &= ~(0x1 << 10);
|
||||
tmp |= drain << 10;
|
||||
|
||||
*reg = tmp;
|
||||
}
|
|
@ -1,71 +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"
|
||||
#include "pinmap.h"
|
||||
#include "gpio_api.h"
|
||||
|
||||
|
||||
PinName port_pin(PortName port, int pin_n) {
|
||||
return (PinName)(((port << PORT_SHIFT) | pin_n));
|
||||
}
|
||||
|
||||
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
|
||||
obj->port = port;
|
||||
obj->mask = mask;
|
||||
|
||||
LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + ((int)port * 0x20));
|
||||
|
||||
port_reg->MASK = ~mask;
|
||||
|
||||
obj->reg_out = &port_reg->PIN;
|
||||
obj->reg_in = &port_reg->PIN;
|
||||
obj->reg_dir = &port_reg->DIR;
|
||||
|
||||
uint32_t i;
|
||||
// The function is set per pin: reuse gpio logic
|
||||
for (i=0; i<32; i++) {
|
||||
if (obj->mask & (1<<i)) {
|
||||
gpio_set(port_pin(obj->port, i));
|
||||
}
|
||||
}
|
||||
|
||||
port_dir(obj, dir);
|
||||
}
|
||||
|
||||
void port_mode(port_t *obj, PinMode mode) {
|
||||
uint32_t i;
|
||||
// The mode is set per pin: reuse pinmap logic
|
||||
for (i=0; i<32; i++) {
|
||||
if (obj->mask & (1<<i)) {
|
||||
pin_mode(port_pin(obj->port, i), mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void port_dir(port_t *obj, PinDirection dir) {
|
||||
switch (dir) {
|
||||
case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break;
|
||||
case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break;
|
||||
}
|
||||
}
|
||||
|
||||
void port_write(port_t *obj, int value) {
|
||||
*obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask);
|
||||
}
|
||||
|
||||
int port_read(port_t *obj) {
|
||||
return (*obj->reg_in & obj->mask);
|
||||
}
|
|
@ -1,119 +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 "rtc_api.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
// ensure rtc is running (unchanged if already running)
|
||||
|
||||
/* Setup the RTC based on a time structure, ensuring RTC is enabled
|
||||
*
|
||||
* Can be clocked by a 32.768KHz oscillator or prescale divider based on the APB clock
|
||||
* - We want to use the 32khz clock, allowing for sleep mode
|
||||
*
|
||||
* Most registers are not changed by a Reset
|
||||
* - We must initialize these registers between power-on and setting the RTC into operation
|
||||
|
||||
* Clock Control Register
|
||||
* RTC_CCR[0] : Enable - 0 = Disabled, 1 = Enabled
|
||||
* RTC_CCR[1] : Reset - 0 = Normal, 1 = Reset
|
||||
*
|
||||
* The RTC may already be running, so we should set it up
|
||||
* without impacting if it is the case
|
||||
*/
|
||||
void rtc_init(void) {
|
||||
LPC_SC->PCONP |= 0x200; // Ensure power is on
|
||||
LPC_RTC->CCR = 0x00;
|
||||
|
||||
LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled
|
||||
}
|
||||
|
||||
void rtc_free(void) {
|
||||
// [TODO]
|
||||
}
|
||||
|
||||
/*
|
||||
* Little check routine to see if the RTC has been enabled
|
||||
*
|
||||
* Clock Control Register
|
||||
* RTC_CCR[0] : 0 = Disabled, 1 = Enabled
|
||||
*
|
||||
*/
|
||||
int rtc_isenabled(void) {
|
||||
return(((LPC_RTC->CCR) & 0x01) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* RTC Registers
|
||||
* RTC_SEC Seconds 0-59
|
||||
* RTC_MIN Minutes 0-59
|
||||
* RTC_HOUR Hour 0-23
|
||||
* RTC_DOM Day of Month 1-28..31
|
||||
* RTC_DOW Day of Week 0-6
|
||||
* RTC_DOY Day of Year 1-365
|
||||
* RTC_MONTH Month 1-12
|
||||
* RTC_YEAR Year 0-4095
|
||||
*
|
||||
* struct tm
|
||||
* tm_sec seconds after the minute 0-61
|
||||
* tm_min minutes after the hour 0-59
|
||||
* tm_hour hours since midnight 0-23
|
||||
* tm_mday day of the month 1-31
|
||||
* tm_mon months since January 0-11
|
||||
* tm_year years since 1900
|
||||
* tm_wday days since Sunday 0-6
|
||||
* tm_yday days since January 1 0-365
|
||||
* tm_isdst Daylight Saving Time flag
|
||||
*/
|
||||
time_t rtc_read(void) {
|
||||
// Setup a tm structure based on the RTC
|
||||
struct tm timeinfo;
|
||||
timeinfo.tm_sec = LPC_RTC->SEC;
|
||||
timeinfo.tm_min = LPC_RTC->MIN;
|
||||
timeinfo.tm_hour = LPC_RTC->HOUR;
|
||||
timeinfo.tm_mday = LPC_RTC->DOM;
|
||||
timeinfo.tm_mon = LPC_RTC->MONTH - 1;
|
||||
timeinfo.tm_year = LPC_RTC->YEAR - 1900;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t;
|
||||
if (_rtc_maketime(&timeinfo, &t, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void rtc_write(time_t t) {
|
||||
// Convert the time in to a tm
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pause clock, and clear counter register (clears us count)
|
||||
LPC_RTC->CCR |= 2;
|
||||
|
||||
// Set the RTC
|
||||
LPC_RTC->SEC = timeinfo.tm_sec;
|
||||
LPC_RTC->MIN = timeinfo.tm_min;
|
||||
LPC_RTC->HOUR = timeinfo.tm_hour;
|
||||
LPC_RTC->DOM = timeinfo.tm_mday;
|
||||
LPC_RTC->MONTH = timeinfo.tm_mon + 1;
|
||||
LPC_RTC->YEAR = timeinfo.tm_year + 1900;
|
||||
|
||||
// Restart clock
|
||||
LPC_RTC->CCR &= ~((uint32_t)2);
|
||||
}
|
|
@ -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 "sleep_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "mbed_interface.h"
|
||||
|
||||
void hal_sleep(void) {
|
||||
LPC_SC->PCON = 0x0;
|
||||
|
||||
// SRC[SLEEPDEEP] set to 0 = sleep
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
// wait for interrupt
|
||||
__WFI();
|
||||
__NOP();
|
||||
}
|
||||
|
||||
/*
|
||||
* The mbed lpc1768 does not support the deepsleep mode
|
||||
* as a debugger is connected to it (the mbed interface).
|
||||
*
|
||||
* As mentionned in an application note from NXP:
|
||||
*
|
||||
* http://www.po-star.com/public/uploads/20120319123122_141.pdf
|
||||
*
|
||||
* {{{
|
||||
* The user should be aware of certain limitations during debugging.
|
||||
* The most important is that, due to limitations of the Cortex-M3
|
||||
* integration, the LPC17xx cannot wake up in the usual manner from
|
||||
* Deep Sleep and Power-down modes. It is recommended not to use these
|
||||
* modes during debug. Once an application is downloaded via JTAG/SWD
|
||||
* interface, the USB to SWD/JTAG debug adapter (Keil ULINK2 for example)
|
||||
* should be removed from the target board, and thereafter, power cycle
|
||||
* the LPC17xx to allow wake-up from deep sleep and power-down modes
|
||||
* }}}
|
||||
*
|
||||
* As the interface firmware does not reset the target when a
|
||||
* mbed_interface_disconnect() semihosting call is made, the
|
||||
* core cannot wake-up from deepsleep.
|
||||
*
|
||||
* We treat a deepsleep() as a normal sleep().
|
||||
*/
|
||||
void hal_deepsleep(void) {
|
||||
hal_sleep();
|
||||
}
|
|
@ -1,74 +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 <stddef.h>
|
||||
#include "us_ticker_api.h"
|
||||
#include "PeripheralNames.h"
|
||||
|
||||
#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE)
|
||||
#define US_TICKER_TIMER_IRQn TIMER3_IRQn
|
||||
|
||||
int us_ticker_inited = 0;
|
||||
|
||||
void us_ticker_init(void) {
|
||||
if (us_ticker_inited) return;
|
||||
us_ticker_inited = 1;
|
||||
|
||||
LPC_SC->PCONP |= 1 << 23; // Clock TIMER_3
|
||||
|
||||
US_TICKER_TIMER->CTCR = 0x0; // timer mode
|
||||
uint32_t PCLK = PeripheralClock;
|
||||
|
||||
US_TICKER_TIMER->TCR = 0x2; // reset
|
||||
|
||||
uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks)
|
||||
US_TICKER_TIMER->PR = prescale - 1;
|
||||
US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0
|
||||
|
||||
NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
|
||||
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
|
||||
}
|
||||
|
||||
uint32_t us_ticker_read() {
|
||||
if (!us_ticker_inited)
|
||||
us_ticker_init();
|
||||
|
||||
return US_TICKER_TIMER->TC;
|
||||
}
|
||||
|
||||
void us_ticker_set_interrupt(timestamp_t timestamp) {
|
||||
// set match value
|
||||
US_TICKER_TIMER->MR0 = (uint32_t)timestamp;
|
||||
// enable match interrupt
|
||||
US_TICKER_TIMER->MCR |= 1;
|
||||
}
|
||||
|
||||
void us_ticker_fire_interrupt(void)
|
||||
{
|
||||
NVIC_SetPendingIRQ(US_TICKER_TIMER_IRQn);
|
||||
}
|
||||
|
||||
void us_ticker_disable_interrupt(void) {
|
||||
US_TICKER_TIMER->MCR &= ~1;
|
||||
}
|
||||
|
||||
void us_ticker_clear_interrupt(void) {
|
||||
US_TICKER_TIMER->IR = 1;
|
||||
}
|
||||
|
||||
void us_ticker_free(void)
|
||||
{
|
||||
|
||||
}
|
|
@ -59,12 +59,6 @@
|
|||
#define INITIAL_SP (0x10008000UL)
|
||||
#endif
|
||||
|
||||
#elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||
|
||||
#ifndef INITIAL_SP
|
||||
#define INITIAL_SP (0x10010000UL)
|
||||
#endif
|
||||
|
||||
#elif defined(TARGET_LPC4330) || defined(TARGET_LPC4337)
|
||||
|
||||
#ifndef INITIAL_SP
|
||||
|
|
|
@ -854,75 +854,6 @@
|
|||
"1018"
|
||||
]
|
||||
},
|
||||
"MCU_LPC4088": {
|
||||
"inherits": [
|
||||
"LPCTarget"
|
||||
],
|
||||
"core": "Cortex-M4F",
|
||||
"extra_labels": [
|
||||
"NXP",
|
||||
"LPC408X",
|
||||
"NXP_EMAC"
|
||||
],
|
||||
"is_disk_virtual": true,
|
||||
"supported_toolchains": [
|
||||
"ARM",
|
||||
"GCC_ARM",
|
||||
"IAR"
|
||||
],
|
||||
"post_binary_hook": {
|
||||
"function": "LPC4088Code.binary_hook"
|
||||
},
|
||||
"device_has": [
|
||||
"ANALOGIN",
|
||||
"ANALOGOUT",
|
||||
"CAN",
|
||||
"DEBUG_AWARENESS",
|
||||
"EMAC",
|
||||
"I2C",
|
||||
"I2CSLAVE",
|
||||
"INTERRUPTIN",
|
||||
"PORTIN",
|
||||
"PORTINOUT",
|
||||
"PORTOUT",
|
||||
"PWMOUT",
|
||||
"SERIAL",
|
||||
"SLEEP",
|
||||
"SPI",
|
||||
"SPISLAVE",
|
||||
"STDIO_MESSAGES",
|
||||
"MPU",
|
||||
"USTICKER"
|
||||
],
|
||||
"device_name": "LPC4088FBD144",
|
||||
"overrides": {
|
||||
"network-default-interface-type": "ETHERNET"
|
||||
}
|
||||
},
|
||||
"LPC4088": {
|
||||
"inherits": [
|
||||
"MCU_LPC4088"
|
||||
],
|
||||
"release_versions": [
|
||||
"2",
|
||||
"5"
|
||||
],
|
||||
"detect_code": [
|
||||
"1060"
|
||||
]
|
||||
},
|
||||
"LPC4088_DM": {
|
||||
"inherits": [
|
||||
"MCU_LPC4088"
|
||||
],
|
||||
"release_versions": [
|
||||
"2",
|
||||
"5"
|
||||
],
|
||||
"detect_code": [
|
||||
"1062"
|
||||
]
|
||||
},
|
||||
"LPC4330_M4": {
|
||||
"inherits": [
|
||||
"LPCTarget"
|
||||
|
|
|
@ -45,7 +45,6 @@ class CMake(Exporter):
|
|||
"MCU_NRF51Code.binary_hook",
|
||||
"TEENSY3_1Code.binary_hook",
|
||||
"LPCTargetCode.lpc_patch",
|
||||
"LPC4088Code.binary_hook",
|
||||
"PSOC6Code.complete"
|
||||
])
|
||||
|
||||
|
|
|
@ -23,8 +23,7 @@ from tools.export.exporters import Exporter, apply_supported_whitelist
|
|||
|
||||
POST_BINARY_WHITELIST = set([
|
||||
"TEENSY3_1Code.binary_hook",
|
||||
"LPCTargetCode.lpc_patch",
|
||||
"LPC4088Code.binary_hook"
|
||||
"LPCTargetCode.lpc_patch"
|
||||
])
|
||||
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ POST_BINARY_WHITELIST = set([
|
|||
"TEENSY3_1Code.binary_hook",
|
||||
"MCU_NRF51Code.binary_hook",
|
||||
"LPCTargetCode.lpc_patch",
|
||||
"LPC4088Code.binary_hook",
|
||||
"PSOC6Code.complete"
|
||||
])
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@ class LPCXpresso(Exporter):
|
|||
|
||||
TARGETS = [
|
||||
'LPC1768',
|
||||
'LPC4088',
|
||||
'LPC4088_DM',
|
||||
'LPC4330_M4',
|
||||
'LPC1114',
|
||||
'LPC11U35_401',
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
|||
{% extends "lpcxpresso/project_common.tmpl" %}
|
|
@ -1 +0,0 @@
|
|||
{% extends "lpcxpresso/project_common.tmpl" %}
|
|
@ -64,7 +64,6 @@ class Makefile(Exporter):
|
|||
"MCU_NRF51Code.binary_hook",
|
||||
"TEENSY3_1Code.binary_hook",
|
||||
"LPCTargetCode.lpc_patch",
|
||||
"LPC4088Code.binary_hook",
|
||||
"PSOC6Code.complete"
|
||||
])
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ from tools.build_api import prepare_toolchain
|
|||
POST_BINARY_WHITELIST = set([
|
||||
"TEENSY3_1Code.binary_hook",
|
||||
"MCU_NRF51Code.binary_hook",
|
||||
"LPCTargetCode.lpc_patch",
|
||||
"LPC4088Code.binary_hook"
|
||||
"LPCTargetCode.lpc_patch"
|
||||
])
|
||||
|
||||
class MCUXpresso(GNUARMEclipse):
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
{% extends "mcuxpresso/.cproject.tmpl" %}
|
||||
|
||||
{% block cpu_config %}<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TargetConfig>
|
||||
<Properties property_0="" property_2="LPC177x_8x_407x_8x_512.cfx" property_3="NXP" property_4="LPC4088" property_count="5" version="1"/>
|
||||
<infoList vendor="NXP"><info chip="LPC4088" flash_driver="LPC177x_8x_407x_8x_512.cfx" match_id="0x481D3F47" name="LPC4088" stub="crt_emu_cm3_nxp"><chip><name>LPC4088</name>
|
||||
<family>LPC407x_8x</family>
|
||||
<vendor>NXP (formerly Philips)</vendor>
|
||||
<reset board="None" core="Real" sys="Real"/>
|
||||
<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/>
|
||||
<memory can_program="true" id="Flash" is_ro="true" type="Flash"/>
|
||||
<memory id="RAM" type="RAM"/>
|
||||
<memory id="Periph" is_volatile="true" type="Peripheral"/>
|
||||
<memoryInstance derived_from="Flash" id="MFlash512" location="0x0" size="0x80000"/>
|
||||
<memoryInstance derived_from="RAM" id="RamLoc64" location="0x10000000" size="0x10000"/>
|
||||
<memoryInstance derived_from="RAM" id="RamPeriph32" location="0x20000000" size="0x8000"/>
|
||||
<prog_flash blocksz="0x1000" location="0x0" maxprgbuff="0x1000" progwithcode="TRUE" size="0x10000"/>
|
||||
<prog_flash blocksz="0x8000" location="0x10000" maxprgbuff="0x1000" progwithcode="TRUE" size="0x70000"/>
|
||||
<peripheralInstance derived_from="V7M_MPU" id="MPU" location="0xe000ed90"/>
|
||||
<peripheralInstance derived_from="V7M_NVIC" id="NVIC" location="0xe000e000"/>
|
||||
<peripheralInstance derived_from="V7M_DCR" id="DCR" location="0xe000edf0"/>
|
||||
<peripheralInstance derived_from="V7M_ITM" id="ITM" location="0xe0000000"/>
|
||||
<peripheralInstance derived_from="FLASHCTRL" id="FLASHCTRL" location="0x200000"/>
|
||||
<peripheralInstance derived_from="GPDMA" id="GPDMA" location="0x20080000"/>
|
||||
<peripheralInstance derived_from="ETHERNET" id="ETHERNET" location="0x20084000"/>
|
||||
<peripheralInstance derived_from="LCD" id="LCD" location="0x20088000"/>
|
||||
<peripheralInstance derived_from="USB" id="USB" location="0x2008c000"/>
|
||||
<peripheralInstance derived_from="CRC" id="CRC" location="0x20090000"/>
|
||||
<peripheralInstance derived_from="GPIO" id="GPIO" location="0x20098000"/>
|
||||
<peripheralInstance derived_from="EMC" id="EMC" location="0x2009c000"/>
|
||||
<peripheralInstance derived_from="WWDT" id="WWDT" location="0x40000000"/>
|
||||
<peripheralInstance derived_from="TIMER0" id="TIMER0" location="0x40004000"/>
|
||||
<peripheralInstance derived_from="TIMER1" id="TIMER1" location="0x40008000"/>
|
||||
<peripheralInstance derived_from="UART0" id="UART0" location="0x4000c000"/>
|
||||
<peripheralInstance derived_from="UART1" id="UART1" location="0x40010000"/>
|
||||
<peripheralInstance derived_from="PWM0" id="PWM0" location="0x40014000"/>
|
||||
<peripheralInstance derived_from="PWM1" id="PWM1" location="0x40018000"/>
|
||||
<peripheralInstance derived_from="I2C0" id="I2C0" location="0x4001c000"/>
|
||||
<peripheralInstance derived_from="COMPARATOR" id="COMPARATOR" location="0x40020000"/>
|
||||
<peripheralInstance derived_from="RTC" id="RTC" location="0x40024000"/>
|
||||
<peripheralInstance derived_from="GPIOINT" id="GPIOINT" location="0x40028080"/>
|
||||
<peripheralInstance derived_from="IOCON" id="IOCON" location="0x4002c000"/>
|
||||
<peripheralInstance derived_from="SSP1" id="SSP1" location="0x40030000"/>
|
||||
<peripheralInstance derived_from="ADC" id="ADC" location="0x40034000"/>
|
||||
<peripheralInstance derived_from="CANAFRAM" id="CANAFRAM" location="0x40038000"/>
|
||||
<peripheralInstance derived_from="CANAF" id="CANAF" location="0x4003c000"/>
|
||||
<peripheralInstance derived_from="CCAN" id="CCAN" location="0x40040000"/>
|
||||
<peripheralInstance derived_from="CAN1" id="CAN1" location="0x40044000"/>
|
||||
<peripheralInstance derived_from="CAN2" id="CAN2" location="0x40048000"/>
|
||||
<peripheralInstance derived_from="I2C1" id="I2C1" location="0x4005c000"/>
|
||||
<peripheralInstance derived_from="SSP0" id="SSP0" location="0x40088000"/>
|
||||
<peripheralInstance derived_from="DAC" id="DAC" location="0x4008c000"/>
|
||||
<peripheralInstance derived_from="TIMER2" id="TIMER2" location="0x40090000"/>
|
||||
<peripheralInstance derived_from="TIMER3" id="TIMER3" location="0x40094000"/>
|
||||
<peripheralInstance derived_from="UART2" id="UART2" location="0x40098000"/>
|
||||
<peripheralInstance derived_from="UART3" id="UART3" location="0x4009c000"/>
|
||||
<peripheralInstance derived_from="I2C2" id="I2C2" location="0x400a0000"/>
|
||||
<peripheralInstance derived_from="UART4" id="UART4" location="0x400a4000"/>
|
||||
<peripheralInstance derived_from="I2S" id="I2S" location="0x400a8000"/>
|
||||
<peripheralInstance derived_from="SSP2" id="SSP2" location="0x400ac000"/>
|
||||
<peripheralInstance derived_from="MCPWM" id="MCPWM" location="0x400b8000"/>
|
||||
<peripheralInstance derived_from="QEI" id="QEI" location="0x400bc000"/>
|
||||
<peripheralInstance derived_from="SDMMC" id="SDMMC" location="0x400c0000"/>
|
||||
<peripheralInstance derived_from="SYSCON" id="SYSCON" location="0x400fc000"/>
|
||||
</chip>
|
||||
<processor><name gcc_name="cortex-m4">Cortex-M4</name>
|
||||
<family>Cortex-M</family>
|
||||
</processor>
|
||||
<link href="nxp_lpc407x_8x_peripheral.xme" show="embed" type="simple"/>
|
||||
</info>
|
||||
</infoList>
|
||||
</TargetConfig>{% endblock %}
|
|
@ -1,72 +0,0 @@
|
|||
{% extends "mcuxpresso/.cproject.tmpl" %}
|
||||
|
||||
{% block cpu_config %}<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TargetConfig>
|
||||
<Properties property_0="" property_2="LPC177x_8x_407x_8x_512.cfx" property_3="NXP" property_4="LPC4088" property_count="5" version="1"/>
|
||||
<infoList vendor="NXP"><info chip="LPC4088" flash_driver="LPC177x_8x_407x_8x_512.cfx" match_id="0x481D3F47" name="LPC4088" stub="crt_emu_cm3_nxp"><chip><name>LPC4088</name>
|
||||
<family>LPC407x_8x</family>
|
||||
<vendor>NXP (formerly Philips)</vendor>
|
||||
<reset board="None" core="Real" sys="Real"/>
|
||||
<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/>
|
||||
<memory can_program="true" id="Flash" is_ro="true" type="Flash"/>
|
||||
<memory id="RAM" type="RAM"/>
|
||||
<memory id="Periph" is_volatile="true" type="Peripheral"/>
|
||||
<memoryInstance derived_from="Flash" id="MFlash512" location="0x0" size="0x80000"/>
|
||||
<memoryInstance derived_from="RAM" id="RamLoc64" location="0x10000000" size="0x10000"/>
|
||||
<memoryInstance derived_from="RAM" id="RamPeriph32" location="0x20000000" size="0x8000"/>
|
||||
<prog_flash blocksz="0x1000" location="0x0" maxprgbuff="0x1000" progwithcode="TRUE" size="0x10000"/>
|
||||
<prog_flash blocksz="0x8000" location="0x10000" maxprgbuff="0x1000" progwithcode="TRUE" size="0x70000"/>
|
||||
<peripheralInstance derived_from="V7M_MPU" id="MPU" location="0xe000ed90"/>
|
||||
<peripheralInstance derived_from="V7M_NVIC" id="NVIC" location="0xe000e000"/>
|
||||
<peripheralInstance derived_from="V7M_DCR" id="DCR" location="0xe000edf0"/>
|
||||
<peripheralInstance derived_from="V7M_ITM" id="ITM" location="0xe0000000"/>
|
||||
<peripheralInstance derived_from="FLASHCTRL" id="FLASHCTRL" location="0x200000"/>
|
||||
<peripheralInstance derived_from="GPDMA" id="GPDMA" location="0x20080000"/>
|
||||
<peripheralInstance derived_from="ETHERNET" id="ETHERNET" location="0x20084000"/>
|
||||
<peripheralInstance derived_from="LCD" id="LCD" location="0x20088000"/>
|
||||
<peripheralInstance derived_from="USB" id="USB" location="0x2008c000"/>
|
||||
<peripheralInstance derived_from="CRC" id="CRC" location="0x20090000"/>
|
||||
<peripheralInstance derived_from="GPIO" id="GPIO" location="0x20098000"/>
|
||||
<peripheralInstance derived_from="EMC" id="EMC" location="0x2009c000"/>
|
||||
<peripheralInstance derived_from="WWDT" id="WWDT" location="0x40000000"/>
|
||||
<peripheralInstance derived_from="TIMER0" id="TIMER0" location="0x40004000"/>
|
||||
<peripheralInstance derived_from="TIMER1" id="TIMER1" location="0x40008000"/>
|
||||
<peripheralInstance derived_from="UART0" id="UART0" location="0x4000c000"/>
|
||||
<peripheralInstance derived_from="UART1" id="UART1" location="0x40010000"/>
|
||||
<peripheralInstance derived_from="PWM0" id="PWM0" location="0x40014000"/>
|
||||
<peripheralInstance derived_from="PWM1" id="PWM1" location="0x40018000"/>
|
||||
<peripheralInstance derived_from="I2C0" id="I2C0" location="0x4001c000"/>
|
||||
<peripheralInstance derived_from="COMPARATOR" id="COMPARATOR" location="0x40020000"/>
|
||||
<peripheralInstance derived_from="RTC" id="RTC" location="0x40024000"/>
|
||||
<peripheralInstance derived_from="GPIOINT" id="GPIOINT" location="0x40028080"/>
|
||||
<peripheralInstance derived_from="IOCON" id="IOCON" location="0x4002c000"/>
|
||||
<peripheralInstance derived_from="SSP1" id="SSP1" location="0x40030000"/>
|
||||
<peripheralInstance derived_from="ADC" id="ADC" location="0x40034000"/>
|
||||
<peripheralInstance derived_from="CANAFRAM" id="CANAFRAM" location="0x40038000"/>
|
||||
<peripheralInstance derived_from="CANAF" id="CANAF" location="0x4003c000"/>
|
||||
<peripheralInstance derived_from="CCAN" id="CCAN" location="0x40040000"/>
|
||||
<peripheralInstance derived_from="CAN1" id="CAN1" location="0x40044000"/>
|
||||
<peripheralInstance derived_from="CAN2" id="CAN2" location="0x40048000"/>
|
||||
<peripheralInstance derived_from="I2C1" id="I2C1" location="0x4005c000"/>
|
||||
<peripheralInstance derived_from="SSP0" id="SSP0" location="0x40088000"/>
|
||||
<peripheralInstance derived_from="DAC" id="DAC" location="0x4008c000"/>
|
||||
<peripheralInstance derived_from="TIMER2" id="TIMER2" location="0x40090000"/>
|
||||
<peripheralInstance derived_from="TIMER3" id="TIMER3" location="0x40094000"/>
|
||||
<peripheralInstance derived_from="UART2" id="UART2" location="0x40098000"/>
|
||||
<peripheralInstance derived_from="UART3" id="UART3" location="0x4009c000"/>
|
||||
<peripheralInstance derived_from="I2C2" id="I2C2" location="0x400a0000"/>
|
||||
<peripheralInstance derived_from="UART4" id="UART4" location="0x400a4000"/>
|
||||
<peripheralInstance derived_from="I2S" id="I2S" location="0x400a8000"/>
|
||||
<peripheralInstance derived_from="SSP2" id="SSP2" location="0x400ac000"/>
|
||||
<peripheralInstance derived_from="MCPWM" id="MCPWM" location="0x400b8000"/>
|
||||
<peripheralInstance derived_from="QEI" id="QEI" location="0x400bc000"/>
|
||||
<peripheralInstance derived_from="SDMMC" id="SDMMC" location="0x400c0000"/>
|
||||
<peripheralInstance derived_from="SYSCON" id="SYSCON" location="0x400fc000"/>
|
||||
</chip>
|
||||
<processor><name gcc_name="cortex-m4">Cortex-M4</name>
|
||||
<family>Cortex-M</family>
|
||||
</processor>
|
||||
<link href="nxp_lpc407x_8x_peripheral.xme" show="embed" type="simple"/>
|
||||
</info>
|
||||
</infoList>
|
||||
</TargetConfig>{% endblock %}
|
|
@ -17,8 +17,7 @@ from tools.build_api import prepare_toolchain
|
|||
POST_BINARY_WHITELIST = set([
|
||||
"TEENSY3_1Code.binary_hook",
|
||||
"MCU_NRF51Code.binary_hook",
|
||||
"LPCTargetCode.lpc_patch",
|
||||
"LPC4088Code.binary_hook"
|
||||
"LPCTargetCode.lpc_patch"
|
||||
])
|
||||
|
||||
|
||||
|
|
|
@ -135,7 +135,6 @@ class Uvision(Exporter):
|
|||
"MCU_NRF51Code.binary_hook",
|
||||
"TEENSY3_1Code.binary_hook",
|
||||
"LPCTargetCode.lpc_patch",
|
||||
"LPC4088Code.binary_hook",
|
||||
"MTSCode.combine_bins_mts_dragonfly",
|
||||
"NCS36510TargetCode.ncs36510_addfib",
|
||||
"LPC55S69Code.binary_hook",
|
||||
|
|
|
@ -52,7 +52,6 @@ LEGACY_IGNORE_DIRS = set([
|
|||
'LPC11U24',
|
||||
'LPC1768',
|
||||
'LPC2368',
|
||||
'LPC4088',
|
||||
'LPC812',
|
||||
'KL25Z',
|
||||
|
||||
|
|
|
@ -470,44 +470,6 @@ class LPCTargetCode(object):
|
|||
t_self.notify.debug("LPC Patch: %s" % os.path.split(binf)[1])
|
||||
patch(binf)
|
||||
|
||||
|
||||
class LPC4088Code(object):
|
||||
"""Code specific to the LPC4088"""
|
||||
@staticmethod
|
||||
def binary_hook(t_self, resources, elf, binf):
|
||||
"""Hook to be run after an elf file is built"""
|
||||
if not os.path.isdir(binf):
|
||||
# Regular binary file, nothing to do
|
||||
LPCTargetCode.lpc_patch(t_self, resources, elf, binf)
|
||||
return
|
||||
outbin = open(binf + ".temp", "wb")
|
||||
partf = open(os.path.join(binf, "ER_IROM1"), "rb")
|
||||
# Pad the fist part (internal flash) with 0xFF to 512k
|
||||
data = partf.read()
|
||||
outbin.write(data)
|
||||
outbin.write(b'\xFF' * (512*1024 - len(data)))
|
||||
partf.close()
|
||||
# Read and append the second part (external flash) in chunks of fixed
|
||||
# size
|
||||
chunksize = 128 * 1024
|
||||
partf = open(os.path.join(binf, "ER_IROM2"), "rb")
|
||||
while True:
|
||||
data = partf.read(chunksize)
|
||||
outbin.write(data)
|
||||
if len(data) < chunksize:
|
||||
break
|
||||
partf.close()
|
||||
outbin.close()
|
||||
# Remove the directory with the binary parts and rename the temporary
|
||||
# file to 'binf'
|
||||
shutil.rmtree(binf, True)
|
||||
os.rename(binf + '.temp', binf)
|
||||
t_self.notify.debug(
|
||||
"Generated custom binary file (internal flash + SPIFI)"
|
||||
)
|
||||
LPCTargetCode.lpc_patch(t_self, resources, elf, binf)
|
||||
|
||||
|
||||
class TEENSY3_1Code(object):
|
||||
"""Hooks for the TEENSY3.1"""
|
||||
@staticmethod
|
||||
|
|
|
@ -33,7 +33,7 @@ class Testcase(Bench):
|
|||
"count": 1,
|
||||
"type": "hardware",
|
||||
"allowed_platforms": [
|
||||
"LPC1768", "KL25Z", "K64F", "K66F", "K22F", "LPC4088", "LPC1549",
|
||||
"LPC1768", "KL25Z", "K64F", "K66F", "K22F", "LPC1549",
|
||||
"NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_F302R8", "NUCLEO_F303K8",
|
||||
"NUCLEO_F303RE", "NUCLEO_F207ZG", "NUCLEO_F334R8", "NUCLEO_F303ZE",
|
||||
"NUCLEO_L053R8", "DISCO_L072CZ_LRWAN1", "NUCLEO_L073RZ", "NUCLEO_L152RE",
|
||||
|
|
|
@ -109,7 +109,6 @@ Wiring:
|
|||
* can_transceiver:
|
||||
* LPC1768: (RX=p9, TX=p10)
|
||||
* LPC1549: (RX=D9, TX=D8)
|
||||
* LPC4088: (RX=p9, TX=p10)
|
||||
* VK_RZ_A1H:(RX=P5_9, TX=P5_10)
|
||||
* NUCLEO_F091RC: (RX=PA_11, TX=PA_12)
|
||||
* NUCLEO_F072RB: (RX=PA_11, TX=PA_12)
|
||||
|
@ -195,7 +194,7 @@ TESTS = [
|
|||
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
|
||||
"automated": True,
|
||||
"peripherals": ["analog_loop"],
|
||||
"mcu": ["LPC1768", "KL25Z", "K64F", "K66F", "K22F", "LPC4088", "LPC1549",
|
||||
"mcu": ["LPC1768", "KL25Z", "K64F", "K66F", "K22F", "LPC1549",
|
||||
"NUCLEO_F072RB", "NUCLEO_F091RC", "NUCLEO_F302R8", "NUCLEO_F303K8", "NUCLEO_F303RE", "NUCLEO_F207ZG",
|
||||
"NUCLEO_F334R8", "NUCLEO_F303ZE", "NUCLEO_L053R8", "DISCO_L072CZ_LRWAN1", "NUCLEO_L073RZ", "NUCLEO_L152RE",
|
||||
"NUCLEO_F410RB", "NUCLEO_F446RE", "NUCLEO_F446ZE", "NUCLEO_F429ZI",
|
||||
|
@ -280,20 +279,6 @@ TESTS = [
|
|||
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
|
||||
"automated": True,
|
||||
},
|
||||
{
|
||||
"id": "MBED_A22", "description": "SPIFI for LPC4088 (test 1)",
|
||||
"source_dir": join(TEST_DIR, "mbed", "spifi1"),
|
||||
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
|
||||
"automated": True,
|
||||
"mcu": ["LPC4088","LPC4088_DM"]
|
||||
},
|
||||
{
|
||||
"id": "MBED_A23", "description": "SPIFI for LPC4088 (test 2)",
|
||||
"source_dir": join(TEST_DIR, "mbed", "spifi2"),
|
||||
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
|
||||
"automated": True,
|
||||
"mcu": ["LPC4088","LPC4088_DM"]
|
||||
},
|
||||
{
|
||||
"id": "MBED_A24", "description": "Serial echo with RTS/CTS flow control",
|
||||
"source_dir": join(TEST_DIR, "mbed", "echo_flow_control"),
|
||||
|
@ -437,7 +422,7 @@ TESTS = [
|
|||
"id": "MBED_4", "description": "Sleep",
|
||||
"source_dir": join(TEST_DIR, "mbed", "sleep"),
|
||||
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
|
||||
"mcu": ["LPC1768", "LPC11U24", "LPC4088","LPC4088_DM","NRF51822", "LPC11U68"]
|
||||
"mcu": ["LPC1768", "LPC11U24", "NRF51822", "LPC11U68"]
|
||||
},
|
||||
{
|
||||
"id": "MBED_5", "description": "PWM",
|
||||
|
@ -592,7 +577,7 @@ TESTS = [
|
|||
"id": "MBED_29", "description": "CAN network test",
|
||||
"source_dir": join(TEST_DIR, "mbed", "can"),
|
||||
"dependencies": [MBED_LIBRARIES],
|
||||
"mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "GR_LYCHEE", "B96B_F446VE", "NUCLEO_F091RC",
|
||||
"mcu": ["LPC1768", "LPC1549", "RZ_A1H", "GR_LYCHEE", "B96B_F446VE", "NUCLEO_F091RC",
|
||||
"NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE",
|
||||
"NUCLEO_F303K8", "NUCLEO_F302R8", "NUCLEO_F446RE","NUCLEO_F446ZE", "DISCO_F469NI", "NUCLEO_F207ZG",
|
||||
"DISCO_F429ZI", "NUCLEO_F103RB", "NUCLEO_F746ZG", "DISCO_F746NG",
|
||||
|
@ -603,7 +588,7 @@ TESTS = [
|
|||
"id": "MBED_30", "description": "CAN network test using interrupts",
|
||||
"source_dir": join(TEST_DIR, "mbed", "can_interrupt"),
|
||||
"dependencies": [MBED_LIBRARIES],
|
||||
"mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "GR_LYCHEE", "B96B_F446VE", "NUCLEO_F091RC", "NUCLEO_F207ZG",
|
||||
"mcu": ["LPC1768", "LPC1549", "RZ_A1H", "GR_LYCHEE", "B96B_F446VE", "NUCLEO_F091RC", "NUCLEO_F207ZG",
|
||||
"NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE",
|
||||
"NUCLEO_F303K8", "NUCLEO_F302R8", "NUCLEO_F446RE", "NUCLEO_F446ZE", "DISCO_F469NI",
|
||||
"DISCO_F429ZI", "NUCLEO_F103RB", "NUCLEO_F746ZG", "DISCO_F746NG",
|
||||
|
|
Loading…
Reference in New Issue