breakLIN_RacEI
Dependencies: mbed mbed-rtos Watchdog MODSERIAL ConfigFile
Revision 0:939d1f478fb5, committed 2021-02-22
- Comitter:
- JavierGC
- Date:
- Mon Feb 22 17:12:27 2021 +0000
- Commit message:
- breakLIN_RacEI
Changed in this revision
diff -r 000000000000 -r 939d1f478fb5 ConfigFile.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ConfigFile.lib Mon Feb 22 17:12:27 2021 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
diff -r 000000000000 -r 939d1f478fb5 MODSERIAL.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODSERIAL.lib Mon Feb 22 17:12:27 2021 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
diff -r 000000000000 -r 939d1f478fb5 Watchdog.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Watchdog.lib Mon Feb 22 17:12:27 2021 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/WiredHome/code/Watchdog/#e0f547e22dd5
diff -r 000000000000 -r 939d1f478fb5 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Feb 22 17:12:27 2021 +0000 @@ -0,0 +1,469 @@ +#include "mbed.h" +#include "rtos.h" +#include "MODSERIAL.h" +#include "Watchdog.h" +#include "ConfigFile.h" + +/***** DEFINITIONS *****/ +#define TxBuffer_NumMess 16 +#define RxBuffer_NumMess 16 +#define MessSizePC 128 +#define MessSizeLIN 128 +#define TxBuffer TxBuffer_NumMess*MessSizePC +#define RxBuffer RxBuffer_NumMess*MessSizePC +#define PC_MaxMailElements 16 +#define LIN_MaxMailElements 16 +#define PCMessWait MessSizePC*10/9.6 //ms +#define LINMessWait 1//ms + +/***** STRUCTURES *****/ + +typedef struct { + char command; /* command to execute */ + char message[MessSizePC]; /* arguments */ +} PC_mail_t; + +typedef struct LINMessage_t // Lin Message Structure +{ + char IDfield; + char Data[8]; // Maximum Number of Data + char Checksum; +} LINMessage; + +typedef struct { + char command; /* command to execute */ + LINMessage mess; +} LIN_mail_t; + +/***** FUNCTIONS *******/ +void read_Full_Message(char Port_); // Reading Buffer from LIN Line [LIN Line Depends on the Port] +void send_Full_Message(char ID_Field, char Data[8], char Checksum, char Port); // Sending a Full Message to the LIN Line +void send_Header_Message(char ID_Field,int Port); // Sending a Header Message to the LIN Line +void send_Break(int Port); // Sending a Break Command to the LIN Line +void LoadPCMail(char comm, char *mess); // Puts a mail in the stuck +void messageFromPC(MODSERIAL_IRQ_INFO *q); // Gets a Message from the PC and Calls the Load Mail [0] +int ComPC_Write(char *mess); // Send a Message Back to the PC +void TLogSTR(char *Tstr); // Get the Time signature +void GetConfig(void); // Read Configuration Data +void Initialize(void); // Initialize MBED after Reboot +void Read_Diagnostics(char *mess); // Return a Message with Diagnostics +void Flash_Messages(int Port); // Discards all messages in LIN Port +void Reset_UUT(void); // Reset The UUT +/**** Watchdog ****/ +Watchdog wd; +extern "C" void mbed_reset(); +/**** End of Watchdog ****/ + +/**** Serial Communication PC ****/ +DigitalOut ledPC(LED1); +DigitalOut Reboot_Pin(p29); +MODSERIAL pc(USBTX, USBRX, TxBuffer,RxBuffer); // The USB as pc +char InitialMessage[50]; // The initial Message when the MBED turns on +bool LOGPC; // Logging information from the PC +int PC_Baudrate=115200; // The Baudrate of the PC +double TxBufferWait; // The Time to Wait +char ChEnd; // The termination character of the PC Serial Communication +Mail<PC_mail_t, PC_MaxMailElements> PC_mail; // The PC_mail +int PCMailNum = 0; // Initialize to zero +time_t ctTime; +struct tm * timeinfo; + +int LIN_Wait_Echo = 0; +int LIN_Wait_Response = 0; +bool Wait_Echo_Response = false; + +/**** LIN 1 ****/ +DigitalOut ledUART1(LED2); +MODSERIAL LIN1(p13, p14, TxBuffer,RxBuffer); // The UART1 as LIN1 +int LIN1Baud = 19200; + +/**** LIN 2 ****/ +MODSERIAL LIN2(p28, p27, TxBuffer,RxBuffer); // The UART2 as LIN2 +DigitalOut ledUART2(LED3); +int LIN2Baud = 19200; + +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 + switch(mail->message[0]) + { + case 'R': // Reboot the Microcontroller/Updates the Firmware + 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 'T': // Set the Current Time + 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 'L': // LIN Line + LINMessage LINMess; + unsigned int temp_ID; + unsigned int temp_Data[8]; + unsigned int temp_Checksum; + switch (mail->message[1]) + { + case '1': //LIN 1 + ledUART1 = true; + switch (mail->message[2]) + { + case 'W': //Write Full Message to LIN1 + sscanf(&mail->message[3],"%u;%u;%u;%u;%u;%u;%u;%u;%u;%u;",&temp_ID,&temp_Data[0],&temp_Data[1],&temp_Data[2],&temp_Data[3],&temp_Data[4],&temp_Data[5],&temp_Data[6],&temp_Data[7],&temp_Checksum); + LINMess.IDfield = temp_ID; + LINMess.Checksum = temp_Checksum; + for(int k=0; k<8; k++){ LINMess.Data[k] = temp_Data[k]; } + send_Full_Message(LINMess.IDfield, LINMess.Data, LINMess.Checksum, 1); // Maybe Disable interrupts here + if(Wait_Echo_Response) { wait_ms(LIN_Wait_Echo); read_Full_Message(1);} + ledUART1 = false; + break; + case 'H': //Write Remote Header to LIN1 + sscanf(&mail->message[3],"%u;",&temp_ID); + LINMess.IDfield = temp_ID; + send_Header_Message(LINMess.IDfield,1); + if(Wait_Echo_Response) { wait_ms(LIN_Wait_Echo); wait_ms(LIN_Wait_Response); read_Full_Message(1); } + ledUART1 = false; + break; + case 'R': //Read Data from LIN1 + read_Full_Message(1); + ledUART1 = false; + break; + case 'T': //Reset + Reset_UUT(); + ledUART1 = false; + LoadPCMail(99,"Reset_OK"); + break; + default: + ledUART1 = false; + break; + } + break; + case '2': //LIN 2 + ledUART2 = true; + switch (mail->message[2]) + { + + case 'W': //Write Full Message to LIN2 + sscanf(&mail->message[3],"%u;%u;%u;%u;%u;%u;%u;%u;%u;%u;",&temp_ID,&temp_Data[0],&temp_Data[1],&temp_Data[2],&temp_Data[3],&temp_Data[4],&temp_Data[5],&temp_Data[6],&temp_Data[7],&temp_Checksum); + LINMess.IDfield = temp_ID; + LINMess.Checksum = temp_Checksum; + for(int k=0; k<8; k++){ LINMess.Data[k] = temp_Data[k]; } + send_Full_Message(LINMess.IDfield, LINMess.Data, LINMess.Checksum, 2); // Maybe Disable interrupts here + if(Wait_Echo_Response) { wait_ms(LIN_Wait_Echo); read_Full_Message(2); } + ledUART2 = false; + break; + case 'H': //Write Remote Header to LIN2 + sscanf(&mail->message[3],"%u;",&temp_ID); + LINMess.IDfield = temp_ID; + send_Header_Message(LINMess.IDfield,2); + if(Wait_Echo_Response) { wait_ms(LIN_Wait_Echo); wait_ms(LIN_Wait_Response); read_Full_Message(2); } + ledUART2 = false; + break; + case 'R': //Read Data from LIN2 + read_Full_Message(2); + ledUART2 = false; + break; + default: + ledUART2 = false; + break; + } + break; + case 'F': //Flash the Buffer of all the LINs + { + ledUART1 = true; + ledUART2 = true; + Flash_Messages(1); + Flash_Messages(2); + ledUART1 = false; + ledUART2 = false; + LoadPCMail(50,"Flash_OK"); + break; + } + default: + 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 50: //Send to PC a Message from LINs + snprintf(mess,MessSizePC,"LINs:%s\r\n",mail->message); + break; + case 51: //Send to PC a Message from LIN1 + snprintf(mess,MessSizePC,"LIN1:%s\r\n",mail->message); + break; + case 52: //Send to PC a Message from LIN2 + snprintf(mess,MessSizePC,"LIN2:%s\r\n",mail->message); + break; + case 99: //Information from the Micro + snprintf(mess,MessSizePC,"MBED:%s\r\n",mail->message); + break; + default: + break; + } + PC_mail.free(mail); + PCMailNum--; + if(PCMailNum==0){ledPC=false;} else {ledPC=true;} + ComPC_Write(mess); + } + } +} + +/**** End of Serial Communication PC ****/ + +int main() +{ + Initialize(); + PCMailNum=0; + + Thread ComPC_thread (ComPC_thread_proc,NULL,osPriorityBelowNormal); // Start a ComPC Thread! + pc.attach(&messageFromPC, MODSERIAL::RxAutoDetect); // Attach an Interrupt to the TX Line + pc.autoDetectChar(ChEnd); // Autodetect the End Characted + + LoadPCMail(99,InitialMessage); + + // ************ WD ************* + wd.WatchdogCausedReset(); + wd.Configure(5.0); + // ************ WD_end ********* + + while(true) + { + wd.Service(); + Thread::wait(500); // what is this doing here? + } +} + +void GetConfig(void) +{ + +#define CfgNumParam 9 +#define CfgSizeParam 50 + + pc.format(8,Serial::Even,1); // Configuration for the Format of the data for the PC + pc.baud(115200); // Configuration for the Baudrate of the communication to the PC [default] + ConfigFile cfg; + LocalFileSystem local("local"); + + int i; + char value[CfgNumParam][CfgSizeParam]; + char CfgK[CfgNumParam][CfgSizeParam]= {"InitialMessage","BaudRate","ChEnd","LOGPC","LIN1Baud","LIN2Baud","LINWaitResp_ms","LINWaitProd_ms","Wait_Response"}; + 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]); + PC_Baudrate=atoi(value[1]); + ChEnd=(char)atoi(value[2]); + LOGPC=(bool)atoi(value[3]); + + LIN1Baud=atoi(value[4]); + LIN2Baud=atoi(value[5]); + + LIN_Wait_Echo = atoi(value[6]); + LIN_Wait_Response = atoi(value[7]); + + Wait_Echo_Response = (bool)atoi(value[8]); + + TxBufferWait= 10000*MessSizePC/PC_Baudrate; + while(!pc.txBufferEmpty()) { Thread::wait(100); }; +} + +void Initialize(void) +{ + Reboot_Pin = false; + GetConfig(); + pc.baud(PC_Baudrate); pc.format(8,Serial::Even,1); // Configuration for PC + LIN1.baud(LIN1Baud); LIN1.format(8,Serial::None,1); // Configuration for LIN1 + LIN2.baud(LIN2Baud); LIN2.format(8,Serial::None,1); // Configuration for LIN2 +} + +void TLogSTR(char *Tstr) // Put to Tstr the Time information as a character +{ + 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) //Working in Parallel to Load a message to the stack +{ + while(PCMailNum>=PC_MaxMailElements) { Thread::wait(PCMessWait); } // Wait if there are many other things in Queue + 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) //Received Message from PC and Put it in stack with a Value of 0 +{ + 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) // Send a Message Back to the PC +{ + int i=strlen(mess); + if(i>0) { + while((TxBuffer-pc.txBufferGetCount())<i) { Thread::wait(TxBufferWait); } // Wait until the Buffer is ready + return pc.printf(mess); + } + return 0; // return code if i negative +} +void Convert_Character_to_Number_to_String(char* temp_string, char Character) +{ + unsigned int Temp_Number = Character; + sprintf (temp_string,"%u",Temp_Number); + temp_string[3]=0; +} +void read_Full_Message(char Port_) // Maybe Disable Interrupts Here +{ + char tmp[MessSizeLIN]; + char digit[4]; + char uniq_char; + int index = 0; + switch(Port_) // Read the Buffer from LIN Port AND Send a Message to the PC + { + case 1: // LIN1 + index = 0; + while(LIN1.readable()==1) + { + uniq_char = LIN1.getc(); + Convert_Character_to_Number_to_String(digit,uniq_char); + for(int j=0; j<strlen(digit);j++) { tmp[index++] = digit[j]; } + tmp[index++]=';'; + } + tmp[index]=0; + LoadPCMail(51,tmp); + break; + case 2: // LIN2 + index = 0; + while(LIN2.readable()==1) + { + uniq_char = LIN2.getc(); + Convert_Character_to_Number_to_String(digit,uniq_char); + for(int j=0; j<strlen(digit);j++) { tmp[index++] = digit[j]; } + tmp[index++]=';'; + } + tmp[index]=0; + LoadPCMail(52,tmp); + break; + default: + break; + } + +} + + +void send_Full_Message(char ID_Field_, char Data_[8], char Checksum_, char Port_) // Maybe Disable interrupts here +{ + switch(Port_) + { + case 1: // LIN1 + send_Break(Port_); //send 15bit of Zero Break; + LIN1.putc(0x55); //send 0x55 Synchronisation Character + LIN1.putc(ID_Field_); //send ID field + for(int k=0;k<8;k++) {LIN1.putc(Data_[k]);} //send Data + LIN1.putc(Checksum_); //send Checksum + break; + case 2: // LIN2 + send_Break(Port_); //send 15bit of Zero Break; + LIN2.putc(0x55); //send 0x55 Synchronisation Character + LIN2.putc(ID_Field_); //send ID field + for(int k=0;k<8;k++) {LIN2.putc(Data_[k]);} //send Data + LIN2.putc(Checksum_); //send Checksum + break; + default: + break; + } +} + +void send_Header_Message(char ID_Field,int Port) // Maybe Disable interrupts here +{ + switch(Port) + { + case 1: // LIN1 + send_Break(Port); //send 15bit of Zero Break; + LIN1.putc(0x55); //send 0x55 Synchronisation Character + LIN1.putc(ID_Field); //send ID field + break; + case 2: // LIN2 + send_Break(Port); //send 15bit of Zero Break; + LIN2.putc(0x55); //send 0x55 Synchronisation Character + LIN2.putc(ID_Field); //send ID field + break; + default: + break; + } +} + +void send_Break(int Port) +{ + int time_BREAK = 0; + switch(Port) + { + case 1: // LIN1 + time_BREAK = 1000000/LIN1Baud; // time in us + LPC_UART1->LCR |= 0x40; + wait_us(time_BREAK*15); + LPC_UART1->LCR &= ~(0x40); + break; + case 2: // LIN2 + time_BREAK = 1000000/LIN2Baud; // time in us + LPC_UART2->LCR |= 0x40; + wait_us(time_BREAK*15); + LPC_UART2->LCR &= ~(0x40); + break; + default: + break; + } +} +void Flash_Messages(int Port_) // Flashes all the Messages from the Buffer on LINs +{ + if(Port_==1) // Read the Buffer from LIN Port AND Send a Message to the PC + { + while(LIN1.readable()==1) { LIN1.getc();} + } + else if(Port_==2) + { + while(LIN2.readable()==1) { LIN2.getc();} + } +} + +void Reset_UUT(void) +{ + Reboot_Pin = true; + wait_ms(200); + Reboot_Pin = false; + } \ No newline at end of file
diff -r 000000000000 -r 939d1f478fb5 mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Mon Feb 22 17:12:27 2021 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#5713cbbdb706
diff -r 000000000000 -r 939d1f478fb5 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Feb 22 17:12:27 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file