Library to control Dodge LX (83.3k) CAN devices

Dependents:   DodgeRadioEmulatorv30

Files at this revision

API Documentation at this revision

Comitter:
rtgree01
Date:
Mon Aug 20 02:35:43 2012 +0000
Child:
1:6dcab41a32df
Commit message:
[mbed] converted /DodgeRadioEmulatorv30/DodgeRadioLib

Changed in this revision

RadioState.h Show annotated file Show diff for this revision Revisions of this file
radioEmulator.cpp Show annotated file Show diff for this revision Revisions of this file
radioEmulator.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RadioState.h	Mon Aug 20 02:35:43 2012 +0000
@@ -0,0 +1,73 @@
+#ifndef RADIOSTATE_H
+#define RADIOSTATE_H
+
+enum radioMode { AM, FM, CD, SAT, VES, MAX_MODE };
+/*
+union SiriusText_u
+{
+    char TextLine[8][64];
+    char data[512];
+};
+*/
+struct RadioState
+{
+    char marker1;
+    char marker2;
+    char marker3;
+    char marker4;
+    radioMode _radioMode;
+    
+    int _amPreset;
+    int _amFreq;
+    
+    int _fmPreset;
+    int _fmFreq;
+    
+    int _cdNum;
+    int _cdTrackNum;
+    int _cdHours;
+    int _cdMinutes;
+    int _cdSeconds;
+    char _cdTime[8];
+    
+    int _siriusPreset;
+    int _siriusChan;
+    
+    int _evicMode;
+    int _evicPreset;
+    int _evicFreq;
+    
+    int _volume;
+    int _balance;
+    int _fade;
+    int _bass;
+    int _mid;
+    int _treble;
+    
+    float _batteryVoltage;
+    int _driverHeatedSeatLevel;
+    int _passHeatedSeatLevel;
+    char _vin[24];
+    int _headlights;
+    int _dimmerMode;
+    int _dimmer;
+    int _gear;
+    int _brake;
+    int _parkingBrake;
+    char _vesControls[32];
+    int _keyPosition;
+    int _rpm;
+    int _fanRequested;
+    int _fanOn;
+    int _rearDefrost;
+    int _fuel;
+    int _speed;
+    int _odometer;
+    
+    int SWCButtons;
+        
+    int count ;
+};
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/radioEmulator.cpp	Mon Aug 20 02:35:43 2012 +0000
@@ -0,0 +1,820 @@
+#include "mbed.h"
+#include "radioEmulator.h"
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+
+#undef CHECK_HW_SHUTDOWN
+
+//LocalFileSystem local("local");
+//#include "SDFileSystem.h"
+
+//SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
+
+char RadioEmulator::unlock[6] = {0x03,0x02,0x00,0x40,0x87,0xa5};
+char RadioEmulator::lock[6] = {0x01, 0x02, 0x00, 0x40, 0x87, 0xa5};
+char RadioEmulator::trunk[6] = {0x05, 0x02, 0x00, 0x40, 0x87, 0xa5};
+
+RadioEmulator::RadioEmulator(CAN *can, DigitalOut *rs, InterruptIn *irq, bool wdTO)
+{
+    printf("RadioEmulator Initializing\r\n");
+
+    HostSock = new UDPSock(new Host(IpAddr(), 50000, NULL), 64, this);
+
+    CANDevice = can;
+    can_RS = rs;
+    canIRQ = irq;
+
+    prevSWC = 0;
+    
+    memset(&status, 0, sizeof(status));  
+    memset(&siriusdata, 0, 512);  
+    status.marker1 = 0x42;  
+    status.marker2 = 0x42;  
+    status.marker3 = 0x42;  
+    status.marker4 = 0x42;  
+
+    status._radioMode = SAT;
+
+//    readInitFile();
+    status._volume = 10;
+    status._bass = 15;
+    status._mid = 13;
+    status._treble = 14;
+    status._balance = 10;
+    status._fade = 10;
+
+    for (int i = 0; i < 8; i++)
+    {
+        if (wdTO)
+        {
+            sprintf(&siriusdata[i * 64], "WATCH DOG TIMED OUT");
+        }
+        else
+        {
+            sprintf(&siriusdata[i * 64], "Fun line text # %d", i);
+        }
+    }
+
+    PowerUp();
+    
+    printf("RadioEmulator initialized\n\r");
+}
+
+/*
+void RadioEmulator::readInitFile()
+{
+    FILE *fp = fopen("/sd/stereo.txt", "r");  // Open "out.txt" on the local file system for writing
+    char temp[100];
+        
+    while ( fscanf(fp, "%s", temp) > 0)
+    {
+        if (strcmp(temp, "volume") == 0)
+        {
+            fscanf(fp, "%d", &status._volume);
+        }
+        if (strcmp(temp, "bass") == 0)
+        {
+            fscanf(fp, "%d", &status._bass);
+        }
+        if (strcmp(temp, "mid") == 0)
+        {
+            fscanf(fp, "%d", &status._mid);
+        }
+        if (strcmp(temp, "treble") == 0)
+        {
+            fscanf(fp, "%d", &status._treble);
+        }
+        if (strcmp(temp, "balance") == 0)
+        {
+            fscanf(fp, "%d", &status._balance);
+        }
+        if (strcmp(temp, "fade") == 0)
+        {
+            fscanf(fp, "%d", &status._fade);
+        }
+        if (strcmp(temp, "MAC") == 0)
+        {
+            char temp2[64];
+            fscanf(fp, "%s", temp2);
+            char *pEnd;
+            hostMACAddress[0] = strtoul(temp2, &pEnd, 16);
+            hostMACAddress[1] = strtoul(pEnd, &pEnd, 16);
+            hostMACAddress[2] = strtoul(pEnd, &pEnd, 16);
+            hostMACAddress[3] = strtoul(pEnd, &pEnd, 16);
+            hostMACAddress[4] = strtoul(pEnd, &pEnd, 16);
+            hostMACAddress[5] = strtoul(pEnd, &pEnd, 16);
+        }
+    }
+    
+    fclose(fp);
+}
+
+void RadioEmulator::writeInitFile()
+{
+    FILE *fp = fopen("/sd/stereo.txt", "w");  // Open "out.txt" on the local file system for writing
+
+    fprintf(fp,"volume %d\r\n", status._volume);
+    fprintf(fp,"bass %d\r\n", status._bass);
+    fprintf(fp,"mid %d\r\n", status._mid);
+    fprintf(fp,"treble %d\r\n", status._treble);
+    fprintf(fp,"balance %d\r\n", status._balance);
+    fprintf(fp,"fade %d\r\n", status._fade);
+    fclose(fp);
+}
+*/
+
+void RadioEmulator::PowerUp(void)
+{
+    led1 = 1;
+
+    needToParseCANMessage = false;   
+    ReceivedCANMsg = false;
+    LPC_CAN2->BTR = 0x52001C;
+    *can_RS = 0;        // Wake up the CAN Transceiver
+    
+    sleeping = false;
+
+    writeCANFlag = false;
+    CANBusTicker.attach(this, &RadioEmulator::WriteCANMessages, 0.5);
+
+    ChangeSiriusStation(status._siriusChan, true);
+    
+    ReceivedHostMsg = false;
+    statusFlag = false;
+    statusTicker.attach(this, &RadioEmulator::SendStatusToHost, 0.1);
+
+    opMode = standalone;
+    hostTimeoutFlag = false;
+    HostTimeout.attach(this, &RadioEmulator::CheckHostTimeout, 1);
+        
+    CANTimeoutFlag = false;    
+    canIRQ->rise(0);
+// only enable this if trying to power up/down the processor
+//    CANTimeout.attach(this, &RadioEmulator::CheckCANTimeout, 1);
+}
+
+void RadioEmulator::PowerDown(void)
+{
+    led1 = 0;
+    // Need to Power Down
+   
+    CANBusTicker.detach();
+    CANTimeout.detach(); 
+    statusTicker.detach();
+    HostTimeout.detach();
+            
+    *can_RS = 1;
+    powerUpIRQCounter = 0;
+    sleeping = true;
+    needToWakeUp = false;
+    
+    canIRQ->rise(this, &RadioEmulator::CANActivity);
+}
+
+void RadioEmulator::Operate(void)
+{
+    if (sleeping)
+    {
+        if (needToWakeUp)
+        {
+            PowerUp();
+            needToWakeUp = false;
+        }
+        
+        return;
+    }
+    
+    if (writeCANFlag)
+    {
+        writeCANFlag = false;
+        
+        led2 = !led2;
+        SendRadioModeMsg();
+        SendEVICMsg();
+        SendStereoSettingsMsg();
+        SendHostMessages();
+    }
+    
+    if (statusFlag)
+    {
+        statusFlag = false;
+        
+        if (opMode == standalone)
+        {
+            StandaloneSWI();
+        }
+    
+        prevSWC = status.SWCButtons;
+    
+        status.count++;
+        static Host statusHost(IpAddr(10,10,10,1), 51000, NULL); //Join multicast group on port 50000
+        HostSock->SendTo(&statusHost, sizeof(status), (char *)&status);
+        
+        if ((status.count % 10) == 0)
+        {
+            static Host siriusTextHost(IpAddr(10,10,10,1), 61000, NULL); //Join multicast group on port 50000
+            HostSock->SendTo(&siriusTextHost, 512, siriusdata);
+        }
+    }
+    
+    if (hostTimeoutFlag)
+    {
+        hostTimeoutFlag = false;
+        
+        if (!ReceivedHostMsg)
+        {
+            led4 = 1;
+            opMode = standalone;
+        }
+        else
+        {
+            led4 = 0;
+        }
+    
+        ReceivedHostMsg = false;
+    }
+    
+// only enable this if trying to power up/down the processor
+    if (CANTimeoutFlag)
+    {
+        CANTimeoutFlag = false;
+        
+        if (!ReceivedCANMsg)
+        {
+            PowerDown();
+        }
+        
+        ReceivedCANMsg = false;
+    }
+    
+    readCANbus();
+}
+
+void RadioEmulator::StandaloneSWI()
+{
+    if (status.SWCButtons == 0)
+    {
+        if ((prevSWC & 0x00000004) != 0)
+        {
+            if (status._volume > 0)
+                status._volume --;
+        }
+        else if ((prevSWC & 0x00000002) != 0)
+        {
+            if (status._volume < 40)
+                status._volume ++;
+        }
+        else if ((prevSWC & 0x00000010) != 0)
+        {
+            if (status._siriusChan > 0)
+                ChangeSiriusStation(status._siriusChan-1, false);
+        }
+        else if ((prevSWC & 0x00000008) != 0)
+        {
+            if ((status._siriusChan < 256) && (status._siriusChan > 0))
+                ChangeSiriusStation(status._siriusChan+1, false);
+        }
+        else if ((prevSWC & 0x00000001) != 0)
+        {
+        }
+    }
+}
+
+void RadioEmulator::SendOnMsg()
+{
+    CANMessage msg;
+    msg.id = 0x416;
+    msg.len = 8;
+    char temp[8] = {0xfe, 0x1b, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff};
+    memcpy(msg.data, temp, 8);
+    CANDevice->write(msg);
+}
+
+void RadioEmulator::SendRadioModeMsg()
+{
+    CANMessage msg;
+    msg.id = 0x09F;
+    msg.len = 8;
+
+    msg.data[7] = 0x0f;
+    msg.data[6] = 0xff;
+    msg.data[5] = 0xff;
+    msg.data[4] = 0xff;
+    msg.data[3] = 0x07;
+    msg.data[2] = 0x00;
+    msg.data[1] = 0x00;
+    msg.data[0] = 0x00;
+
+    if (status._radioMode == AM)
+    {
+        if ((status._amPreset >= 0) && (status._amPreset < 16))
+        {
+            msg.data[0] = (status._amPreset + 1) << 4;
+        }
+        msg.data[1] = (status._amFreq & 0xFF00) >> 8;
+        msg.data[2] = (status._amFreq & 0x00FF);
+    }
+    else if (status._radioMode == FM)
+    {
+        if ((status._fmPreset >= 0) && (status._fmPreset < 16))
+        {
+            msg.data[0] = (status._fmPreset + 1) << 4;
+        }
+        msg.data[0] |= 0x01;
+        msg.data[1] = (status._fmFreq & 0xFF00) >> 8;
+        msg.data[2] = (status._fmFreq & 0x00FF);
+    }
+    else if (status._radioMode == CD)
+    {
+        msg.data[0] = status._cdNum << 4;
+        msg.data[1] = 0x20;
+        msg.data[0] |= 0x03;
+        msg.data[2] = status._cdTrackNum;
+        msg.data[4] = status._cdHours;
+        msg.data[5] = status._cdMinutes;
+        msg.data[6] = status._cdSeconds;
+    }
+    else if (status._radioMode == SAT)
+    {
+        if ((status._siriusPreset >= 0) && (status._siriusPreset < 16))
+        {
+            msg.data[0] = (status._siriusPreset + 1) << 4;
+        }
+        msg.data[0] |= 0x04;
+        msg.data[1] = 0;
+        msg.data[2] = status._siriusChan;
+    }
+    else if (status._radioMode == VES)
+    {
+        msg.data[0] = 0x16;
+        msg.data[1] = 0x10;
+        msg.data[2] = 0x01;
+    }
+
+    msg.data[1] |= 0x10;
+
+    CANDevice->write(msg);
+}
+
+void RadioEmulator::SendEVICMsg()
+{
+    CANMessage msg;
+    msg.id = 0x394;
+    msg.len = 6;
+    
+    memset(msg.data, 0, 8);
+
+    if (status._radioMode == AM)
+    {
+        if ((status._amPreset >= 0) && (status._amPreset < 16))
+        {
+            msg.data[0] = (status._amPreset + 1) << 4;
+        }
+        msg.data[1] = (status._amFreq & 0xFF00) >> 8;
+        msg.data[2] = (status._amFreq & 0x00FF);
+    }
+    else
+    {
+        if ((status._fmPreset >= 0) && (status._fmPreset < 16))
+        {
+            msg.data[0] = (status._fmPreset + 1) << 4;
+        }
+        msg.data[0] |= 0x01;
+        msg.data[1] = (status._fmFreq & 0xFF00) >> 8;
+        msg.data[2] = (status._fmFreq & 0x00FF);
+    }
+
+    CANDevice->write(msg);
+}
+
+void RadioEmulator::SendStereoSettingsMsg()
+{
+    CANMessage msg;
+    msg.id = 0x3D0;
+    msg.len = 7;
+
+    msg.data[0] = status._volume;
+    msg.data[1] = status._balance;
+    msg.data[2] = status._fade;
+    msg.data[3] = status._bass;
+    msg.data[4] = status._mid;
+    msg.data[5] = status._treble;
+
+    CANDevice->write(msg);
+}
+
+void RadioEmulator::SendHostMessages()
+{
+    if (hostMessages.size() > 0)
+    {
+        CANDevice->write(hostMessages.front());
+        
+        hostMessages.pop_front();
+    }
+}
+
+void RadioEmulator::ChangeSiriusStation(int station, bool turn_on)
+{
+    if (station == 0)
+    {
+        return;
+    }
+    
+    CANMessage msg;
+    msg.id = 0x3B0;
+    msg.len = 6;
+
+    if (turn_on)
+    {
+        msg.data[0] = 21;
+    }
+    else
+    {
+        msg.data[0] = 23;
+    }
+    msg.data[1] = station;
+
+    CANDevice->write(msg);
+
+    memset(msg.data, 0, 8);
+    msg.data[1] = station;
+
+    CANDevice->write(msg);
+    
+    status._siriusChan = station;
+
+    memset(&siriusdata, 0, 512);  
+}
+
+void RadioEmulator::ParseCANMessage(CANMessage can_MsgRx)
+{
+    // this message seems to be a message requesting all other devices
+    // to start announcing their presence
+    if ((can_MsgRx.id >= 0x400) && (can_MsgRx.data[0] == 0xfd))
+    {
+    }
+
+    if (can_MsgRx.id == 0x000)
+    {
+/*
+        if (can_MsgRx.data[0] > 1)
+        {
+            radioOn = true;
+        }
+        else
+        {
+            radioOn = false;
+        }
+*/
+        status._keyPosition = can_MsgRx.data[0];
+    }
+    else if (can_MsgRx.id == 0x002)
+    {
+        status._rpm = (can_MsgRx.data[0] << 8) + can_MsgRx.data[1];
+        status._speed = ((can_MsgRx.data[2] << 8) + can_MsgRx.data[3]) >> 7;
+        
+        // what are the other 4 bytes?
+    }
+    else if (can_MsgRx.id == 0x003)
+    {
+        status._brake = can_MsgRx.data[3] & 0x01;
+        status._gear = can_MsgRx.data[4];
+    }
+    else if (can_MsgRx.id == 0x012)
+    {
+        if (memcmp(can_MsgRx.data, unlock, 6) == 0)
+        {
+        }
+        else if (memcmp(can_MsgRx.data, lock, 6) == 0)
+        {
+        }
+        else if (memcmp(can_MsgRx.data, trunk, 6) == 0)
+        {
+        }
+    }
+    else if (can_MsgRx.id == 0x14)
+    {
+        status._odometer = (can_MsgRx.data[0] << 16) + (can_MsgRx.data[1] << 8) + can_MsgRx.data[2];
+        // what are the other 4 bytes?
+    }
+    else if (can_MsgRx.id == 0x15)
+    {
+        status._batteryVoltage = (float)(can_MsgRx.data[1]) / 10;
+    }
+    else if (can_MsgRx.id == 0x01b)
+    {
+        // vin number
+        int part = can_MsgRx.data[0];
+        if ((part >= 0) && (part < 3))
+        {
+            for (int i = 1; i < 8; i++)
+            {
+                status._vin[(part*7) + i-1] = can_MsgRx.data[i];
+            }
+        }
+    }
+    else if (can_MsgRx.id == 0x0d0)
+    {
+        if (can_MsgRx.data[0] == 0x80)
+        {
+            status._parkingBrake = true;
+        }
+        else
+        {
+            status._parkingBrake = false;
+        }                    
+    }
+    else if (can_MsgRx.id == 0x0EC)
+    {
+        if ((can_MsgRx.data[0] & 0x40) == 0x40)
+        {
+            status._fanRequested = true;
+        }
+        else
+        {
+            status._fanRequested = false;
+        }
+
+        if ((can_MsgRx.data[0] & 0x01) == 0x01)
+        {
+            status._fanOn = true;
+        }
+        else
+        {
+            status._fanOn = false;
+        }
+    }
+    else if (can_MsgRx.id == 0x159)
+    {
+        status._fuel = can_MsgRx.data[5];
+    }
+    else if (can_MsgRx.id == 0x1a2)
+    {
+        if ((can_MsgRx.data[0] & 0x80) == 0x80)
+        {
+            status._rearDefrost = true;
+        }
+        else
+        {
+            status._rearDefrost = false;
+        }
+
+        if ((can_MsgRx.data[0] & 0x40) == 0x40)
+        {
+            status._fanRequested = true;
+        }
+        else
+        {
+            status._fanRequested = false;
+        }
+
+        if ((can_MsgRx.data[0] & 0x01) == 0x01)
+        {
+            status._fanOn = true;
+        }
+        else
+        {
+            status._fanOn = false;
+        }
+    }
+    else if (can_MsgRx.id == 0x1bd)
+    {
+        // SDAR status
+        
+        if (status._siriusChan == 0)
+        {
+            status._siriusChan = can_MsgRx.data[1];
+        }
+
+        if (can_MsgRx.data[0] == 0x85)
+        {
+            ChangeSiriusStation(status._siriusChan, true);
+        }
+        
+        if (status._siriusChan != can_MsgRx.data[1])
+        {
+            ChangeSiriusStation(status._siriusChan, true);
+        }
+    }
+    else if (can_MsgRx.id == 0x1c8)
+    {
+        status._headlights = can_MsgRx.data[0];
+    }
+    else if (can_MsgRx.id == 0x210)
+    {
+        status._dimmerMode = can_MsgRx.data[0];
+        if (can_MsgRx.data[0] == 0x03)
+        {
+            status._dimmer = -1;
+        }
+        else if (can_MsgRx.data[0] == 0x02)
+        {
+            status._dimmer = can_MsgRx.data[1];
+        }
+    }
+    else if (can_MsgRx.id == 0x3a0)
+    {        
+        // note = 0x01
+        // volume up = 0x02
+        // volume down = 0x04
+        // up arrow = 0x08
+        // down arrow = 0x10
+        // right arrow = 0x20
+               
+        status.SWCButtons = can_MsgRx.data[0];
+    }
+    else if (can_MsgRx.id == 0x3bd)
+    {
+        ReadSiriusText((char *)can_MsgRx.data);
+    }
+}
+
+void RadioEmulator::ReadSiriusText(char *data)
+{
+    int num = (data[0] & 0xF0) >> 4;
+    if ((num > 7) || (num < 0))
+    {
+        return;
+    }
+    
+    int part = (data[0] & 0x0E) >> 1;
+    if ((part > 7) || (part < 0))
+    {
+        return;
+    }
+
+    if ((data[0] & 0x01) != 0)
+    {
+        memset(&siriusdata[num * 64], 0, 64);
+    }
+
+    memset(&siriusdata[(num * 64) + (part * 7)], 0, 7);
+    
+    for (int i = 1; i < 8; i++)
+    {
+        siriusdata[(num * 64) + (part * 7) + (i-1)] = data[i];
+    }
+/*
+    int cls = (data[0] & 0x0F) >> 1;
+    if (cls - 1 == 0)
+    {
+        for (int i = 0; i < 8; i++)
+        {
+            memset(st.TextLine[i], 0, 64);
+            for (int j = 0; j < 8; j++)
+            {
+                strcat(st.TextLine[i], siriusText[i][j]);
+            }
+            
+            printf("%d: %s\r\n", i, st.TextLine[i]);
+        }
+    }
+*/
+}
+
+void RadioEmulator::readCANbus(void)
+{
+    if (CANDevice->read(can_MsgRx))
+    {
+        led3 = !led3;
+        needToParseCANMessage = true;
+        ReceivedCANMsg = true;
+        
+        
+        char buffer[11];
+        buffer[0] = (can_MsgRx.id & 0xFF00) >> 8;
+        buffer[1] = can_MsgRx.id & 0x00FF;
+        buffer[2] = can_MsgRx.len;
+        memcpy(&buffer[3], can_MsgRx.data, 8);
+
+        static Host monitorHost(IpAddr(10,10,10,1), 41000, NULL);        
+        HostSock->SendTo(&monitorHost, 11, buffer);
+
+    }
+    
+    if (needToParseCANMessage)
+    {           
+        needToParseCANMessage = false;   
+        
+        ParseCANMessage(can_MsgRx);
+    }
+}
+
+void RadioEmulator::ReceivedData(int socketStatus, int len, char *msg)
+{
+    if ((msg[0] == 0x42) && (msg[1] == 0x42) && (msg[2] == 0x42) && (msg[3] == 0x42))
+    {
+        ReceivedHostMsg = true;
+        
+        switch (msg[4])
+        {
+            case 0x00:
+                opMode = slave;
+            break;
+            
+            case 0x01:
+                if (len >= 11)
+                {
+                    status._volume = msg[5];
+                    status._balance = msg[6];
+                    status._fade = msg[7];
+                    status._bass = msg[8];
+                    status._mid = msg[9];
+                    status._treble = msg[10];
+                }
+                
+//              writeInitFile();
+            break;
+            
+            case 0x02:
+                if (len >= 6)
+                {
+                    status._siriusChan = msg[5];
+                    ChangeSiriusStation(msg[5], false);
+                }
+            break;
+            
+            case 0x03:
+                if (len >= 11)
+                {
+                    status._radioMode = (radioMode)msg[5];
+                    
+                    switch (status._radioMode)
+                    {
+                        case AM:
+                            status._amPreset = msg[6];
+                            status._amFreq = msg[7] + (msg[8] << 8);
+                        break;
+                        
+                        case FM:
+                            status._fmPreset = msg[6];
+                            status._fmFreq = msg[7] + (msg[8] << 8);
+                        break;
+                        
+                        case SAT:
+                            status._siriusPreset = msg[6];
+                            status._siriusChan = msg[7];
+                        break;
+                        
+                        case CD:
+                            status._cdNum = msg[6];
+                            status._cdTrackNum = msg[7];
+                            status._cdHours = msg[8];
+                            status._cdMinutes = msg[9];
+                            status._cdSeconds =  msg[10];
+                        break;
+                        
+                        case VES:
+                        break;
+                    }
+                }
+            break;
+            
+            case 0x04:
+//                CANMessage canMsg;
+//                canMsg.id = msg[5] + (msg[6] << 8);
+//                canMsg.len = msg[7];
+//                memcpy(canMsg.data, msg + 8, canMsg.len);
+                
+//                hostMessages.push_back(canMsg);
+            break;
+                
+        }
+
+    }
+}
+
+void RadioEmulator::WriteCANMessages()
+{
+    writeCANFlag = true;
+}
+
+void RadioEmulator::SendStatusToHost(void)
+{
+    statusFlag = true;
+}
+
+void RadioEmulator::CheckHostTimeout(void)
+{
+    hostTimeoutFlag = true;
+}
+
+// only enable this if trying to power up/down the processor
+void RadioEmulator::CheckCANTimeout(void)
+{
+    CANTimeoutFlag = true;
+}
+
+void RadioEmulator::CANActivity(void)
+{
+    if (powerUpIRQCounter == 5)
+    {
+        canIRQ->rise(0);
+        needToWakeUp = true;
+    }
+    powerUpIRQCounter++;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/radioEmulator.h	Mon Aug 20 02:35:43 2012 +0000
@@ -0,0 +1,85 @@
+#ifndef RADIOEMULATOR_H
+#define RADIOEMULATOR_H
+
+#include "mbed.h"
+#include "Eth.h"
+
+#include "RadioState.h"
+
+
+class RadioEmulator : public SocketReceiver
+{
+public:
+    RadioEmulator(CAN *can, DigitalOut *rs, InterruptIn *irq, bool wdTO);
+    ~RadioEmulator() {};
+    
+    void Operate(void);
+    
+    virtual void ReceivedData(int status, int size, char *data);
+    
+private:
+
+    CAN *CANDevice;
+    CANMessage can_MsgRx;
+    DigitalOut *can_RS;
+    InterruptIn *canIRQ;    
+    UDPSock *HostSock;
+    
+    RadioState status;
+    char siriusdata[512];
+    int prevSWC;
+
+//    void readInitFile();
+//    void writeInitFile();
+
+    void PowerUp(void);
+    void PowerDown();
+    
+    enum {standalone, slave} opMode;
+
+    void readCANbus(void);
+
+    void SendOnMsg();
+    void SendEVICMsg();
+    void SendRadioModeMsg();
+    void SendStereoSettingsMsg();
+    void SendHostMessages();
+    
+    void ChangeSiriusStation(int station, bool turn_on);
+    
+    void StandaloneSWI();
+    
+    void ParseCANMessage(CANMessage can_MsgRx);
+    void ReadSiriusText(char *data);    
+
+    Ticker CANBusTicker;
+    bool writeCANFlag;
+    void WriteCANMessages();
+    std::list<CANMessage> hostMessages;
+    
+    Ticker statusTicker;
+    bool statusFlag;
+    void SendStatusToHost();
+
+    Ticker CANTimeout;
+    bool CANTimeoutFlag;
+    void CheckCANTimeout(void);
+    void CANActivity(void);
+    bool ReceivedCANMsg;
+    bool needToParseCANMessage;
+    int powerUpIRQCounter;
+    bool sleeping;
+    bool needToWakeUp;
+
+    Ticker HostTimeout;
+    bool hostTimeoutFlag;
+    void CheckHostTimeout(void);
+    bool ReceivedHostMsg;
+    
+    
+    static char unlock[6];
+    static char lock[6];
+    static char trunk[6];
+};
+
+#endif
\ No newline at end of file