Space / Mbed 2 deprecated DORA_lv

Dependencies:   mbed

main.cpp

Committer:
paologiorgio
Date:
2022-06-30
Revision:
0:8f7c961a5966
Child:
1:00cee5df0f76

File content as of revision 0:8f7c961a5966:

// Librerie
#include "mbed.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "tlc_tlm_list.h"

// Macros
#define cmd_num 32
#define buf_max_size 512
#define tlc_to_tx 16
#define tlm_size 16
#define tlm_hsk_size 912
#define tlm_hsk_sd_size 90608
#define identifier_field 5
#define max31865_buf_size 13
#define channel_size 5
#define size 1

// Serial e periferiche 
Serial spacecraft(USBTX, USBRX);
Serial mima(PC_4, PC_5);
Serial max31865(PA_9, PA_10);

// Buffer
volatile int sizeBuffer;
int CMD[cmd_num];
char TLM[tlm_size];
char TLM_HSK[tlm_hsk_size];
char TLM_HSK_SD[tlm_hsk_sd_size];
char tlc_rx[buf_max_size];
char caRxPacket[max31865_buf_size];
char tempCH1[channel_size];
char tempCH2[channel_size];
char CH1_to_string[2*channel_size];
char CH2_to_string[2*channel_size];

// L16 Actuonix - Relay (spare commands)
PwmOut M1 (PA_6);
PwmOut M2 (PA_8);
DigitalOut Relay5V (PA_7);
DigitalOut Relay12V (PB_4);
DigitalOut Relay24V (PB_5);
DigitalOut Relay15_15_5V (PB_10);
float offset = 0.0f;

// Timer
Timer timer;
float TIMEOUT = 10, tTimeStart, tTimeStop, tTimeRead;

// Vars definitions
int temperature_flag;
volatile int payload_to_dec;
volatile int tlmode_option_1;
volatile int tlmode_option_2;
volatile int commandId;
volatile int nRxCharCount;
volatile int tlc_rx_length;
volatile int checkZerosIndex, checkOnesIndex;
volatile float CH1, CH2;
volatile int increment_read;
volatile int indexJ, indexT;

// Functions
void RxTelecommand();
void TxTelecommand();
void RxTelemetry();
void TxTelemetry();
void TxTemperature();
void RxTemperature();
void SpareCommand(int command);
void printMyArray(Telecommand *myArray);
void clearBuffer(char *arr, int arrLen);
void checksum_tlc(Telecommand *toCheck_tlc);
void checksum_tlm(Telemetry *toCheck_tlm);
int BinToDec(int t, int dim, char *a);

// Main
int main()
{
    // Baudrate
    spacecraft.baud(115200);
    mima.baud(9600);
    max31865.baud(115200);

    // Interrupts
    spacecraft.attach(&RxTelecommand, Serial::RxIrq);
    //max31865.attach(&RxTemperature, Serial::RxIrq);
    
    while (true)
    {
        /**********************************************************************
                        RICEZIONE DEI DATI DI TEMPERATURA
        **********************************************************************/
        
        if ((commandId == 0) && (payload_to_dec == 32) && (temperature_flag == 1))
        {
            TxTemperature();
            increment_read++;

            if (increment_read == 40) 
            {
                temperature_flag = 0;
            }
        }
        
        /**********************************************************************
                         RICEZIONE DI TELEMETRIE DA MIMA
        **********************************************************************/

        // Scrittura del telecomando
        cmd00[(size-1)].PAYLOAD = "00000000"; 
        if (cmd00[(size-1)].PAYLOAD != '\0')
        {
            checksum_tlc(&cmd00[(size-1)]);   
            printMyArray(&cmd00[(size-1)]);
        }                   
        
        // In arrivo da periferica mima
        sizeBuffer = 0; // reset 
        clearBuffer(TLM, sizeof(TLM)/sizeof(TLM[0]));
        clearBuffer(TLM_HSK, sizeof(TLM_HSK)/sizeof(TLM_HSK[0]));
        clearBuffer(TLM_HSK_SD, sizeof(TLM_HSK_SD)/sizeof(TLM_HSK_SD[0]));

        timer.start();
        tTimeStart = timer.read(); 
        tTimeRead = tTimeStart;
        
        // Interrupt: entra nella routine quando riceve dalla seriale 
        mima.attach(&RxTelemetry, Serial::RxIrq);

        // Diagnostica del pacchetto ricevuto
        if (commandId == 5)
        {
            /* Ricezione di tutte le telemetrie. 57 parole da 16 bit contenenti
            tutte le telemetrie di tipo HOUSEKEEPING. */
            if (tlmode_option_1 == 0)
            {
                while ((sizeBuffer < tlm_hsk_size) && ((tTimeRead - tTimeStart) < TIMEOUT))
                {
                    tTimeRead = timer.read();
                }

                timer.stop();

                if ((tTimeRead - tTimeStart) >= TIMEOUT)
                {
                    sizeBuffer = 0;
                    clearBuffer(TLM_HSK, tlm_hsk_size);
                }
                else
                {
                    TxTelemetry();
                }
            }
            /* Ricezione di tutte le telemetrie e dati scientifici
            5663 parole da 16 bit così strutturate: 57 HSKP data packets,
            5606 di scientific data dell'interferometro su MIMA, */
            else if (tlmode_option_2 == 0)
            {
                while ((sizeBuffer < tlm_hsk_sd_size) && ((tTimeRead - tTimeStart) < TIMEOUT))
                {
                    tTimeRead = timer.read();
                }

                timer.stop();

                if ((tTimeRead - tTimeStart) >= TIMEOUT)
                {
                    sizeBuffer = 0;
                    clearBuffer(TLM_HSK_SD, tlm_hsk_sd_size);
                }
                else
                {
                    TxTelemetry();
                }
            }
        }
        /* Ricezione di un dato di telemetria da 16 bit. */
        else    
        {
            while ((sizeBuffer < tlm_size) && ((tTimeRead - tTimeStart) < TIMEOUT))
            {
                tTimeRead = timer.read();
            }

            timer.stop();

            if ((tTimeRead - tTimeStart) >= TIMEOUT)
            {
                sizeBuffer = 0;
                clearBuffer(TLM, tlm_size);
            }
            else
            {
                TxTelemetry();
            }
        }
    }
}


