A program that allows you to send CANMessages from your PC via ethernet.

Dependencies:   EthernetNetIf mbed

main.cpp

Committer:
OTBsolar
Date:
2011-03-22
Revision:
0:4abab30c3917

File content as of revision 0:4abab30c3917:

#include "mbed.h"
#include "CAN.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "EthernetNetIf.h"
#include "TCPSocket.h"

Ticker ticker;      
Serial pc(USBTX, USBRX);
EthernetNetIf eth;
DigitalOut write_activity(LED1); //CAN activity
DigitalOut read_activity(LED2);
DigitalOut ethernet_activity(LED3);    //Ethernet activity
DigitalOut live(LED4);           //program running
CAN can1(p9, p10);  // rd, td Transmitter
CAN can2(p30, p29); // rd, td Monitor

TCPSocket tcp;  //The listening port where requests are queued
TCPSocket* link; //The port where accepted requests can communicate

Host local(IpAddr(130,144,3,9), 24682); //mbed IP
Host client;

TCPSocketErr accErr;

int counter = 0;
int shift = 0;
char candata[8];
char pc_msg[128];
char pc_canmsg[128];
CANType pc_type;
CANFormat pc_format;
int pc_ID; //standard 11bit ID
//int pc_IDe; //extended 29 (not used yet)
int pc_length;
int pcd0; int pcd1; int pcd2; int pcd3; int pcd4; int pcd5; int pcd6; int pcd7; //8 bytes data
CANMessage msg;
int size;
char test;
char *dump;
char *buffer;


/************************************************************************************
 *                                   CAN STUFF                                      *
 ************************************************************************************/
void setdata(int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) {
    candata[0] = (char) (d0); // LSB
    candata[1] = (char) (d1);
    candata[2] = (char) (d2);
    candata[3] = (char) (d3);
    candata[4] = (char) (d4);
    candata[5] = (char) (d5);
    candata[6] = (char) (d6);
    candata[7] = (char) (d7); // MSB
}

void canread() {
    pc.printf("Read:    [ ID: %d", msg.id);
    pc.printf(" Length: %d", msg.len);
    pc.printf(" Data: %x", msg.data[0]);
    pc.printf(" %x", msg.data[1]);
    pc.printf(" %x", msg.data[2]);
    pc.printf(" %x", msg.data[3]);
    pc.printf(" %x", msg.data[4]);
    pc.printf(" %x", msg.data[5]);
    pc.printf(" %x", msg.data[6]);
    pc.printf(" %x", msg.data[7]);
    pc.printf(" Type: %d", msg.type);
    pc.printf(" Format: %d ]\n", msg.format);
    
    read_activity = !read_activity;  //Blink!
    
    sprintf(pc_canmsg,"!%d %d %d %d %x %x %x %x %x %x %x %x",
    msg.format, msg.type, msg.id, msg.len, 
    msg.data[0], msg.data[1], msg.data[2], msg.data[3], 
    msg.data[4], msg.data[5], msg.data[6], msg.data[7]);
    link->send(pc_canmsg,sizeof(pc_canmsg));

}

void pc_msg_read() {
    // Data to be sent as ("_" = space):
    //!<format>_<type>_<ID>_<length>_<d0>_<d1>_<d2>_<d3>_<d4>_<d5>_<d6>_<d7> 
    for(shift=0;shift<128;shift++) {
        pc_msg[shift] = pc_msg[shift+1];
    }
    // Read pc_msg and extract all data
    sscanf(pc_msg,"%d %d %d %d %x %x %x %x %x %x %x %x",
    &pc_format, &pc_type, &pc_ID, &pc_length, 
    &pcd0, &pcd1, &pcd2, &pcd3, &pcd4, &pcd5, &pcd6, &pcd7);
    
    // Printing extracted data, mostly for testing
    pc.printf("Entered: [ ID: %d ",pc_ID);
    pc.printf("length: %d ",pc_length);
    pc.printf("data: %x %x %x %x %x %x %x %x ",
    pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7);
    pc.printf("type: %d ",pc_type);
    pc.printf("format: %d ]\n",pc_format);
    
    // Setting the data to CANMessage.data format
    setdata(pcd0, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6, pcd7);
    
    // Transmitting CANMessage
    if(pc_type==0) {
        if(can1.write(CANMessage(pc_ID,candata,(char)pc_length,pc_type,pc_format))) {
            pc.printf("MBED:    [ Message compiled and sent. ]\n");
            write_activity = !write_activity;
        }
    }
    else if(pc_type==1) {
        if(can1.write(CANMessage(pc_ID,pc_format))) {
            pc.printf("MBED:    [ RTR Message compiled and sent. ]\n");
            write_activity = !write_activity;
        }
    }
}


/************************************************************************************
 *                                   TCP STUFF                                      *
 ************************************************************************************/
void eth_act() {
    ethernet_activity = !ethernet_activity;
} 
 
