Skip to content

Commit

Permalink
Add PLL lock lost/gained interrupt handler, sync loss reason, ign/inj…
Browse files Browse the repository at this point in the history
… cuts, and flaggable counter, etc. You'll never see the cuts in the logs because those packets will be rejected ;-) Have faith, this has been thoroughly bench tested.
  • Loading branch information
fredcooke committed May 18, 2013
1 parent cbfb8a5 commit 3959ba8
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 16 deletions.
91 changes: 91 additions & 0 deletions src/main/inc/9S12XDP512flags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* FreeEMS - the open source engine management system
*
* Copyright 2013 Fred Cooke
*
* This file is part of the FreeEMS project.
*
* FreeEMS software is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FreeEMS software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with any FreeEMS software. If not, see http://www.gnu.org/licenses/
*
* We ask that if you make any changes to this file you email them upstream to
* us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
*
* Thank you for choosing FreeEMS to run your engine!
*/


/** @file
*
* @ingroup allHeaders
* @ingroup globalHeaders
*
* @brief MC9S12XDP512 flag definitions
*
* This is the flag header for the FreeScale MC9S12XDP512 MCU. It contains
* a unified set of masks to be used with configuration registers.
*
* These are taken from MC9S12XDP512V2.pdf Appendix G, note some are shared across multiple registers.
*/


/* see if we've seen this, if not, mark seen and process */
#ifndef FILE_9S12XDP512_FLAGS_H_SEEN
#define FILE_9S12XDP512_FLAGS_H_SEEN


// CRGFLG
#define RTIF BIT7 // Mask for clearing the Real Time Interrupt flag
#define PORF BIT6 // Mask for checking to see whether this was a fresh start, or not
#define LVRF BIT5 // Mask for checking to see whether this was a post-low-Voltage start, or not
#define PLLLOCKIF BIT4 // Mask for clearing the PLL Lock Interrupt flag
#define PLLLOCK BIT3 // Mask for checking to see when the PLL is locked onto its target
#define PLLTRACK BIT2 // Mask for checking to see when the PLL is tracking its target
#define SCMIF BIT1 // Mask for clearing the Self Clock Mode Interrupt flag
#define SCM BIT0 // Mask for checking to see whether we're in Self Clock Mode, or not

// CRGINT
#define RTIE BIT7 // TODO
#define ILAF BIT6 // TODO
//#define 0 BIT5 // Reserved
#define PLLLOCKIE BIT4 // TODO
//#define 0 BIT3 // Reserved
//#define 0 BIT2 // Reserved
#define SCMIE BIT1 // TODO
//#define 0 BIT0 // Reserved

// CLKSEL
#define PLLSEL BIT7 // Mask for selecting internally multiplied PLL clock mode
#define PSTP BIT6 // TODO
//#define 0 BIT5 // Reserved
//#define 0 BIT4 // Reserved
#define PLLWAI BIT3 // TODO
//#define 0 BIT2 // Reserved
#define RTIWAI BIT1 // TODO
#define COPWAI BIT0 // TODO

// PLLCTL
#define CME BIT7 // TODO
#define PLLON BIT6 // Mask for turning PLL circuitry on
#define PLLAUTO BIT5 // TODO
#define ACQ BIT4 // TODO
#define FSTWKP BIT3 // TODO
#define PRE BIT2 // TODO
#define PCE BIT1 // TODO
#define SCME BIT0 // TODO


