-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Squashed 'lib/FlexCAN_Library/' changes from 9a678c0..4ad16aa
4ad16aa Mailbox specific buffers, some fixes fef43b1 IRQ locking, some fix and compatibility fix eee307a Merge pull request #4 from tni/tx-notification 9458e8e Add support for transmission complete callback. Add write method allowing the use of a specific mailbox. Fix signed shift undefined behavior. 74359ad Fix up whitespace and formatting e1171eb Merge pull request #3 from mdapoz/master c6dced2 Add controller number to the mailbox call-back to identify which controller the mailbox belongs to. 0ba9416 Merge pull request #2 from mdapoz/master b375f77 Add documentation for getFilter(). 2d2031b Rework ring buffer code to be API driven. Correctly handle up to 64K entries in the ring. d16ff9e Merge remote-tracking branch 'upstream/master' 3a92077 Update readme for new functionality 1847448 Merge branch 'master' of github.com:collin80/FlexCAN_Library cb6008c Merge pull request #1 from mdapoz/master 6abc144 Changed the way status is grabbed - very minor update 8faf148 Add getFilter() API. 5288f30 Add interface statistics API (start/stop/clear/get) dd06e5b Add CAN timestamp to packet structure. 5b478c8 Add tracking of lost messages. Fix filter mask parameter in begin(). 781b2fd Update README.md 65d7e6d Update README.md a1dd2c0 New example file that shows how to receive extended frames (29 bit ID) 9af9498 Better support for Teensy 3.5, more pictures and description in README, very basic RTR support dbdd008 Merge branch 'master' of github.com:collin80/FlexCAN_Library cd8e7d9 Add listen only mode, add code to automatically support any viable baud rate ff00b94 Update readme... again. ef73c13 Updated readme. 8e4809a Added example for single CAN boards (Teensy 3.2, Teensy 3.5). Moved ISR status clearing to end of ISR. aafe166 Fixed bugs in code, added implementation of OO callbacks, added two examples that use new library functionality, deleted old examples that wouldn't compile anyway d6c3566 Rewrote library to be interrupt driven for Rx/Tx. Start of support for filters and object oriented callback. 2d27761 Add files via upload 5e0ef70 Added example for dual CAN 9b20f5b Cleanup and comment updates 0030c83 Added Teensy 3.6 pinout 3790161 Updated Readme.md to include Teensy 3.6 93eb6d0 Added support for second FlexCAN controller on MK66FX1M0 e8d6ddf Added support for second FlexCAN controller on MK66FX1M0 git-subtree-dir: lib/FlexCAN_Library git-subtree-split: 4ad16aa19b07007f94451ba4d2be694003f25904
- Loading branch information
Showing
13 changed files
with
2,308 additions
and
328 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,232 @@ | ||
// ------------------------------------------------------------- | ||
// a simple Arduino Teensy3.1 CAN driver | ||
// a simple Arduino Teensy 3.1/3.2/3.6 CAN driver | ||
// by teachop | ||
// dual CAN support for MK66FX1M0 by Pawelsky | ||
// | ||
#ifndef __FLEXCAN_H__ | ||
#define __FLEXCAN_H__ | ||
|
||
#include <Arduino.h> | ||
|
||
#define FlexCAN_MAILBOX_TX_BUFFER_SUPPORT // helper definition for handling different FlexCAN revisions | ||
#define FlexCAN_DYNAMIC_BUFFER_SUPPORT // helper definition for handling different FlexCAN revisions | ||
|
||
#if !defined(SIZE_RX_BUFFER) | ||
#define SIZE_RX_BUFFER 32 // receive incoming ring buffer size | ||
#endif | ||
|
||
#if !defined(SIZE_TX_BUFFER) | ||
#define SIZE_TX_BUFFER 16 // transmit ring buffer size | ||
#endif | ||
|
||
#define SIZE_LISTENERS 4 // number of classes that can register as listeners on each CAN bus | ||
#define NUM_MAILBOXES 16 // architecture specific but all Teensy 3.x boards have 16 mailboxes | ||
#define IRQ_PRIORITY 64 // 0 = highest, 255 = lowest | ||
|
||
#define COLLECT_CAN_STATS | ||
|
||
typedef struct CAN_message_t { | ||
uint32_t id; // can identifier | ||
uint8_t ext; // identifier is extended | ||
uint8_t len; // length of data | ||
uint16_t timeout; // milliseconds, zero will disable waiting | ||
uint8_t buf[8]; | ||
uint32_t id; // can identifier | ||
uint16_t timestamp; // FlexCAN time when message arrived | ||
struct { | ||
uint8_t extended:1; // identifier is extended (29-bit) | ||
uint8_t remote:1; // remote transmission request packet type | ||
uint8_t overrun:1; // message overrun | ||
uint8_t reserved:5; | ||
} flags; | ||
uint8_t len; // length of data | ||
uint8_t buf[8]; | ||
} CAN_message_t; | ||
|
||
typedef struct CAN_filter_t { | ||
uint8_t rtr; | ||
uint8_t ext; | ||
uint32_t id; | ||
uint32_t id; | ||
struct { | ||
uint8_t extended:1; // identifier is extended (29-bit) | ||
uint8_t remote:1; // remote transmission request packet type | ||
uint8_t reserved:6; | ||
} flags; | ||
} CAN_filter_t; | ||
|
||
// statistics about the CAN interface | ||
|
||
typedef struct CAN_stats_t { | ||
bool enabled; // enable collecting statistics | ||
uint32_t ringRxMax; // number of entries in the ring buffer | ||
uint32_t ringRxHighWater; // maximum entries used in the ring buffer | ||
uint32_t ringRxFramesLost; // total number of frames lost | ||
uint32_t ringTxMax; // number of entries in the ring buffer | ||
uint32_t ringTxHighWater; // maximum entries used in the ring buffer | ||
struct { | ||
uint32_t refCount; // mailbox reference (use) count | ||
uint32_t overrunCount; // mailbox message overrun count | ||
} mb[NUM_MAILBOXES]; | ||
} CAN_stats_t; | ||
|
||
// ring buffer data structure | ||
|
||
typedef struct ringbuffer_t { | ||
volatile uint16_t head; | ||
volatile uint16_t tail; | ||
uint16_t size; | ||
volatile CAN_message_t *buffer; | ||
} ringbuffer_t; | ||
|
||
// for backwards compatibility with previous structure members | ||
|
||
#define ext flags.extended | ||
#define rtr flags.remote | ||
|
||
class CANListener | ||
{ | ||
public: | ||
CANListener (); | ||
|
||
virtual bool frameHandler (CAN_message_t &frame, int mailbox, uint8_t controller); | ||
virtual void txHandler (int mailbox, uint8_t controller); | ||
|
||
void attachMBHandler (uint8_t mailBox); | ||
void detachMBHandler (uint8_t mailBox); | ||
void attachGeneralHandler (void); | ||
void detachGeneralHandler (void); | ||
|
||
private: | ||
uint32_t callbacksActive; // bitfield indicating which callbacks are installed (for object oriented callbacks only) | ||
|
||
friend class FlexCAN; // class has to have access to the the guts of this one | ||
}; | ||
|
||
// ------------------------------------------------------------- | ||
|
||
class FlexCAN | ||
{ | ||
private: | ||
struct CAN_filter_t defaultMask; | ||
uint32_t flexcanBase; | ||
struct CAN_filter_t MBFilters[NUM_MAILBOXES]; | ||
static struct CAN_filter_t defaultMask; | ||
void mailbox_int_handler (uint8_t mb, uint32_t ul_status); | ||
CANListener *listener[SIZE_LISTENERS]; | ||
|
||
ringbuffer_t txRing; | ||
volatile CAN_message_t *tx_buffer; | ||
ringbuffer_t rxRing; | ||
volatile CAN_message_t *rx_buffer; | ||
ringbuffer_t * txRings[NUM_MAILBOXES]; | ||
|
||
bool IrqEnabled; | ||
|
||
void writeTxRegisters (const CAN_message_t &msg, uint8_t buffer); | ||
void readRxRegisters (CAN_message_t &msg, uint8_t buffer); | ||
|
||
void initRingBuffer (ringbuffer_t &ring, volatile CAN_message_t *buffer, uint32_t size); | ||
bool addToRingBuffer (ringbuffer_t &ring, const CAN_message_t &msg); | ||
bool removeFromRingBuffer (ringbuffer_t &ring, CAN_message_t &msg); | ||
bool isRingBufferEmpty (ringbuffer_t &ring); | ||
uint32_t ringBufferCount (ringbuffer_t &ring); | ||
|
||
void irqLock() { IrqEnabled=NVIC_IS_ENABLED(IRQ_CAN_MESSAGE); NVIC_DISABLE_IRQ(IRQ_CAN_MESSAGE); } | ||
void irqRelease() { if (IrqEnabled) NVIC_ENABLE_IRQ(IRQ_CAN_MESSAGE); } | ||
|
||
void initializeBuffers(); | ||
bool isInitialized() { return tx_buffer!=0; } | ||
void setPins(uint8_t txAlt, uint8_t rxAlt); | ||
void setBaudRate(uint32_t baud); | ||
void softReset(); | ||
void halt(); | ||
void exitHalt(); | ||
void freeze(); | ||
void waitFrozen(); | ||
void waitNotFrozen(); | ||
void waitReady(); | ||
bool isFrozen(); | ||
|
||
bool usesGlobalTxRing(uint8_t mbox) { return (mbox<getNumMailBoxes()?txRings[mbox]==0:true); } | ||
bool isTxBox(uint8_t mbox) { return (mbox>=getFirstTxBox() && mbox<getNumMailBoxes() ); } | ||
|
||
#ifdef COLLECT_CAN_STATS | ||
CAN_stats_t stats; | ||
#endif | ||
|
||
protected: | ||
uint8_t numTxMailboxes; | ||
uint16_t sizeRxBuffer; | ||
uint16_t sizeTxBuffer; | ||
|
||
public: | ||
FlexCAN(uint32_t baud = 125000); | ||
void begin(const CAN_filter_t &mask); | ||
inline void begin() | ||
{ | ||
begin(defaultMask); | ||
} | ||
void setFilter(const CAN_filter_t &filter, uint8_t n); | ||
void end(void); | ||
int available(void); | ||
int write(const CAN_message_t &msg); | ||
int read(CAN_message_t &msg); | ||
FlexCAN (uint8_t id = 0); | ||
|
||
// Before begin, you can define rx buffer size. Default is SIZE_RX_BUFFER. This does not have effect after begin. | ||
void setRxBufferSize(uint16_t size) { if (!isInitialized() ) sizeRxBuffer=size; } | ||
|
||
// Before begin, you can define global tx buffer size. Default is SIZE_TX_BUFFER. This does not have effect after begin. | ||
void setTxBufferSize(uint16_t size) { if (!isInitialized() ) sizeTxBuffer=size; } | ||
|
||
// You can define mailbox specific tx buffer size. This can be defined only once per mailbox. | ||
// As default prioritized messages will not be buffered. If you define buffer size for mail box, the messages will be | ||
// buffered to own buffer, if necessary. | ||
void setMailBoxTxBufferSize(uint8_t mbox, uint16_t size); | ||
|
||
inline uint8_t getFirstTxBox() { return getNumMailBoxes()-numTxMailboxes; } | ||
inline uint8_t getLastTxBox() { return getNumMailBoxes()-1; } | ||
inline uint8_t getNumMailBoxes() { return NUM_MAILBOXES; } | ||
inline uint8_t getNumRxBoxes() { return getNumMailBoxes()-numTxMailboxes; } | ||
|
||
void begin (uint32_t baud = 250000, const CAN_filter_t &mask = defaultMask, uint8_t txAlt = 0, uint8_t rxAlt = 0); | ||
|
||
void setFilter (const CAN_filter_t &filter, uint8_t n); | ||
bool getFilter (CAN_filter_t &filter, uint8_t n); | ||
void setMask (uint32_t mask, uint8_t n); | ||
void end (void); | ||
uint32_t available (void); | ||
int write (const CAN_message_t &msg); | ||
int write (const CAN_message_t &msg, uint8_t n); | ||
int read (CAN_message_t &msg); | ||
uint32_t rxBufferOverruns (void) | ||
{ | ||
return stats.ringRxFramesLost; | ||
}; | ||
|
||
#ifdef COLLECT_CAN_STATS | ||
void startStats (void) | ||
{ | ||
stats.enabled = true; | ||
}; | ||
void stopStats (void) | ||
{ | ||
stats.enabled = false; | ||
}; | ||
void clearStats (void); | ||
CAN_stats_t getStats (void) | ||
{ | ||
return stats; | ||
}; | ||
#endif | ||
|
||
//new functionality added to header but not yet implemented. Fix me | ||
void setListenOnly (bool mode); //pass true to go into listen only mode, false to be in normal mode | ||
|
||
bool attachObj (CANListener *listener); | ||
bool detachObj (CANListener *listener); | ||
|
||
//int watchFor(); //allow anything through | ||
//int watchFor(uint32_t id); //allow just this ID through (automatic determination of extended status) | ||
//int watchFor(uint32_t id, uint32_t mask); //allow a range of ids through | ||
//int watchForRange(uint32_t id1, uint32_t id2); //try to allow the range from id1 to id2 - automatically determine base ID and mask | ||
|
||
uint8_t setNumTxBoxes (uint8_t txboxes); | ||
// Obsolete, for compatibility with version provided with Teensyduino | ||
uint8_t setNumTXBoxes (uint8_t txboxes) { return setNumTxBoxes(txboxes); } | ||
|
||
void message_isr (void); | ||
void bus_off_isr (void); | ||
void error_isr (void); | ||
void tx_warn_isr (void); | ||
void rx_warn_isr (void); | ||
void wakeup_isr (void); | ||
}; | ||
|
||
extern FlexCAN Can0; | ||
#ifdef __MK66FX1M0__ | ||
extern FlexCAN Can1; | ||
#endif | ||
|
||
#endif // __FLEXCAN_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[Project] | ||
Name=FlexCAN | ||
Manager=KDevCMakeManager | ||
VersionControl=kdevgit |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.