/* Gestione delle routine di ricezione e trasmissione del driver */

// DORA riceve telecomando da Space/craft
void RxTelecommand()
{
    while (spacecraft.readable())
    {
        clearBuffer(tlc_rx, sizeof(tlc_rx) / sizeof(tlc_rx[0]));
        spacecraft.gets(tlc_rx, sizeof(tlc_rx));
        tlc_rx_length = strlen(tlc_rx) - 2; // rimozione tag di NR

        if (tlc_rx_length == tlc_to_tx)
        {
            int bit_B0 = 0, bit_B7 = 7, k = 0; 
            commandId = 0;  // init
            payload_to_dec = 0; // init

            commandId = BinToDec(bit_B0, identifier_field, tlc_rx);
            payload_to_dec = BinToDec(bit_B7, (tlc_to_tx - 1), tlc_rx);

            k = commandId;
            
            if (k == 2 || k == 15 || k == 30)
            {
                // Spare
                break;
            }

            /* Gestiione della lettura della temperatura */
            else if ((k == 0) && (tlc_rx[5] == '0') && (tlc_rx[6] == '0') && (payload_to_dec == 32))
            {
                temperature_flag = 1;
                break;
            }

            /* Gestione delle perifieriche HW: relay, attuatori, alimentazione */
            else if ((k == 0) && (tlc_rx[5] == '0') && (tlc_rx[6] == '0'))
            {
                //SpareCommand(payload_to_dec);
                break;
            }
            else if (k == 5)
            {
            /* Istruzione che serve a scorrere il Payload e a settare un determinato flag
            per consentire a DORA di aprire o meno determinati canali di comunicazione
            (buffer da riempire). */
            checkZerosIndex = bit_B7;

            while (checkZerosIndex < tlc_to_tx)
            {
                if (tlc_rx[checkZerosIndex] == '0')
                {
                    tlmode_option_1 = 0;
                    checkZerosIndex++;
                }
                else
                {
                    tlmode_option_1 = 1;
                    break;
                }
            }

            checkOnesIndex = bit_B7;
            while (checkOnesIndex < tlc_to_tx)
            {
                if (tlc_rx[checkOnesIndex] == '1')
                {
                    tlmode_option_2 = 0;
                    checkOnesIndex++;
                }
                else
                {
                    tlmode_option_2 = 1;
                    break;
                }
            }
            }
        }
        TxTelecommand();
    }
}

// Trasmetti il pacchetto
void TxTelecommand()
{
    for (int i = 0; i < tlc_to_tx + 1; i++)
    {
        mima.putc(tlc_rx[i]);
    }
}

// Riceve dalla seriale mima
void RxTelemetry()
{
    char data;
    
    while((mima.readable()))
    {
        data = mima.getc(); 
        
        if (tlmode_option_1 == 0)
        {
            TLM_HSK[sizeBuffer++] = data;
        } 
        else if (tlmode_option_2 == 0)
        {
            TLM_HSK_SD[sizeBuffer++] = data;
        }
        else 
        {
            TLM[sizeBuffer++] = data;
        }
            
    }
}

