Updated pin mapping and CAN HAL for LPC4088 target

pull/23/head
Andreas Rebert 2013-08-08 13:57:02 +02:00
parent 348c24e578
commit 75dba19438
18 changed files with 252 additions and 67 deletions

View File

@ -32,8 +32,9 @@
#define PCUSB (1UL<<31)
// USB Clock Control register
#define DEV_CLK_EN (1UL<<1)
#define AHB_CLK_EN (1UL<<4)
#define DEV_CLK_EN (1UL<<1)
#define PORT_CLK_EN (1UL<<3)
#define AHB_CLK_EN (1UL<<4)
// USB Clock Status register
#define DEV_CLK_ON (1UL<<1)
@ -364,21 +365,23 @@ USBHAL::USBHAL(void) {
LPC_SC->PCONP |= PCUSB;
// Enable USB clocks
LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON));
LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN;
while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON | PORT_CLK_EN));
// Select port USB2
LPC_USB->StCtrl |= 3;
// Configure pins P0.29 and P0.30 to be USB D+ and USB D-
LPC_IOCON->P0_29 &= ~0x07;
LPC_IOCON->P0_29 |= 0x01;
LPC_IOCON->P0_30 &= ~0x07;
LPC_IOCON->P0_30 |= 0x01;
// Configure pin P0.31 to be USB2
LPC_IOCON->P0_31 &= ~0x07;
LPC_IOCON->P0_31 |= 0x01;
// Disconnect USB device
SIEdisconnect();
// Configure pin P2.9 to be Connect
LPC_IOCON->P2_9 &= ~0x07;
LPC_IOCON->P2_9 |= 0x01;
// Configure pin P0.14 to be Connect
LPC_IOCON->P0_14 &= ~0x07;
LPC_IOCON->P0_14 |= 0x03;
// Connect must be low for at least 2.5uS
wait(0.3);

View File

@ -40,38 +40,45 @@ typedef enum {
P5_0, P5_1, P5_2, P5_3, P5_4,
// mbed DIP Pin Names
p5 = P0_9,
p6 = P0_8,
p7 = P0_7,
p8 = P0_6,
p5 = P1_24,
p6 = P1_23,
p7 = P1_20,
p8 = P0_21,
p9 = P0_0,
p10 = P0_1,
p11 = P0_18,
p12 = P0_17,
p13 = P0_15,
p14 = P0_16,
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,
p21 = P2_5,
p22 = P2_4,
p23 = P2_3,
p24 = P2_2,
p25 = P2_1,
p26 = P2_0,
p27 = P0_11,
p28 = P0_10,
p29 = P0_5,
p30 = P0_4,
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 = P2_27,
LED2 = P2_26,
LED3 = P2_26,
LED4 = P2_26,
LED1 = P1_18,
LED2 = P0_13,
LED3 = P1_13,
LED4 = P2_19,
USBTX = P0_2,
USBRX = P0_3,

View File

@ -13,14 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include <string.h>
#include "can_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.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
@ -60,6 +63,9 @@ struct CANMsg {
};
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;
@ -72,6 +78,101 @@ static inline void can_enable(can_t *obj) {
}
}
int can_mode(can_t *obj, CanMode mode)
{
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_CAN1->IER | LPC_CAN2->IER != 0) {
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] = {
@ -132,6 +233,7 @@ static unsigned int can_speed(unsigned int sclk, unsigned int pclk, unsigned int
}
return btr;
}
void can_init(can_t *obj, PinName rd, PinName td) {
@ -141,19 +243,24 @@ void can_init(can_t *obj, PinName rd, PinName td) {
if ((int)obj->dev == NC) {
error("CAN pin mapping failed");
}
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, 100000);
LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter
}
@ -166,8 +273,9 @@ void can_free(can_t *obj) {
int can_frequency(can_t *obj, int f) {
int pclk = PeripheralClock;
int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1);
int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1);
if (btr > 0) {
uint32_t modmask = can_disable(obj);
obj->dev->BTR = btr;
@ -181,16 +289,16 @@ int can_frequency(can_t *obj, int f) {
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;
@ -203,7 +311,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
obj->dev->CMR = 0x21;
}
return 1;
} else if (CANStatus & 0x00000400) {
obj->dev->TFI2 = buf[0] & 0xC00F0000;
obj->dev->TID2 = buf[1];
@ -215,7 +323,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
obj->dev->CMR = 0x41;
}
return 1;
} else if (CANStatus & 0x00040000) {
obj->dev->TFI3 = buf[0] & 0xC00F0000;
obj->dev->TID3 = buf[1];
@ -228,23 +336,23 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
}
return 1;
}
return 0;
}
int can_read(can_t *obj, CAN_Message *msg) {
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;
@ -252,7 +360,7 @@ int can_read(can_t *obj, CAN_Message *msg) {
memcpy(msg->data,x.data,x.dlc);
return 1;
}
return 0;
}

