CAN Functions -- allow applications and other packages to access CAN devices
Synopsis
#include <cyg/io/can.h>
int cyg_can_init(void);
int cyg_can_open(char* devname, cyg_can_dev* dev);
int cyg_can_close(cyg_can_dev dev);
cyg_can_msg* cyg_can_msg_alloc(void);
void cyg_can_msg_free(cyg_can_msg* msg);
int cyg_can_send(cyg_can_dev dev, cyg_can_msg* msg);
int cyg_can_send_nowait(cyg_can_dev dev, cyg_can_msg* msg);
int cyg_can_recv(cyg_can_dev dev, cyg_can_msg** msg);
int cyg_can_recv_poll(cyg_can_dev dev, cyg_can_msg** msg);
int cyg_can_recv_timeout(cyg_can_dev dev, cyg_can_msg** msg, cyg_tick_count_t timeout);
void cyg_can_poll(void);
int cyg_can_filter_set(cyg_can_dev dev, cyg_bool ide, cyg_uint32 match, cyg_uint32 mask);
int cyg_can_filter_get(cyg_can_dev dev, cyg_bool* ide, cyg_uint32* match, cyg_uint32* mask);
int cyg_can_baud_set(cyg_can_dev dev, cyg_uint32 baud);
int cyg_can_baud_get(cyg_can_dev dev, cyg_uint32* baud);
const char cyg_can_error_string(int code);
Initialization and Device Access
Before performing any CAN system operations, the application must call
cyg_can_init(). This function causes the CAN
subsystem to be initialized and causes all the configured devices to
initialize themselves. Only the first call to this function will
initialize the subsystem, subsequent calls will do nothing, so
libraries and independent systems may call it in their initialization
routines without needing to ensure it is called only once.
To gain access to a specific CAN channel, the application must call
cyg_can_open(). Channel names are defined in
the configuration and are typically "can0"
"can1" and so on. If the channel is not found this
function will return CYG_CAN_NOTFOUND; it may also
return errors generated by the device driver. If the channel is
found the call will return CYG_CAN_NOERROR and the
location pointed to by the dev parameter will
be initialized with a handle on the channel. This handle must be
used in all subsequent calls to access this channel.
When the application has finished with a channel it must call
cyg_can_close() on the handle.
Buffer Management
The CAN subsystem uses buffers to pass messages between the
application and the CAN subsystem. These buffers are allocated and
managed by the CAN subsystem. The exact number of buffers is
controllable in the configuration.
Each buffer contains the following fields:
cyg_can_msg *next
This field is used within the CAN subsystem to link this message
buffer into lists. When the buffer is in the possession of the user
(state is
CYG_CAN_MSG_STATE_USER) then this may be used for
application purposes.
unsigned intrtr
Remote Transmission Request. If this field is set in a transmitted
message buffer, then the RTR bit on the message will be set and the
data field will be ignored. On reception this field
reflects the state of the RTR bit in the received message.
unsigned intide
Extended ID. If this field is set then the id field
contains a 29 bit extended ID. If it is clear then the ID is 11 bits.
unsigned intstate
This field is used within the CAN subsystem to track the current state
of the buffer. The following states are supported:
CYG_CAN_MSG_STATE_FREE
The message buffer is not currently being used and is on the CAN
subsystem's free list.
CYG_CAN_MSG_STATE_USER
The message buffer is currently in the possession of the application code
and is outside the control of the CAN subsystem.
CYG_CAN_MSG_STATE_TX
The message buffer is either currently being transmitted, or is in a
queue of buffers awaiting transmission.
CYG_CAN_MSG_STATE_RX
The message buffer is the current pending receive buffer for a CAN
channel. The next message from that channel will be received into
this buffer.
CYG_CAN_MSG_STATE_RXQ
The message buffer is currently on a channel's receive queue. A
message has been received into it but not yet been passed on to the
user.
unsigned intlen
The length of the data carried in the message. This can range from
zero to 8. In a message with the RTR field set, this indicates the
size of data being requested.
intresult
An error code. For normal successful receptions of messages this will
be CYG_CAN_NOERROR. Message buffers are also used
to report special events on the channel such as transitions to
passive error and bus off states. In these cases, the event will be
reported using a message buffer with this field set to the appropriate
error code.
cyg_uint32timestamp
Some CAN channels contain a timer that can be used to timestamp
received packets. If that is the case, then the timestamp will be
stored in this field. If the channel does not have any hardware
timing facility, this field will not be used. This field is used for
internal purposes during message transmission.
cyg_uint32id
Message ID. This is the ID to be transmitted with the message, or the
ID received. If the ide field is set, then this
will contain a 29 bit ID, otherwise it will contain an 11 bit ID.
cyg_uint8data[8]
Message data. Only the first len bytes of data are
valid. If the rtr field is set, then the contents
of this field are ignored.
A message buffer may be allocated by calling
cyg_can_msg_alloc() and freed by calling
cyg_can_msg_free().
Transmit and Receive
To transmit a message an application must acquire a message buffer from
the CAN subsystem, fill it in with the message to be sent and call
cyg_can_send(). Following a successful call the buffer
becomes the property of the CAN subsystem and will be returned to the
free pool when the message has been transmitted. If an error is detected
then the call will return an error code and the message buffer will be
returned to the user for reuse or retransmission.
To send a message without waiting for it to complete, the application
can call cyg_can_send_nowait().
To receive a message the application calls
cyg_can_recv(). If there is a message waiting,
then a pointer to the message buffer will be installed in the location
pointed to by the msg argument and
CYG_CAN_NOERROR is returned.
If the application does no want to wait for a message to arrive, it
can call cyg_can_recv_poll() which will just test
for a message and return. If a message is present then
CYG_CAN_NOERROR is returned and
the msg filled in with a pointer to a message
buffer. If no message is present then the function will return
CYG_CAN_AGAIN.
The application can also wait for a defined length of time for a
message to arrive by calling
cyg_can_recv_timeout(). The additional
timeout argument supplies an
absolute timeout in system ticks. If a message is
present then CYG_CAN_NOERROR is returned and the
msg filled in with a pointer to a message
buffer. If no message arrives before the timeout expires then the
function will return CYG_CAN_TIMEOUT.
Regardless of which receive function is used, a successful return
results in a message buffer being passed back to the caller. The
result field of this message buffer will either
contain CYG_CAN_NOERROR for a normal message, or it
will contain an error code indicating an event that has occurred on
the channel. When the application has finished with the buffer it
must return it to the CAN subsystem by calling
cyg_can_msg_free().
The function cyg_can_poll() may be called to
force all channels to check for transmission completion or pending
receptions. When using interrupt driven devices it is unnecessary to
call this. However, if there are any polled devices, this is the only
way to ensure timely processing of received messages. This function
should therefore be called from the application main loop, or
from a separate timer driven thread, or by any other appropriate means
to ensure communication proceeds in a timely fashion.
Filtering
The functions cyg_can_filter_set() and
cyg_can_filter_get() allow the hardware filter to
be set and queried. The standard filter model consists of a mask and a
match value such that if an ID when bitwise ANDed with the mask equals
the match value, then the message is accepted. If the hardware does
not support a filter that conforms to this model then no hardware
filtering is done, but the filter will still be applied by the CAN
subsystem to all incoming packets.
In cyg_can_filter_set(), the
match and mask arguments
define the filter. The ide indicates whether
the filter is for normal or extended IDs. It is hardware dependent
what happens when the filter ID size does not match the ID size being
used on the network.
Baud Rate
The functions cyg_can_baud_set() and
cyg_can_baud_get() allow the channel baud rate
to be set and queried. Baud rates from 10kb/s to 1Mb/s may be set,
although not all device drivers will necessarily support all rates,
many will only support a subset. Also, due to interactions between the
input clock to the device and the divider granularity, it may not be
possible to set some baud rates accurately at some system clock rates;
it may be necessary to alter the system clock speed to enable
communication.
Errors
Many of the CAN API calls return error codes. The
result field of the message buffer structure may
also contain an error code from this set. The following error codes
may be returned by API calls:
CYG_CAN_NOERROR
No error, the operation completed successfully.
CYG_CAN_NOTFOUND
When returned from cyg_can_open() this error code
means that the named CAN channel could not be found.
CYG_CAN_INVALID
When returned from cyg_can_filter_set() this
error code means that the filter is invalid.
When returned from cyg_can_baud_get() this error
code means that the baud rate is invalid or the hardware cannot
support it with sufficient accuracy in the current system
configuration.
CYG_CAN_TIMEOUT
When returned from cyg_can_recv_timeout() this
error code means that the timeout has expired with no message being
received.
The following error codes may be passed back in the result field of a
message buffer acquired from one of the receive functions. Refer to
the CAN specification for details of what these events actually mean.
CYG_CAN_NOERROR
The message buffer contains a CAN message that was received from the channel.
CYG_CAN_WARN_TX
This error code indicates that the CAN channel's transmit error
counter has exceeded its warning limit, which is usually 96.
CYG_CAN_WARN_RX
This error code indicates that the CAN channel's receive error
counter has exceeded its warning limit, which is usually 96.
CYG_CAN_PASSIVE
This error code indicates that the CAN channel has gone into "error
passive" mode.
CYG_CAN_BUSOFF
This error code indicates that the CAN channel had gone into "bus
off" mode.
CYG_CAN_OVERRUN
This error code indicates that the CAN channel has lost one or more
CAN messages due to all the hardware buffers being full.
The cyg_can_error_string() translates these error
codes into strings for diagnostic purposes.