diff --git a/libraries/mbed/api/CAN.h b/libraries/mbed/api/CAN.h index 4f43806b7e..25b7620c02 100644 --- a/libraries/mbed/api/CAN.h +++ b/libraries/mbed/api/CAN.h @@ -150,6 +150,25 @@ public: */ 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(); @@ -158,33 +177,45 @@ public: */ 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::IRQ_RX, CAN::IRQ_TX, CAN::IRQ_ERROR, CAN::IRQ_OVERRUN, CAN::IRQ_WAKEUP, CAN::IRQ_PASSIVE, CAN::IRQ_ARB, CAN::IRQ_BUS, CAN::IRQ_READY) - Note that not every event is supported by all hardware + * @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), can_irq_event event=IRQ_RX); + 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::IRQ_RX, CAN::IRQ_TX, CAN::IRQ_ERROR, CAN::IRQ_OVERRUN, CAN::IRQ_WAKEUP, CAN::IRQ_PASSIVE, CAN::IRQ_ARB, CAN::IRQ_BUS, CAN::IRQ_READY) - Note that not every event is supported by all hardware + * @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 - void attach(T* tptr, void (T::*mptr)(void), can_irq_event event=IRQ_RX) { + void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) { if((mptr != NULL) && (tptr != NULL)) { - _irq[event].attach(tptr, mptr); - can_irq_set(&_can, event, 1); + _irq[type].attach(tptr, mptr); + can_irq_set(&_can, (CanIrqType)type, 1); } else { - can_irq_set(&_can, event, 0); + can_irq_set(&_can, (CanIrqType)type, 0); } } - static void _irq_handler(uint32_t id, can_irq_event event); + static void _irq_handler(uint32_t id, CanIrqType type); protected: can_t _can; diff --git a/libraries/mbed/common/CAN.cpp b/libraries/mbed/common/CAN.cpp index 936400309b..2b1fd4fdac 100644 --- a/libraries/mbed/common/CAN.cpp +++ b/libraries/mbed/common/CAN.cpp @@ -59,19 +59,23 @@ void CAN::monitor(bool silent) { can_monitor(&_can, (silent) ? 1 : 0); } -void CAN::attach(void (*fptr)(void), can_irq_event event) { - if (fptr) { - _irq[event].attach(fptr); - can_irq_set(&_can, event, 1); - } else { - can_irq_set(&_can, event, 0); - } +int CAN::mode(Mode mode) { + return can_mode(&_can, (CanMode)mode); } -void CAN::_irq_handler(uint32_t id, can_irq_event event) { - CAN *handler = (CAN*)id; - handler->_irq[event].call(); -} + 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::_irq_handler(uint32_t id, CanIrqType type) { + CAN *handler = (CAN*)id; + handler->_irq[type].call(); + } } // namespace mbed diff --git a/libraries/mbed/hal/can_api.h b/libraries/mbed/hal/can_api.h index ed9bf90648..5f2179cded 100644 --- a/libraries/mbed/hal/can_api.h +++ b/libraries/mbed/hal/can_api.h @@ -38,9 +38,19 @@ typedef enum { IRQ_ARB, IRQ_BUS, IRQ_READY -} can_irq_event; +} CanIrqType; -typedef void (*can_irq_handler)(uint32_t id, can_irq_event event); + +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; @@ -50,10 +60,11 @@ 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, can_irq_event irq, uint32_t enable); +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); diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/can_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/can_api.c index 00df9c809e..ac316468dd 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/can_api.c +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/can_api.c @@ -78,6 +78,11 @@ 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; @@ -133,10 +138,10 @@ void can_irq_free(can_t *obj) { } // Clear or set a irq -void can_irq_set(can_t *obj, can_irq_event event, uint32_t enable) { +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { uint32_t ier; - switch (event) { + switch (type) { case IRQ_RX: ier = (1 << 0); break; case IRQ_TX: ier = (1 << 1); break; case IRQ_ERROR: ier = (1 << 2); break;