View File

@ -41,8 +41,8 @@
#define DEVICE_PWMOUT 1
#define DEVICE_SEMIHOST 0 // Need HW?
#define DEVICE_LOCALFILESYSTEM 0 // Need HW?
#define DEVICE_SEMIHOST 0
#define DEVICE_LOCALFILESYSTEM 0
#define DEVICE_ID_LENGTH 32
#define DEVICE_MAC_OFFSET 20

View File

@ -60,6 +60,7 @@ struct dac_s {
struct can_s {
LPC_CAN_TypeDef *dev;
int index;
};
struct i2c_s {

View File

@ -18,10 +18,15 @@
namespace mbed {
PinName parse_pins(const char *str) {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
static const PinName pin_names[] = {p5, p6, p7, p8, p9, p10, p11, p12, p13, p14
, p15, p16, p17, p18, p19, p20, p21, p22, p23
, p24, p25, p26, p27, p28, p29, p30};
#elif defined(TARGET_LPC4088)
static const PinName pin_names[] = {p5, p6, p7, p8, p9, p10, p11, p12, p13, p14
, p15, p16, p17, p18, p19, p20, NC, NC, p23
, p24, p25, p26, p27, p28, p29, p30, p31, p32
, p33, p34, NC, NC, p37, p38, p39};
#endif
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC812) || defined(TARGET_LPC4088)
@ -46,7 +51,7 @@ PinName parse_pins(const char *str) {
return port_pin((PortName)port, pin);
#endif
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC2368)
} else if (str[0] == 'p') { // pn
uint32_t pin = str[1] - '0'; // pn
uint32_t pin2 = str[2] - '0'; // pnn
@ -57,6 +62,17 @@ PinName parse_pins(const char *str) {
return NC;
}
return pin_names[pin - 5];
#elif defined(TARGET_LPC4088)
} else if (str[0] == 'p') { // pn
uint32_t pin = str[1] - '0'; // pn
uint32_t pin2 = str[2] - '0'; // pnn
if (pin2 <= 9) {
pin = pin * 10 + pin2;
}
if (pin < 5 || pin > 39) {
return NC;
}
return pin_names[pin - 5];
#endif
} else if (str[0] == 'L') { // LEDn

View File

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

View File

@ -4,7 +4,11 @@ Ticker ticker;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
CAN can1(p9, p10);
#if defined(TARGET_LPC4088)
CAN can2(p34, p33);
#else
CAN can2(p30, p29);
#endif
char counter = 0;
void printmsg(char *title, CANMessage *msg) {

View File

@ -4,7 +4,11 @@ Ticker ticker;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
CAN can1(p9, p10);
#if defined(TARGET_LPC4088)
CAN can2(p34, p33);
#else
CAN can2(p30, p29);
#endif
char counter = 0;
void printmsg(char *title, CANMessage *msg) {

View File

@ -7,6 +7,9 @@ TMP102 temperature(PTC9, PTC8, 0x90);
#elif defined(TARGET_LPC812)
TMP102 temperature(D10, D11, 0x90);
#elif defined(TARGET_LPC4088)
TMP102 temperature(p9, p10, 0x90);
#else
TMP102 temperature(p28, p27, 0x90);
#endif

View File

@ -6,6 +6,8 @@
#if defined(TARGET_KL25Z)
I2CSlave slave(PTE0, PTE1);
#elif defined(TARGET_LPC4088)
I2CSlave slave(p9, p10);
#else
I2CSlave slave(p28, p27);
#endif

View File

@ -23,6 +23,10 @@ void in_handler() {
#define PIN_OUT D10
#define PIN_IN D11
#elif defined(TARGET_LPC4088)
#define PIN_IN (p11)
#define PIN_OUT (p12)
#else
#define PIN_IN (p5)
#define PIN_OUT (p25)

View File

@ -3,7 +3,7 @@
#include "cmsis.h"
#include "test_env.h"
#if defined(TARGET_LPC1768)
#if defined(TARGET_LPC1768) || defined(TARGET_LPC4088)
#define TIMER_IRQ TIMER3_IRQn
#elif defined(TARGET_LPC11U24)
#define TIMER_IRQ TIMER_32_1_IRQn

View File

@ -25,6 +25,10 @@ void in_handler() {
#define PIN_OUT dp1
#define PIN_IN dp2
#elif defined(TARGET_LPC4088)
#define PIN_IN (p11)
#define PIN_OUT (p12)
#else
#define PIN_IN (p5)
#define PIN_OUT (p25)

View File

@ -1,5 +1,19 @@
#include "mbed.h"
#if defined(TARGET_LPC4088)
InterruptIn button(p18);
InterruptIn button1(p17);
InterruptIn button2(p16);
InterruptIn button3(p15);
InterruptIn button4(p14);
InterruptIn button5(p13);
InterruptIn button6(p12);
InterruptIn button7(p11);
InterruptIn button8(p10);
InterruptIn button9(p9);
DigitalOut led(LED1);
DigitalOut flash(LED4);
#else
InterruptIn button(p30);
InterruptIn button1(p29);
InterruptIn button2(p28);
@ -12,6 +26,7 @@ InterruptIn button8(p22);
InterruptIn button9(p21);
DigitalOut led(LED1);
DigitalOut flash(LED4);
#endif
void flip() {
led = !led;

View File

@ -9,7 +9,7 @@
#define P2_2 (1 << 25) // p1.25
#define PORT_2 Port1
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#define P1_1 (1 << 9) // p0.9 -> p5
#define P1_2 (1 << 8) // p0.8 -> p6
#define PORT_1 Port0
@ -18,6 +18,15 @@
#define P2_2 (1 << 0) // p2.0 -> p26
#define PORT_2 Port2
#elif defined(TARGET_LPC4088)
#define P1_1 (1 << 7) // p0.7 -> p13
#define P1_2 (1 << 6) // p0.6 -> p14
#define PORT_1 Port0
#define P2_1 (1 << 2) // p1.2 -> p30
#define P2_2 (1 << 3) // p1.3 -> p29
#define PORT_2 Port1
#elif defined(TARGET_LPC1114)
#define P1_1 (1 << 9) // p0.9
#define P1_2 (1 << 8) // p0.8

View File

@ -9,7 +9,7 @@
#define P2_2 (1 << 25) // p1.25
#define PORT_2 Port1
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
#define P1_1 (1 << 9) // p0.9 -> p5
#define P1_2 (1 << 8) // p0.8 -> p6
#define PORT_1 Port0
@ -18,6 +18,15 @@
#define P2_2 (1 << 0) // p2.0 -> p26
#define PORT_2 Port2
#elif defined(TARGET_LPC4088)
#define P1_1 (1 << 7) // p0.7 -> p13
#define P1_2 (1 << 6) // p0.6 -> p14
#define PORT_1 Port0
#define P2_1 (1 << 2) // p1.2 -> p30
#define P2_2 (1 << 3) // p1.3 -> p29
#define PORT_2 Port1
#elif defined(TARGET_LPC1114)
#define P1_1 (1 << 9) // p0.9
#define P1_2 (1 << 8) // p0.8

View File

@ -119,7 +119,7 @@ TESTS = [
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
"automated": True,
"peripherals": ["analog_loop"],
"mcu": ["LPC1768", "LPC2368", "KL25Z"]
"mcu": ["LPC1768", "LPC2368", "KL25Z", "LPC4088"]
},
{
"id": "MBED_A9", "description": "Serial Echo at 115200",
@ -259,7 +259,7 @@ TESTS = [
"source_dir": join(TEST_DIR, "mbed", "sleep"),
"dependencies": [MBED_LIBRARIES, TEST_MBED_LIB],
"duration": 30,
"mcu": ["LPC1768", "LPC11U24"]
"mcu": ["LPC1768", "LPC11U24", "LPC4088"]
},
{
"id": "MBED_5", "description": "PWM",
@ -395,13 +395,13 @@ TESTS = [
"id": "MBED_30", "description": "CAN network test",
"source_dir": join(TEST_DIR, "mbed", "can"),
"dependencies": [MBED_LIBRARIES],
"mcu": ["LPC1768"]
"mcu": ["LPC1768", "LPC4088"]
},
{
"id": "MBED_31", "description": "CAN network test using interrupts",
"source_dir": join(TEST_DIR, "mbed", "can_interrupt"),
"dependencies": [MBED_LIBRARIES],
"mcu": ["LPC1768"]
"mcu": ["LPC1768", "LPC4088"]
},
# CMSIS RTOS tests