test code for our MBED board

Dependencies:   mbed lwip

can.c

Committer:
lolpcc
Date:
2011-05-04
Revision:
1:6877bb99aa17
Parent:
0:9edfcca7cd25

File content as of revision 1:6877bb99aa17:

#include "mbed.h"
#include "useful.h"
#include "led.h"
#include "cmd.h"        /* used to get at the command code */
#include "can_layer.h"
#include "can.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);

// We use can on mbed pins 29(CAN_TXD) and 30(CAN_RXD).
CAN can(p30, p29);

int    can_cnt=0;
extern char station_id;
char    *can_str;

/******************************************/
/*                                        */
/*    Can Bus Send a string to remote add */
/*                                        */
/******************************************/
void can_send_string(char remote, char *str)
{
    unsigned char    buf[0x8];
    int     len = strlen(str);
    int     id;
    int     cnt = 0;
    int     sub;
    int     pt = 0;
     
    if(len > 128){
        lprintf("Max string lenght of 128 bytes, current string %d bytes long, not sending\n",len);
        return;
    }
    
    /* Set up the TX buffer for start packet */
    can_clear_data(buf);
    buf[0] = station_id;  /* who we are */
    buf[1] = len;         /* number of bytes been sent, overall */
    buf[2] = (len/8)+1;   /* guess at how many packets it should be */
      
    id = can_build_id(station_id,remote,CAN_SPRT);
    if(!can.write(CANMessage(id, (char *)buf, 8))) {
        lprintf("Error sending %s packet (%03x),",cancmd[CAN_SPRT],id);
        can_dump_buffer(buf);
        lprintf("\n");
        return;
    }
    /* About to send the data */
    sub = 1;
    pt = 0;
    while(sub > 0){
        can_clear_data(buf);
        sub = can_build_data(len,pt,(unsigned char*)str,buf);
        id = can_build_id(station_id,remote,CAN_PRT);
        if(!can.write(CANMessage(id | cnt, (char *)buf, 8))) {
            lprintf("Error sending %s packet PRT (%03x),",cancmd[CAN_PRT],id);
            can_dump_buffer(buf);
            lprintf("\n");
      } else {
            pt = sub;
       }
       wait(0.1);
       cnt++;
    }
    
    /* Set up the TX buffer for end packet */
    can_clear_data(buf);
    buf[0] = station_id;    /* Who we are */
    buf[1] = len;           /* number of bytes sent */
    buf[2] = cnt;           /* atual packet count */
    id = can_build_id(station_id,remote,CAN_EPRT);
    if(!can.write(CANMessage(id, (char *)buf, 8))) {
        lprintf("Error sending %s packet EPRT (%03x),",cancmd[CAN_EPRT],id);
        can_dump_buffer(buf);
        lprintf("\n");
        return;
    }
}
/******************************************/
/*                                        */
/*    Can Bus Send raw data to remote add */
/*                                        */
/******************************************/
void can_send_raw(char remote, char *str)
{
    lprintf("In Can Send String with '%02x%02x%02x%02x%02x%02x%02x%02x' going to %d\n",
    str[0],str[1],str[2],str[3],str[4],str[5],str[6],str[7], remote);
}
/******************************************/
/*                                        */
/*    Can Bus Send BUS Reset              */
/*                                        */
/******************************************/
void can_send_sync(void)
{
    unsigned char    buf[0x8];
    int     id;
    
    can_clear_data(buf);
    id = can_build_id(0,0,CAN_SYNC);
    if(!can.write(CANMessage(id, (char *)buf, 8))) {
        lprintf("Error sending %s packet SYNC (%03x),",cancmd[CAN_SYNC],id);
        lprintf("\n");
        return;
    }
}
/******************************************/
/*                                        */
/*    Can Bus Send Intger to remote add   */
/*    mode = 0, Int, mode = 1, Time       */
/*                                        */
/******************************************/
void can_send_int(int remote,int value,char mode)
{
    unsigned char    buf[0x8];
    int     id;
    
    can_clear_data(buf);
    if(mode==0)
        id = can_build_id(station_id,remote,CAN_INT);
    else if(mode == 1)
        id = can_build_id(station_id,remote,CAN_TIME);
    else {
        lprintf("can_send_int: unknown mode with %d\n",mode);
        return;
    }
    buf[0]=value & 0x000000ff;
    buf[1]=(value >> 8)  & 0x000000ff;
    buf[2]=(value >> 16) & 0x000000ff;
    buf[3]=(value >> 24) & 0x000000ff;
    if(!can.write(CANMessage(id, (char *)buf, 8))) {
        lprintf("Error sending %s packet INT (%03x),",cancmd[CAN_INT],id);
        can_dump_buffer(buf);
        lprintf("\n");
        return;
    }
}
/******************************************/
/*                                        */
/*    Can Bus Send Who is Out there mes   */
/*                                        */
/******************************************/
void can_send_who(void)
{
    unsigned char    buf[0x8];
    int     id;
    
    can_clear_data(buf);
    buf[0]=station_id;
    id = can_build_id(station_id,0,CAN_WHOIS);
    if(!can.write(CANMessage(id, (char *)buf, 8))) {
        lprintf("Error sending %s packet WhoIs (%03x),",cancmd[CAN_WHOIS],id);
        can_dump_buffer(buf);
        lprintf("\n");
        return;
    }
}
/******************************************/
/*                                        */
/*    Can Bus Send I Am Out there mes   */
/*                                        */
/******************************************/
void can_send_iam(int from)
{
    unsigned char    buf[0x8];
    int     id;
    
    can_clear_data(buf);
    buf[0]=station_id;
    buf[1]=from;
    id = can_build_id(station_id,from,CAN_IAM);
    if(!can.write(CANMessage(id, (char *)buf, 8))) {
        lprintf("Error sending %s packet I'm Here (%03x),",cancmd[CAN_IAM],id);
        can_dump_buffer(buf);
        lprintf("\n");
        return;
    }
}
/******************************************/
/*                                        */
/*    CAN Bus Send a ticker message       */
/*                                        */
/******************************************/
void can_ticker_tx(int v)
{
    unsigned char    buf[0x8];
    int     id;
    
    can_clear_data(buf);
    buf[0]=station_id;
    buf[4]=v;
    id = can_build_id(station_id,0,CAN_IAM);
    if(!can.write(CANMessage(id, (char *)buf, 8))) {
        lprintf("Error sending %s packet CAN Ticker (%03x),",cancmd[CAN_IAM],id);
        can_dump_buffer(buf);
        lprintf("\n");
        return;
    }
}
/******************************************/
/*                                        */
/*    CAN Bus receiver, show the messages */
/*                                        */
/******************************************/
void can_receive(void)
{
    CANMessage  msg;
    int pt;
    time_t seconds;
        
    if(can.read(msg)) {
        switch(can_decode_id(msg.id,CAN_GET_CMD)){
            case CAN_SYNC    :
                lprintf("CAN SYNC MESSAGE< what do we do :-)\n");
                break;
            case CAN_RAW     :
                break;
            case CAN_SPRT    :
                if(can_str != NULL){
                    lprintf("trying to start a string packet, when the buffer is in use\n");
                } else {
                    can_str = can_buffer_create(msg.data[1]+2);
                }                    
                break;
            case CAN_EPRT    :
                find_cmd(can_str);
                free(can_str);
                can_str = NULL;
                break;
            case CAN_INT     :
                lprintf("Recieved an int 0x%08x\n", msg.data[0] | msg.data[1]<<8 | msg.data[2]<<16 | msg.data[3]<<24);
                break;
            case CAN_TIME    :
                seconds = msg.data[0] | msg.data[1]<<8 | msg.data[2]<<16 | msg.data[3]<<24;
                set_time(seconds);
                break;
            case CAN_WHOIS   :
                wait(station_id/10);
                can_send_iam(msg.data[0]);
                break;
            case CAN_IAM     :
                lprintf("Can_I_AM responce station id %02x, you where %02x\n",
                    msg.data[0],msg.data[1]);
                break;
            case CAN_PRT     :
                pt = can_decode_id(msg.id,CAN_GET_CNT);
                can_str[(pt*8)+0] = msg.data[0];
                can_str[(pt*8)+1] = msg.data[1];
                can_str[(pt*8)+2] = msg.data[2];
                can_str[(pt*8)+3] = msg.data[3];
                can_str[(pt*8)+4] = msg.data[4];
                can_str[(pt*8)+5] = msg.data[5];
                can_str[(pt*8)+6] = msg.data[6];
                can_str[(pt*8)+7] = msg.data[7];
                break;
            default     :
                lprintf("CAN receive, unknown message %d\n",can_decode_id(msg.id,CAN_GET_CMD));
        }
    }
}

