Skip to content

Commit 790a71b

Browse files
committed
Merge pull request #20 from matthewelse/master
CAN-Related Pull Request
2 parents 2c88219 + 45470ab commit 790a71b

File tree

46 files changed

+5003
-65
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+5003
-65
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ NXP:
2929
* LPC4330 (Cortex-M4 + Cortex-M0)
3030
* LPC1347 (Cortex-M3)
3131
* LPC1114 (Cortex-M0)
32+
* LPC11C24 (Cortex-M0)
3233

3334
Freescale:
3435
* [KL25Z](http://mbed.org/handbook/mbed-FRDM-KL25Z) (Cortex-M0+)

libraries/mbed/api/CAN.h

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,25 @@ class CAN {
150150
*/
151151
void monitor(bool silent);
152152

153+
enum Mode {
154+
Reset = 0,
155+
Normal,
156+
Silent,
157+
LocalTest,
158+
GlobalTest,
159+
SilentTest
160+
};
161+
162+
/** Change CAN operation to the specified mode
163+
*
164+
* @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
165+
*
166+
* @returns
167+
* 0 if mode change failed or unsupported,
168+
* 1 if mode change was successful
169+
*/
170+
int mode(Mode mode);
171+
153172
/** Returns number of read errors to detect read overflow errors.
154173
*/
155174
unsigned char rderror();
@@ -158,35 +177,49 @@ class CAN {
158177
*/
159178
unsigned char tderror();
160179

180+
enum IrqType {
181+
RxIrq = 0,
182+
TxIrq,
183+
EwIrq,
184+
DoIrq,
185+
WuIrq,
186+
EpIrq,
187+
AlIrq,
188+
BeIrq,
189+
IdIrq
190+
};
191+
161192
/** Attach a function to call whenever a CAN frame received interrupt is
162193
* generated.
163194
*
164195
* @param fptr A pointer to a void function, or 0 to set as none
196+
* @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, CAN::TxIrq for transmitted or aborted, CAN::EwIrq for error warning, CAN::DoIrq for data overrun, CAN::WuIrq for wake-up, CAN::EpIrq for error passive, CAN::AlIrq for arbitration lost, CAN::BeIrq for bus error)
165197
*/
166-
void attach(void (*fptr)(void));
198+
void attach(void (*fptr)(void), IrqType type=RxIrq);
167199

168200
/** Attach a member function to call whenever a CAN frame received interrupt
169201
* is generated.
170202
*
171203
* @param tptr pointer to the object to call the member function on
172204
* @param mptr pointer to the member function to be called
205+
* @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error)
173206
*/
174207
template<typename T>
175-
void attach(T* tptr, void (T::*mptr)(void)) {
208+
void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
176209
if((mptr != NULL) && (tptr != NULL)) {
177-
_rxirq.attach(tptr, mptr);
178-
setup_interrupt();
179-
} else {
180-
remove_interrupt();
210+
_irq[type].attach(tptr, mptr);
211+
can_irq_set(&_can, (CanIrqType)type, 1);
212+
}
213+
else {
214+
can_irq_set(&_can, (CanIrqType)type, 0);
181215
}
182216
}
183217

184-
private:
185-
can_t _can;
186-
FunctionPointer _rxirq;
218+
static void _irq_handler(uint32_t id, CanIrqType type);
187219

188-
void setup_interrupt(void);
189-
void remove_interrupt(void);
220+
protected:
221+
can_t _can;
222+
FunctionPointer _irq[9];
190223
};
191224

192225
} // namespace mbed

libraries/mbed/common/CAN.cpp

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ namespace mbed {
2323

2424
CAN::CAN(PinName rd, PinName td) {
2525
can_init(&_can, rd, td);
26+
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
2627
}
2728

2829
CAN::~CAN() {
2930
can_free(&_can);
31+
can_irq_free(&_can);
3032
}
3133

3234
int CAN::frequency(int f) {
@@ -57,62 +59,23 @@ void CAN::monitor(bool silent) {
5759
can_monitor(&_can, (silent) ? 1 : 0);
5860
}
5961

60-
static FunctionPointer* can_obj[2] = { NULL };
61-
62-
// Have to check that the CAN block is active before reading the Interrupt
63-
// Control Register, or the mbed hangs
64-
void can_irq(void) {
65-
uint32_t icr;
66-
67-
if(LPC_SC->PCONP & (1 << 13)) {
68-
icr = LPC_CAN1->ICR;
69-
70-
if(icr && (can_obj[0] != NULL)) {
71-
can_obj[0]->call();
72-
}
73-
}
74-
75-
if(LPC_SC->PCONP & (1 << 14)) {
76-
icr = LPC_CAN2->ICR;
77-
if(icr && (can_obj[1] != NULL)) {
78-
can_obj[1]->call();
79-
}
80-
}
81-
62+
int CAN::mode(Mode mode) {
63+
return can_mode(&_can, (CanMode)mode);
8264
}
8365

84-
void CAN::setup_interrupt(void) {
85-
switch ((int)_can.dev) {
86-
case CAN_1: can_obj[0] = &_rxirq; break;
87-
case CAN_2: can_obj[1] = &_rxirq; break;
88-
}
89-
_can.dev->MOD |= 1;
90-
_can.dev->IER |= 1;
91-
_can.dev->MOD &= ~1;
92-
NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq);
93-
NVIC_EnableIRQ(CAN_IRQn);
94-
}
95-
96-
void CAN::remove_interrupt(void) {
97-
switch ((int)_can.dev) {
98-
case CAN_1: can_obj[0] = NULL; break;
99-
case CAN_2: can_obj[1] = NULL; break;
100-
}
101-
102-
_can.dev->IER &= ~(1);
103-
if ((can_obj[0] == NULL) && (can_obj[1] == NULL)) {
104-
NVIC_DisableIRQ(CAN_IRQn);
66+
void CAN::attach(void (*fptr)(void), IrqType type) {
67+
if (fptr) {
68+
_irq[(CanIrqType)type].attach(fptr);
69+
can_irq_set(&_can, (CanIrqType)type, 1);
70+
} else {
71+
can_irq_set(&_can, (CanIrqType)type, 0);
72+
}
10573
}
106-
}
10774

108-
void CAN::attach(void (*fptr)(void)) {
109-
if (fptr != NULL) {
110-
_rxirq.attach(fptr);
111-
setup_interrupt();
112-
} else {
113-
remove_interrupt();
75+
void CAN::_irq_handler(uint32_t id, CanIrqType type) {
76+
CAN *handler = (CAN*)id;
77+
handler->_irq[type].call();
11478
}
115-
}
11679

11780
} // namespace mbed
11881

libraries/mbed/hal/can_api.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,43 @@
2828
extern "C" {
2929
#endif
3030

31+
typedef enum {
32+
IRQ_RX,
33+
IRQ_TX,
34+
IRQ_ERROR,
35+
IRQ_OVERRUN,
36+
IRQ_WAKEUP,
37+
IRQ_PASSIVE,
38+
IRQ_ARB,
39+
IRQ_BUS,
40+
IRQ_READY
41+
} CanIrqType;
42+
43+
44+
typedef enum {
45+
MODE_RESET,
46+
MODE_NORMAL,
47+
MODE_SILENT,
48+
MODE_TEST_GLOBAL,
49+
MODE_TEST_LOCAL,
50+
MODE_TEST_SILENT
51+
} CanMode;
52+
53+
typedef void (*can_irq_handler)(uint32_t id, CanIrqType type);
54+
3155
typedef struct can_s can_t;
3256

3357
void can_init (can_t *obj, PinName rd, PinName td);
3458
void can_free (can_t *obj);
3559
int can_frequency(can_t *obj, int hz);
60+
61+
void can_irq_init (can_t *obj, can_irq_handler handler, uint32_t id);
62+
void can_irq_free (can_t *obj);
63+
void can_irq_set (can_t *obj, CanIrqType irq, uint32_t enable);
64+
3665
int can_write (can_t *obj, CAN_Message, int cc);
3766
int can_read (can_t *obj, CAN_Message *msg);
67+
int can_mode (can_t *obj, CanMode mode);
3868
void can_reset (can_t *obj);
3969
unsigned char can_rderror (can_t *obj);
4070
unsigned char can_tderror (can_t *obj);

0 commit comments

Comments
 (0)