Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
main.cpp
- Committer:
- paologiorgio
- Date:
- 2022-06-01
- Revision:
- 0:295db98f7ea0
File content as of revision 0:295db98f7ea0:
#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;
}
}