// Dora trasmette il pacchetto allo space/craft
void TxTelemetry()
{
    if (tlmode_option_1 == 0)
    {        
        for (int i = 0; i < tlm_hsk_size; i++)
        {
             spacecraft.putc(TLM_HSK[i]);
        } 
    }
    else if (tlmode_option_2 == 0)
    {
        for (int i = 0; i < tlm_hsk_sd_size; i++)
        {
            spacecraft.putc(TLM_HSK_SD[i]);
        }
    }
    else 
    {
        for (int i = 0; i < tlm_size; i++)
        {
            spacecraft.putc(TLM[i]);
        }
    }
    
}

/* Routines dedicate alla ricezione di dati della temperatura (Pt100) */

void RxTemperature()
{
    char cReadChar; 
    
    while((max31865.readable()))
    {
        cReadChar = max31865.getc();
        nRxCharCount++; 
        caRxPacket[nRxCharCount] = cReadChar;
    }
} 

void TxTemperature(void)
{
    nRxCharCount = 0; // reset dell'indice del buffer

    int y = 0, u = 0; // indici dei buffer temporanei per i due canali

    for (int i = 0; i < max31865_buf_size; i++)
    {
        if (caRxPacket[i] == 'S')
        {
            indexJ = i + 1;

            while (indexJ < max31865_buf_size)
            {
                if (caRxPacket[indexJ] == ';')
                {
                    break;
                }
                else
                {
                    tempCH1[y++] = caRxPacket[indexJ];
                }

                indexJ++;
            } // se trova ; esce dall'istruzione e salva il valore di uscita dell'indice

            indexT = indexJ + 1;

            while (indexT < max31865_buf_size)
            {
                if (caRxPacket[indexT] == 'P')
                {
                    break;
                }
                else
                {
                    tempCH2[u++] = caRxPacket[indexT];
                }

                indexT++;
            }
            
            // trasforma il dato da sequenza di caratteri a numero float utile per analisi

            strcpy(CH1_to_string, tempCH1);
            CH1 = atof(CH1_to_string);

            strcpy(CH2_to_string, tempCH2);
            CH2 = atof(CH2_to_string);

            spacecraft.printf("> TEMPERATURE - CH1: %4.8f[Celsius], CH2: %4.8f[Celsius]\n\r", CH1, CH2);

            break;
        }
    }

    wait_ms(150); // pausa per garantire sincronizzazione tra riempimento buffer e svuotamento
}

/* Comandi spare/not used */

void SpareCommand(int command)                                                      // Spare command (Relay, L16)
{        
    if((command == 128) && (offset < 1.0f)) 
    { 
        offset += 0.2f; 
        M1.write(offset);
        M2.write(offset); 
        spacecraft.printf("> Duty Cycle %.2f / estensione \n\r", offset);    
    } 
    else if((command == 64) && (offset > 0.0f)) 
    {
        offset -= 0.2f; 
        M1.write(offset);
        M2.write(offset); 
        spacecraft.printf("> Duty Cycle %.2f / estensione \n\r", offset);  
    }
    else if (command == 1) 
    {
        Relay5V = 0;
        spacecraft.printf("\r\nRelay 5V ON\r\n");       
    } 
    else if (command == 0) 
    {
        Relay5V = 1;
        spacecraft.printf("\r\nRelay 5V OFF\r\n");
    } 
    else if (command == 3) 
    {
        Relay12V = 0;
        spacecraft.printf("\r\nRelay 12V ON\r\n");           
    }  
    else if (command == 2) 
    {
        Relay12V = 1;
        spacecraft.printf("\r\nRelay 12V OFF\r\n");
    } 
    else if (command == 7) 
    {
        Relay15_15_5V = 0;
        spacecraft.printf("\r\nRelay +15V, -15V, -5V ON\r\n");     
    } 
    else if (command == 6) 
    {
        Relay15_15_5V = 1;
        spacecraft.printf("\r\nRelay +15V, -15V, -5V OFF\r\n");
    } 
    else if (command == 15) 
    {
        Relay24V = 0;
        spacecraft.printf("\r\nRelay 24V ON\r\n");        
    } 
    else if (command == 8) 
    {
        Relay24V = 1;
        spacecraft.printf("\r\nRelay 24V OFF\r\n");   
    } 
    else if (command == 255) 
    {
        Relay5V = 1;
        Relay12V = 1;
        Relay15_15_5V = 1; // +15, -15, -5
        Relay24V = 1;
        offset = 0.0f;
            
        spacecraft.printf("**** SHUTTING DOWN ALL RELAYS... ****\n\r");
        M1.write(offset);
        M2.write(offset); 
        spacecraft.printf("> Duty Cycle %.2f / extension \n\r", offset);
    }
    else if ((command == 128) || (command == 64) && (Relay12V == 1))
    {
        offset = 0.0f;
        M1.write(offset);
        M2.write(offset); 
    }                   
}

