Peter Cooper
/
diags
test code for our MBED board
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); }