![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
A simple CAN adapter that supports two channels of CAN on the mbed. Configurable speed, monitor mode, statistics and send/receive via the USB serial port to a PC (or terminal program set for 921.6 kbaud)
Dependencies: CommandProcessor Watchdog mbed
Diff: CANadapter.cpp
- Revision:
- 1:6b831d0c058c
- Parent:
- 0:ea85c59ec672
--- a/CANadapter.cpp Mon Apr 11 11:32:05 2011 +0000 +++ b/CANadapter.cpp Mon Apr 11 11:42:08 2011 +0000 @@ -34,7 +34,7 @@ //Ticker ticker; // for automated sending of messages during development -//Timer timestamp; +// Services for each of the two CAN channels CAN can1(p9, p10); // bind CAN1 to the hardware CAN can2(p30, p29); // bind CAN2 to the hardware Timeout t1; // create a timeout mechanism for can1 @@ -42,6 +42,7 @@ void c1off(); // extinquish the can1 activity indicator void c2off(); // extinquish the can2 activity indicator +/// binding the services together for a simpler interface struct { CAN *can; Timeout *flash; @@ -56,10 +57,15 @@ {&can2, &t2, LED2, c2off, false, 250000, 0, 0} }; +// Support up to this many inbound CAN messages from the attached callbacks CANQueue inQueue(10); +// A method to transmit a CAN message of the derived type bool CANTransmitMsg(CANmsg msg); + +// The included command processor supports interactive sessions, with these +// and the built-in commands. RUNRESULT_T CANconfig(char *p); const CMD_T CANconfigCmd = {"CANconfig", "Configure [channel mode speed], ? for more", CANconfig, visible}; RUNRESULT_T CANmessage(char *p); @@ -75,6 +81,8 @@ RUNRESULT_T Reboot(char *p); const CMD_T RebootCmd = {"Reboot", "Causes a near immediate reboot", Reboot, visible}; +// Implementation of Command Processor accessed commands + RUNRESULT_T Reboot(char *p) { (void)p; pc.printf(" now...\r\n"); @@ -103,7 +111,6 @@ return runok; } - RUNRESULT_T CANconfig(char *p) { int ch, mode, bitrate; char *token; @@ -148,7 +155,6 @@ return runok; } - RUNRESULT_T CANmessage(char *p) { pc.printf( "\r\n// CAN Message Format\r\n" "//\r\n" @@ -173,7 +179,7 @@ RUNRESULT_T CANtransmit(char *p) { if (*p) { CANmsg msg(p); - if (msg.dir == xmt) + if (msg.dir == xmt) // silent failure if they try to transmit a receive msg CANTransmitMsg(msg); pc.printf("\r\n"); } else { @@ -199,7 +205,7 @@ - +// Helper functions provided to the command processor as a means of I/O int mReadable() { return pc.readable(); } @@ -213,6 +219,8 @@ return pc.printf("%s\r\n", s); } + +// LED activity indicators need to extinguish on timeout void c1off() { can[CH1].led = false; } @@ -220,6 +228,7 @@ can[CH2].led = false; } +// When a CAN message is received, it is placed in queue void canreceive(CANCHANNEL_T ch) { CANMessage msg; @@ -233,7 +242,7 @@ } } - +// received bound to each CAN channel void can1rcv() { canreceive(CH1); } @@ -241,6 +250,7 @@ canreceive(CH2); } +// method to transmit a CAN message of type CANmsg bool CANTransmitMsg(CANmsg msg) { if (msg.dir == xmt) { if (can[msg.ch].can->write(CANMessage(msg.id, (char *)&msg.data, msg.len, CANData, msg.format))) @@ -249,6 +259,7 @@ return false; } +// quick transmitter for testing only void cantransmit(int ch) { char byte = (char)can[ch].txCounter; @@ -275,7 +286,7 @@ pc.printf("Watchdog caused reset. WD is now rearmed\r\n"); wd.Configure(2.0); // sets the timeout interval pretty short - // Set up the Command Processor interface + // Set up the Command Processor interface and commands. cp->Init( 0xFFFF, // Everything is enabled TRUE, // Case Insensitive @@ -301,7 +312,7 @@ // This just sends a message every now and again //ticker.attach(&can1send, 1); - // Do nothing to waste time in here... + // Do nothing to waste time in here... (e.g. do not "wait(1.2);") do { myled = !myled; // activity indicator