mirror of https://github.com/ARMmbed/mbed-os.git
pull/20/head
commit
bf02700a32
|
@ -150,6 +150,25 @@ public:
|
||||||
*/
|
*/
|
||||||
void monitor(bool silent);
|
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.
|
/** Returns number of read errors to detect read overflow errors.
|
||||||
*/
|
*/
|
||||||
unsigned char rderror();
|
unsigned char rderror();
|
||||||
|
@ -158,33 +177,45 @@ public:
|
||||||
*/
|
*/
|
||||||
unsigned char tderror();
|
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
|
/** Attach a function to call whenever a CAN frame received interrupt is
|
||||||
* generated.
|
* generated.
|
||||||
*
|
*
|
||||||
* @param fptr A pointer to a void function, or 0 to set as none
|
* @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
|
/** Attach a member function to call whenever a CAN frame received interrupt
|
||||||
* is generated.
|
* is generated.
|
||||||
*
|
*
|
||||||
* @param tptr pointer to the object to call the member function on
|
* @param tptr pointer to the object to call the member function on
|
||||||
* @param mptr pointer to the member function to be called
|
* @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<typename T>
|
template<typename T>
|
||||||
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)) {
|
if((mptr != NULL) && (tptr != NULL)) {
|
||||||
_irq[event].attach(tptr, mptr);
|
_irq[type].attach(tptr, mptr);
|
||||||
can_irq_set(&_can, event, 1);
|
can_irq_set(&_can, (CanIrqType)type, 1);
|
||||||
}
|
}
|
||||||
else {
|
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:
|
protected:
|
||||||
can_t _can;
|
can_t _can;
|
||||||
|
|
|
@ -59,18 +59,22 @@ void CAN::monitor(bool silent) {
|
||||||
can_monitor(&_can, (silent) ? 1 : 0);
|
can_monitor(&_can, (silent) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAN::attach(void (*fptr)(void), can_irq_event event) {
|
int CAN::mode(Mode mode) {
|
||||||
|
return can_mode(&_can, (CanMode)mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAN::attach(void (*fptr)(void), IrqType type) {
|
||||||
if (fptr) {
|
if (fptr) {
|
||||||
_irq[event].attach(fptr);
|
_irq[(CanIrqType)type].attach(fptr);
|
||||||
can_irq_set(&_can, event, 1);
|
can_irq_set(&_can, (CanIrqType)type, 1);
|
||||||
} else {
|
} else {
|
||||||
can_irq_set(&_can, event, 0);
|
can_irq_set(&_can, (CanIrqType)type, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAN::_irq_handler(uint32_t id, can_irq_event event) {
|
void CAN::_irq_handler(uint32_t id, CanIrqType type) {
|
||||||
CAN *handler = (CAN*)id;
|
CAN *handler = (CAN*)id;
|
||||||
handler->_irq[event].call();
|
handler->_irq[type].call();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mbed
|
} // namespace mbed
|
||||||
|
|
|
@ -38,9 +38,19 @@ typedef enum {
|
||||||
IRQ_ARB,
|
IRQ_ARB,
|
||||||
IRQ_BUS,
|
IRQ_BUS,
|
||||||
IRQ_READY
|
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;
|
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_init (can_t *obj, can_irq_handler handler, uint32_t id);
|
||||||
void can_irq_free (can_t *obj);
|
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_write (can_t *obj, CAN_Message, int cc);
|
||||||
int can_read (can_t *obj, CAN_Message *msg);
|
int can_read (can_t *obj, CAN_Message *msg);
|
||||||
|
int can_mode (can_t *obj, CanMode mode);
|
||||||
void can_reset (can_t *obj);
|
void can_reset (can_t *obj);
|
||||||
unsigned char can_rderror (can_t *obj);
|
unsigned char can_rderror (can_t *obj);
|
||||||
unsigned char can_tderror (can_t *obj);
|
unsigned char can_tderror (can_t *obj);
|
||||||
|
|
|
@ -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) {
|
static inline void can_irq(uint32_t icr, uint32_t index) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
|
@ -133,10 +138,10 @@ void can_irq_free(can_t *obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear or set a irq
|
// 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;
|
uint32_t ier;
|
||||||
|
|
||||||
switch (event) {
|
switch (type) {
|
||||||
case IRQ_RX: ier = (1 << 0); break;
|
case IRQ_RX: ier = (1 << 0); break;
|
||||||
case IRQ_TX: ier = (1 << 1); break;
|
case IRQ_TX: ier = (1 << 1); break;
|
||||||
case IRQ_ERROR: ier = (1 << 2); break;
|
case IRQ_ERROR: ier = (1 << 2); break;
|
||||||
|
|
Loading…
Reference in New Issue