#else
/* let us know if we are being untidy with headers */
#warning "Header file 9S12XDP512_FLAGS_H seen before, sort it out!"
/* end of the wrapper ifdef from the very top */
#endif
4 changes: 2 additions & 2 deletions src/main/inc/containerTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ typedef struct { // BIT7 at the top
unsigned Spare5 :1;
unsigned Spare4 :1;
unsigned Spare3 :1;
unsigned Spare2 :1;
unsigned InjLostPLL :1; ///< @todo document this
unsigned InjOverBoost :1; ///< @todo document this
unsigned InjectionRPM :1; ///< @todo document this
} injectionCutFlags; // BIT0 at the bottom
Expand All @@ -187,7 +187,7 @@ typedef struct { // BIT7 at the top
unsigned Spare5 :1;
unsigned Spare4 :1;
unsigned Spare3 :1;
unsigned Spare2 :1;
unsigned IgnLostPLL :1; ///< @todo document this
unsigned IgnOverBoost :1; ///< @todo document this
unsigned IgnitionRPM :1; ///< @todo document this
} ignitionCutFlags; // BIT0 at the bottom
Expand Down
5 changes: 3 additions & 2 deletions src/main/inc/counterTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ typedef struct {
#define FLAG_SERIAL_CHECKSUM_MISMATCHES_OFFSET 12
#define FLAG_SERIAL_PACKETS_UNDER_LENGTH_OFFSET 13

unsigned char phaseLockedLoopLockLost; ///< Incremented when PLL lock is lost
#define PHASE_LOCKED_LOOP_LOCK_LOST_OFFSET 14

// Not currently used
unsigned char commsDebugMessagesNotSent; ///< Incremented when a debug message can't be sent due to the TX buffer
unsigned char commsErrorMessagesNotSent; ///< Incremented when an error message can't be sent due to the TX buffer
#define FLAG_COMMS_DEBUG_MESSAGES_NOT_SENT_OFFSET 14
#define FLAG_COMMS_ERROR_MESSAGES_NOT_SENT_OFFSET 15
} Flaggable;

Expand Down
1 change: 1 addition & 0 deletions src/main/inc/freeEMS.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include "globalDefines.h"
#include "scalerDefines.h"
#include "constantsLibrary.h"
#include "9S12XDP512flags.h"

/* Include data types at the top as other includes use them */
#include "generalTypes.h"
Expand Down
3 changes: 0 additions & 3 deletions src/main/inc/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,8 @@ EXTERN void init(void) FPAGE_FE;


// PLL control values
#define PLLLOCK 0x08 /* Mask for checking to see when the PLL loop is locked onto its target */
#define PLLSELOFF 0x7F /* Mask for switching to base external OSCCLK clock 0b_0111_1111 */
#define PLLSELON 0x80 /* Mask for switching to internally multiplied PLL clock 0b_1000_0000 */
#define PLLOFF 0xBF /* Mask for turning the PLLON bit to ZERO 0b_1011_1111, IE, turning PLL off */
#define PLLON 0x40 /* Mask for setting PLLON bit to ONE 0b_0100_0000, IE, turning PLL on */
#define PLLDIVISOR 0x03 /* Input crystal frequency is divided by this number */
#define PLLMULTIPLIER 0x09 /* The result of the above is multiplied by this number to give the bus frequency */

Expand Down
3 changes: 1 addition & 2 deletions src/main/inc/interrupts.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ void Injector6ISR(void) INT TEXT1; ///< @copydoc Injector1ISR
*
* For details on any specific decoder implementation, see the documentation for
* that specific file.
*
* @author Various
*/
void PrimaryRPMISR(void) INT TEXT1;
void SecondaryRPMISR(void) INT TEXT1; ///< @copydoc PrimaryRPMISR
Expand All @@ -114,6 +112,7 @@ void SCI0ISR(void) INT TEXT1; /* Serial 0 interrupt service routine */

void LowVoltageISR(void) INT TEXT1; /* Low voltage counter ISR */
void VRegAPIISR(void) INT TEXT1; /* VReg periodic interrupt ISR */
void PLLLockISR(void) INT TEXT1; /* PLL lock lost ISR */

typedef void (* interruptTable)(void);

Expand Down
5 changes: 3 additions & 2 deletions src/main/inc/syncLossIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@
#ifndef FILE_SYNC_LOSS_IDS_H_SEEN
#define FILE_SYNC_LOSS_IDS_H_SEEN

// Special case for buggy code
#define BUG_REACHED_UNREACHABLE_CODE 0xFF
// Special cases:
#define BUG_REACHED_UNREACHABLE_CODE 0xFF // Buggy code indicator, called from places that should not be possible to reach.
#define PLL_LOCK_LOST_PRECAUTIONARY 0xFE // Don't override count down, perhaps up? this is bad...