/******************************************/
/*                                        */
/*    Setup the CAN bus for use           */
/*                                        */
/******************************************/
void can_init(void)
{
    // 500kbit/s
    // can.frequency(500000);
    // 10kbits/s, for testing
    can.frequency(10000);
    // activate external can transceiver
    can_Pca82c250SlopePin = 0;
    can_str = NULL;             /* Mark the input buffer as free */
}
/******************************************/
/*                                        */
/*    Setup the CAN message ID            */
/*                                        */
/******************************************/
int can_build_id(char station, char dest, int cmd)
{
    int add, dst,c = 0,id = 0;
    add = station << 8;
    dst = dest << 4;
    
    switch(cmd) {
        case CAN_SYNC    :
            c = 0;
            add = 0;
            dst = 0;
            break;
        case CAN_RAW     :
            c = 1;
            break;
        case CAN_SPRT    :
            c = 2;
            break;
        case CAN_EPRT    :
            c = 3;
            break;
        case CAN_INT     :
            c = 4;
            break;
        case CAN_TIME    :
            c = 5;
            break;
        case CAN_S2      :
            c = 6;
            break;
        case CAN_S3      :
            c = 7;
            break;
        case CAN_S4      :
            c = 8;
            break;
        case CAN_S5      :
            c = 9;
            break;
        case CAN_S6      :
            c = 0xa;
            break;
        case CAN_S7      :
            c = 0xb;
            break;
        case CAN_S8      :
            c = 0xc;
            break;
        case CAN_S9      :
            c = 0xd;
            break;
        case CAN_WHOIS   :
            c = 0xe;
            break;
        case CAN_IAM     :
            c = 0xf;
            break;
        case CAN_PRT     :
            c = 0x80;
            break;
        default     :
            lprintf("CAN Message Selector switch, unknown message %d\n",cmd);
            return(-1);
    }
    /* Build the message ID */
    id = c | add | dst;
    return(id);
}
/******************************************/
/*                                        */
/*   Get the data from the can message ID */
/*                                        */
/******************************************/
int can_decode_id(int id, int what)
{
    switch(what){
        case    CAN_SENDER_ID   :       /* Who sent the message */
            return((id & 0xf00)>>8);
        case    CAN_OUR_ID      :       /* who is it for */
            return((id &0x070)>>4);
        case    CAN_IS_PRT      :       /* is it a string packet */
            return((id &0x080));
        case    CAN_GET_CNT     :       /* Get the packet count value */
            return((id & 0x00f));
        case    CAN_GET_CMD     :       /* count and cmd live on the first 4 bits */
            if(can_decode_id(id,CAN_IS_PRT))
                return(CAN_PRT);
            return((id & 0x00f));
        default                 :
            lprintf("Unknown CAN Id decode request %02x\n",what);
            return(0);
    }
}
/******************************************/
/*                                        */
/* Build a buffer for transmit, from a    */
/* source buffer, of variable length      */
/* this code is re-entrant, state held    */
/* in the parent routine                  */
/* Safe for raw, and string data          */
/*                                        */
/******************************************/
int can_build_data(int len, int pt, unsigned char *data, unsigned char *buffer)
{
    int a = 0;
    int px;
        
    px = pt;
        
    while(a!=MAX_CAN_BUF){
        if(px<=len){
            buffer[a] = data[px];
            px++;
        } else {
            buffer[a] = 0x00;
        }       
        a++;
    }
    if(px <= len)
        return(px);
    else
        return(0);
}
/******************************************/
/*                                        */
/* Clear the TX buffer to Zero's          */
/* Safe for raw, and string data          */
/*                                        */
/******************************************/
void can_clear_data(unsigned char *buffer)
{
    int a = 0;
    while(a != MAX_CAN_BUF){
        buffer[a] = 0x00;
        a++;
    }
}
/******************************************/
/*                                        */
/* Dump the TX buffer to the user         */
/* Safe for raw, and string data          */
/*                                        */
/******************************************/
void can_dump_buffer(unsigned char *buffer)
{
    int a = 0;
    lprintf("   ");
    while(a != MAX_CAN_BUF){
        lprintf("%02x",buffer[a]);
        if(buffer[a] > 0x20 & buffer[a] < 0x7f)
            lprintf("(%c),",buffer[a]);
        else
            lprintf(",   ");
        a++;
    }
}
/******************************************/
/*                                        */
/* Create a new string buffer for can RX  */
/*                                        */
/******************************************/
char *can_buffer_create(int size)
{
    char *str;
    int   pt;
    
    str = (char *)malloc(sizeof(char)*size);
    pt = 0;
    while(pt!=size){
        str[pt]='\0';
        pt++;
    }
    return(str);
}