Skip to content

Commit ed2f350

Browse files
committed
Merge pull request #23 from arebert/lpc4088
Updated pin mapping and CAN HAL impl for LPC4088 target
2 parents 348c24e + 75dba19 commit ed2f350

File tree

18 files changed

+252
-67
lines changed

18 files changed

+252
-67
lines changed

libraries/USBDevice/USBDevice/USBHAL_LPC40.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
#define PCUSB (1UL<<31)
3333

3434
// USB Clock Control register
35-
#define DEV_CLK_EN (1UL<<1)
36-
#define AHB_CLK_EN (1UL<<4)
35+
#define DEV_CLK_EN (1UL<<1)
36+
#define PORT_CLK_EN (1UL<<3)
37+
#define AHB_CLK_EN (1UL<<4)
3738

3839
// USB Clock Status register
3940
#define DEV_CLK_ON (1UL<<1)
@@ -364,21 +365,23 @@ USBHAL::USBHAL(void) {
364365
LPC_SC->PCONP |= PCUSB;
365366

366367
// Enable USB clocks
367-
LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
368-
while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON));
368+
LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN;
369+
while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON | PORT_CLK_EN));
370+
371+
// Select port USB2
372+
LPC_USB->StCtrl |= 3;
373+
369374

370-
// Configure pins P0.29 and P0.30 to be USB D+ and USB D-
371-
LPC_IOCON->P0_29 &= ~0x07;
372-
LPC_IOCON->P0_29 |= 0x01;
373-
LPC_IOCON->P0_30 &= ~0x07;
374-
LPC_IOCON->P0_30 |= 0x01;
375+
// Configure pin P0.31 to be USB2
376+
LPC_IOCON->P0_31 &= ~0x07;
377+
LPC_IOCON->P0_31 |= 0x01;
375378

376379
// Disconnect USB device
377380
SIEdisconnect();
378381

379-
// Configure pin P2.9 to be Connect
380-
LPC_IOCON->P2_9 &= ~0x07;
381-
LPC_IOCON->P2_9 |= 0x01;
382+
// Configure pin P0.14 to be Connect
383+
LPC_IOCON->P0_14 &= ~0x07;
384+
LPC_IOCON->P0_14 |= 0x03;
382385

