//Es.3 CORRETTO
/*
REMINDER: questo è un programma di acquisizione dei tempi dell'evento
in cui avveniva il cambiamento di un determinato input digitale
(e che quindi può avere o 0 o 1).
Quello che vogliamo è il valore di quanto tempo è passato in ms da
quando si è accesso l'MCU -> questo programma ci darà tutta la
tabella con i vari tempi. In modo tale noi riusciamo a disegnare
il segnale digitale dato che partendo dall'asse 0 con tempo 0, ci
si potrà registrare la famosa onda quadra che ci dà il programma
che abbiamo utilizzato per leggere l'analizzatore del PulseView.
In poche parole, quello che ci da in output sono i valori che
potremmo ottenere con il pulseview.
I valori però che stiamo sytampando non sono quelli in tempo reale,
dato che se stiamo scrivendo una routine di servizio all'interrupt,
il tempo di servbizio dev'essere il minimo possibile perché durante
l'esecuzione della routine di interrupt, il processore tiene i flag
disabilitati, per cui non può avvenire nessun altro interrupt.
Quando si è finito la routine di servzio potranno essere serviti gli altri.
Immaginiamo che arrivano 3 interrupt, uno dietro l'altro: il primo
viene servito, appena finito, si riabilita e per cui al prossimo
ciclo di clock il processore vede se ci sono interrupt pendenti
e va al secondo e mano a mano li esegue tutti.
Una routine che fa questso tipo di lavoro è quella del micros():
se noi dovessimo restituire i ms come si fa visto che il conteggio
avviene ogni 4ms e l'interrupt avviene all'ovf, quindi quando sono
passati 1024 ms ovvero 1,024 millisecondi?
Semplicemento andandolo ad accostare il conteggio dei ms con quanto
è contuneto nel registro TCNT0 (ovvero il contatore dei tick, dove
ognuno di loro vale 4ms).
Quando TCNT0 va a 0 arriva l'interrupt -> ricordiamo che TCNT0 va a
0-255, 0-255, ecc... fa sempre quello il contatore.
Si è scelto di puntare solo sul timer0 piuttosto che utilizzarne
un altro che poteva comunque essere più efficiente anche in termini
di codice, perché a seconda delle flag che abilitiamo, il timer
genererà diverse operazioni.
La modalità che abbiamo scelto ci serve per dire che quando c'è
l'interrupt del timer0 allora c'è l'interrupt anche dell'OCRA dato
che quando c'è l'ovf allora si va da FF a 00
*/
#include "wiring_private.h"
// Area modulo cattura
#define NCAMPIONI 128
volatile uint32_t vMicros[NCAMPIONI];
volatile uint8_t iMicros, vCamp[NCAMPIONI];
/*la prima cosa che si deve andare a fare ora
è creare un contatore tutto nostro che venga collegato direttamente al timer
*/
// Area per modulo mytimer
//definiamo di già che che il nostro tic tac è di 4 ms
#define MYTICK 4
volatile uint32_t mytick;
void setup() {
Serial.begin(300);
//Inizializzazione per Area modulo cattura
iMicros = 0;
//Modalità con sui si abilitano gli interrupt
sbi(PCMSK2, PCINT18);
sbi(PCICR, PCIE2);
//Inizializzazione per modulo mytimer
mytick = 0;
OCR0A = 0;
/* Mentre per abilitare l’interrupt dobbiamo
mettere a 1 il bit OCIE0A del registro TIMSK0
*/
sbi(TIMSK0, OCIE0A);
Serial.println("Salve, mondo");
delay(1000);
//adesso c'è la parte di stampa del codice
for (uint8_t i = 0; i<iMicros; i++){
Serial.print(i);
Serial.print("\t");
Serial.print(vCamp[i]>>2); //in questo modo si stampa o 0 o 1 dato che si divide per 4 con lo shift di 2
Serial.print("\t");
Serial.println(vMicros[i]);
}
}
void loop() {
}
// Una nuova ISR che dobbiamo fare è una agganciata all'interrupt del timer
ISR(TIMER0_COMPA_vect){ //N.B. avremmo anche potuto scegliere il COMPB! --> ovviamente con i suoi rispettivi pin
mytick++; //questo ci serve solo per contare gli overflow
}
ISR(PCINT2_vect){
//se partiamo da imicros = 0
if(iMicros<NCAMPIONI){
vCamp[iMicros]=PIND;
vMicros[iMicros++] = (mytick << 8) + TCNT0;
}
}