Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAN-Related Pull Request #20

Merged
merged 23 commits into from
Aug 6, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
200b263
Added basic stuff necessary to compile for LPC11C24 target.
matthewelse Jul 27, 2013
429d2e6
Enabled CAN for LPC11CXX in device.h
matthewelse Jul 29, 2013
07cddbf
Merge remote-tracking branch 'upstream/master'
matthewelse Jul 30, 2013
51bfe26
Add can_t->index to struct and set it during can_init
omdathetkan Jul 30, 2013
8ef8aac
Merge remote-tracking branch 'upstream/master'
omdathetkan Jul 31, 2013
454935a
Update README.md to include LPC11C24 under supported chips.
matthewelse Jul 31, 2013
63b2b27
Refactor CAN interrupt handling to LPC176X HAL implementation
omdathetkan Jul 31, 2013
a16dc72
Add @param documentation for new event parameter
omdathetkan Jul 31, 2013
d899612
Merge branch 'forpullrequest'
matthewelse Aug 1, 2013
f685efa
Merge remote-tracking branch 'upstream/master'
omdathetkan Aug 2, 2013
48fc1aa
Add test case MBED_30 and MBED_31 to test CAN api
omdathetkan Aug 2, 2013
b470ea0
Fixed things that shouldn't have been changed
matthewelse Aug 5, 2013
7c8c722
Pushed LPC1114 I2C updates to the LPC11C24
matthewelse Aug 5, 2013
2c45596
Merge https://github.com/jorisa/mbed
matthewelse Aug 5, 2013
ef28879
Merged remote tracking branch 'upstream/master'
matthewelse Aug 5, 2013
e38b3df
Added LPC11C24 to README.md
matthewelse Aug 5, 2013
c747e25
Rename some argument and enum names to match existing naming
omdathetkan Aug 6, 2013
f7a2be4
Merge remote-tracking branch 'upstream/master'
matthewelse Aug 6, 2013
bf02700
Merge https://github.com/jorisa/mbed
matthewelse Aug 6, 2013
714daff
Fix CAN Test (MBED_30)
matthewelse Aug 6, 2013
6cf35db
Fix CAN Interrupt Test (MBED_31)
matthewelse Aug 6, 2013
4401516
Removed unnecessary core_cm* files, as they are now shared in cmsis
matthewelse Aug 6, 2013
45470ab
Updated READMEs
matthewelse Aug 6, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ NXP:
* LPC4330 (Cortex-M4 + Cortex-M0)
* LPC1347 (Cortex-M3)
* LPC1114 (Cortex-M0)
* LPC11C24 (Cortex-M0)