383386
// Connect must be low for at least 2.5uS
384387
wait(0.3);

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/PinNames.h

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,45 @@ typedef enum {
4040
P5_0, P5_1, P5_2, P5_3, P5_4,
4141

4242
// mbed DIP Pin Names
43-
p5 = P0_9,
44-
p6 = P0_8,
45-
p7 = P0_7,
46-
p8 = P0_6,
43+
p5 = P1_24,
44+
p6 = P1_23,
45+
p7 = P1_20,
46+
p8 = P0_21,
4747
p9 = P0_0,
4848
p10 = P0_1,
49-
p11 = P0_18,
50-
p12 = P0_17,
51-
p13 = P0_15,
52-
p14 = P0_16,
49+
p11 = P0_9,
50+
p12 = P0_8,
51+
p13 = P0_7,
52+
p14 = P0_6,
5353
p15 = P0_23,
5454
p16 = P0_24,
5555
p17 = P0_25,
5656
p18 = P0_26,
5757
p19 = P1_30,
5858
p20 = P1_31,
59-
p21 = P2_5,
60-
p22 = P2_4,
61-
p23 = P2_3,
62-
p24 = P2_2,
63-
p25 = P2_1,
64-
p26 = P2_0,
65-
p27 = P0_11,
66-
p28 = P0_10,
67-
p29 = P0_5,
68-
p30 = P0_4,
6959

60+
p23 = P2_10,
61+
p24 = P1_12,
62+
p25 = P1_11,
63+
p26 = P1_7,
64+
p27 = P1_6,
65+
p28 = P1_5,
66+
p29 = P1_3,
67+
p30 = P1_2,
68+
p31 = P5_3,
69+
p32 = P5_2,
70+
p33 = P0_5,
71+
p34 = P0_4,
72+
73+
p37 = P5_4,
74+
p38 = P5_1,
75+
p39 = P5_0,
76+
7077
// Other mbed Pin Names
71-
LED1 = P2_27,
72-
LED2 = P2_26,
73-
LED3 = P2_26,
74-
LED4 = P2_26,
78+
LED1 = P1_18,
79+
LED2 = P0_13,
80+
LED3 = P1_13,
81+
LED4 = P2_19,
7582

7683
USBTX = P0_2,
7784
USBRX = P0_3,

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/can_api.c

Lines changed: 125 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
#include <math.h>
17-
#include <string.h>
18-
1916
#include "can_api.h"
17+
2018
#include "cmsis.h"
2119
#include "pinmap.h"
2220
#include "error.h"
2321

22+
#include <math.h>
23+
#include <string.h>
24+
25+
#define CAN_NUM 2
26+
2427
/* Acceptance filter mode in AFMR register */
2528
#define ACCF_OFF 0x01
2629
#define ACCF_BYPASS 0x02
@@ -60,6 +63,9 @@ struct CANMsg {
6063
};
6164
typedef struct CANMsg CANMsg;
6265

66+
static uint32_t can_irq_ids[CAN_NUM] = {0};
67+
static can_irq_handler irq_handler;
68+
6369
static uint32_t can_disable(can_t *obj) {
6470
uint32_t sm = obj->dev->MOD;
6571
obj->dev->MOD |= 1;
@@ -72,6 +78,101 @@ static inline void can_enable(can_t *obj) {
7278
}
7379
}
7480

81+
int can_mode(can_t *obj, CanMode mode)
82+
{
83+
return 0; // not implemented
84+
}
85+
86+
static inline void can_irq(uint32_t icr, uint32_t index) {
87+
uint32_t i;
88+
89+
for(i = 0; i < 8; i++)
90+
{
91+
if((can_irq_ids[index] != 0) && (icr & (1 << i)))
92+
{
93+
switch (i) {
94+
case 0: irq_handler(can_irq_ids[index], IRQ_RX); break;
95+
case 1: irq_handler(can_irq_ids[index], IRQ_TX); break;
96+
case 2: irq_handler(can_irq_ids[index], IRQ_ERROR); break;
97+
case 3: irq_handler(can_irq_ids[index], IRQ_OVERRUN); break;
98+
case 4: irq_handler(can_irq_ids[index], IRQ_WAKEUP); break;
99+
case 5: irq_handler(can_irq_ids[index], IRQ_PASSIVE); break;
100+
case 6: irq_handler(can_irq_ids[index], IRQ_ARB); break;
101+
case 7: irq_handler(can_irq_ids[index], IRQ_BUS); break;
102+
case 8: irq_handler(can_irq_ids[index], IRQ_READY); break;
103+
}
104+
}
105+
}
106+
}
107+
108+
// Have to check that the CAN block is active before reading the Interrupt
109+
// Control Register, or the mbed hangs
110+
void can_irq_n() {
111+
uint32_t icr;
112+
113+
if(LPC_SC->PCONP & (1 << 13)) {
114+
icr = LPC_CAN1->ICR & 0x1FF;
115+
can_irq(icr, 0);
116+
}
117+
118+
if(LPC_SC->PCONP & (1 << 14)) {
119+
icr = LPC_CAN2->ICR & 0x1FF;
120+
can_irq(icr, 1);
121+
}
122+
}
123+
124+
// Register CAN object's irq handler
125+
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
126+
irq_handler = handler;
127+
can_irq_ids[obj->index] = id;
128+
}
129+
130+
// Unregister CAN object's irq handler
131+
void can_irq_free(can_t *obj) {
132+
obj->dev->IER &= ~(1);
133+
can_irq_ids[obj->index] = 0;
134+
135+
if ((can_irq_ids[0] == 0) && (can_irq_ids[1] == 0)) {
136+
NVIC_DisableIRQ(CAN_IRQn);
137+
}
138+
}
139+
140+
// Clear or set a irq
141+
void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
142+
uint32_t ier;
143+
144+
switch (type) {
145+
case IRQ_RX: ier = (1 << 0); break;
146+
case IRQ_TX: ier = (1 << 1); break;
147+
case IRQ_ERROR: ier = (1 << 2); break;
148+
case IRQ_OVERRUN: ier = (1 << 3); break;
149+
case IRQ_WAKEUP: ier = (1 << 4); break;
150+
case IRQ_PASSIVE: ier = (1 << 5); break;
151+
case IRQ_ARB: ier = (1 << 6); break;
152+
case IRQ_BUS: ier = (1 << 7); break;
153+
case IRQ_READY: ier = (1 << 8); break;
154+
default: return;
155+
}
156+
157+
obj->dev->MOD |= 1;
158+
if(enable == 0) {
159+
obj->dev->IER &= ~ier;
160+
}
161+
else {
162+
obj->dev->IER |= ier;
163+
}
164+
obj->dev->MOD &= ~(1);
165+
166+
// Enable NVIC if at least 1 interrupt is active
167+
if(LPC_CAN1->IER | LPC_CAN2->IER != 0) {
168+
NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq_n);
169+
NVIC_EnableIRQ(CAN_IRQn);
170+
}
171+
else {
172+
NVIC_DisableIRQ(CAN_IRQn);
173+
}
174+
}
175+
75176
// This table has the sampling points as close to 75% as possible. The first
76177
// value is TSEG1, the second TSEG2.
77178
static const int timing_pts[23][2] = {
@@ -132,6 +233,7 @@ static unsigned int can_speed(unsigned int sclk, unsigned int pclk, unsigned int
132233
}
133234

134235
return btr;
236+
135237
}
136238

