Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: CommandProcessor Watchdog mbed
Revision 0:ea85c59ec672, committed 2011-04-11
- Comitter:
- WiredHome
- Date:
- Mon Apr 11 11:32:05 2011 +0000
- Child:
- 1:6b831d0c058c
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CANUtilities.lib Mon Apr 11 11:32:05 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/WiredHome/code/CANUtilities/#5ac97276c770
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CANadapter.cpp Mon Apr 11 11:32:05 2011 +0000
@@ -0,0 +1,329 @@
+/// CANadapter is a simple program that permits monitoring as well as transmitting
+/// on both CAN buses that the mbed supports. It communicates to either the user or
+/// a PC hosted program via the USB Serial port.
+///
+/// For robustness, there is a small CommandProcessor, which permits setting
+/// CAN interface metrics, reviewing statistics, and sending messages.
+///
+/// There is also a watchdog, which will keep the system running and recover
+/// if there was a problem.
+///
+/// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved.
+/// Individuals may use this application for evaluation or non-commercial
+/// purposes. Within this restriction, changes may be made to this application
+/// as long as this copyright notice is retained. The user shall make
+/// clear that their work is a derived work, and not the original.
+/// Users of this application and sources accept this application "as is" and
+/// shall hold harmless Smartware Computing, for any undesired results while
+/// using this application - whether real or imagined.
+/// @author David Smart, Smartware Computing
+///
+#include "mbed.h"
+#include "Watchdog.h"
+#include "CommandProcessor.h"
+#include "CANUtilities.h"
+#include "CANQueue.h"
+#include "vs_string.h" // helpers that normalize between compilers for string functions
+
+extern "C" void mbed_reset();
+
+Serial pc(USBTX, USBRX); ///!< Used as the console for interactively reporting progress
+DigitalOut myled(LED4); /// LED sign of life
+
+Watchdog wd;
+
+//Ticker ticker; // for automated sending of messages during development
+
+//Timer timestamp;
+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
+Timeout t2; // create a timeout mechanism for can2
+void c1off(); // extinquish the can1 activity indicator
+void c2off(); // extinquish the can2 activity indicator
+
+struct {
+ CAN *can;
+ Timeout *flash;
+ DigitalOut led;
+ void (*off)(void);
+ bool active;
+ int bitrate;
+ uint32_t txCounter;
+ uint32_t rxCounter;
+} can[] = {
+ {&can1, &t1, LED1, c1off, false, 250000, 0, 0},
+ {&can2, &t2, LED2, c2off, false, 250000, 0, 0}
+};
+
+CANQueue inQueue(10);
+
+bool CANTransmitMsg(CANmsg msg);
+
+RUNRESULT_T CANconfig(char *p);
+const CMD_T CANconfigCmd = {"CANconfig", "Configure [channel mode speed], ? for more", CANconfig, visible};
+RUNRESULT_T CANmessage(char *p);
+const CMD_T CANmessageCmd = {"CANmessage", "Shows the CAN message format", CANmessage, visible};
+RUNRESULT_T CANtransmit(char *p);
+const CMD_T CANtransmitCmd = {"t", "transmit a CAN message (see CANmessage format)", CANtransmit, visible};
+RUNRESULT_T CANstatistics(char *p);
+const CMD_T CANstatisticsCmd = {"CANstats", "Shows the CAN statistics", CANstatistics, visible};
+RUNRESULT_T CANreset(char *p);
+const CMD_T CANresetCmd = {"CANreset", "Reset CAN channel [0|1|*]", CANreset, visible};
+RUNRESULT_T Free(char *p);
+const CMD_T FreeCmd = {"Free", "Shows the free memory in bytes", Free, visible};
+RUNRESULT_T Reboot(char *p);
+const CMD_T RebootCmd = {"Reboot", "Causes a near immediate reboot", Reboot, visible};
+
+RUNRESULT_T Reboot(char *p) {
+ (void)p;
+ pc.printf(" now...\r\n");
+ wait(0.5);
+ mbed_reset();
+ return runok;
+}
+
+RUNRESULT_T Free(char *p) {
+ (void)p;
+ uint32_t max = 100000;
+ uint32_t x = max / 2;
+ uint32_t min = 0;
+
+ while (min < max-1) {
+ void * p = malloc(x);
+ if (p) {
+ free(p);
+ min = x;
+ } else {
+ max = x;
+ }
+ x = (max + min)/2;
+ }
+ pc.printf("\r\n%u bytes free\r\n", x);
+ return runok;
+}
+
+
+RUNRESULT_T CANconfig(char *p) {
+ int ch, mode, bitrate;
+ char *token;
+ char *search = " ,\t";
+
+ token = strtok(p, search);
+ ch = atoi(token);
+ token = strtok(NULL, search);
+ if (mystrnicmp(token, "monitor", 7) == 0)
+ mode = 0;
+ else if (mystrnicmp(token, "0", 1) == 0)
+ mode = 0;
+ else if (mystrnicmp(token, "active", 7) == 0)
+ mode = 1;
+ else if (mystrnicmp(token, "1", 1) == 0)
+ mode = 1;
+ else
+ mode = -1;
+ token = strtok(NULL, search);
+ bitrate = atoi(token);
+
+ if (ch >=1 && ch <= 2 && mode != -1 && bitrate > 1000 && bitrate <= 1000000) {
+ can[ch-1].can->monitor(mode);
+ can[ch-1].can->frequency(bitrate);
+ pc.printf("\r\n");
+ } else {
+ pc.printf("\r\n CANconfig [channel mode bits/sec]\r\n"
+ " channel = 1 or 2\r\n"
+ " mode = 0|monitor|1|active\r\n"
+ " speed = baud rate (e.g. 10000, 250000, 500000, etc.)\r\n"
+ "");
+ }
+ return runok;
+}
+
+RUNRESULT_T CANreset(char *p) {
+ if (*p == '1' || *p == '*')
+ can[CH1].can->reset();
+ if (*p == '2' || *p == '*')
+ can[CH2].can->reset();
+ pc.printf("\r\n");
+ return runok;
+}
+
+
+RUNRESULT_T CANmessage(char *p) {
+ pc.printf( "\r\n// CAN Message Format\r\n"
+ "//\r\n"
+ "// +--- 'r'eceive or 't'ransmit\r\n"
+ "// | +--- 'nrm' 11 bit identifier, 'xtd' 29 bit identifier\r\n"
+ "// | | +--- channel '1' to '2'\r\n"
+ "// | | | +--- identifier in hex\r\n"
+ "// | | | | +--- dlc is data length control from 0 to 8\r\n"
+ "// | | | | | +--- data bytes 1 to 8\r\n"
+ "// | | | | | | [Below not required to send\r\n"
+ "// | | | | | | +--- fixed zero\r\n"
+ "// | | | | | | | +--- err count\r\n"
+ "// | | | | | | | | +--- timestamp\r\n"
+ "// | | | | | | | | |\r\n"
+ "// _ ___ __ ________ __ _______________________ _ ___ ___________\r\n"
+ "// r xtd 02 1CF00400 08 11 22 33 44 55 66 77 88 0 0 1234.567890\r\n"
+ "// t xtd 01 18EAFF03 03 EE EE 00 0 0 1235.654321\r\n"
+ "// 12345678901234567890123456789012345678901234567890123456789012\r\n");
+ return runok;
+}
+
+RUNRESULT_T CANtransmit(char *p) {
+ if (*p) {
+ CANmsg msg(p);
+ if (msg.dir == xmt)
+ CANTransmitMsg(msg);
+ pc.printf("\r\n");
+ } else {
+ pc.printf( "\r\n't'ransmit a CAN message in the message format\r\n");
+ }
+ return runok;
+}
+
+RUNRESULT_T CANstatistics(char *p) {
+ pc.printf("\r\n ch mode bitrate rxCount rxErrors txCount txErrors\r\n");
+ for (int i=0; i<CANCHANNELS; i++)
+ pc.printf(" %2u %7s %8u %7u %8u %7u %8u\r\n",
+ i+1,
+ can[i].active ? "active" : "monitor",
+ can[i].bitrate,
+ can[i].rxCounter,
+ can[i].can->rderror(),
+ can[i].txCounter,
+ can[i].can->tderror()
+ );
+ return runok;
+}
+
+
+
+
+int mReadable() {
+ return pc.readable();
+}
+int mGetCh() {
+ return pc.getc();
+}
+int mPutCh(int a) {
+ return pc.putc(a);
+}
+int mPutS(const char * s) {
+ return pc.printf("%s\r\n", s);
+}
+
+void c1off() {
+ can[CH1].led = false;
+}
+void c2off() {
+ can[CH2].led = false;
+}
+
+void canreceive(CANCHANNEL_T ch) {
+ CANMessage msg;
+
+ if (can[ch].can->read(msg)) {
+ CANmsg _msg(ch, rcv, msg);
+
+ inQueue.Enqueue(_msg);
+ can[ch].rxCounter++;
+ can[ch].led = true;
+ can[ch].flash->attach(can[ch].off, 0.02);
+ }
+}
+
+
+void can1rcv() {
+ canreceive(CH1);
+}
+void can2rcv() {
+ canreceive(CH2);
+}
+
+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)))
+ return true;
+ }
+ return false;
+}
+
+void cantransmit(int ch) {
+ char byte = (char)can[ch].txCounter;
+
+ if (can[ch].can->write(CANMessage(1337, &byte, 1))) {
+ can[ch].txCounter++;
+ }
+}
+
+void can1send() {
+ cantransmit(1);
+}
+void can2send() {
+ cantransmit(2);
+}
+
+
+
+int main(int argc, char* argv[]) {
+ CMDP_T * cp = GetCommandProcessor();
+ RUNRESULT_T cp_state;
+
+ pc.baud(921600);
+ if (wd.WatchdogCausedReset())
+ 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
+ cp->Init(
+ 0xFFFF, // Everything is enabled
+ TRUE, // Case Insensitive
+ TRUE, // Echo on
+ 50, // Command Buffer length
+ mReadable, // User provided API (kbhit())
+ mGetCh, // User provided API
+ mPutCh, // User provided API
+ mPutS); // User provided API
+ cp->Add(&CANconfigCmd);
+ cp->Add(&CANmessageCmd);
+ cp->Add(&CANtransmitCmd);
+ cp->Add(&CANstatisticsCmd);
+ cp->Add(&CANresetCmd);
+ cp->Add(&FreeCmd);
+ cp->Add(&RebootCmd);
+
+ can2.attach(can2rcv);
+ can1.attach(can1rcv);
+ can[CH1].can->monitor(false); // make them active on the network or tx errors result
+ can[CH2].can->monitor(false);
+
+ // This just sends a message every now and again
+ //ticker.attach(&can1send, 1);
+
+ // Do nothing to waste time in here...
+ do {
+ myled = !myled; // activity indicator
+
+ wd.Service(); // service the dog
+ cp_state = cp->Run(); // user interactions on the console interface
+
+ while (inQueue.QueueCount()) { // If we handle messages badly, could watchdog in here
+ CANmsg msg;
+
+ if (inQueue.Dequeue(&msg)) {
+ char buf[100];
+ msg.FormatCANMessage(buf, sizeof(buf));
+ pc.printf("%s\r\n", buf);
+ // To test, just enable the following, which tosses the ball back and forth
+ //wait(0.2);
+ //msg.dir = xmt; // What we received, we reflect back
+ //CANTransmitMsg(msg);
+ }
+ }
+ } while (cp_state == runok);
+ cp->End();
+ return 0;
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CommandProcessor.lib Mon Apr 11 11:32:05 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/WiredHome/code/CommandProcessor/#41046d2fd8e7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VStudioCompat.lib Mon Apr 11 11:32:05 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/WiredHome/libraries/VStudioCompat/lpfk6g \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Watchdog.lib Mon Apr 11 11:32:05 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/WiredHome/code/Watchdog/#5a1ff72b5915
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Apr 11 11:32:05 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912