/* Funzionalità di sistema */

// Funzione che serve a ripulire un buffer di caratteri  
void clearBuffer(char *arr, int arrLen)
{
    int nIndex;
    
    for (nIndex = 0; nIndex < arrLen; nIndex++)
    {
        arr[nIndex] = '\0';
    }
}

// Inizializzazione del set di identificativi dello Spacecraft
void CMD_REF()
{
    int id = 0;
    
    for (int i = 0; i < cmd_num; i++)
    {
        CMD[id++] = i;
    }
}

// Trasformazione da binario a decimale per una sequenza di bit in un array
int BinToDec(int t, int dim, char *a)                                               
{
    volatile int result = 0;

    while (t < dim)
    {
        if (a[t] == '1')
        {
            int raise = dim - 1 - t;
            result += pow((float) 2, (float) raise);
        }
        else
        {
            result += 0;
        }
        t++;
    }
    return result;
}

// Print
void printMyArray(Telecommand *myArray)
{
    for (int i = 0; i < sizeof(myArray)/sizeof(myArray[0]); i++)
    {
        mima.puts(myArray[i].ID);
        mima.puts(myArray[i].TAG);
        mima.puts(myArray[i].PAYLOAD);
        mima.putc(myArray[i].LSB);
  
        spacecraft.printf("\n\r");
    }
}


// Checksum per telecomandi
void checksum_tlc(Telecommand *toCheck_tlc)
{
    int ones_tlc = 0;
    
    for (int i = 0; i < sizeof(toCheck_tlc)/sizeof(toCheck_tlc[0]); i++)
    {
        // contatore degli "1" nel campo "identifier"
        for (int j = 0; i < sizeof(toCheck_tlc[i].ID)/sizeof(toCheck_tlc[i].ID[0]); j++)
        {
            if (toCheck_tlc[i].ID[j] == '1')
            {
                ones_tlc++;
            }
        }
        
        // contatore degli "1" nel campo "tag"
        for (int k = 0; i < sizeof(toCheck_tlc[i].TAG)/sizeof(toCheck_tlc[i].TAG[0]); k++)
        {
            if (toCheck_tlc[i].TAG[k] == '1')
            {
                ones_tlc++;
            }
        }

        // contatore degli "1" nel campo "payload" (da assegnare nel file main)
        for (int l = 0; i < sizeof(toCheck_tlc[i].TAG)/sizeof(toCheck_tlc[i].TAG[0]); l++)
        {
            if (toCheck_tlc[i].PAYLOAD[l] == '1')
            {
                ones_tlc++;
            }
        }
        
        // Scrivi LSB
        if (ones_tlc % 2 == 0)
        {
            toCheck_tlc[i].LSB = '0';  // If the number of ones in[B0÷B14] bits is even
        }
        else
        {
            toCheck_tlc[i].LSB = '1';  // If the number of ones in[B0÷B14] bits is odd
        }
        
        
    }
}

// Checksum per telemetrie housekeeping
void checksum_tlm(Telemetry *toCheck_tlm)
{
    int ones_tlm = 0;
    
    for (int i = 0; i < sizeof(toCheck_tlm)/sizeof(toCheck_tlm[0]); i++)
    {
        // contatore degli "1" nel campo "identifier"
        for (int j = 0; i < sizeof(toCheck_tlm[i].ID)/sizeof(toCheck_tlm[i].ID[0]); j++)
        {
            if (toCheck_tlm[i].ID[j] == '1')
            {
                ones_tlm++;
            }
        }
        
        // contatore degli "1" nel campo "tag"
        for (int k = 0; i < sizeof(toCheck_tlm[i].TAG)/sizeof(toCheck_tlm[i].TAG[0]); k++)
        {
            if (toCheck_tlm[i].TAG[k] == '1')
            {
                ones_tlm++;
            }
        }

        // contatore degli "1" nel campo "payload" (da assegnare nel file main)
        for (int l = 0; i < sizeof(toCheck_tlm[i].TAG)/sizeof(toCheck_tlm[i].TAG[0]); l++)
        {
            if (toCheck_tlm[i].PAYLOAD[l] == '1')
            {
                ones_tlm++;
            }
        }
        
        // Scrivi LSB
        if (ones_tlm % 2 == 0)
        {
            toCheck_tlm[i].LSB = '0';  // If the number of ones in[B0÷B14] bits is even
        }
        else
        {
            toCheck_tlm[i].LSB = '1';  // If the number of ones in[B0÷B14] bits is odd
        }
        
        
    }
}