Hi everyone. This is my first post, so if I happen to break the rules, I ask for forgiveness in advance.
And since I'm also a novice with C and Arduino, I come to my request for help.
With the Arduino R4 Minima, I receive an input signal that needs to be doubled in frequency and at which a delay of programmable value must be added. In detail:
Input signal (red) with period of approximately 100 mS (variable) on D2, connected to GTERGA, configured for GPT0 Timer Start. GPT0 exits on GTIOC0A (D7) with PWM signal, pulse with fixed duration of 10 mS.
The red signal is also received by GPT1, which captures its period, in the register R_GPT1-GTCCR[0].
The same signal also generates an IRQ, which is intercepted by "void P_irq": the routine reads the
captured period, divides it by 2 and writes it to the End of Cycle register of GPT0 (R_GPT0->GTPR).
The result I get is the blue signal. First pulse on Falling edge synchronous to input, and second pulse at 180° from the first. So far everything is smooth.
The second goal to achieve (I'm not sure how) is to delay this signal by a minimum of 1 mS to a maximum of approximately 50 mS (it would be the green one).
The idea was to produce a variable duty cycle with GPT1, working on Compare B, and link the event of end pulse at GPT0 start.
But the link doesn't work. Anyone have any suggestions? it would be very welcome.
Thanks in advance. Giorgio
long periodo;
long semi_periodo;
void setup() {
Serial.begin(250000);
//PIN USCITA Test ritardo GPT1 su porta P106
//Pag. 361: setta P106 / D6, PDR a 1 = Output), PMR a 1 = Usata per periferica, PSEL a 3 = uscita su GTIOC0B per test PW£M GPT1
R_PFS->PORT[1].PIN[6].PmnPFS = (1 << R_PFS_PORT_PIN_PmnPFS_PDR_Pos) | (1 << R_PFS_PORT_PIN_PmnPFS_PMR_Pos) | (3 << R_PFS_PORT_PIN_PmnPFS_PSEL_Pos);
//PIN USCITA TRIGGER TELECAMERA GPT0 su porta P107
//Pag. 361: setta P107 / D7, PDR a 1 = Output), PMR a 1 = Usata per periferica, PSEL a 3 = uscita su GTIOC0A per trigger telecamera
R_PFS->PORT[1].PIN[7].PmnPFS = (1 << R_PFS_PORT_PIN_PmnPFS_PDR_Pos) | (1 << R_PFS_PORT_PIN_PmnPFS_PMR_Pos) | (3 << R_PFS_PORT_PIN_PmnPFS_PSEL_Pos);
//PIN INGRESSO TACH RP (diretto a timer) Le 2 istruzioni seguenti servono per usare il vecchio sistema con P_IRQ. Puo essere usato in parallelo a GTETRGA
pinMode(5, INPUT_PULLUP); //pin 2 interrupt Ingresso sensore giri RP
attachInterrupt(digitalPinToInterrupt(2), P_IRQ,FALLING);
//Pag. 361:
R_PFS->PORT[1].PIN[5].PmnPFS = 0b00010000000010110010000010000; //Pag. 362: Periferica = GTETRGA, Usato per periferica, Non analogico, Usa IRQ, Falling edge, Input pull-up, Input era 5
//SETUP REGISTRI VARI
R_MSTP->MSTPCRD &= ~(1 << R_MSTP_MSTPCRD_MSTPD2_Pos); //Pag. 177: Cancella Stop State AGT1
R_MSTP->MSTPCRD &= ~(1 << R_MSTP_MSTPCRD_MSTPD3_Pos); //Cancella Stop State AGT0
R_MSTP->MSTPCRD &= ~(1 << R_MSTP_MSTPCRD_MSTPD5_Pos); //Cancella Stop State GPT320 e 321
R_MSTP->MSTPCRD &= ~(1 << R_MSTP_MSTPCRD_MSTPD6_Pos); //Cancella Stop State GPT16x
R_MSTP->MSTPCRD &= ~(1 << R_MSTP_MSTPCRD_MSTPD14_Pos); //Come sopra, per abilitare POEG
//SETUP GPT0: Ha il compito di generare la 2 x giro
R_GPT0->GTWP = 0xA500; //Pag. 397: A500h Abilita la scrittura dei registri timer
R_GPT0->GTUDDTYC = 0x00000001; //Pag. 418: Count UP
R_GPT0->GTCR = 0x00000; //Pag. 417: Clock 48 MHz, triangolare
R_GPT0->GTPR=9600000; //Pag. 431: Massimo conteggio = 48.000.000 * 0.2 = 9600000 = 0,2 secondi. Viene poi settato da P_IRQ a semi_periodo
R_GPT0->GTCNT = 0; //Pag. 430: Valore iniziale contatore
R_GPT0->GTIOR = 0b100011001; //Pag. 420: Uscita GTIOCA alta a fine ciclo, alta allo stop, bassa al compare match di GTCCRA, Uscita abilitata 0b100011001
R_GPT0->GTCCR[0] = 480000; //Pag. 430: Initial Compare A = 480000 = 10 mS. It will be set by GPT1 Capture A
R_GPT0->GTSSR = 2; //Pag. 399: Start counter da GTETRGA su falling edge 1 o 2 sembra non cambiare niente
R_GPT0->GTCSR = 2; //Pag. 404: Clear counter da GTETRGA su falling edge 1: il trigger camera parte da rising, 2 parte da falling
//SETUP GPT1: Ha il compito di misurare il periodo del RP. Il valore in conteggi è in "R_GPT1->GTCCR[0]"
R_GPT1->GTWP = 0xA500; //Pag. 397: A500h Abilita la scrittura dei registri timer
R_GPT1->GTUDDTYC = 0x00000001; //Pag. 418: Count UP
R_GPT1->GTCR = 0x00000000; //Pag. 417: Clock 48 MHz
R_GPT1->GTPR=9600000; //Pag. 431: Massimo conteggio = 48.000.000 * 0.2 = 9600000 = 0,2 secondi, per vedere qualcosa all'oscilloscopio
R_GPT1->GTCNT = 0; //Pag. 430: Valore iniziale contatore
R_GPT1->GTIOR = 0b0000001000011110000000000000000; //Pag. 420: Uscita GTIOCB alta a fine ciclo, alta allo stop, bassa al compare match di GTCCRB, Uscita abilitata 0b100011001
R_GPT1->GTCCR[1] = 1000000; //Compare B: 48000000/1000000 = variabile delay on GPT0 counter start (correzione dell'angolo di tracking) via ELC
R_GPT1->GTICASR = 2; //Pag. 411: Cattura su falling edge di GTETRGA
R_GPT1->GTSSR = 2; //Pag. 399: Start counter da GTETRGA su falling edge 1 o 2 sembra non cambiare niente
R_GPT1->GTCSR = 2; //Pag. 404: Clear counter da GTETRGA su falling edge 1: l'impulso parte da rising, 2 parte da falling
R_ELC->ELSR[0].HA = 0x60; //Pag. 347 Attivo ELC Event Link Controller per linkare Compare B GPT1 GTCCR1 (60h) a Start GPT0 (0h)
R_ELC->ELCR = 128; //ELC enable
}
void loop() {
}
void P_IRQ() { //irq RP su pin P105 / D2 / IRQ0
periodo = R_GPT1->GTCCR[0];
semi_periodo = periodo / 2;
R_GPT0->GTPR = semi_periodo; //setta fine ciclo di GPT0 a circa 50 mS
}