JGCtoGdT

Dependencies:   ConfigFile MODSERIAL_uVision Watchdog mbed-rtos mbed

Revision:
0:2e1b2d9fa0de
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun May 05 16:39:34 2013 +0000
@@ -0,0 +1,519 @@
+#include "mbed.h"
+#include "MODSERIAL.h"
+#include "rtos.h"
+#include "Watchdog.h"
+#include "ConfigFile.h"
+
+Watchdog wd;
+
+extern "C" void mbed_reset();
+
+char InitialMessage[50];
+
+DigitalOut ledCAN1(LED1);
+DigitalOut ledCAN2(LED2);
+DigitalOut led3(LED3);
+DigitalOut ledPC(LED4);
+
+
+time_t ctTime;
+struct tm * timeinfo;
+
+Ticker SpkTick;
+Timer myT;
+
+
+void LoadPCMail(char comm,  char *mess);
+
+/************* Frequency ****************/
+InterruptIn Freq1(p15);
+InterruptIn Freq2(p16);
+InterruptIn Freq3(p17);
+Timer F1;
+Timer F2;
+Timer F3;
+
+int Period1,Period2,Period3;
+
+void Freq1_Meas(void)
+{
+    Period1=F1.read_us();
+    F1.reset();
+}
+void Freq2_Meas(void)
+{
+    Period2=F2.read_us();
+    F2.reset();
+}
+void Freq3_Meas(void)
+{
+    Period3=F3.read_us();
+    F3.reset();
+}
+/************* End Frequency ************/
+
+/************* PWM ****************/
+PwmOut PwmO1(LED3);
+/************* End PWM ************/
+
+/************* CAN ***********************/
+#define CAN_MaxMailElements 16
+#define CANMessWait 1//ms
+#define MessSizeCAN 128
+
+typedef struct {
+    char command;   /* command to execute */
+    CANMessage mess;
+} CAN_mail_t;
+/************* CAN 1 *********************/
+CAN can1(p9,p10);
+int CAN1Freq=1000000;
+
+Mail<CAN_mail_t, CAN_MaxMailElements> CAN1_mail;
+int CAN1MailNum;
+
+void LoadCAN1Mail(char command,  CANMessage mess) //para cargar mensajes de trabajo al proceso paralelo CAN1_thread_proc
+{
+    while(CAN1MailNum>=CAN_MaxMailElements) {
+        Thread::wait(CANMessWait);
+    }
+    CAN_mail_t *mail = CAN1_mail.alloc();
+    mail->command = command;
+    mail->mess=mess;
+    CAN1_mail.put(mail);
+    CAN1MailNum++;
+}
+
+void messageFromCAN1()
+{
+    ledCAN1=true;
+    CANMessage msg;
+    can1.read(msg);
+    LoadCAN1Mail(10,msg);
+}
+
+void CAN1_thread_proc(void const *args) //proceso paralelo de gestión CAN1
+{
+    char tmp[MessSizeCAN];
+    while(true) {
+        osEvent evt = CAN1_mail.get(osWaitForever);
+        if (evt.status == osEventMail) {
+            CAN_mail_t *mail = (CAN_mail_t*)evt.value.p;
+
+            switch (mail->command) {
+                case 0: //request Reset CAN
+                    can1.reset();
+                    LoadPCMail(1,"Reset CAN1");
+                    break;
+                case 1: //set frequency
+                    can1.frequency(mail->mess.id);
+                    LoadPCMail(1,"Set Frequency CAN1");
+                    break;
+                case 10: //Read from CAN
+                    snprintf(tmp,MessSizeCAN,"ID=%i;TYPE=%i;FORMAT=%i;LEN=%d;DATA[0]=%u;DATA[1]=%u;DATA[2]=%u;DATA[3]=%u;DATA[4]=%u;DATA[5]=%u;DATA[6]=%u;DATA[7]=%u",mail->mess.id,mail->mess.type,mail->mess.format,mail->mess.len,mail->mess.data[0],mail->mess.data[1],mail->mess.data[2],mail->mess.data[3],mail->mess.data[4],mail->mess.data[5],mail->mess.data[6],mail->mess.data[7]);
+                    LoadPCMail(2,tmp);
+                    break;
+                case 20: //Write to CAN
+                    can1.write(mail->mess);
+                    LoadPCMail(1,"Write to CAN1");
+                    break;
+                default: // request to send message from code
+                    break;
+            }
+            CAN1_mail.free(mail);
+            CAN1MailNum--;
+            ledCAN1=false;
+        }
+    }
+}
+/************* END CAN 1 ****************/
+/************* CAN 2 ********************/
+CAN can2(p30,p29);
+int CAN2Freq=1000000;
+
+Mail<CAN_mail_t, CAN_MaxMailElements> CAN2_mail;
+int CAN2MailNum;
+
+void LoadCAN2Mail(char command,  CANMessage mess) //para cargar mensajes de trabajo al proceso paralelo CAN1_thread_proc
+{
+    while(CAN2MailNum>=CAN_MaxMailElements) {
+        Thread::wait(CANMessWait);
+    }
+    CAN_mail_t *mail = CAN2_mail.alloc();
+    mail->command = command;
+    mail->mess=mess;
+    CAN2_mail.put(mail);
+    CAN2MailNum++;
+}
+void messageFromCAN2()
+{
+    ledCAN2=true;
+    CANMessage msg;
+    can2.read(msg);
+    LoadCAN2Mail(10,msg);
+}
+void CAN2_thread_proc(void const *args) //proceso paralelo de gestión CAN1
+{
+    char tmp[MessSizeCAN];
+    while(true) {
+        osEvent evt = CAN2_mail.get(osWaitForever);
+        if (evt.status == osEventMail) {
+            CAN_mail_t *mail = (CAN_mail_t*)evt.value.p;
+
+            switch (mail->command) {
+                case 0: //request Reset CAN
+                    can2.reset();
+                    LoadPCMail(1,"Reset CAN2");
+                    break;
+                case 1: //set frequency
+                    can2.frequency(mail->mess.id);
+                    LoadPCMail(1,"Set Frequency CAN2");
+                    break;
+                case 10: //Read from CAN
+                    snprintf(tmp,MessSizeCAN,"ID=%i;TYPE=%i;FORMAT=%i;LEN=%d;DATA[0]=%u;DATA[1]=%u;DATA[2]=%u;DATA[3]=%u;DATA[4]=%u;DATA[5]=%u;DATA[6]=%u;DATA[7]=%u",mail->mess.id,mail->mess.type,mail->mess.format,mail->mess.len,mail->mess.data[0],mail->mess.data[1],mail->mess.data[2],mail->mess.data[3],mail->mess.data[4],mail->mess.data[5],mail->mess.data[6],mail->mess.data[7]);
+                    LoadPCMail(3,tmp);
+                    break;
+                case 20: //Write to CAN
+                    can2.write(mail->mess);
+                    LoadPCMail(1,"Write to CAN2");
+                    break;
+                default: // request to send message from code
+                    break;
+            }
+            CAN2_mail.free(mail);
+            CAN2MailNum--;
+            ledCAN2=false;
+        }
+    }
+}
+/************* END CAN 2 ****************/
+/************* END CAN ******************/
+
+/************* RS232 PC ******************/
+#define TxBuffer_NumMess 16
+#define RxBuffer_NumMess 16
+#define MessSizePC 128
+#define TxBuffer TxBuffer_NumMess*MessSizePC
+#define RxBuffer RxBuffer_NumMess*MessSizePC
+#define PC_MaxMailElements 16
+#define PCMessWait MessSizePC*10/9.6 //ms
+
+MODSERIAL pc(USBTX, USBRX,TxBuffer,RxBuffer);
+bool LOGPC;
+int BaudRate;
+double TxBufferWait;
+char ChEnd;
+
+typedef struct {
+    char command;   /* command to execute */
+    char message[MessSizePC];   /* arguments */
+} PC_mail_t;
+
+Mail<PC_mail_t, PC_MaxMailElements> PC_mail;
+int PCMailNum;
+
+void TLogSTR(char *Tstr)
+{
+    ctTime = time(NULL);
+    timeinfo = localtime ( &ctTime );
+    timeinfo->tm_hour=(timeinfo->tm_hour+1)%24;
+    strftime (Tstr,MessSizePC,"%H:%M:%S",timeinfo);
+}
+
+void LoadPCMail(char comm,  char *mess) //para cargar mensajes de trabajo al proceso paralelo ComPC_thread_proc
+{
+    while(PCMailNum>=PC_MaxMailElements) {
+        Thread::wait(PCMessWait);
+    }
+    if(comm!=1 || LOGPC) {
+        PC_mail_t *mail = PC_mail.alloc();
+        mail->command = comm;
+        snprintf(mail->message,MessSizePC,"%s",mess);
+        PC_mail.put(mail);
+        PCMailNum++;
+    }
+}
+
+void messageFromPC(MODSERIAL_IRQ_INFO *q) //trabajo solicitado desde PC
+{
+    ledPC=true;
+    MODSERIAL *sys = q->serial;
+    char temp[MessSizePC];
+
+    int i=sys->move(temp,MessSizePC,ChEnd);
+    if (temp[i-2]=='\r') {
+        i-=2;
+    } else {
+        i-=1;
+    }
+    temp[i]=0;
+    LoadPCMail(0,temp);
+}
+
+int ComPC_Write(char *mess) //sólo para usarse en ComPC_thread_proc
+{
+    int i=strlen(mess);
+    if(i>0) {
+        while((TxBuffer-pc.txBufferGetCount())<i) {
+            Thread::wait(TxBufferWait);
+        }
+        return pc.printf(mess);
+    }
+    return 0;
+}
+
+void ComPC_thread_proc(void const *args) //proceso paralelo de gestión PC: tareas solicitadas y envío a PC
+{
+
+    while(true) {
+        osEvent evt = PC_mail.get(osWaitForever);
+        if (evt.status == osEventMail) {
+            PC_mail_t *mail = (PC_mail_t*)evt.value.p;
+
+            char mess[MessSizePC];
+            char Tstr[20];
+            TLogSTR(Tstr);
+            switch (mail->command) {
+                case 0: //request from PC
+                    CANMessage CanMess;
+                    switch (mail->message[0]) {
+                        case 'T':
+                            float seconds;
+                            sscanf(&mail->message[1],"%f",&seconds);
+                            set_time((double)seconds);
+                            time_t ctTime;
+                            ctTime = time(NULL);
+                            snprintf(mess,MessSizePC,"%s",ctime(&ctTime));
+                            LoadPCMail(1,mess);
+                            break;
+                        case 'C': //CAN
+                            switch (mail->message[1]) {
+                                case '1': //CAN1, Send from PC a Message to CAN1
+                                    switch (mail->message[2]) {
+                                        case 'R': //reset CAN
+                                            LoadCAN1Mail(0,CanMess);
+                                            snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                        case 'F': //set Frequency CAN
+                                            sscanf(&mail->message[3],"%i",&CanMess.id);
+                                            LoadCAN1Mail(1,CanMess);
+                                            snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                        case 'W': //Write CAN
+                                            sscanf(&mail->message[3],"%i;%i;%i;%u;%u;%u;%u;%u;%u;%u;%u;%u",&CanMess.id,&CanMess.type,&CanMess.format,&CanMess.len,&CanMess.data[0],&CanMess.data[1],&CanMess.data[2],&CanMess.data[3],&CanMess.data[4],&CanMess.data[5],&CanMess.data[6],&CanMess.data[7]);
+                                            LoadCAN1Mail(20,CanMess);
+                                            snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                        default:
+                                            snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                    }
+                                    break;
+                                case '2': //CAN2, Send from PC a Message to CAN2
+                                    switch (mail->message[2]) {
+                                        case 'R': //reset CAN
+                                            LoadCAN2Mail(0,CanMess);
+                                            snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                        case 'F': //set Frequency CAN
+                                            sscanf(&mail->message[3],"%i",&CanMess.id);
+                                            LoadCAN2Mail(1,CanMess);
+                                            snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                        case 'W': //Write CAN
+                                            sscanf(&mail->message[3],"%i;%i;%i;%u;%u;%u;%u;%u;%u;%u;%u;%u",&CanMess.id,&CanMess.type,&CanMess.format,&CanMess.len,&CanMess.data[0],&CanMess.data[1],&CanMess.data[2],&CanMess.data[3],&CanMess.data[4],&CanMess.data[5],&CanMess.data[6],&CanMess.data[7]);
+                                            LoadCAN2Mail(20,CanMess);
+                                            snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                        default:
+                                            snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                                            break;
+                                    }
+                                    break;
+                                default:
+                                    snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                                    break;
+                            }
+                            break;
+                        case 'F': //Frequencies
+                            switch (mail->message[1]) {
+                                case '1': //Freq1, Get Freq11
+                                    snprintf(mess,MessSizePC,"F1= %i usec\r\n",Period1);
+                                    break;
+                                case '2': //Freq2, Get Freq2
+                                    snprintf(mess,MessSizePC,"F2= %i usec\r\n",Period2);
+                                    break;
+                                case '3': //Freq3, Get Freq3
+                                    snprintf(mess,MessSizePC,"F3= %i usec\r\n",Period3);
+                                    break;
+                                default:
+                                    snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                                    break;
+                            }
+                            break;
+                        case 'P':
+                            float duty=0;
+                            int periodus=0;
+                            switch (mail->message[1]) {
+                                case '1':
+                                    sscanf(&mail->message[2],"%f;%i",&duty,&periodus);
+                                    PwmO1.write(duty);
+                                    PwmO1.period_us(periodus);
+                                    snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
+                                    break;
+                                default:
+                                    snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                                    break;
+                            }
+                            break;
+                        case 'R':
+                            if(strcmp(mail->message,"REBOOT")==0) {
+                                mbed_reset();//wd.Configure(2.0);
+                            } else {
+                                snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                            }
+                            break;
+                        case 'r':
+                            if(strcmp(mail->message,"reboot")==0) {
+                                mbed_reset();//wd.Configure(2.0);
+                            } else {
+                                snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                            }
+                            break;
+                        default:
+                            snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
+                            break;
+                    }
+                    break;
+                case 1: //Send LOG to PC
+                    if(LOGPC) {
+                        snprintf(mess,MessSizePC,"LOG(%s):%s\r\n",Tstr ,mail->message);
+                    } else {
+                        mess[0]=0;
+                    }
+                    break;
+                case 2: //Send to PC a Message from CAN1
+                    snprintf(mess,MessSizePC,"CAN1:%s\r\n",mail->message);
+                    break;
+                case 3: //Send to PC a Message from CAN2
+                    snprintf(mess,MessSizePC,"CAN2:%s\r\n",mail->message);
+                    break;
+                default:
+                    break;
+            }
+            PC_mail.free(mail);
+            PCMailNum--;
+            ledPC=false;
+            ComPC_Write(mess);
+        }
+    }
+}
+/************* END RS232 PC **************/
+
+void GetConfig()
+{
+
+#define CfgNumParam 6
+#define CfgSizeParam 50
+
+    pc.format(8,Serial::Even,1);
+    pc.baud(115200);
+    ConfigFile cfg;
+    LocalFileSystem local("local");
+
+    int i;
+    char value[CfgNumParam][CfgSizeParam];
+    char CfgK[CfgNumParam][CfgSizeParam]= {"InitialMessage","BaudRate","ChEnd","LOGPC","CAN1Freq","CAN2Freq"};
+
+    pc.printf("\r\n* * *\r\n* * *\r\n");
+
+    if (!cfg.read("/local/config.cfg")) {
+        error("\r\nFailure to read a configuration file");
+    }
+    char Tstr[10];
+    for (i=0; i<CfgNumParam; i++) {
+        if (cfg.getValue(CfgK[i], &value[i][0], sizeof(value[i]))) {
+            TLogSTR(Tstr);
+            pc.printf("CFG_Param(%s): '%s'='%s'\r\n", Tstr,CfgK[i], value[i]);
+        } else {
+            error("Failure Reading '%s'\r\n", CfgK[i]);
+        }
+    }
+    strcpy(InitialMessage,value[0]);
+    BaudRate=atoi(value[1]);
+    ChEnd=(char)atoi(value[2]);
+    LOGPC=(bool)atoi(value[3]);
+    CAN1Freq=atoi(value[4]);
+    CAN2Freq=atoi(value[5]);
+
+    TxBufferWait= 10000*MessSizePC/BaudRate;
+
+    pc.printf("* * *\r\n* * *\r\n");
+
+    while(!pc.txBufferEmpty()) {
+        Thread::wait(100);
+    };
+}
+
+int main()
+{
+
+    //char tempMessPC[MessSizePC];
+    PCMailNum=0;
+    GetConfig();
+
+    // ************ PC ^^^^^^^^^^^^^
+    pc.baud(BaudRate);
+    Thread ComPC_thread (ComPC_thread_proc,NULL,osPriorityBelowNormal);
+    pc.attach(&messageFromPC, MODSERIAL::RxAutoDetect);
+    pc.autoDetectChar(ChEnd);
+
+    // ************ PC_end ^^^^^^^^^^^^^
+
+    LoadPCMail(1,"");
+    LoadPCMail(1,"");
+    LoadPCMail(1,"");
+    LoadPCMail(1,"*****************************");
+    LoadPCMail(1,InitialMessage);
+    LoadPCMail(1,"*****************************");
+    LoadPCMail(1,"");
+    LoadPCMail(1,"");
+    LoadPCMail(1,"");
+
+    // ************ CAN1 ^^^^^^^^^^^
+    Thread CAN1_thread (CAN1_thread_proc,NULL,osPriorityNormal);
+    can1.frequency(CAN1Freq);
+    can1.attach(&messageFromCAN1);
+    // ************ CAN1_end ^^^^^^^
+
+    // ************ CAN2 ^^^^^^^^^^^
+    Thread CAN2_thread (CAN2_thread_proc,NULL,osPriorityNormal);
+    can2.frequency(CAN2Freq);
+    can2.attach(&messageFromCAN2);
+    // ************ CAN2_end ^^^^^^^
+
+    // ************ WD *************
+    wd.WatchdogCausedReset();
+    wd.Configure(5.0);
+    // ************ WD_end *********
+
+    // ************ Interrupts Freqs
+    F1.start();
+    F2.start();
+    F3.start();
+    Period1=0;
+    Period2=0;
+    Period3=0;
+
+    Freq1.rise(Freq1_Meas);
+    Freq2.rise(Freq2_Meas);
+    Freq3.rise(Freq3_Meas);
+
+    // ************ End Interrupts Freqs
+
+    while(true) {
+        //Thread::wait(osWaitForever);
+        wd.Service();
+        Thread::wait(1000);
+    }
+}