Freescale:
* [KL25Z](http://mbed.org/handbook/mbed-FRDM-KL25Z) (Cortex-M0+)
Expand Down
55 changes: 44 additions & 11 deletions libraries/mbed/api/CAN.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,25 @@ class CAN {
*/
void monitor(bool silent);

enum Mode {
Reset = 0,
Normal,
Silent,
LocalTest,
GlobalTest,
SilentTest
};

/** Change CAN operation to the specified mode
*
* @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
*
* @returns
* 0 if mode change failed or unsupported,
* 1 if mode change was successful
*/
int mode(Mode mode);

/** Returns number of read errors to detect read overflow errors.
*/
unsigned char rderror();
Expand All @@ -158,35 +177,49 @@ class CAN {
*/
unsigned char tderror();

enum IrqType {
RxIrq = 0,
TxIrq,
EwIrq,
DoIrq,
WuIrq,
EpIrq,
AlIrq,
BeIrq,
IdIrq
};

/** Attach a function to call whenever a CAN frame received interrupt is
* generated.
*
* @param fptr A pointer to a void function, or 0 to set as none
* @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)
*/
void attach(void (*fptr)(void));
void attach(void (*fptr)(void), IrqType type=RxIrq);

/** Attach a member function to call whenever a CAN frame received interrupt
* is generated.
*
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
* @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)
*/
template<typename T>
void attach(T* tptr, void (T::*mptr)(void)) {
void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
if((mptr != NULL) && (tptr != NULL)) {
_rxirq.attach(tptr, mptr);
setup_interrupt();
} else {
remove_interrupt();
_irq[type].attach(tptr, mptr);
can_irq_set(&_can, (CanIrqType)type, 1);
}
else {
can_irq_set(&_can, (CanIrqType)type, 0);
}
}

private:
can_t _can;
FunctionPointer _rxirq;
static void _irq_handler(uint32_t id, CanIrqType type);

void setup_interrupt(void);
void remove_interrupt(void);
protected:
can_t _can;
FunctionPointer _irq[9];
};

} // namespace mbed
Expand Down
65 changes: 14 additions & 51 deletions libraries/mbed/common/CAN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ namespace mbed {

CAN::CAN(PinName rd, PinName td) {
can_init(&_can, rd, td);
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
}

CAN::~CAN() {
can_free(&_can);
can_irq_free(&_can);
}

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

static FunctionPointer* can_obj[2] = { NULL };

// Have to check that the CAN block is active before reading the Interrupt
// Control Register, or the mbed hangs
void can_irq(void) {
uint32_t icr;

if(LPC_SC->PCONP & (1 << 13)) {
icr = LPC_CAN1->ICR;

if(icr && (can_obj[0] != NULL)) {
can_obj[0]->call();
}
}

if(LPC_SC->PCONP & (1 << 14)) {
icr = LPC_CAN2->ICR;
if(icr && (can_obj[1] != NULL)) {
can_obj[1]->call();
}
}

int CAN::mode(Mode mode) {
return can_mode(&_can, (CanMode)mode);
}

void CAN::setup_interrupt(void) {
switch ((int)_can.dev) {
case CAN_1: can_obj[0] = &_rxirq; break;
case CAN_2: can_obj[1] = &_rxirq; break;
}
_can.dev->MOD |= 1;
_can.dev->IER |= 1;
_can.dev->MOD &= ~1;
NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq);
NVIC_EnableIRQ(CAN_IRQn);
}

void CAN::remove_interrupt(void) {
switch ((int)_can.dev) {
case CAN_1: can_obj[0] = NULL; break;
case CAN_2: can_obj[1] = NULL; break;
}

_can.dev->IER &= ~(1);
if ((can_obj[0] == NULL) && (can_obj[1] == NULL)) {
NVIC_DisableIRQ(CAN_IRQn);
void CAN::attach(void (*fptr)(void), IrqType type) {
if (fptr) {
_irq[(CanIrqType)type].attach(fptr);
can_irq_set(&_can, (CanIrqType)type, 1);
} else {
can_irq_set(&_can, (CanIrqType)type, 0);
}
}
}

void CAN::attach(void (*fptr)(void)) {
if (fptr != NULL) {
_rxirq.attach(fptr);
setup_interrupt();
} else {
remove_interrupt();
void CAN::_irq_handler(uint32_t id, CanIrqType type) {
CAN *handler = (CAN*)id;
handler->_irq[type].call();
}
}

} // namespace mbed

Expand Down
30 changes: 30 additions & 0 deletions libraries/mbed/hal/can_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,43 @@
extern "C" {
#endif

typedef enum {
IRQ_RX,
IRQ_TX,
IRQ_ERROR,
IRQ_OVERRUN,
IRQ_WAKEUP,
IRQ_PASSIVE,
IRQ_ARB,
IRQ_BUS,
IRQ_READY
} CanIrqType;


typedef enum {
MODE_RESET,
MODE_NORMAL,
MODE_SILENT,
MODE_TEST_GLOBAL,
MODE_TEST_LOCAL,
MODE_TEST_SILENT
} CanMode;

typedef void (*can_irq_handler)(uint32_t id, CanIrqType type);

typedef struct can_s can_t;

void can_init (can_t *obj, PinName rd, PinName td);
void can_free (can_t *obj);
int can_frequency(can_t *obj, int hz);

void can_irq_init (can_t *obj, can_irq_handler handler, uint32_t id);
void can_irq_free (can_t *obj);
void can_irq_set (can_t *obj, CanIrqType irq, uint32_t enable);

int can_write (can_t *obj, CAN_Message, int cc);
int can_read (can_t *obj, CAN_Message *msg);
int can_mode (can_t *obj, CanMode mode);
void can_reset (can_t *obj);
unsigned char can_rderror (can_t *obj);
unsigned char can_tderror (can_t *obj);
Expand Down
Loading