196 lines
8.9 KiB
Plaintext
196 lines
8.9 KiB
Plaintext
|
The library has a ton of functions. A lot of them are complicated
|
||
|
and really aren't necessary for normal use. This document
|
||
|
explains how to use the library simply and will suffice for most
|
||
|
applications.
|
||
|
|
||
|
To start with, you'll need to initialize the canbus hardware. There are two
|
||
|
Canbus ports on the Due. There are objects already created
|
||
|
for each port: Can0 and Can1. All functions below are called on one
|
||
|
of those two objects. Note: The library used to use CAN and CAN2 in place
|
||
|
of Can0 and Can1. You can still use those other names as they've been maintained
|
||
|
as aliases. Where functions have been added the old functions have been left behind
|
||
|
so backward compatibility is maintained. Use whichever functions work best for you.
|
||
|
|
||
|
init(baudrate) - Initializes the given canbus port with the given baud
|
||
|
rate. Sets up for interrupt driven canbus with 7 receive mailboxes
|
||
|
and 1 transmit mailbox. You don't need to worry about mailboxes though
|
||
|
if you don't want to. Also sets the default enable pin (62 for Can0, 65 for Can1)
|
||
|
Example: Can0.init(250000);
|
||
|
|
||
|
begin(baudrate) - Exactly like init above.
|
||
|
|
||
|
begin(baudrate, enablepin) - Like above two but with addition of an enable pin. The enable pin
|
||
|
will be raised high when the relevant canbus port is enabled and sunk low when the relevant port
|
||
|
is disabled. If you do not need an enable pin then pass 255.
|
||
|
Example: Can0.begin(250000, 62);
|
||
|
|
||
|
begin() - Initializes with default settings for both baud and enable (250k baud, enable as above)
|
||
|
|
||
|
set_baudrate(baudrate) - Set the baud rate of the canbus. This
|
||
|
can be set to anything you'd like (within reason) but the common
|
||
|
baud rates are 33333, 125000, 250000, 500000, 1000000. Do not
|
||
|
use this unless you are changing the baud rate of an already
|
||
|
initialized canbus port.
|
||
|
Example: Can0.set_baudrate(500000);
|
||
|
|
||
|
enable() - Enable the canbus port. You don't need to call this unless
|
||
|
you've disabled the port at some time in the past.
|
||
|
Example: Can0.enable();
|
||
|
|
||
|
disable() - Disable the canbus port. You will no longer be able to
|
||
|
properly use it.
|
||
|
Example: Can0.disable();
|
||
|
|
||
|
Then, it is on to using the newly set-up canbus port:
|
||
|
|
||
|
This is the structure you will use for both sending and receiving.
|
||
|
typedef struct
|
||
|
{
|
||
|
uint32_t id; // Can0 be either 11 or 29 bit ID
|
||
|
uint32_t fid; // Family ID is a somewhat advanced thing. You Can0 ignore it.
|
||
|
uint8_t rtr; // Remote Transmission Request - Don't use this.
|
||
|
uint8_t priority; // Priority for TX frames. Probably not that useful normally
|
||
|
uint8_t extended;//Set to true for extended frames, false for standard
|
||
|
uint8_t length; // Number of data bytes
|
||
|
BytesUnion data; // Data bytes
|
||
|
} CAN_FRAME;
|
||
|
|
||
|
In turn, BytesUnion is a way to access the 8 data bytes in a variety of ways with a variety of names:
|
||
|
typedef union {
|
||
|
uint64_t value;
|
||
|
struct {
|
||
|
uint32_t low;
|
||
|
uint32_t high;
|
||
|
};
|
||
|
struct {
|
||
|
uint16_t s0;
|
||
|
uint16_t s1;
|
||
|
uint16_t s2;
|
||
|
uint16_t s3;
|
||
|
};
|
||
|
uint8_t bytes[8];
|
||
|
uint8_t byte[8]; //alternate name so you can omit the s if you feel it makes more sense
|
||
|
} BytesUnion;
|
||
|
|
||
|
int setRXFilter(id, mask, extended) - Set up a filter for incoming frames.
|
||
|
This version of the function allows one to forget about mailboxes and just
|
||
|
set a filter. It will handle the details for you and return which mailbox it used
|
||
|
in case you need to change it later. It returns -1 if there was a problem.
|
||
|
Example: Can0.setRXFilter(0x7E0, 0x7E0, false);
|
||
|
|
||
|
int setRXFilter(mailbox,id,mask,extended) - The other version of setting a filter.
|
||
|
It takes the mailbox to change. So long as you pass a valid mailbox number (0-7)
|
||
|
you will get that number back as the return value. It returns -1 on error.
|
||
|
Example: Can0.setRXFilter(0, 0x10000, 0x10000, true);
|
||
|
|
||
|
int watchFor() - An easy way to allow all traffic through. Will automatically add 1 mailbox
|
||
|
for standard frames and 1 for extended frames.
|
||
|
Example: Can0.watchFor();
|
||
|
|
||
|
int watchFor(uint32_t id) - Watch for a specific and single ID. Will automatically determine whether to accept
|
||
|
extended or standard frames.
|
||
|
Example: Can0.watchFor(0x740);
|
||
|
|
||
|
int watchFor(uint32_t id, uint32_t mask) - Watch for a group of IDs based on ID and a mask. Also uses
|
||
|
automatic determination of extended/standard.
|
||
|
Example: Can0.watchFor(0x620, 0x7F0); //Watch for a range of ids from 0x620 to 0x62F
|
||
|
|
||
|
int watchForRange(uint32_t id1, uint32_t id2) - A potentially much easier routine. Pass the lowest and highest
|
||
|
IDs you want to accept and it will automatically determine a suitable ID and mask to use. It might accept
|
||
|
more IDs than what you passed if necessary.
|
||
|
Example: Can0.watchForRange(0x620, 0x64F); //Accept frames with IDs from 0x620 to 0x64F
|
||
|
|
||
|
int findFreeRXMailbox() - Allows your program to get a free mailbox if you're
|
||
|
going to use the above function directly. You shouldn't need to use this very often.
|
||
|
Example: mailbox = Can0.findFreeRXMailbox();
|
||
|
|
||
|
setNumTXBoxes(txboxes) - Above it was mentioned that the default setup is to
|
||
|
have 7 RX mailboxes and 1 TX mailbox. This should work for 95% of programs
|
||
|
because the underlying library code uses interrupts with large buffers. But, if you
|
||
|
will only be sending or only receiving or if you otherwise really need to tweak the
|
||
|
arrangement you Can0 with this function. This function totally reinitializes all
|
||
|
mailboxes so be sure to call this function before you start setting up your filters.
|
||
|
Example: Can0.setNumTXBoxes(2);
|
||
|
|
||
|
There are two ways to receive canbus frames with this library. You Can0 choose from
|
||
|
callback driven reception or buffered frames. Either one is interrupt driven. The
|
||
|
choice really comes down to whether you'd like to process frames at a given point
|
||
|
in your code or whether you'd like to immediately get a call when a frame comes in.
|
||
|
|
||
|
Buffered / Polling version:
|
||
|
|
||
|
bool rx_avail() - The actual frame reception code is interrupt driven so you do not
|
||
|
need to rapidly poll for incoming frames at risk of losing some. However, it is still
|
||
|
handy to know if one or more frames came in. This function returns true if there
|
||
|
are received frames waiting to be processed by your program.
|
||
|
Example: if (Can0.rx_avail()) //do something here.
|
||
|
|
||
|
int available() - Returns the number of waiting frames in the receive buffer. Can be used in place
|
||
|
of rx_avail()
|
||
|
Example: if (Can0.available() > 0) //do something
|
||
|
|
||
|
get_rx_buff(CAN_FRAME &) - Read a waiting frame into the variable passed to the function.
|
||
|
Example:
|
||
|
CAN_FRAME myFrame;
|
||
|
if (Can0.rx_avail()) get_rx_buff(myFrame);
|
||
|
|
||
|
read(CAN_FRAME &) - Exactly like get_rx_buff but with an easier to remember name.
|
||
|
Example: Can0.read(myFrame);
|
||
|
|
||
|
Callback version:
|
||
|
|
||
|
setCallback(mailbox, cb) - Set a callback function for a mailbox (0-7)
|
||
|
Example:
|
||
|
void someFunction(Can0_FRAME *frame)
|
||
|
{
|
||
|
//do something with frame in here
|
||
|
}
|
||
|
setCallback(3, someFunction); //sets callback for third mailbox
|
||
|
|
||
|
setGeneralCallback(cb) - Set a callback that will be used for any mailbox that doesn't have a registered callback
|
||
|
Example: Can0.setGeneralCallback(someFunction);
|
||
|
|
||
|
void attachCANInterrupt(void (*cb)(CAN_FRAME *)) - Merely an alternative name for setGeneralCallback
|
||
|
|
||
|
void attachCANInterrupt(uint8_t mailBox, void (*cb)(CAN_FRAME *)) - An alternative name for setCallback
|
||
|
|
||
|
void detachCANInterrupt(uint8_t mailBox) - Removes the handler from the given mailbox.
|
||
|
Example: Can0.detachCANInterrupt(0);
|
||
|
|
||
|
These calls will not require any polling at all. You will immediately be given any frames that come into the system.
|
||
|
However, care must be taken as your callback function will be in interrupt context. Do not do very much work
|
||
|
in the callback function. Any frame that was returned via callback will not be buffered and thus will not be available
|
||
|
to the buffered system described previously.
|
||
|
|
||
|
|
||
|
Frame sending:
|
||
|
|
||
|
bool sendFrame(Can0_FRAME&) - Send a frame over canbus. It will try to send immediately
|
||
|
but will automatically fall back to buffering the frame and sending via interrupt
|
||
|
when the bus frees up. Returns whether it could send a frame (true/false). Only false if the TX buffer
|
||
|
fills up for some reason. In that cases you'll have to send frames at a slower rate or check to be sure
|
||
|
that the CAN bus is actually operational.
|
||
|
Example:
|
||
|
CAN_FRAME myFrame;
|
||
|
myFrame.id = 45;
|
||
|
myFrame.length = 1
|
||
|
myFrame.data[0] = 128;
|
||
|
Can0.sendFrame(myFrame);
|
||
|
|
||
|
There is an alternative output method now. You can set the ID and then use write to write out frames. This will
|
||
|
send one frame per call but can be used to output the value of variables up to 8 bytes in size:
|
||
|
|
||
|
void setWriteID(uint32_t id) - Set the ID to use for the write function.
|
||
|
Example: Can0.setWriteID(0x620);
|
||
|
|
||
|
void setBigEndian(bool) - Set how to output the bytes sent by the write function. The Due is little endian so
|
||
|
setting True to this function will cause bytes to be output in reverse order (big endian)
|
||
|
Example: Can0.setBigEndian(true);
|
||
|
|
||
|
template <typename t> void write(t inputValue) - Write the given input bytewise into a frame and send it. Uses
|
||
|
the ID from the setWriteID function. Immediately tries to send the frame. This function is probably most useful
|
||
|
for simple tests as it does not support sending multiple values in the same frame.
|
||
|
Example:
|
||
|
int SomeValue = 23423;
|
||
|
Can0.write(SomeValue);
|