// Special case for timeout
#define EVENT_ARRIVAL_TIMEOUT 0
Expand Down
8 changes: 4 additions & 4 deletions src/main/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void init(){
/** @brief Set the PLL clock frequency
*
* Set the Phase Locked Loop to our desired frequency (80MHz) and switch to
* using it for clock (40MHz bus speed).
* using it for clock (40MHz bus speed). Interrupt is enabled elsewhere.
*/
void initPLL(){
CLKSEL &= PLLSELOFF; /* Switches to base external OSCCLK to ensure PLL is not being used (off out of reset, but not sure if the monitor turns it on before passing control or not) */
Expand All @@ -102,7 +102,7 @@ void initPLL(){
/* Bus frequency is half PLL frequency and given by ((crystal frequency / (REFDV + 1)) * (SYNR + 1)) */
}

CLKSEL = PLLSELON; /* Switches to PLL clock for internal bus frequency */
CLKSEL = PLLSEL; /* Switches to PLL clock for internal bus frequency */
/* from MC9S12XDP512V2.pdf Section 2.4.1.1.2 page 101 Third paragraph */
/* "This takes a MAXIMUM of 4 OSCCLK clock cylces PLUS 4 PLL clock cycles" */
/* "During this time ALL clocks freeze, and CPU activity ceases" */
Expand Down Expand Up @@ -660,8 +660,8 @@ void initInterrupts(){
/* Set up the Real Time Interrupt */
RTICTL = 0x81; /* 0b_1000_0001 0.125ms/125us period http://duckduckgo.com/?q=1+%2F+%2816MHz+%2F+%282+*+10^3%29+%29 */
// RTICTL = 0xF9; /* 0b_1111_1001 0.125s/125ms period http://duckduckgo.com/?q=1+%2F+%2816MHz+%2F+%282*10^6%29+%29 */
CRGINT |= 0x80; /* Enable the RTI */
CRGFLG = 0x80; /* Clear the RTI flag */
CRGINT |= (RTIE | PLLLOCKIE); /* Enable the Real Time Interrupt and PLL Lock Interrupt */
CRGFLG = (RTIF | PLLLOCKIF); /* Clear the RTI flag and LOCKI flag*/

// set up port H for testing
PPSH = ZEROS; // falling edge/pull up for all
Expand Down
2 changes: 1 addition & 1 deletion src/main/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ const interruptTable _vectors[] VECTORS = {
/* */

/* 0xFFC0 to 0xFFCF */
UISR, UISR, UISR, UISR, UISR, UISR, PortHISR, PortJISR,
UISR, UISR, UISR, PLLLockISR, UISR, UISR, PortHISR, PortJISR,
/* IIC0 Reserved CRG self clock CRG PLL lock PAB Overflow ModDwnCtrUF Port H Port J */
/* */

Expand Down
26 changes: 26 additions & 0 deletions src/main/miscISRs.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include "inc/freeEMS.h"
#include "inc/interrupts.h"
#include "inc/decoderInterface.h"


/** @brief Unimplemented Interrupt Handler
Expand All @@ -53,6 +54,31 @@ void UISR(void){
DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
}

/** @brief PLL Lock Lost/Gained
*
* When the Phase Locked Loop is lost or gained, this is called.
*/
void PLLLockISR(void){
// Clear the flag
CRGFLG = PLLLOCKIF;
DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT7, PORTB);
// Check the state of PLL lock
if(CRGFLG & PLLLOCK){ // Recovered
// Re-enable outputs with return of accurate clock
((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnLostPLL = 0;
((injectionCutFlags *)&KeyUserDebugs.injectionCuts)->InjLostPLL = 0;
}else{ // Lock lost
// Record the loss of PLL lock
FLAG_AND_INC_FLAGGABLE(PHASE_LOCKED_LOOP_LOCK_LOST_OFFSET);
// Force sync loss with special code to prevent engine damage from incorrect timings
resetToNonRunningState(PLL_LOCK_LOST_PRECAUTIONARY);
// Disable outputs as a precaution with dodgy clock
((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnLostPLL = 1;
((injectionCutFlags *)&KeyUserDebugs.injectionCuts)->InjLostPLL = 1;
}
DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT7, PORTB);
}


/** @brief Port P pins ISR
*
Expand Down

0 comments on commit 3959ba8

Please sign in to comment.