Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

CANUtils.cpp

Committer:
Just4pLeisure
Date:
2010-05-19
Revision:
0:e0b964252a05

File content as of revision 0:e0b964252a05:

// 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;
}