Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Revision:
0:e0b964252a05
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CANUtils.cpp	Wed May 19 12:39:18 2010 +0000
@@ -0,0 +1,97 @@
+// CANUtils.cpp - functions that work with the CAN bus directly
+// Anything to do with the CAN bus must (should anyway) be done by one of these functions.
+
+#include "CANUtils.h"
+
+// CAN_RS pin at Philips PCA82C250 can bus controller.
+// activate transceiver by pulling this pin to GND.
+// (Rise and fall slope controlled by resistor R_s)
+// (+5V result in tranceiver standby mode)
+// For further information see datasheet page 4
+DigitalOut can_Pca82c250SlopePin(p28);// second can controller on these pins. Not used here.
+// CAN can1(p9, p10);
+// We use can on mbed pins 29(CAN_TXD) and 30(CAN_RXD).
+CAN can2(p30, p29);
+// Use a timer to see if things take too long
+Timer CANTimer;
+
+// Use the LEDs to if anything is happening on the CAN bus
+// LED1 CAN send
+DigitalOut led1(LED1);
+// LED2 CAN receive
+DigitalOut led2(LED2);
+
+
+void CANOpen() {
+    // 600kbit/s first - basically sets up CAN interface, but to wrong speed - not sure what else it does
+    can2.frequency(600000);
+    // 615kbit/s direct write of 615 kbit/s speed setting
+    LPC_CAN2->BTR = 0x370002;
+    // activate external can transceiver
+    can_Pca82c250SlopePin = 0;
+}
+
+void CANClose() {
+    // disable external can transceiver
+    can_Pca82c250SlopePin = 1;
+}
+
+//
+// Sends a CAN Message, returns FALSE if the message wasn't sent in time
+//
+// inputs:  integer CAN message 'id', pointer to 'frame', integer message length and integer timeout
+// return:     TRUE if the CAN message was sent before the 'timeout' expires
+//          FALSE if 'timeout' expires or the message length is wrong
+//
+extern bool CANSendTimeout (int id, char *frame, int len, int timeout) {
+    CANTimer.reset();
+    CANTimer.start();
+    while (CANTimer.read_ms() < timeout) {
+        if (can2.write(CANMessage(id, frame, len))) {
+            CANTimer.stop();
+            led1 = !led1;
+            return TRUE;
+        }
+    }
+    CANTimer.stop();
+    return FALSE;
+}
+
+//
+// Waits for a CAN Message with the specified 'id' for a time specified by the 'timeout'
+// All other messages are ignored
+// The CAN message frame is returned using the pointer to 'frame'
+//
+// inputs:    integer CAN message 'id', pointer to 'frame' for returning the data
+//          integer expected length of message, len and integer for the waiting time 'timeout'
+//
+// return:    TRUE if a qualifying message was received
+//          FALSE if 'timeout' expires or the message length is wrong
+//
+extern bool CANWaitTimeout (int id, char *frame, int len, int timeout) {
+    CANMessage CANMsgRx;
+    CANTimer.reset();
+    CANTimer.start();
+    while (CANTimer.read_ms() < timeout) {
+        if (can2.read(CANMsgRx)) {
+/*
+            printf("w%03x8", CANMsgRx.id);
+            for (char i=0; i<len; i++) {
+                printf("%02x", CANMsgRx.data[i]);
+            }
+            printf("\n\r");
+//            */
+            led2 = !led2;
+            if (CANMsgRx.id == id) {
+                CANTimer.stop();
+//                if (T5MsgRx.len != len)
+//                    return FALSE;
+                for (int i=0; i<len; i++)
+                    frame[i] = CANMsgRx.data[i];
+                return TRUE;
+            }
+        }
+    }
+    CANTimer.stop();
+    return FALSE;
+}