Space / Mbed 2 deprecated SC-MIMA-Protocol

Dependencies:   mbed

Revision:
0:295db98f7ea0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jun 01 11:17:04 2022 +0000
@@ -0,0 +1,536 @@
+#include "mbed.h"
+#include <math.h>
+
+/*----------------------------
+   ---------- INFO ----------- */
+
+// DORA SETTING to-do-6 giugno !!!
+// master-slave: slave MIMA comunica con DORA con collegamento UART (tx, rx, gnd)
+// PC S/C sends packets to DORA -> MIMA (STM32) -> PC
+
+//  ------                  ------------
+// | MIMA | ---- DORA ---- | SPACE/CRAFT |
+//  ------                  ------------
+
+/*----------------------------
+   ---------- DEFINE ----------- */
+// definisce dimensione pacchetto inviato da pc
+// telecommand: 15 bit + 1 di controllo
+#define PACKETSIZE 20   // lunghezza massima della stringa trasmissibile prima di interrupt
+#define PACKET 15   // 15 bit, 1 di parità di controllo
+#define PACKET_CHECKED 16 // COMMAND IDENTIFIER + TAG + PAYLOAD + PARITY CHECK
+#define IDENTIFIER 5
+#define TAG 2
+#define PAYLOAD 8
+#define CMD_NUM 32 
+#define OPTION_1 912 // 57*16
+#define OPTION_2 90608 // 5663*16
+#define tb 7 // bit sampling period
+
+/*----------------------------
+   ---------- INIT ----------- */
+// comunicazioni seriali DORA
+
+// PIN OCCUPATI: D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10
+
+// ************** CN7 ********************
+Serial SC(USBTX, USBRX);            // A4 TX, A6 RX - DATA OUT, DATA IN
+DigitalOut GATE_WRITE_SC(PB_0);     // A3
+DigitalOut GATE_READ_SC(PA_4);      // A2
+DigitalOut DATA_CLOCK_OUT_SC(PA_1); // A1
+
+// ************** CN10 *******************
+Serial MIMA(PB_6, PA_10); // IN - OUT               // TX D1, RX D0 -> DATA_OUT, DATA_IN -> D0 e D1 non vanno bene! Risorse già occupate
+// PA_8, PA_9, PC_1, PC_0, PA_10, PB_3 // RX, TX
+DigitalOut GATE_WRITE_MIMA(PA_9);       // D8
+DigitalOut GATE_READ_MIMA(PC_7);        // D9
+DigitalOut DATA_CLOCK_OUT_MIMA(PB_6);   // D10
+
+// DATA_OUT_CLOCK.write(0) -> wait_ms(7) -> DATA_OUT_CLOCK.write(0) -> wait_ms(7)
+
+// informazioni circa il pacchetto trasmesso
+volatile int nIndex;    // indice del pacchetto per lo "spacchettamento"
+char getPacket[PACKETSIZE]; // buffer - pacchetto inviato di dimensione max PACKETSIZE
+char PacketChecked[PACKET_CHECKED]; // lato Space/Craft
+char TLM[OPTION_1]; // lato MIMA per check
+char TLM_SD[OPTION_2]; // lato MIMA per check
+char TLM_SC[OPTION_1]; // lato space/craft per check
+char TLM_SD_SC[OPTION_2]; // lato space/craft per check
+
+volatile int LEN;   // numero di bit da ricevere per ricezione corretta 
+volatile int commandId;
+volatile int size;
+volatile unsigned char data;    // in arrivo da MIMA per telemetria
+
+int base = 2;   // base per l'esponenziale (conversione binary to decimal)
+int CMD[CMD_NUM];   // CMD in decimale
+//const char *CODE[] = {};  // LISTA comandi 
+
+volatile int option_1 = 0;   // default
+volatile int option_2 = 0;
+
+/*----------------------------
+   ---------- SETUP ----------- */
+void CMD_REF(void);
+void init(void);
+void RxTelecommand(void);
+void TxTelecommand(void);
+void RxTelemetry(void);
+void TxTelemetry(void);
+
+/*----------------------------
+   ---------- MAIN ----------- */
+int main()
+{
+    SC.baud(115200);
+    MIMA.baud(115200);
+    
+    // Setup
+    GATE_READ_MIMA = 1;
+    GATE_WRITE_MIMA = 1;
+    
+    GATE_READ_SC = 1;
+    GATE_WRITE_SC = 1;
+    
+    SC.printf("******* Starting... *******\n\r");
+
+    // interrupt quando arriva stringa da PC (space/craft)
+    SC.attach(&RxTelecommand, Serial::RxIrq);
+    // interript quando invia stringa a MIMA
+    MIMA.attach(&TxTelecommand, Serial::TxIrq);
+    // interrupt quando riceve stringa da MIMA
+    MIMA.attach(&RxTelemetry, Serial::RxIrq);
+    // interrupt quando invia stringa a SC
+    SC.attach(&TxTelemetry, Serial::TxIrq);
+
+}
+
+
+
+// *********************************************************************
+
+
+
+/*----------------------------
+   -------- FUNCTIONS --------- */
+void CMD_REF(void)
+{
+    for (int i = 0; i < CMD_NUM; i++)
+    {
+        CMD[i] = i;
+    }
+}
+
+// inizializzazione pacchetto TBC
+void init(void)
+{
+    // reset pacchetto
+    nIndex = 0;
+    for (nIndex = 0; nIndex < PACKETSIZE; nIndex++)
+    {
+        getPacket[nIndex] = '\0';
+    }
+}
+
+// DORA riceve telecomando da MIMA
+void RxTelecommand(void)
+{
+    init(); // clear the buffer
+    CMD_REF();  // carica vettore dei comandi
+
+    while (SC.readable())   // finché sulla porta USB arrivano dati, esegui
+    {
+        SC.gets(getPacket, sizeof(getPacket));  // leggi la stringa in ingresso
+        LEN = strlen(getPacket) - 2;    // calcola la sua lunghezza ignorando i tag \r\n
+
+        if (LEN != PACKET)
+        {
+            // controlla se la stringa ricevuta è consona (16 bit)
+            SC.printf("> Bit number: %i is not equal to 15 - ERROR\n\r", LEN);  // diagnostica        
+        }
+        else
+        {
+            for (int n = 0; n < LEN; n++)
+            {
+                PacketChecked[n] = getPacket[n];    // riempi il nuovo array
+            }
+
+            // ***CONTROLLO DEI BIT - LSB: EVEN/ODD ***
+            int ones = 0;
+            int check = 0;
+            while (check < PACKET)
+            {
+                if (getPacket[check] == '1')
+                {
+                    ones++;
+                }
+
+                check++;
+            }
+
+            char newItem;
+
+            if (ones % 2 == 0)
+            {
+                newItem = '0';  // If the number of ones in[B0÷B14] bits is even (making the total number of ones even)
+            }
+            else
+            {
+                newItem = '1';  // If the number of ones in[B0÷B14] bits is odd (making the total number of ones even)
+            }
+
+            int nPacket = PACKET + 1;
+            // shift elements 
+            for (int i = nPacket - 1; i >= PACKET_CHECKED; i--)
+            {
+                PacketChecked[i] = PacketChecked[i - 1];
+            }
+
+            // insert LSB
+            PacketChecked[PACKET_CHECKED - 1] = newItem;
+
+            SC.printf("> Send: ");
+            for (int z = 0; z < PACKET_CHECKED; z++)
+            {
+                SC.printf("%c", PacketChecked[z]);
+            }
+
+            SC.printf("\n\r");
+
+            // ************DIAGNOSTICA ************
+            // un telecommand è formato da 16 bit. i primi 5 sono identificativi,
+            // poi ho due bit che mi specificano se i dati in arrivo sono una o più parole,
+            // dopodiché ho un payload da 8 bit e per concludere ho LSB (parity bit)
+            // MSB IIII TT PPPPPPPP PC
+
+            // ***COMMAND IDENTIFIER ***
+            int CMDIndex = 0;   // puntatore dell'identificativo
+            commandId = 0;
+            // trasformo l'identificatore in numero
+            while (CMDIndex < IDENTIFIER)
+            {
+                if (PacketChecked[CMDIndex] == '1')
+                {
+                    int raise = IDENTIFIER - 1 - CMDIndex;
+                    commandId += pow((float) base, (float) raise);
+                }
+                else
+                {
+                    commandId += 0;
+                }
+
+                CMDIndex++;
+            }
+
+            // scorro la lista di comandi disponibli e verifico se il comando trasmesso rientra
+            // nella lista, altrimenti finisco in uno dei 3 SPARE
+            int k = 0;
+            int isElementPresent = 0;
+            while (k < CMD_NUM)
+            {
+                if (commandId == CMD[k])
+                {
+                    isElementPresent = 1;
+                    SC.printf("> Telcommand sent belgons to MIMA command list: CMD %i\n\r", k);
+                    break;
+
+                }
+
+                k++;
+            }
+
+            if (isElementPresent == '0')
+            {
+                SC.printf("Telecommand sent doesn't exist\n\r");
+            }
+
+            // ***TAG ***
+            int B5 = PacketChecked[5];
+            int B6 = PacketChecked[6];
+
+            if (B5 == '0' && B6 == '0')
+            {
+                // Single word telemetry
+                SC.printf("Single word telemetry\n\r");
+            }
+            else if (B5 == '0' && B6 == '1')
+            {
+                // Multiple words telemetry (1st word)
+                SC.printf("Multiple words telemetry (1st word)\n\r");
+            }
+            else if (B5 == '1' && B6 == '0')
+            {
+                // Multiple words telemetry (2nd word)
+                SC.printf("Multiple words telemetry (2nd word)\n\r");
+            }
+            else
+            {
+                // Not used
+                SC.printf("NOT USED\n\r");
+            }
+
+            // ***PAYLOAD ***
+            SC.printf("> Payload: ");
+            for (int IndexPayload = 7; IndexPayload <= PACKET; IndexPayload++)
+            {
+                SC.printf("%c", PacketChecked[IndexPayload]);
+            }
+
+            SC.printf("\n\r");
+            int B7 = PacketChecked[7];
+            int B9 = PacketChecked[9];
+            int B11 = PacketChecked[11];
+
+            // ******************************
+            // ********CHECK CMD01 *********
+            // ******************************
+            if (PacketChecked[11] == '0' &&
+                PacketChecked[12] == '0' &&
+                PacketChecked[13] == '0' &&
+                PacketChecked[14] == '1')
+            {
+                SC.printf("> Setting MIMA... Sleeping mode\n\r");
+            }
+            else if (PacketChecked[11] == '0' &&
+                PacketChecked[12] == '0' &&
+                PacketChecked[13] == '1' &&
+                PacketChecked[14] == '0')
+            {
+                SC.printf("> Setting MIMA... Awake mode\n\r");
+            }
+            else if (PacketChecked[11] == '0' &&
+                PacketChecked[12] == '0' &&
+                PacketChecked[13] == '1' &&
+                PacketChecked[14] == '1')
+            {
+                SC.printf("> Setting MIMA... Calibration mode\n\r");
+            }
+            else if (PacketChecked[11] == '0' &&
+                PacketChecked[12] == '1' &&
+                PacketChecked[13] == '0' &&
+                PacketChecked[14] == '0')
+            {
+                SC.printf("> Setting MIMA... Observation mode\n\r");
+            }
+            else if (PacketChecked[11] == '0' &&
+                PacketChecked[12] == '1' &&
+                PacketChecked[13] == '0' &&
+                PacketChecked[14] == '1')
+            {
+                SC.printf("> Setting MIMA... Auto-test mode\n\r");
+            }
+            else if (PacketChecked[11] == '0' &&
+                PacketChecked[12] == '1' &&
+                PacketChecked[13] == '1' &&
+                PacketChecked[14] == '0')
+            {
+                SC.printf("> Setting MIMA... Full testing mode\n\r");
+            }
+
+            // IR sensor thermal loop
+            if (B7 == '1')
+            {
+                SC.printf("> IR sensor thermal loop...\n\r");
+                SC.printf("IRT1 telemetry: feedback signal in the thermal control loop (default). IRT2 only for monitoring\n\r");
+            }
+            else
+            {
+                SC.printf("> IR sensor thermal loop...\n\r");
+                SC.printf("IRT2 telemetry: feedback signal in the thermal control. IRT1 only for monitoring\n\r");
+            }
+
+            // Laser Diode thermal loop
+            if (B9 == '1')
+            {
+                SC.printf("> Laser Diode thermal loop...\n\r");
+                SC.printf("LDT1 telemetry: feedback signal in the thermal control loop (default). LDT2 only for monitoring\n\r");
+            }
+            else
+            {
+                SC.printf("> Laser Diode thermal loop...\n\r");
+                SC.printf("LDT2 telemetry: feedback signal in the thermal control. LDT1 only for monitoring\n\r");
+
+            }
+
+            // BlackBody thermal loop
+            if (B11 == '1')
+            {
+                SC.printf("> BlackBody thermal loop...\n\r");
+                SC.printf("BBT1 telemetry: feedback signal in the thermal control loop (default). BBT2 only for monitoring\n\r");
+            }
+            else
+            {
+                SC.printf("> BlackBody thermal loop...\n\r");
+                SC.printf("BBT2 telemetry: feedback signal in the thermal control. BBT1 only for monitoring\n\r");
+            }
+
+            //***********FINE DIAGNOSTICA PACCHETTO***********
+        }   
+    }   
+
+}   
+
+// DORA trasmette telecomando a MIMA
+void TxTelecommand(void)
+{
+
+    while (MIMA.writeable())
+    {
+        GATE_WRITE_MIMA = 0;
+        
+        DATA_CLOCK_OUT_MIMA = 1;
+        wait_ms(7);
+            
+        for (int i = 0; i < PACKET_CHECKED + 1; i++)
+        {
+            DATA_CLOCK_OUT_MIMA = 0;
+            // The data are read on the falling-edge of the DATA_CLOCK_OUT signal
+            MIMA.putc(PacketChecked[i]);
+            wait_ms(7);
+            DATA_CLOCK_OUT_MIMA = 1;
+            wait_ms(7);
+        }
+    }
+    
+    GATE_WRITE_MIMA = 1;
+    
+}
+
+// DORA riceve telemetrie/telemetrie+scientific data da MIMA
+void RxTelemetry(void)
+{
+    while (MIMA.readable()) // finché la seriale sul MIMA manda caratteri
+    {
+        GATE_READ_MIMA = 0;
+        
+        // check del payload per scelta del buffer
+        // 00000000 -> Option 1: transfer all Housekeeping and Status telemetries (from TLM00 to TLM56)
+        // 11111111 -> Option 2: transfer telemetries and scientific data packets (from TLM00 to TLM5662)
+
+        int j = 7;
+        while (j < PACKET_CHECKED)
+        {
+            if (PacketChecked[j] == '0')
+            {
+                j++;
+            }
+            else
+            {
+                option_1 = 1;
+                break;
+            }
+        }
+
+        int k = 7;
+        while (k < PACKET_CHECKED)
+        {
+            if (PacketChecked[k] == '1')
+            {
+                k++;
+            }
+            else
+            {
+                option_2 = 1;
+                break;
+            }
+        }
+
+        if (commandId == 5) // TLMODE
+        {
+            if (option_1 == 0)
+            {
+                size = 0;   // reset 
+
+                TLM[0] = '\0';
+                SC.printf("Receiving 57 words...\n\r");
+
+                while (size < OPTION_1)
+                {
+                    DATA_CLOCK_OUT_MIMA = 1;
+                    wait_ms(tb/2);
+                    DATA_CLOCK_OUT_MIMA = 0;
+                    data = MIMA.getc(); // prendi carattere in arrivo
+                    TLM[size] = data;
+                    size++;
+                    wait_ms(tb/2);
+                    
+                    if ((size+1) == OPTION_1)
+                    {
+                        SC.printf("%s", TLM);
+                        size = 0;
+                        break;
+                    }
+                }
+            }
+            else if (option_2 == 0)
+            {
+                size = 0;
+
+                TLM_SD[0] = '\0';
+                SC.printf("Receiving 5663 words...\n\r");
+
+                while (size < OPTION_2)
+                {
+                    DATA_CLOCK_OUT_MIMA = 1;
+                    wait_ms(tb/2);
+                    DATA_CLOCK_OUT_MIMA = 0;
+                    data = MIMA.getc();
+                    TLM_SD[size] = data;
+                    size++;
+                    wait_ms(tb/2);
+                    
+                    
+                    if ((size+1) == OPTION_2)
+                    {
+                        SC.printf("%s", TLM_SD);
+                        size = 0;
+                        break;
+                    }
+                }
+
+            }
+        }
+        
+    GATE_READ_MIMA = 1;
+    
+    }
+}
+
+
+// DORA trasmette dati verso Space/craft
+void TxTelemetry(void)
+{
+    while(SC.writeable())
+    {
+        GATE_WRITE_SC = 0;
+        
+        DATA_CLOCK_OUT_SC = 1;
+        wait_ms(tb/2);
+        
+        // The data are read on the falling-edge of the DATA_CLOCK_OUT signal
+        if (option_1 == 0) 
+        {
+            for (int i = 0; i < OPTION_1; i++) 
+            {
+                DATA_CLOCK_OUT_SC = 0;
+                SC.putc(TLM[i]);
+                wait_ms(tb/2);
+                DATA_CLOCK_OUT_SC = 1;
+                wait_ms(tb/2);
+            }
+        } else if (option_2 == 0) 
+        {
+            for (int i = 0; i < OPTION_2; i++) 
+            {
+                DATA_CLOCK_OUT_SC = 0;
+                SC.putc(TLM_SD[i]);
+                wait_ms(tb/2);
+                DATA_CLOCK_OUT_SC = 1;
+                wait_ms(tb/2);
+            }
+        }
+        
+        GATE_WRITE_SC = 1;
+    }
+    
+}