Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

canutils.cpp

Committer:
Just4pLeisure
Date:
2011-06-07
Revision:
3:92dae9083c83
Parent:
2:bf3a2b29259a
Child:
4:682d96ff6d79

File content as of revision 3:92dae9083c83:

/*******************************************************************************

canutils.cpp
(c) 2010 by Sophie Dexter

General purpose CAN bus functions for Just4Trionic by Just4pLeisure
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.

********************************************************************************

WARNING: Use at your own risk, sadly this software comes with no guarantees.
This software is provided 'free' and in good faith, but the author does not
accept liability for any damage arising from its use.

*******************************************************************************/

#include "canutils.h"

//CAN can2(p30, p29);
// Use a timer to see if things take too long
Timer CANTimer;


void can_open() {
    // activate external can transceiver
    can.reset();
    can_rs_pin = 0;
}

void can_close() {
    // disable external can transceiver
    can_rs_pin = 1;
    can.reset();
}

uint8_t can_set_speed(uint32_t speed) {
    // 600kbit/s first - basically sets up CAN interface, but to wrong speed - not sure what else it does
//    can.frequency(600000);
    // 615kbit/s direct write of 615 kbit/s speed setting
//    LPC_CAN2->BTR = 0x370002;
    return (can.frequency(speed)) ? TERM_OK : TERM_ERR;
}

//
// show_can_message
//
// Displays a CAN message in the RX buffer if there is one.
//
// inputs:    none
// return:    bool TRUE if there was a message, FALSE if no message.
//
extern void show_can_message() {
    CANMessage can_MsgRx;
    if (can.read(can_MsgRx)) {
        CANRXLEDON;
        printf("w%03x%d", can_MsgRx.id, can_MsgRx.len);
        for (char i=0; i<can_MsgRx.len; i++)
            printf("%02x", can_MsgRx.data[i]);
        printf(" %c ", can_MsgRx.data[2]);
        printf("\r\n");
    }
    return;
}

//
// silent_can_message
//
// Turns on the CAN receive LED if there is a CAN message
// but doesn't displays anything.
//
// inputs:    none
// return:    bool TRUE if there was a message, FALSE if no message.
//
extern void silent_can_message() {
    CANMessage can_MsgRx;
    if (can.read(can_MsgRx)) {
        CANRXLEDON;
    }
    return;
}

//
// 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 can_send_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) {
    CANTimer.reset();
    CANTimer.start();
    while (CANTimer.read_ms() < timeout) {
        if (can.write(CANMessage(id, frame, len))) {
            CANTimer.stop();
            CANTXLEDON;
//            led1 = 1;
            return TRUE;
        }
    }
    can.reset();
    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 can_wait_timeout (uint32_t id, char *frame, uint8_t len, uint16_t timeout) {
    CANMessage CANMsgRx;
    CANTimer.reset();
    CANTimer.start();
    while (CANTimer.read_ms() < timeout) {
        if (can.read(CANMsgRx)) {
/*
            printf("w%03x8", CANMsgRx.id);
            for (char i=0; i<len; i++) {
                printf("%02x", CANMsgRx.data[i]);
            }
            printf("\n\r");
//            */
            CANRXLEDON;
//            led2 = 1;
            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;
            }
        }
    }
    can.reset();
    CANTimer.stop();
    return FALSE;
}