JGCtoGdT
Dependencies: ConfigFile MODSERIAL_uVision Watchdog mbed-rtos mbed
main.cpp
- Committer:
- JavierGC
- Date:
- 2013-05-05
- Revision:
- 0:2e1b2d9fa0de
File content as of revision 0:2e1b2d9fa0de:
#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); } }