137239
void can_init(can_t *obj, PinName rd, PinName td) {
@@ -141,19 +243,24 @@ void can_init(can_t *obj, PinName rd, PinName td) {
141243
if ((int)obj->dev == NC) {
142244
error("CAN pin mapping failed");
143245
}
144-
246+
145247
switch ((int)obj->dev) {
146248
case CAN_1: LPC_SC->PCONP |= 1 << 13; break;
147249
case CAN_2: LPC_SC->PCONP |= 1 << 14; break;
148250
}
149-
251+
150252
pinmap_pinout(rd, PinMap_CAN_RD);
151253
pinmap_pinout(td, PinMap_CAN_TD);
152254

255+
switch ((int)obj->dev) {
256+
case CAN_1: obj->index = 0; break;
257+
case CAN_2: obj->index = 1; break;
258+
}
259+
153260
can_reset(obj);
154261
obj->dev->IER = 0; // Disable Interrupts
155262
can_frequency(obj, 100000);
156-
263+
157264
LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter
158265
}
159266

@@ -166,8 +273,9 @@ void can_free(can_t *obj) {
166273

167274
int can_frequency(can_t *obj, int f) {
168275
int pclk = PeripheralClock;
169-
int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1);
170276

277+
int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1);
278+
171279
if (btr > 0) {
172280
uint32_t modmask = can_disable(obj);
173281
obj->dev->BTR = btr;
@@ -181,16 +289,16 @@ int can_frequency(can_t *obj, int f) {
181289
int can_write(can_t *obj, CAN_Message msg, int cc) {
182290
unsigned int CANStatus;
183291
CANMsg m;
184-
292+
185293
can_enable(obj);
186-
294+
187295
m.id = msg.id ;
188296
m.dlc = msg.len & 0xF;
189297
m.rtr = msg.type;
190298
m.type = msg.format;
191299
memcpy(m.data, msg.data, msg.len);
192300
const unsigned int *buf = (const unsigned int *)&m;
193-
301+
194302
CANStatus = obj->dev->SR;
195303
if (CANStatus & 0x00000004) {
196304
obj->dev->TFI1 = buf[0] & 0xC00F0000;
@@ -203,7 +311,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
203311
obj->dev->CMR = 0x21;
204312
}
205313
return 1;
206-
314+
207315
} else if (CANStatus & 0x00000400) {
208316
obj->dev->TFI2 = buf[0] & 0xC00F0000;
209317
obj->dev->TID2 = buf[1];
@@ -215,7 +323,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
215323
obj->dev->CMR = 0x41;
216324
}
217325
return 1;
218-
326+
219327
} else if (CANStatus & 0x00040000) {
220328
obj->dev->TFI3 = buf[0] & 0xC00F0000;
221329
obj->dev->TID3 = buf[1];
@@ -228,31 +336,31 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
228336
}
229337
return 1;
230338
}
231-
339+
232340
return 0;
233341
}
234342

235343
int can_read(can_t *obj, CAN_Message *msg) {
236344
CANMsg x;
237345
unsigned int *i = (unsigned int *)&x;
238-
346+
239347
can_enable(obj);
240-
348+
241349
if (obj->dev->GSR & 0x1) {
242350
*i++ = obj->dev->RFS; // Frame
243351
*i++ = obj->dev->RID; // ID
244352
*i++ = obj->dev->RDA; // Data A
245353
*i++ = obj->dev->RDB; // Data B
246354
obj->dev->CMR = 0x04; // release receive buffer
247-
355+
248356
msg->id = x.id;
249357
msg->len = x.dlc;
250358
msg->format = (x.type)? CANExtended : CANStandard;
251359
msg->type = (x.rtr)? CANRemote: CANData;
252360
memcpy(msg->data,x.data,x.dlc);
253361
return 1;
254362
}
255-
363+
256364
return 0;
257365
}
258366

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/device.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141

4242
#define DEVICE_PWMOUT 1
4343

44-
#define DEVICE_SEMIHOST 0 // Need HW?
45-
#define DEVICE_LOCALFILESYSTEM 0 // Need HW?
44+
#define DEVICE_SEMIHOST 0
45+
#define DEVICE_LOCALFILESYSTEM 0
4646
#define DEVICE_ID_LENGTH 32
4747
#define DEVICE_MAC_OFFSET 20
4848

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct dac_s {
6060

6161
struct can_s {
6262
LPC_CAN_TypeDef *dev;
63+
int index;
6364
};
6465

6566
struct i2c_s {

0 commit comments

Comments
 (0)