• Non ci sono risultati.

2 DESCRIZIONE DI SISTEMA E SPECIFICHE

5.3 Main

Il main del programma chiama tutte le funzioni d’inizializzazione di periferica e abilita gli interrupt in modo che all’inizio del programma il DSP sia configurato come descritto nel capito 5.1. Successivamente inizializza tutte le classi ed entra in un ciclo infinito che contiene il codice che implementa la GCU.

Il compito del main è semplice non fa altro che interpretare i tasti premuti dal pilota, chiamare le funzioni associate al tasto premuto ed aggiornare il display sul cruscotto. Ad esempio se il pilota tira la leva del cambio in modo da salire di marcia, viene rilevato il tasto premuto, viene chiamata la funzione di cambiata in salita la procedura di cambiata e viene aggiornato il display.

Si ricorda che il veicolo deve poter effettuare la partenza Launch-Control, e per eseguirla è necessaria una combinazione di tasti particolare. Una volta abilitata la procedura di Launch-Control, il veicolo rimane nello stato di Racing Mode in modo che ogni volta che si ferma e decide di ripartire riparte in modalità Launch-Control. (si veda paragrafo 2). Per disabilitare la modalità Launch-Control è necessario eseguire la sequenza di disattivazione di partenza lanciata, in tal modo il veicolo parte con una partenza normale Quiet-Moving. Tramite questo flag si possono effettuare anche cambiate tranquille e scalate più tranquille, operazione che non è stata implementata.

Figura 5-17: diagramma di flusso del Main del programma.

Per poter comprendere il codice del main è necessario introdurre alcune funzioni, della classe CDriverConsole, che saranno descritte dettagliatamente nei successivi paragrafi.

L’informazione sul tasto attualmente premuto è contenuta nella variabile, privata, KeyReg. Alcuni bit di tale variabile corrispondono ai tasti premuti e sono bassi se i tasti sono premuti ed alti se i tasti non sono premuti. I tasti che sono presenti sul cruscotto sono le leve del cambio, cambiata in salita e cambiata in discesa, il tasto d’inserimento della folle e il tasto di Launch. I valori che assume la variabile KeyReg in corrispondenza delle pressioni dei vari tasti sono rispettivamente: GEARUP_MASK (=0xC800), GEARDWN_MASK (=0x6800), NEUTRAL_MASK (=0xA800),

LAUNCH_MASK (=0xE000). Inoltre può assumere il valore KEYBOARD_MASK che corrisponde a nessun tasto premuto, tale valore è assunto dalla variabile KeyReg solo al rilascio di un tasto. Quando non si deve compiere nessun’azione sui tasti la variabile KeyReg è pari a CLEAR.

La funzione GetKeyRegister()restituisce il valore della variabile KeyReg, mentre la funzione SetKeyRegister() scrive un valore nella variabile KeyReg.

L’array KeyRegisterBuffer[] contiene la storia dei tasti premuti.

La funzione WriteKeyRegBuffer() scrive il valore passato come argomento all’interno di KeyRegisterBuffer[]. Normalmente il valore da scrivere corrisponde all’ultimo tasto premuto.

La funzione ReadKeyRegBuffer() permette di analizzare la storia dei tasti. Se l’argomento della funzione è pari a zero il restituisce il valore del tasto attualmente premuto, mentre se il valore dell’argomento è pari a uno restituisce il valore dell’ultimo tasto premuto, ecc…

La funzione RefreshDisplay() aggiorna il display, ad esempio indicando l’ultima marcia inserita.

Quindi il main chiama la funzione GetKeyRegister() e memorizza il valore ritornato nella variabile KeyRegValue, che conterrà il medesimo valore della variabile privata KeyReg della classe CDriverConsole. Tramite il costrutto switch, su KeyRegValue, si esegue la discriminazione tra i vari tasti premuti. Si ammetta ad esempio che sia stato premuto il tasto di cambiata in salita, in tal caso la variabile ritornata dalla funzione GetKeyRegister() vale GEARUP_MASK, quindi del costrutto switch verrà eseguito il case relativo al valore GEARUP_MASK. A questo punto sono eseguite le seguenti operazioni: si chiama la funzione GetKeyRegister() con argomento CLEAR, ad indicare che il compito relativo alla pressione del tasto di cambiata sta venendo assolto (analogamente a quando sa fa per un flag di interrupt). Poi tramite WriteKeyRegBuffer() si scrive nell’array della storia dei tasti che il tasto che è stato appena premuto è quello di cambiata in salita. Vengono poi eseguiti alcuni controlli sui tasti precedentemente premuti e viene chiamata la funzione ShiftUp() membro della classe CGear. In tale funzione viene calcolata la marcia attualmente inserita e viene innestata la marcia superiore. Nel caso il veicolo si trovi in folle verrà inserita ancora la marcia superiore (cioè la prima) e chiamata la procedura di partenza. Successivamente si va ad aggiornare il display per visualizzare la nuova marcia inserita.

Il codice appena descritto è sotto riportato.

