breakLIN_RacEI

Dependencies:   mbed mbed-rtos Watchdog MODSERIAL ConfigFile

Files at this revision

API Documentation at this revision

Comitter:
JavierGC
Date:
Mon Feb 22 17:12:27 2021 +0000
Commit message:
breakLIN_RacEI

Changed in this revision

ConfigFile.lib Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.lib Show annotated file Show diff for this revision Revisions of this file
Watchdog.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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