void tcperrcheck(TCPSocketErr tcpsocketerr,char *phase) {
    switch(tcpsocketerr) {
    case TCPSOCKET_SETUP:   printf("Err:Setup\n");      break;  //TCPSocket not properly configured.
    case TCPSOCKET_TIMEOUT: printf("Err:Timeout\n");    break;  //Connection timed out.
    case TCPSOCKET_IF:      printf("Err:Interface\n");  break;  //Interface has problems, does not exist or is not initialized.
    case TCPSOCKET_MEM:     printf("Err:Memory\n");     break;  //Not enough mem.
    case TCPSOCKET_INUSE:   printf("Err:In use\n");     break;  //Interface / Port is in use.
    case TCPSOCKET_EMPTY:   printf("Err:Empty\n");      break;  //Connections queue is empty.
    case TCPSOCKET_RST:     printf("Err:Reset\n");      break;  //Connection was reset by remote host.
    case TCPSOCKET_OK:      if(phase == "bind") printf("Bound to port\n");
                            if(phase == "listen") printf("Listening\n");
                            if(phase == "accept") printf("Accepted: ");
                            break;  //Success.
    }
}

void onLinkSocketEvent(TCPSocketEvent e) {
    switch(e) {
        case TCPSOCKET_CONNECTED: eth_act(); printf("TCP Socket Connected\r\n"); break;
        case TCPSOCKET_WRITEABLE: eth_act(); printf("TCP Socket Writable\r\n"); break;
        case TCPSOCKET_READABLE: {
            //Can now read some data...
            eth_act(); 
            printf("TCP Socket Readable\r\n");
            // Read in any available data into the buffer
            int len = link->recv(pc_msg, 128);
            test = pc_msg[0];
            if (test == '!') {          // See if it's a valid message
                pc_msg_read();          // Valid => read the message and extract the data
            }
            else {                      // Invalid data or leftover characters
                pc.printf("Dumped:%s\n",pc_msg);
                memset(pc_msg, 0, sizeof(pc_msg));
                printf("%s",pc_msg);
            }
        }
        break;
        case TCPSOCKET_CONTIMEOUT: eth_act(); printf("TCP Socket Timeout\r\n"); break;
        case TCPSOCKET_CONRST: eth_act(); printf("TCP Socket CONRST\r\n"); break;
        case TCPSOCKET_CONABRT: eth_act(); printf("TCP Socket CONABRT\r\n"); break;
        case TCPSOCKET_ERROR: eth_act(); printf("TCP Socket Error\r\n"); break;
        case TCPSOCKET_DISCONNECTED: {
            //Close socket...
            printf("TCP Socket Disconnected\r\n");        
            link->close();
        }
        break;
        default: printf("DEFAULT\r\n"); 
    }
}

void onTCPSocketEvent(TCPSocketEvent e) {
    switch(e) {
        case TCPSOCKET_CONNECTED: eth_act(); printf("Connected\n"); break;
        case TCPSOCKET_ACCEPT: {
            eth_act();
            accErr = tcp.accept(&client,&link);
            tcperrcheck(accErr,"accept");
            link->setOnEvent(&onLinkSocketEvent);
            IpAddr clientIp = client.getIp();
            printf("Incoming TCP connection from %d.%d.%d.%d\r\n", 
            clientIp[0], clientIp[1], clientIp[2], clientIp[3]);
        }
        break;
        case TCPSOCKET_READABLE: eth_act(); printf("Readable\n"); break;
        case TCPSOCKET_WRITEABLE: eth_act(); printf("Writeable\n"); break;
        case TCPSOCKET_CONTIMEOUT: eth_act(); printf("Timeout\n"); break;
        case TCPSOCKET_CONRST: eth_act(); printf("Reset\n"); break;
        case TCPSOCKET_CONABRT: eth_act(); printf("Aborted\n"); break;
        case TCPSOCKET_ERROR: eth_act(); printf("Error\n"); break;
        case TCPSOCKET_DISCONNECTED: eth_act(); printf("Disconnected\n"); tcp.close(); break;    
    }
}

int main() {
    //----------------Initialization-----------------------
    can2.frequency(1000000);             //kbit/s
    can1.frequency(1000000);
    can2.monitor(1); //Works without this, in my case.
    pc.baud(115200); //Tested, works. Set terminal to the same. Also works with the c file.
    
    //Ethernet setup
    printf("Setting up ethernet\n");
    EthernetErr ethErr = eth.setup();
    if (ethErr) {
        printf("Error %d in setup.\n", ethErr);
        return -1;
    }
    IpAddr ip = eth.getIp();
    printf("Setup OK. ");
    printf("MBED IP is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);

    //Generate method to deal with requests
    tcp.setOnEvent(&onTCPSocketEvent); 
    
    //Bind to local port
    printf("Init bind... ");
    TCPSocketErr bindErr = tcp.bind(local);
    tcperrcheck(bindErr, "bind");
            
    //Listen to local port
    printf("Init listen... ");
    TCPSocketErr listenErr = tcp.listen();
    tcperrcheck(listenErr, "listen");
    
    //Start timer
    Timer tmr;
    tmr.start();
    

    pc.printf("Please enter !<format>_<type>_<ID>_<length>_<d0>_<d1>_<d2>_<d3>_<d4>_<d5>_<d6>_<d7> ('_' = space)\n");
    while(1) {
        Net::poll();
        if(tmr.read() > 1) //Every second
        {
            tmr.reset();
            live=!live; //Show that we are alive
        }
        if (can2.read(msg)) {
            canread(); //Read when interupted.
        }
    }
}