JGCtoGdT

Dependencies:   ConfigFile MODSERIAL_uVision Watchdog mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "MODSERIAL.h"
00003 #include "rtos.h"
00004 #include "Watchdog.h"
00005 #include "ConfigFile.h"
00006 
00007 Watchdog wd;
00008 
00009 extern "C" void mbed_reset();
00010 
00011 char InitialMessage[50];
00012 
00013 DigitalOut ledCAN1(LED1);
00014 DigitalOut ledCAN2(LED2);
00015 DigitalOut led3(LED3);
00016 DigitalOut ledPC(LED4);
00017 
00018 
00019 time_t ctTime;
00020 struct tm * timeinfo;
00021 
00022 Ticker SpkTick;
00023 Timer myT;
00024 
00025 
00026 void LoadPCMail(char comm,  char *mess);
00027 
00028 /************* Frequency ****************/
00029 InterruptIn Freq1(p15);
00030 InterruptIn Freq2(p16);
00031 InterruptIn Freq3(p17);
00032 Timer F1;
00033 Timer F2;
00034 Timer F3;
00035 
00036 int Period1,Period2,Period3;
00037 
00038 void Freq1_Meas(void)
00039 {
00040     Period1=F1.read_us();
00041     F1.reset();
00042 }
00043 void Freq2_Meas(void)
00044 {
00045     Period2=F2.read_us();
00046     F2.reset();
00047 }
00048 void Freq3_Meas(void)
00049 {
00050     Period3=F3.read_us();
00051     F3.reset();
00052 }
00053 /************* End Frequency ************/
00054 
00055 /************* PWM ****************/
00056 PwmOut PwmO1(LED3);
00057 /************* End PWM ************/
00058 
00059 /************* CAN ***********************/
00060 #define CAN_MaxMailElements 16
00061 #define CANMessWait 1//ms
00062 #define MessSizeCAN 128
00063 
00064 typedef struct {
00065     char command;   /* command to execute */
00066     CANMessage mess;
00067 } CAN_mail_t;
00068 /************* CAN 1 *********************/
00069 CAN can1(p9,p10);
00070 int CAN1Freq=1000000;
00071 
00072 Mail<CAN_mail_t, CAN_MaxMailElements> CAN1_mail;
00073 int CAN1MailNum;
00074 
00075 void LoadCAN1Mail(char command,  CANMessage mess) //para cargar mensajes de trabajo al proceso paralelo CAN1_thread_proc
00076 {
00077     while(CAN1MailNum>=CAN_MaxMailElements) {
00078         Thread::wait(CANMessWait);
00079     }
00080     CAN_mail_t *mail = CAN1_mail.alloc();
00081     mail->command = command;
00082     mail->mess=mess;
00083     CAN1_mail.put(mail);
00084     CAN1MailNum++;
00085 }
00086 
00087 void messageFromCAN1()
00088 {
00089     ledCAN1=true;
00090     CANMessage msg;
00091     can1.read(msg);
00092     LoadCAN1Mail(10,msg);
00093 }
00094 
00095 void CAN1_thread_proc(void const *args) //proceso paralelo de gestión CAN1
00096 {
00097     char tmp[MessSizeCAN];
00098     while(true) {
00099         osEvent evt = CAN1_mail.get(osWaitForever);
00100         if (evt.status == osEventMail) {
00101             CAN_mail_t *mail = (CAN_mail_t*)evt.value.p;
00102 
00103             switch (mail->command) {
00104                 case 0: //request Reset CAN
00105                     can1.reset();
00106                     LoadPCMail(1,"Reset CAN1");
00107                     break;
00108                 case 1: //set frequency
00109                     can1.frequency(mail->mess.id);
00110                     LoadPCMail(1,"Set Frequency CAN1");
00111                     break;
00112                 case 10: //Read from CAN
00113                     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]);
00114                     LoadPCMail(2,tmp);
00115                     break;
00116                 case 20: //Write to CAN
00117                     can1.write(mail->mess);
00118                     LoadPCMail(1,"Write to CAN1");
00119                     break;
00120                 default: // request to send message from code
00121                     break;
00122             }
00123             CAN1_mail.free(mail);
00124             CAN1MailNum--;
00125             ledCAN1=false;
00126         }
00127     }
00128 }
00129 /************* END CAN 1 ****************/
00130 /************* CAN 2 ********************/
00131 CAN can2(p30,p29);
00132 int CAN2Freq=1000000;
00133 
00134 Mail<CAN_mail_t, CAN_MaxMailElements> CAN2_mail;
00135 int CAN2MailNum;
00136 
00137 void LoadCAN2Mail(char command,  CANMessage mess) //para cargar mensajes de trabajo al proceso paralelo CAN1_thread_proc
00138 {
00139     while(CAN2MailNum>=CAN_MaxMailElements) {
00140         Thread::wait(CANMessWait);
00141     }
00142     CAN_mail_t *mail = CAN2_mail.alloc();
00143     mail->command = command;
00144     mail->mess=mess;
00145     CAN2_mail.put(mail);
00146     CAN2MailNum++;
00147 }
00148 void messageFromCAN2()
00149 {
00150     ledCAN2=true;
00151     CANMessage msg;
00152     can2.read(msg);
00153     LoadCAN2Mail(10,msg);
00154 }
00155 void CAN2_thread_proc(void const *args) //proceso paralelo de gestión CAN1
00156 {
00157     char tmp[MessSizeCAN];
00158     while(true) {
00159         osEvent evt = CAN2_mail.get(osWaitForever);
00160         if (evt.status == osEventMail) {
00161             CAN_mail_t *mail = (CAN_mail_t*)evt.value.p;
00162 
00163             switch (mail->command) {
00164                 case 0: //request Reset CAN
00165                     can2.reset();
00166                     LoadPCMail(1,"Reset CAN2");
00167                     break;
00168                 case 1: //set frequency
00169                     can2.frequency(mail->mess.id);
00170                     LoadPCMail(1,"Set Frequency CAN2");
00171                     break;
00172                 case 10: //Read from CAN
00173                     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]);
00174                     LoadPCMail(3,tmp);
00175                     break;
00176                 case 20: //Write to CAN
00177                     can2.write(mail->mess);
00178                     LoadPCMail(1,"Write to CAN2");
00179                     break;
00180                 default: // request to send message from code
00181                     break;
00182             }
00183             CAN2_mail.free(mail);
00184             CAN2MailNum--;
00185             ledCAN2=false;
00186         }
00187     }
00188 }
00189 /************* END CAN 2 ****************/
00190 /************* END CAN ******************/
00191 
00192 /************* RS232 PC ******************/
00193 #define TxBuffer_NumMess 16
00194 #define RxBuffer_NumMess 16
00195 #define MessSizePC 128
00196 #define TxBuffer TxBuffer_NumMess*MessSizePC
00197 #define RxBuffer RxBuffer_NumMess*MessSizePC
00198 #define PC_MaxMailElements 16
00199 #define PCMessWait MessSizePC*10/9.6 //ms
00200 
00201 MODSERIAL pc(USBTX, USBRX,TxBuffer,RxBuffer);
00202 bool LOGPC;
00203 int BaudRate;
00204 double TxBufferWait;
00205 char ChEnd;
00206 
00207 typedef struct {
00208     char command;   /* command to execute */
00209     char message[MessSizePC];   /* arguments */
00210 } PC_mail_t;
00211 
00212 Mail<PC_mail_t, PC_MaxMailElements> PC_mail;
00213 int PCMailNum;
00214 
00215 void TLogSTR(char *Tstr)
00216 {
00217     ctTime = time(NULL);
00218     timeinfo = localtime ( &ctTime );
00219     timeinfo->tm_hour=(timeinfo->tm_hour+1)%24;
00220     strftime (Tstr,MessSizePC,"%H:%M:%S",timeinfo);
00221 }
00222 
00223 void LoadPCMail(char comm,  char *mess) //para cargar mensajes de trabajo al proceso paralelo ComPC_thread_proc
00224 {
00225     while(PCMailNum>=PC_MaxMailElements) {
00226         Thread::wait(PCMessWait);
00227     }
00228     if(comm!=1 || LOGPC) {
00229         PC_mail_t *mail = PC_mail.alloc();
00230         mail->command = comm;
00231         snprintf(mail->message,MessSizePC,"%s",mess);
00232         PC_mail.put(mail);
00233         PCMailNum++;
00234     }
00235 }
00236 
00237 void messageFromPC(MODSERIAL_IRQ_INFO *q) //trabajo solicitado desde PC
00238 {
00239     ledPC=true;
00240     MODSERIAL *sys = q->serial;
00241     char temp[MessSizePC];
00242 
00243     int i=sys->move(temp,MessSizePC,ChEnd);
00244     if (temp[i-2]=='\r') {
00245         i-=2;
00246     } else {
00247         i-=1;
00248     }
00249     temp[i]=0;
00250     LoadPCMail(0,temp);
00251 }
00252 
00253 int ComPC_Write(char *mess) //sólo para usarse en ComPC_thread_proc
00254 {
00255     int i=strlen(mess);
00256     if(i>0) {
00257         while((TxBuffer-pc.txBufferGetCount())<i) {
00258             Thread::wait(TxBufferWait);
00259         }
00260         return pc.printf(mess);
00261     }
00262     return 0;
00263 }
00264 
00265 void ComPC_thread_proc(void const *args) //proceso paralelo de gestión PC: tareas solicitadas y envío a PC
00266 {
00267 
00268     while(true) {
00269         osEvent evt = PC_mail.get(osWaitForever);
00270         if (evt.status == osEventMail) {
00271             PC_mail_t *mail = (PC_mail_t*)evt.value.p;
00272 
00273             char mess[MessSizePC];
00274             char Tstr[20];
00275             TLogSTR(Tstr);
00276             switch (mail->command) {
00277                 case 0: //request from PC
00278                     CANMessage CanMess;
00279                     switch (mail->message[0]) {
00280                         case 'T':
00281                             float seconds;
00282                             sscanf(&mail->message[1],"%f",&seconds);
00283                             set_time((double)seconds);
00284                             time_t ctTime;
00285                             ctTime = time(NULL);
00286                             snprintf(mess,MessSizePC,"%s",ctime(&ctTime));
00287                             LoadPCMail(1,mess);
00288                             break;
00289                         case 'C': //CAN
00290                             switch (mail->message[1]) {
00291                                 case '1': //CAN1, Send from PC a Message to CAN1
00292                                     switch (mail->message[2]) {
00293                                         case 'R': //reset CAN
00294                                             LoadCAN1Mail(0,CanMess);
00295                                             snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
00296                                             break;
00297                                         case 'F': //set Frequency CAN
00298                                             sscanf(&mail->message[3],"%i",&CanMess.id);
00299                                             LoadCAN1Mail(1,CanMess);
00300                                             snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
00301                                             break;
00302                                         case 'W': //Write CAN
00303                                             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]);
00304                                             LoadCAN1Mail(20,CanMess);
00305                                             snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
00306                                             break;
00307                                         default:
00308                                             snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00309                                             break;
00310                                     }
00311                                     break;
00312                                 case '2': //CAN2, Send from PC a Message to CAN2
00313                                     switch (mail->message[2]) {
00314                                         case 'R': //reset CAN
00315                                             LoadCAN2Mail(0,CanMess);
00316                                             snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
00317                                             break;
00318                                         case 'F': //set Frequency CAN
00319                                             sscanf(&mail->message[3],"%i",&CanMess.id);
00320                                             LoadCAN2Mail(1,CanMess);
00321                                             snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
00322                                             break;
00323                                         case 'W': //Write CAN
00324                                             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]);
00325                                             LoadCAN2Mail(20,CanMess);
00326                                             snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
00327                                             break;
00328                                         default:
00329                                             snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00330                                             break;
00331                                     }
00332                                     break;
00333                                 default:
00334                                     snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00335                                     break;
00336                             }
00337                             break;
00338                         case 'F': //Frequencies
00339                             switch (mail->message[1]) {
00340                                 case '1': //Freq1, Get Freq11
00341                                     snprintf(mess,MessSizePC,"F1= %i usec\r\n",Period1);
00342                                     break;
00343                                 case '2': //Freq2, Get Freq2
00344                                     snprintf(mess,MessSizePC,"F2= %i usec\r\n",Period2);
00345                                     break;
00346                                 case '3': //Freq3, Get Freq3
00347                                     snprintf(mess,MessSizePC,"F3= %i usec\r\n",Period3);
00348                                     break;
00349                                 default:
00350                                     snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00351                                     break;
00352                             }
00353                             break;
00354                         case 'P':
00355                             float duty=0;
00356                             int periodus=0;
00357                             switch (mail->message[1]) {
00358                                 case '1':
00359                                     sscanf(&mail->message[2],"%f;%i",&duty,&periodus);
00360                                     PwmO1.write(duty);
00361                                     PwmO1.period_us(periodus);
00362                                     snprintf (mess,MessSizePC,"ACK(%s):%s\r\n",Tstr, mail->message);
00363                                     break;
00364                                 default:
00365                                     snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00366                                     break;
00367                             }
00368                             break;
00369                         case 'R':
00370                             if(strcmp(mail->message,"REBOOT")==0) {
00371                                 mbed_reset();//wd.Configure(2.0);
00372                             } else {
00373                                 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00374                             }
00375                             break;
00376                         case 'r':
00377                             if(strcmp(mail->message,"reboot")==0) {
00378                                 mbed_reset();//wd.Configure(2.0);
00379                             } else {
00380                                 snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00381                             }
00382                             break;
00383                         default:
00384                             snprintf (mess,MessSizePC,"NAK(%s):%s\r\n",Tstr, mail->message);
00385                             break;
00386                     }
00387                     break;
00388                 case 1: //Send LOG to PC
00389                     if(LOGPC) {
00390                         snprintf(mess,MessSizePC,"LOG(%s):%s\r\n",Tstr ,mail->message);
00391                     } else {
00392                         mess[0]=0;
00393                     }
00394                     break;
00395                 case 2: //Send to PC a Message from CAN1
00396                     snprintf(mess,MessSizePC,"CAN1:%s\r\n",mail->message);
00397                     break;
00398                 case 3: //Send to PC a Message from CAN2
00399                     snprintf(mess,MessSizePC,"CAN2:%s\r\n",mail->message);
00400                     break;
00401                 default:
00402                     break;
00403             }
00404             PC_mail.free(mail);
00405             PCMailNum--;
00406             ledPC=false;
00407             ComPC_Write(mess);
00408         }
00409     }
00410 }
00411 /************* END RS232 PC **************/
00412 
00413 void GetConfig()
00414 {
00415 
00416 #define CfgNumParam 6
00417 #define CfgSizeParam 50
00418 
00419     pc.format(8,Serial::Even,1);
00420     pc.baud(115200);
00421     ConfigFile cfg;
00422     LocalFileSystem local("local");
00423 
00424     int i;
00425     char value[CfgNumParam][CfgSizeParam];
00426     char CfgK[CfgNumParam][CfgSizeParam]= {"InitialMessage","BaudRate","ChEnd","LOGPC","CAN1Freq","CAN2Freq"};
00427 
00428     pc.printf("\r\n* * *\r\n* * *\r\n");
00429 
00430     if (!cfg.read("/local/config.cfg")) {
00431         error("\r\nFailure to read a configuration file");
00432     }
00433     char Tstr[10];
00434     for (i=0; i<CfgNumParam; i++) {
00435         if (cfg.getValue(CfgK[i], &value[i][0], sizeof(value[i]))) {
00436             TLogSTR(Tstr);
00437             pc.printf("CFG_Param(%s): '%s'='%s'\r\n", Tstr,CfgK[i], value[i]);
00438         } else {
00439             error("Failure Reading '%s'\r\n", CfgK[i]);
00440         }
00441     }
00442     strcpy(InitialMessage,value[0]);
00443     BaudRate=atoi(value[1]);
00444     ChEnd=(char)atoi(value[2]);
00445     LOGPC=(bool)atoi(value[3]);
00446     CAN1Freq=atoi(value[4]);
00447     CAN2Freq=atoi(value[5]);
00448 
00449     TxBufferWait= 10000*MessSizePC/BaudRate;
00450 
00451     pc.printf("* * *\r\n* * *\r\n");
00452 
00453     while(!pc.txBufferEmpty()) {
00454         Thread::wait(100);
00455     };
00456 }
00457 
00458 int main()
00459 {
00460 
00461     //char tempMessPC[MessSizePC];
00462     PCMailNum=0;
00463     GetConfig();
00464 
00465     // ************ PC ^^^^^^^^^^^^^
00466     pc.baud(BaudRate);
00467     Thread ComPC_thread (ComPC_thread_proc,NULL,osPriorityBelowNormal);
00468     pc.attach(&messageFromPC, MODSERIAL::RxAutoDetect);
00469     pc.autoDetectChar(ChEnd);
00470 
00471     // ************ PC_end ^^^^^^^^^^^^^
00472 
00473     LoadPCMail(1,"");
00474     LoadPCMail(1,"");
00475     LoadPCMail(1,"");
00476     LoadPCMail(1,"*****************************");
00477     LoadPCMail(1,InitialMessage);
00478     LoadPCMail(1,"*****************************");
00479     LoadPCMail(1,"");
00480     LoadPCMail(1,"");
00481     LoadPCMail(1,"");
00482 
00483     // ************ CAN1 ^^^^^^^^^^^
00484     Thread CAN1_thread (CAN1_thread_proc,NULL,osPriorityNormal);
00485     can1.frequency(CAN1Freq);
00486     can1.attach(&messageFromCAN1);
00487     // ************ CAN1_end ^^^^^^^
00488 
00489     // ************ CAN2 ^^^^^^^^^^^
00490     Thread CAN2_thread (CAN2_thread_proc,NULL,osPriorityNormal);
00491     can2.frequency(CAN2Freq);
00492     can2.attach(&messageFromCAN2);
00493     // ************ CAN2_end ^^^^^^^
00494 
00495     // ************ WD *************
00496     wd.WatchdogCausedReset();
00497     wd.Configure(5.0);
00498     // ************ WD_end *********
00499 
00500     // ************ Interrupts Freqs
00501     F1.start();
00502     F2.start();
00503     F3.start();
00504     Period1=0;
00505     Period2=0;
00506     Period3=0;
00507 
00508     Freq1.rise(Freq1_Meas);
00509     Freq2.rise(Freq2_Meas);
00510     Freq3.rise(Freq3_Meas);
00511 
00512     // ************ End Interrupts Freqs
00513 
00514     while(true) {
00515         //Thread::wait(osWaitForever);
00516         wd.Service();
00517         Thread::wait(1000);
00518     }
00519 }