KeyRegValue=DriverConsole.GetKeyRegister(); switch( KeyRegValue ) { case GEARUP_MASK: { DriverConsole.SetKeyRegister(CLEAR);

//Scrivo i valori in un buffer per riconoscere la sequenza DriverConsole.WriteKeyRegBuffer(GEARUP_MASK); Vehicle.RacingModeKeySequenceFlag=0; OPEN_LAUNCH_ECU_PIN;

if (

DriverConsole.ReadKeyRegBuffer(0)==GEARUP_MASK//è ovvio che lo sia && ( DriverConsole.ReadKeyRegBuffer(1)==KEYBOARD_MASK || DriverConsole.ReadKeyRegBuffer(1)==GEARDWN_MASK || DriverConsole.ReadKeyRegBuffer(1)==GEARUP_MASK ) ) Gear.ShiftUp(); DriverConsole.WriteGear(Gear.GetActualGearRatio()); DriverConsole.SetSevSeg2DisplayReg(Gear.GetActualGearRatio()); DriverConsole.RefreshDisplay(); } break; case GEARDWN_MASK: {...analogo a sopra... } break; case NEUTRAL_MASK: {...analogo a sopra...

}

break; ...continua sotto...

La partenza può avvenire in due modi, in modalità lanciata o normale, per eseguire tale discriminazione si esegue un controllo sulla variabile RacingMode della classe CVehicle che può essere acceduta direttamente perché pubblica. Tale variabile viene gestita all’interno del solito switch nel main del programma in questo modo: viene settata una volta riconosciuta la sequenza tasti della procedura di launch e resettata una volta riconosciuta la procedura che disabilita il Launch-Control. Eseguendo controlli su tale variabile si lancerà la procedura di partenza relativa. Per riconoscere la sequenza dei tasti si deve scrivere e leggere l’array KeyRegisterBuffer[] tramite le funzioni WriteKeyRegBuffer() e ReadKeyRegBuffer().

Si ricorda che per abilitare la procedura di partenza Launch Control il veicolo si deve trovare in folle e si deve eseguire la seguente sequenza tasti: nessun tasto del cruscotto è premuto, poi si preme e si mantiene premuto il tasto di Launch, si preme la leva per salire di marcia, si rilascia il tasto tale leva, a questo punto la prima deve essere inserita, si rilascia il tasto di launch e il veicolo parte. Visto che durante la sequenza vengono eseguiti due compiti il riconoscimento della sequenza deve essere spezzato in due. All’inizio nessun tasto è premuto e la variabile KeyRegValue vale KEYBOARD_MASK; quando si preme il tasto launch, la variabile KeyRegValue vale LAUNCH_MASK; quando si preme la leva del cambio, visto che il tasto di launch è mantenuto premuto, KeyRegValue vale LAUNCH_MASK & GEARUP_MASK; quando la leva del cambio viene rilasciata allora KeyRegValue torna a valere LAUNCH_MASK. Quindi l’analisi della sequenza può essere, in parte, eseguita dentro il case relativo a LAUNCH_MASK (perché prima del rilascio del tasto di Launch, appena prima della fine delle sequenza, la variabile KeyRegValue vale nuovamente LAUNCH_MASK). Dentro tale case, tramite la funzione ReadKeyRegBuffer(), si va ad interrogare i valori premuti precedentemente se questi valori sono uguali a quelli della sequenza di Launch-Control, come appena descritto, allora il pilota sta richiedendo la procedura e, se il veicolo si trova in folle, viene innescata la prima. A questo punto se viene rilasciato il tasto di launch il veicolo dovrà partire in modalità lanciata altrimenti se si preme un tasto diverso (ovviamente il tasto di lauch è ancora premuto) la sequenza viene interrotta. Quindi fino ad ora, nonostante la prima sia già stata inserita, non c’è sicurezza che la sequenza venga completata correttamente, ovvero con il rilascio del tasto di Launch; infatti potrebbe venir interrotta con la pressione di un altro tasto. A causa di ciò si fa uso di un flag che indica che la sequenza di Launch è in corso e può venir compiuta con successo: si pone ad uno il valore della variabile RacingModeKeySequenceFlag della classe CVehicle (nota volendo come flag potrebbe venir utilizzato la prima che è stata appena inserita). Se a questo punto il tasto di launch viene rilasciato allora il valore di KeyRegValue vale di nuovo KEYBOARD_MASK quindi il riconoscimento completo della sequenza deve essere eseguito all’interno del case relativo a KEYBOARD_MASK. All’interno di tale case si pone a uno la variabile RacingMode e si lancia la procedura di Launch-Control e la variabile RacingModeKeySequenceFlag viene messa di nuovo a zero.

Se invece di rilasciare il tasto di Launch viene premuto un qualsiasi altro tasto allora la variabile KeyRegValue assume un valore non contemplato e il costrutto switch cade nel caso default dentro il quale si azzera il flag RacingModeKeySequenceFlag e si inserisce nuovamente la folle.

Per togliere il veicolo dallo stato di RacingMode deve essere eseguita la solita sequenza solamente che invece di premere il tasto di marcia in salita si preme il tasto di marcia in discesa. Tale procedura può essere eseguita in qualsiasi momento, la pressione della leva di cambiata in salita o in discesa ha effetti, viene mantenuta la marcia attuale. Il riconoscimento di tale sequenza è effettuato al rilascio del tasto di Launch e quindi, come prima, all’interno del case relativo a KEYBOARD_MASK, dove viene posta a zero la variabile RacingMode.

Il codice relativo è sotto riportato. case LAUNCH_MASK: { DriverConsole.SetKeyRegister(CLEAR); DriverConsole.WriteKeyRegBuffer(LAUNCH_MASK); Gear.SetActualGearRatio(); DriverConsole.WriteGear(Gear.GetActualGearRatio()); DriverConsole.SetSevSeg2DisplayReg(Gear.GetActualGearRatio()); DriverConsole.RefreshDisplay(); if ( DriverConsole.ReadKeyRegBuffer(0)==LAUNCH_MASK &&

DriverConsole.ReadKeyRegBuffer(1)==(LAUNCH_MASK & GEARUP_MASK) && DriverConsole.ReadKeyRegBuffer(2)==LAUNCH_MASK && DriverConsole.ReadKeyRegBuffer(3)==KEYBOARD_MASK ) { Gear.SetActualGearRatio(); if (Gear.GetActualGearRatio()==0) { DriverConsole.SetSevSeg2DisplayReg(SEVSEGi_L); DriverConsole.RefreshDisplay(); Vehicle.RacingModeKeySequenceFlag=1; GND_LAUNCH_ECU_PIN; Gear.ShiftUp(); DriverConsole.WriteGear(Gear.GetActualGearRatio()); } } else { Vehicle.RacingModeKeySequenceFlag=0; OPEN_LAUNCH_ECU_PIN; } DriverConsole.SetSevSeg2DisplayReg(Gear.GetActualGearRatio()); DriverConsole.RefreshDisplay(); } break;

case KEYBOARD_MASK: //l’ultimo tasto premuto è stato rilasciato e adesso non c’è nessun tasto premuto { DriverConsole.SetKeyRegister(CLEAR); DriverConsole.WriteKeyRegBuffer(KEYBOARD_MASK); if ( Vehicle.RacingModeKeySequenceFlag==1 &&

DriverConsole.ReadKeyRegBuffer(0)==KEYBOARD_MASK//è ovvio che lo sia &&

DriverConsole.ReadKeyRegBuffer(1)==LAUNCH_MASK &&

DriverConsole.ReadKeyRegBuffer(2)== (LAUNCH_MASK & GEARUP_MASK) && DriverConsole.ReadKeyRegBuffer(3)==LAUNCH_MASK && DriverConsole.ReadKeyRegBuffer(4)==KEYBOARD_MASK ) { Gear.SetActualGearRatio(); if (Gear.GetActualGearRatio()==1) { Vehicle.RacingMode=1; DriverConsole.SetSevSeg2DisplayReg(Gear.GetActualGearRatio()); DriverConsole.RefreshDisplay(); Clutch.SportStartReleaseClutch(); Vehicle.RacingMode=1; }

else //significa che non è entrata la prima (Se sono qui) if (Clutch.ClucthIsPressed()==1)

Clutch.LinearReleaseClutch(Clutch.GetActuatorDuty(), ERROR_OFF_CLUTCH_ACT_DUTY,ERROR_CA_RELEASE_TIME); }

if (

DriverConsole.ReadKeyRegBuffer(0)==KEYBOARD_MASK//è ovvio che lo sia &&

DriverConsole.ReadKeyRegBuffer(1)==LAUNCH_MASK &&

DriverConsole.ReadKeyRegBuffer(2)== (LAUNCH_MASK & GEARDWN_MASK) && DriverConsole.ReadKeyRegBuffer(3)==LAUNCH_MASK && DriverConsole.ReadKeyRegBuffer(4)==KEYBOARD_MASK ) { Vehicle.RacingMode=0; Gear.SetActualGearRatio(); DriverConsole.SetSevSeg2DisplayReg(Gear.GetActualGearRatio()); DriverConsole.RefreshDisplay(); } Vehicle.RacingModeKeySequenceFlag=0; DriverConsole.SetSevSeg2DisplayReg(Gear.GetActualGearRatio()); DriverConsole.RefreshDisplay(); } break; case CLEAR: {NOP;} break; default: { DriverConsole.SetKeyRegister(CLEAR); DriverConsole.WriteKeyRegBuffer(KeyRegValue);

// tutte le eventuali procedure if (Vehicle.RacingModeKeySequenceFlag==1) { Vehicle.RacingModeKeySequenceFlag=0; OPEN_LAUNCH_ECU_PIN; Gear.GoNeutral(); } DriverConsole.SetSevSeg2DisplayReg(Gear.GetActualGearRatio()); DriverConsole.RefreshDisplay(); } break; } }

Un difetto di questo codice è l’inserimento della prima solo al rilascio della leva del cambio e non alla pressione come in tutti gli altri casi. Se è necessario si può risolvere il problema aggiungendo un case che contempla il valore LAUNCH_MASK & GEARUP_MASK. Questo infatti è il valore che la variabile KeyRegValue assume alla pressione della leva del cambio.