This 'Hello World' program uses many of the SEEED_CAN library functions to display the VIN number stored in a GMLAN ECU then display all CAN messages on the CAN-BUS.
Fork of Seeed_CAN_Hello_World by
Revision 2:7e78ba1e5921, committed 2013-11-12
- Comitter:
- Just4pLeisure
- Date:
- Tue Nov 12 21:06:15 2013 +0000
- Parent:
- 1:d31ce42d53a1
- Commit message:
- Updated 12-11-2013 to make use of newly working interrupt 'attach' functions/methods
Changed in this revision
SEEED_CAN.lib | Show annotated file Show diff for this revision Revisions of this file |
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/SEEED_CAN.lib Wed Nov 06 20:24:49 2013 +0000 +++ b/SEEED_CAN.lib Tue Nov 12 21:06:15 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/Just4pLeisure/code/SEEED_CAN/#ad71faa09868 +http://mbed.org/users/Just4pLeisure/code/SEEED_CAN/#fd026fcfde94
--- a/main.cpp Wed Nov 06 20:24:49 2013 +0000 +++ b/main.cpp Tue Nov 12 21:06:15 2013 +0000 @@ -1,17 +1,38 @@ #include "mbed.h" #include "seeed_can.h" -SEEED_CAN CAN; // No parameters needed when Seeed Studios' CAN-BUS Shield is plugged into a FRDM-KL25Z mbed +SEEED_CAN can; // No parameters needed when Seeed Studios' CAN-BUS Shield is plugged into a FRDM-KL25Z mbed + // or an LPC1768b and using pins p9, p10, p11, p12 and p13. Serial pc(USBTX, USBRX); // USB serial port TTYACM0 (or COMn in a Windows environment - use device manager to find 'n') Ticker minute; Timer timestamp; -void resetTimestamp() +bool msgRxFlag = 0; + +void canInterrupt() +{ + can.attach(NULL); // Disable the interrupt - the application must re-anable the interrupt after it has acted upon it + msgRxFlag = 1; // Set a 'Flag' to say that there is an interrupt that needs to be processed +} + +void resetTimestamp() // Resets the 'timestamp' Timer (attached to the 'minute' Ticker) { timestamp.reset(); } +void displayMessage() // Display a CAN message if there is one in a receive buffer +{ + SEEED_CANMessage canMsg; + + if (can.read(canMsg)) { + printf("*** T%05dI%03xL%dD", timestamp.read_ms(), canMsg.id, canMsg.len); // Show a Timestamp in ms, message Id and message Length + for (uint32_t i = 0; i < canMsg.len; i++) + printf("%02x", canMsg.data[i]); // Show the message's data bytes in Hex representation + printf(" ***\r"); + } +} + int main() { SEEED_CANMessage canMsg; @@ -22,36 +43,37 @@ printf("Seeed Studios CAN-BUS Shield 'Hello World' program :-)\r\n"); timestamp.start(); minute.attach(&resetTimestamp, 60.0); // Reset the 'Timestamp' timer every minute - CAN.open(500000); // Initialise Seeed Studios' CAN-BUS shield with a baudrate of 500 kbps (P-bus) - CAN.mask(0, 0x7FF); // Configure Mask 0 to check all bits of a Standard CAN message Id - CAN.mask(1, 0x7FF, CANStandard); // Configure Mask 1 to check all bits of a Standard CAN message Id - CAN.filter(0, 0x7E8); // Configure Filter 0 - 0x7E8 is the id used by ECUs on GMLAN - while (CAN.read(canMsg)); // Empty any unfiltered messages in the receive buffers + can.open(500000, SEEED_CAN::Config); // Initialise Seeed Studios' CAN-BUS shield with a baudrate of 500 kbps (P-bus) + can.mask(0, 0x7FF); // Configure Mask 0 to check all bits of a Standard CAN message Id + can.mask(1, 0x7FF, CANStandard); // Configure Mask 1 to check all bits of a Standard CAN message Id + can.filter(0, 0x7E8); // Configure Filter 0 - 0x7E8 is the id used by ECUs on GMLAN // Read and Display the VIN code stored in a GMLAN ECU -// +// // ***!!! NOTE: Using while(...) as I am here is not a good idea because !!!*** // ***!!! this 'Hello World' will get stuck if the message never arrives !!!*** // ***!!! I should really perform checking and include a timeout. !!!*** // ***!!! It's sort of OK for a quick demo (Just don't show Nigel Jones) !!!*** -// - CAN.write(SEEED_CANMessage(0x7E0, reqvin)); // Request VIN using ReadDataByIdentifier method (GMLAN_DID) - while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8))); // Wait for the response +// + can.write(SEEED_CANMessage(0x7E0, reqvin)); // Request VIN using ReadDataByIdentifier method (GMLAN_DID) + while (!(can.read(canMsg) && (canMsg.id == 0x7E8))); // Wait for the response memcpy(VIN+0, canMsg.data+4, 4); // 1st 4 Bytes are part of message protocol, last 4 bytes are 1st 4 characters of VIN - CAN.write(SEEED_CANMessage(0x7E0, floctl)); // Send Trionic8 a "Flow Control Message to get the rest of the VIN - while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8))); // Wait for the 1st continuation message + can.write(SEEED_CANMessage(0x7E0, floctl)); // Send Trionic8 a "Flow Control Message to get the rest of the VIN + while (!(can.read(canMsg) && (canMsg.id == 0x7E8))); // Wait for the 1st continuation message memcpy(VIN+4, canMsg.data+1, 7); // 1st Byte is message continuation sequence number, last 7 bytes are next 7 characters of VIN - while (!(CAN.read(canMsg) && (canMsg.id == 0x7E8))); // Wait for the last message + while (!(can.read(canMsg) && (canMsg.id == 0x7E8))); // Wait for the last message memcpy(VIN+11, canMsg.data+1, 6); // 1st Byte is message continuation sequence number, last 6 bytes are remaining characters of VIN printf("VIN code: %s\r\n",VIN); // Display all messages on the CAN-BUS - CAN.monitor(1); // Select Moniter mode to listen only (do not ack messages on the CAN bus) - CAN.mask(0, NULL); // Clear acceptance mask 0 (i.e. accept all meassages) + can.monitor(1); // Select Moniter mode to listen only (do not ack messages on the CAN bus) + can.mask(0, NULL); // Clear acceptance mask 0 (i.e. accept all meassages) + can.attach(&canInterrupt, SEEED_CAN::RxAny); while (1) { - if (CAN.read(canMsg)) { - printf("*** T%05dI%03xL%dD", timestamp.read_ms(), canMsg.id, canMsg.len); - for (uint32_t i=0; i<canMsg.len; i++) - printf("%02x", canMsg.data[i]); - printf(" ***\r"); + if (msgRxFlag) { + displayMessage(); + if (can.interrupts(SEEED_CAN::RxAny)) { + msgRxFlag = 0; + can.attach(&canInterrupt, SEEED_CAN::RxAny); + } } } }