[En-Nut-Discussion] Ethernut with CAN-IF
Ole Reinhardt
ole.reinhardt at kernelconcepts.de
Wed Jul 27 12:29:19 CEST 2005
Hello,
> I'm searching for some information how the ethernut could be extended with a new CAN device.
> I've seen already some sources sja1000.c etc. with a complete set of HW Driver functions.
> How is this connected with Nut/OS ? (Same as already existing devices NutRegister,NUTDEVICE......)
I have added CAN support for SJA1000 devices. Especialy I have made
these extensions having our own CAN board in mind.
http://www.kernelconcepts.de/products/mcan/
In detail you can use the SJA1000 driver like a "normal" device driver.
Initialisation phase:
u_short base_address = 0x8000;
NutRegisterDevice(&devSJA1000, base_address, 0);
The base address can be passed as parameter of NutRegisterDevice.
The interrupt can not be passed, but specified in include files (see
include/cfg/m-can.h). I don't use the configurator as it is not running
on my system, but it should be possible to set the interrupt in the
configurator as well.
Configuration example:
#define SJA_SIGNAL sig_INTERRUPT7
#define SJA_EICR EICRB
#define SJA_SIGNAL_BIT 7
After initialisation you can use the functions defined in
include/dev/can_dev.h
These functions can transmit only raw frames. A frame is defined as:
struct _CANFRAME { // todo: Implement flags
u_long id; // Identifier
u_char len; // Length of frame, max = 8
u_char byte[8];
u_char ext; // Boolean, extendet frame
u_char rtr; // Boolean, remote transmition bit
};
The functions you can use are:
Setting an acceptance filter and acceptance mask:
void CAN_SetFilter(NUTDEVICE *dev, u_char *ac, u_char *am);
For more information about this filter take a look into the sja1000
datasheet.
Transmit a frame (blocking):
void CAN_TxFrame(NUTDEVICE *dev, CANFRAME *frame);
Try to transmit a frame:
u_char CAN_TryTxFrame(NUTDEVICE *dev, CANFRAME *frame);
On success this returns 0, if there is no free transmit buffer 1.
u_char CAN_TxFree(NUTDEVICE *dev);
This returns the space available in the transmit buffer.
Same for the receiving functions:
void CAN_RxFrame(NUTDEVICE *dev, CANFRAME *frame);
u_char CAN_TryRxFrame(NUTDEVICE *dev, CANFRAME *frame);
u_char CAN_RxAvail(NUTDEVICE *dev);
An example receive code could look like this:
while (!CAN_TryRxFrame(&devSJA1000, &frame))
{
if (count == MAX_DEVICES) {
error = ERR_TOO_MUCH_DEVICES;
break;
}
if ((frame.rtr) || (!frame.ext)) {
error = ERR_INVALID_FRAME;
} else {
source_id = (u_char) frame.id;
dest_id = (u_char) (frame.id >> 8);
cmd = (u_char) (frame.id >> 16);
...
An example send code could look like this:
void SendCANFrame(u_char prio, u_char source, u_char dest, u_char cmd,
u_char length, can_msg_t * message)
{
CANFRAME frame;
frame.id = ((u_long) (prio & 0x07) << 26) | ((u_long) cmd << 16) |
((u_long) dest << 8) | ((u_long) source);
frame.len = length;
frame.ext = 1;
frame.rtr = 0;
memcpy(frame.byte, message, length);
CAN_TxFrame(&devSJA1000, &frame);
}
Hope this helps... If you need help with your application feel free to
contact us.
Best regards,
Ole Reinhardt
--
kernel concepts Tel: +49-271-771091-14
Dreisbachstr. 24 Fax: +49-271-771091-19
D-57250 Netphen E+ : +49-177-7420433
--
More information about the En-Nut-Discussion
mailing list