<<

ECE 4510/5530 Applications

Week 2 Lab 2 Preparations

Dr. Bradley J. Bazuin Associate Professor Department of Electrical and Engineering College of Engineering and Applied Sciences Lab 2 Elements

• Hardware Development – Parallel I/O ports (Chap. 7.5) – LEDs (Chap. 4.11) – Dip (Chap. 4.11) – 7-segment display (Chap. 4.11, Chap. 7.6) – Keypad (Chap. 7.9) – Clock-recovery-generator (Chap. 6.6, 6.7) • Software Development Environment – Software control flow (Chap. 2.6, Chap. 5.4) – Function calls (Chap. 5.6) – Software delay loops (Chap. 2.10)

ECE 2510 2 SOFTWARE TIME DELAY

ECE 3 4510/5530 Creating Time Delays

• There are many applications that require the generation of time delays. – Program loops are often used to create a certain amount of delay unless the time delay needs to be very accurate. • The creation of a time delay involves two steps: – Select a sequence of instructions that takes a certain amount of time to execute. (a basic unit) – Repeat the selected instruction sequence for an appropriate number of times. (Delay = Number x basic unit)

ECE 2510 4 Program Execution Time

• The HCS12 uses the clock (E clock) as a timing reference. – The of the E clock is half of that of the onboard clock oscillator (clock, 48 MHz, E-clock, 24 MHz). – Execution times of the instructions are also measured in E clock cycles

ECE 2510 5 Program Execution Time

• Execution times of each instruction can be obtained from Appendix A of the textbook or from the reference manual – Number of letters in the column “Access Detail” of Appendix A indicates the number of E cycles that a specific instruction takes to execute that particular instruction – For example access detail column of PULA instruction contains three letters UFO which indicates that the PULA instruction takes 3 E cycles to complete

ECE 2510 6 Program Execution Time

• Speed of the E clock varies from controller to controller – Higher E clock indicates higher processing times – The E clock for the HCS12 is 24 MHz = 41.67ns – The least amount of time HCS12 takes to execute an instruction is 41.67ns – So HCS12 can only be used in applications that require a per instruction computation time of >= 41.67ns

• How to Program Execution Time – Count all the E Cycles in the code – Multiply by 41.67 nsec

ECE 2510 7 Program Execution Time

Example: • The following instruction takes 14E cycles for 1 loop Loop: psha ; 2E cycles pula ; 3E cycles psha ; 2E cycles pula ; 3E cycles nop ; 1E cycle Dbne X,Loop ; 3E cycles  condition not satisfied ; 3E cycle  condition satisfied – Assume that the HCS12 runs under a with a frequency of 16 MHz, with an E freq. of 8 MHz. The E-clock period is then 125 ns. – Therefore, each repeated loop would take 14*125=1750ns=1.75us ECE 2510 8 to execute. Total delay  1.75usec x X_value Program Execution Time (2)

Example: • Time the following instructions ldx #1234 ; 2E cycles Loop: psha ; 2E cycles pula ; 3E cycles psha ; 2E cycles 14/12 E-clock pula ; 3E cycles dex ; 1E cycle bne Loop ; 3E cycles  branch taken ; 1E cycle  branch not taken

• This requires a slightly different count! X = 1234 ECE 2510 2 + ( (X-1)*14 + (1)*12) E Cycles = 17,276 E Cycles 9 Program Execution Time

• Example: find delay created if E = 41.67ns = 1/24 MHz. ldx #$1234 ; 2E Loop1: ldy #$ABCD ; 2E Loop2: dbne Y, Loop2 ; 3E taken/3E not dbne X, Loop1 ; 3E taken/3E not

• Total time  – Inner loop: (2 + ($ABCD-1)*3 + 3) E Cycles – Assume IL = (($ABCD)*3 )*41.67ns = 43981*3/24 MHz – IL = 0.005497625 sec – Outer loop: (2+$1234*IL+($1234-1)*3 +1) * 41.67ns – Total = ($1234*$ABCD*3 +$1234*3) * 41.67ns ECE 2510 10 – Total = (4660*(43981+1)*3) /24 MHz = 25.629515 sec Program Execution

• How many E cycles in 0.001 sec? – 24 MHz * 0.001 sec  24000 E-cycles – Or 8000*3 inner loops. Use $1F40 • How many inner loops needed for 1 sec? – 1 sec/0.001 sec  1000 or $03E8 • If we used these numbers in the last program … – Total = ($03E8*$1F40*3 +$ 03E8 *3) * 41.67ns – Total = (1000*(8000+1)*3) /24 MHz = 1.000125 sec (use Y=>$1F3F and X=>$03E8 instead for 1.00 sec)

• Comment: if the average instruction requires 3 E cycles – The machine would average 24/3  8 Mips

ECE 2510 11 Program Execution Time

Loop: psha ; 2 E cycles pula ; 3 E cycles psha ; 2 E cycles pula ; 3 E cycles psha ; 2 E cycles pula ; 3 E cycles psha ; 2 E cycles 37  3 D 1 37  3 pula ; 3 E cycles Time  reg psha ; 2 E cycles 24,000,000 pula ; 3 E cycles psha ; 2 E cycles pula ; 3 E cycles psha ; 2 E cycles pula ; 3 E cycles nop ; 1 E cycle nop ; 1 E cycle dbne d,loop ; 3 E cycles when condition is not satisfied ; 3 E cycles when condition is satisfied ECE 2510 12 Software Delay: Example 2.25

Write a program loop to create a delay of 100 ms, assuming E=125ns. . Solution: A delay of 100 ms can be created by repeating the previous loop 20,000 times. The following instruction sequence creates a delay of 100 ms. ldx #20000 ; 2 E cycles loop psha ; 2 E cycles pula ; 3 E cycles psha pula 2  40 Dreg 1 40 psha Timesec  pula 8,000,000 MHz psha pula psha 800,000  2  40 Dreg 1 40 pula psha pula Dreg  20,000  $4E20 psha pula nop ; 1 E cycle nop ; 1 E cycle dbne x,loop ; 3 E cycles/3 E cycles ECE 2510 13 (2(ldx)+40*(20000))*E ≈ 20000*E ≈ 20000*125ns ≈ 100ms. Software Time Delays

• Time delays created by program loops are not accurate – Some overhead is required to set up the loop count – To reduce the overheads one can adjust the number to be placed in the index registers – By doing so one can achieve closer to the required time delays • Program loops are not advisable to use in applications requiring precise timing calculation – Interrupts may exist that could significantly change time delays • Typically, Microcontroller Timer modules are used in applications requiring precise timing calculations – Enhanced Capture Timer – 8 PWM channels

ECE 2510 14 SUBROUTINE & FUNCTION CALLS

ECE 15 4510/5530 Subroutines/Functions

• Good program design is based on the concept of modularity – Modularity  partitioning of a large program into subroutines • Program can be divided into two sections – Main program – Subroutines • Main program  contains the logical structure of the algorithm • Subroutines  Execute many of the details involved in the program

ECE 2510 16 Subroutine Hierarchy

• Structure of a modular program can be visualized as shown • Principles of program design involved in high-level languages can be applied to assembly language programs – Subroutine “objects” with calls and returns

ECE 2510 17 Subroutines

• Subroutine is a sequence of instructions that can be called from many different places in a program • A key issue in a subroutine call is to make sure that the program execution returns to the point immediately after the subroutine call after the subroutine completes its computations. • The address for returning to the point immediately after the subroutine completes its computation is known as the “return address” • This is normally achieved by saving and retrieving the return address in and from the stack

ECE 2510 18 Subroutine Program Flow

• The subroutine call (2) saves the return address, which is the address of the instruction immediately following the subroutine call instruction, in the stack system • After completing the subroutine computation task (3), the subroutine will return to the instruction immediately following the instruction that made the call (4) • This is achieved by executing a return instruction (4), which will retrieve the return address from the stack and transfer CPU control to it

ECE 2510 19 Issues in Subroutine Calls

• Parameter passing • Local variables allocation – Use registers – Allocated by the callee – Use the stack or stack frame – Use the following instruction is – Use global memory the most efficient way for local variable allocation – leas -n,sp ; • allocate n bytes in the stack for local variables • Returning results • Local variables deallocation – Use registers – Performed by the subroutine – Use the stack frame – Use the following instruction is (caller created a hole in which the most efficient way the result will be placed) – Leas n,sp ; – Use global memory • deallocate n bytes from the stack

ECE 2510 HCS12 Assembly Language Subroutines Instructions

• HCS12 provides three different instructions for making subroutine calls and two different instructions for returning from a subroutine • Subroutine calls –BSR  Branch Subroutine –JSR  Jump Subroutine – Call  Call a Subroutine • Return Instructions –RTS  Return from Subroutine –RTC  Return from Call

ECE 2510 21 Jump and Subroutine Table

Mnemonic Function Operation BSR Branch to subroutine SP – 2  SP RTNH : RTNL  M(SP) : M(SP+1) Push PC PC + Rel offset  PC CALL Call subroutine in expanded SP – 2  SP memory RTNH:RTNL M(SP) : M(SP+1) Push PC SP – 1  SP (PPAGE)  M(SP) Push PPAGE Page  PPAGE Subroutine address  PC JMP Jump Address  PC JSR Jump to subroutine SP – 2  SP RTNH : RTNL M(SP) : M(SP+1) Push PC Subroutine address  PC RTC Return from call M(SP)  PPAGE SP + 1  SP Pull PPAGE M(SP) : M(SP+1)  PCH : PCL SP + 2  SP Pull PC RTS Return from subroutine M(SP) : M(SP+1)  PCH : PCL SP + 2  SP Pull PC

The return address is

ECE 2510 stored on the stack! 22 C Language Function Calls

• Function prototype in included header file or “main” code typc func_name(type variable_to_pass);

• Compose the function (included with main or in another *.c) typc func_name(type argiments_to_pass) { … return(typed_return_value); }

• C does the rest automatically ….

ECE 23 4510/5530 C Language Function Calls

• A few more important details ….

• In preparing for the call to a function, a copy is made of each argument … they are passed by value. – Assembly interpretation: pushed on the stack before the call. They are part of the “stack frame” used by the function. – When done this way, the called function can not change the arguments! It works in a separate memory space and just returns the return value-parameter.

• Making C “pass by reference” – If a pointer is passed (i.e. the address of a value or array), then the actual program arguments can be changed. ECE 24 4510/5530 C Parameter passing

• Pass by value – C is described as only passing by value … but …

• Pass by reference (use pointers) – If a pointer is passed, the “global parameters” address is present in the function and can be used. – Regularly done for arrays instead of copying all the data

• Pass by global variable (define and declare globals) – The “extern” storage class specifier can be used in the function. – Variables declared “before the main function definition” Example: Swap Function “Does and Don’ts”

void Swap(int x, int y) { // NO! Does not work int temp; Does not work: temp = x; x and y are local to x = y; // these operations just change the local x,y,temp the function y = temp; // -- nothing connects them back to the caller's a,b }

static void Swap(int* x, int* y) { // params are int* instead of int int temp; temp = *x; // use * to follow the pointer back to the caller's memory *x = *y; Does work: *y = temp; x and y pointers point to the } calling codes values for x and y ECE 26 4510/5530 Assembly Stack Frame

• Expand on the simple data passing approach

– Incoming Parameters are pushed SP (copies for C function) onto the stack Local variables prior to a BSR or JSR

– After the BSR or JSR, the subroutine Saved registers push all relevant registers (D, X, Y) to be restored prior to an RTS Return address – Additional space needed by the Incoming parameters subroutine is allocated in the stack

(C locally defined variables) Figure 4.9 Structure of the 68HC12 stack frame – The stack pointer (SP) is set above all this so nested subroutines can be called. (The locations/values needed

ECE 2510 by C are all known or defined) 27 MORE CODING PRACTICES

ECE 28 4510/5530 Example of Real-Time Code Flow

• Sequential Code with Infinite Loop – as time is available • Interrupts that must be immediately processed

External Interrupt Priority

Interrupt 1 Interrupt 2 Interrupt M

Int 1 Int 2 Int M Process Process Process

Set Int 1 Set Int 2 Set Int M Flag Flag Flag

RTI RTI RTI

ECE 2510 29 Where to use functions: main()

• Keep the main routine focused on high level tasks void main(void) { // declare variables // call initializations functions for each required peripheral • examples: io_init(), crg_init(), sci0_int(), xyz_init() while(1) // main loop • the infinite loop that keeps running //make the main loop easily readable at a high level • avoid bit level operations where reasonable • define operations as “modes of operation” with certain “states” existing within or shard by the “modes” • use function calls when interacting with peripherals

ECE } 30 4510/5530 Where to use functions

• When I get a component that has to be “communicated” with by the microcontroller – I write multiple functions that perform each of the “types of communication” needed. – Example … an analog-to-digital converter • initialization – get all the ADC internal registers set • start conversion – tell the ADC to start converting the analog signal • check ADC status – is it done doing the conversion? • read the converted data – get the data to process

ECE 31 4510/5530 CLOCK RECOVERY GENERATOR (CRG)

ECE 32 4510/5530 Microcontroller Clocks

• Typical have multi-function clock generation circuitry. Built in user flexibility … – On IC clock generation – External input clock ports – External crystal connections for clocks – Clock rate multiplication/division circuits (PLL or counters) – Low power allowances (slow or stop the clock) – Special operation during power-on reset and hardware reset – Periodic clock based interrupts (watchdog timer) – And more …..

ECE 2510 33 Clock and Reset Generation Block (CRG) (1 of 2)

VREG Power on reset CRG Clock and Reset Control Reset System RESET generator Reset CM fail XCLKS Clock Clock quality monitor Bus clock EXTAL checker XTAL OSC COP RTI Core clock OSCCLK Oscillator Registers XFC PLLCLK clock PLL VDDPLL VSSPLL

ECE 2510 Figure 6.4 Block diagram of CRG 34 Clock and Reset Generation Block (CRG) (2 of 2)

• CRG generates the clock signals required by the HCS12 instruction execution and all peripheral operations. – The has the form of square waveform.

• Crystal oscillators are often used to generate clock signals. – The crystal oscillator output is sinusoidal wave and must be squared up before it can be used. The HCS12 has an internal circuit to do this square up operation. – The CRG block also has a PLL circuit that can multiply the frequency of the incoming clock signal.

• The CRG can also accept an external oscillator (square waveform). – The XCLKS signal must be tied low (for MC9S12DP256B) in order to use external clock signal.

ECE 2510 35 CRG Configuration Registers

Note: Address = $34 + Address Offset

Header File SYNR = $34 REFDV = $35 CTFLG = $36 CRGFLG = $37 CRGINT = $38 CLKSEL = $39 PLLCTL = $3A RTICTL = $3B COPCTL = $3C FORBYP = $3D CTCTL = $3E ARMCOP = $3F

ECE 2510 36 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D Device User Guide

ECE 2510 37 MC9S12DP256B Device User Guide V02.15, Doc. Number 9S12DP256BDGV2/D Choice of Clock Source (1 of 3)

PLLSEL or SCM wait (CWAI,SYSWAI) PLLCLK SYSCLK stop Phase 1 Core lock clock loop 0 WAIT, STOP clock 2 phase Bus clock E-Clock wait(RTIWAI), generator SCM stop(PSTP,PRE) RTI enable 1 extal Real Time Oscillator OSCCLK RTI 0 Interrupt xtal wait (COPWAI), stop(PSTP, PCE) COP enable Clock COP monitor Comp. wait (SYSWAI), Operating stop oscillator Properly gating clock condition stop (PSTP) oscillator = clock gate clock ( pseudo stop mode) ECE 2510 38 Figure 6.15 HCS12 clock generation circuit Choice of Clock Source (2 of 3)

• The user can choose between using the external crystal or oscillator to produce the clock signal. – The external crystal is connected between the EXTAL and XTAL pins and needs an on-chip oscillator circuitry to square it up. – The external clock source provided by the oscillator is connected to the EXTAL pin and has a 2.5V peak-to-peak magnitude for the D family or CPUs (9s12DP256). • The XCLKS signal must be grounded to select the external clock signal.

ECE 2510 39 Crystal or External Clock Connection

ECE 2510 40 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D Choice of Clock Source (3 of 3)

• The output from the OSC module in Figure 6.4 may bypass or go through the PLL circuit. – The PLL circuit has the capability to multiply incoming signal frequency and stabilize its output signal frequency.

• Either the OSCCLK or the PLLCLK can be chosen as the SYSCLK which will be divided by 2 to derive the bus clock to control the instruction execution and peripheral operation. (E-clock from timing).

ECE 2510 41 Phase Lock Loops

• A Phase Lock Loop is capable of providing an integer change up or down in the clock rate input to the PLL – A voltage controlled oscillator is used

ECE 2510 42 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D Phase Locked Loop (PLL) (1 of 5)

• The frequency of the PLLCLK is controlled by registers synthesizer (SYNR) and reference divide (REFDY) using the following equation: (SYNR + 1) PLLCLK = 2  OSCCLK  ------(6.1) (REFDV + 1) NOTE: PLLCLK must not exceed the maximum operating system frequency.

Maximum bus frequency is 25 MHz. Therefore, maximum PLLCLK is 50 MHz.

The lab modules use a 16 MHz external crystal, PLLCLK of 48 MHz, and ECE 2510 E-clock (bus frequency) of 24 MHz. 43 PLL Rate Registers

64 PLLCLK max  2OSCCLK  • SYNR: 0 to 63 1 1 • REFDV: 0 to 15 PLLCLK  2OSCCLK  ECE 2510 min 16 44 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D PLL Control Register (1)

• Read: anytime • Write: refer to each bit for individual write conditions • CME — Clock Monitor Enable Bit – 1 = Clock monitor is enabled. Slow or stopped clocks will cause a clock monitor reset sequence or Self Clock Mode. – 0 = Clock monitor is disabled. • PLLON — Phase Lock Loop On Bit – 1 = PLL is turned on. If AUTO bit is set, the PLL will lock automatically. – 0 = PLL is turned off. • AUTO — Automatic Bandwidth Control Bit – 1 = Automatic Mode Control is enabled and ACQ bit has no effect. – 0 = Automatic Mode Control is disabled and the PLL is under software control, using ACQ bit. • ACQ — Acquisition Bit – 1 = High bandwidth filter is selected. – 0 = Low bandwidth filter is selected. ECE 2510 45 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D PLL Control Register (2)

• PRE — RTI Enable during Pseudo Stop Bit – 1 = RTI continues running during Pseudo Stop Mode. – 0 = RTI stops running during Pseudo Stop Mode. • PCE — COP Enable during Pseudo Stop Bit – 1 = COP continues running during Pseudo Stop Mode – 0 = COP stops running during Pseudo Stop Mode • SCME — Self Clock Mode Enable Bit – 0 = Detection of crystal clock failure causes clock monitor reset . – 1 = Detection of crystal clock failure forces the MCU in Self Clock Mode

ECE 2510 46 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D CRG Clock Selection (1)

Read: anytime Write: refer to each bit for individual write conditions • PLLSEL — PLL Select Bit – 1 = System clocks are derived from PLLCLK. – 0 = System clocks are derived from OSCCLK. • PSTP — Pseudo Stop Bit – This bit controls the functionality of the oscillator during Stop Mode. – 1 = Oscillator continues to run in Stop Mode (Pseudo Stop). The oscillator amplitude is reduced. – 0 = Oscillator is disabled in Stop Mode. • SYSWAI — System clocks stop in Wait Mode Bit – 1 = In Wait Mode the system clocks stop. – 0 = In Wait Mode the system clocks continue to run. • ROAWAI — Reduced Oscillator Amplitude in Wait Mode Bit. – 1 = Reduced oscillator amplitude in Wait Mode. – 0 = Normal oscillator amplitude in Wait Mode. ECE 2510 47 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D CRG Clock Selection (2)

• PLLWAI — PLL stops in Wait Mode Bit – 1 = PLL stops in Wait Mode. – 0 = PLL keeps running in Wait Mode. – If PLLWAI is set, the CRG will clear the PLLSEL bit before entering Wait Mode. The PLLON bit remains set during Wait Mode but the PLL is powered down. Upon exiting Wait Mode, the PLLSEL bit has to be set manually in case PLL clock is required. – While the PLLWAI bit is set the AUTO bit is set to 1 in order to allow the PLL to automatically lock on the selected target frequency after exiting Wait Mode. • CWAI — Core stops in Wait Mode Bit – 1 = Core clock stops in Wait Mode. – 0 = Core clock keeps running in Wait Mode. • RTIWAI — RTI stops in Wait Mode Bit – 1 = RTI stops and initializes the RTI dividers whenever the part goes into Wait Mode. – 0 = RTI keeps running in Wait Mode. • COPWAI — COP stops in Wait Mode Bit – 1 = COP stops and initializes the COP dividers whenever the part goes into Wait Mode. – 0 = COP keeps running in Wait Mode. ECE 2510 48 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D Phase Locked Loop Example 6.2

• Example 6.2 There is a system that derives its bus clock from the PLL circuit and an external clock of 8 MHz is selected. The desired bus clock is 24 MHz. Write an instruction sequence to perform the desired configuration. – Solution: • The frequency of OSCCLK is 8 MHz. – The XCLKS pin must be grounded to select oscillator as clock source. • Make the SYSCLK frequency 48 MHz. • 48 MHz = 2  8 MHz  [SYNR + 1] /[REFDV + 1] – One solution is to set SYNR and REFDV to 2 and 0, respectively.

SetClk8: movb #2,SYNR ; set SYNR to 2 movb #0,REFDV ; set REFDV to 0 movb #$80,CRGSEL ; enable PLL, keep SYSCLK running in wait mode, ; keep RTI, COP, PLL & core running in wait mode movb #$60,PLLCTL ; disable clock monitor, enable PLL, set automatic ; bandwidth control, disable RTI & COP in pseudo stop ClkWait: brclr CRGFLG,LOCK ,ClkWait ; wait until PLL locks ECE 2510 rts 49 Phase Locked Loop Example 6.3

• Example 6.3 There is a system that uses a 4 MHz crystal oscillator to derive a 24 MHz bus clock. Write an instruction sequence to perform the required configuration. – Solution: • The OSCCLK and PLLCLK are 4 MHz and 48 MHz, respectively. – The XCLKS pin must be pulled to high to select external crystal to generate clock signals • 48 MHz = 2  4 MHz  [SYNR + 1] /[REFDV + 1] • One solution is to set SYNR and REFDV to 5 and 0, respectively.

SetClk4: movb #05,SYNR ; set SYNR to 5 movb #00,REFDV ; set REFDV to 0 movb #$80,CLKSEL ; enable PLL, keep SYSCLK running in wait mode, ; keep RTI, COP, PLL & core running in wait mode movb #$60,PLLCTL ; disable clock monitor, enable PLL, set automatic ; bandwidth control, disable RTI & COP in pseudo stop ClkWait: brclr CRGFLG,LOCK ,ClkWait ; wait until PLL locks rts

ECE 2510 50 CRG and PLL Status

• RTIF — Real Time Interrupt Flag – 1 = RTI time-out has occurred. (Write a “1” to clear the flag) – 0 = RTI time-out has not yet occurred. • PORF — Power on Reset Flag – 1 = Power on reset has occurred. – 0 = Power on reset has not occurred. • LOCKIF — PLL Lock Interrupt Flag – 1 = LOCK bit has changed. – 0 = No change in LOCK bit. • LOCK — Lock Status Bit – 1 = PLL VCO is within the desired tolerance of the target frequency. – 0 = PLL VCO is not within the desired tolerance of the target frequency. ECE 2510 51 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D CRG and PLL Status

• TRACK — Track Status Bit – 1 = Tracking mode status. – 0 = Acquisition mode status. • SCMIF — Self Clock Mode Interrupt Flag – 1 = SCM bit has changed. – 0 = No change in SCM bit. • SCM — Self Clock Mode Status Bit – 1 = MCU is operating in Self Clock Mode with OSCCLK in an unknown state. All clocks are derived from PLLCLK running at its minimum frequency fSCM. – 0 = MCU is operating normally with OSCCLK available.

ECE 2510 52 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D Clock Monitor

• The clock monitor circuit is based on an internal resistor-capacitor (RC) time delay so that it can operate without any MCU clocks. – If no OSCCLK edges are detected within this RC time delay, the clock monitor indicates failure which asserts self clock mode or generates a system reset depending on the state of SCME bit. – If the clock monitor is disabled or the presence of clocks is detected no failure is indicated.

• The clock monitor function is enabled/disabled by the CME control bit. (PLLCTL) – If no OSCCLK edges are detected within the RC time delay, the clock monitor may reset the MCU if the CME bit in the PLLCTL register is set to 1. – The SCME bit of the PLLCTL register must be cleared to 0 for clock monitor to work.

ECE 2510 53 Real-time interrupt (RTI) (1 of 3)

• The RTI can be used to generate a hardware interrupt at a fixed periodic rate. If enabled (by setting RTIE=1), this interrupt will occur at the rate selected by the RTICTL ($003B) register. – The RTI runs with a gated OSCCLK. At the end of the RTI time-out period the RTIF flag is set to one and a new RTI time-out period starts immediately. • A write to the RTICTL register restarts the RTI time-out period. – If the PRE bit is set, the RTI will continue to run in Pseudo-Stop Mode. (in PLLCTL)

• The RTI interrupt is enabled by the interrupt enable register (CRGINT).

ECE 2510 54 RTI Chain

Note: OSCCLK 10 not SYSCLK 2 and not E-Clock 211 212

213 214

215 1 to 16

216

ECE 2510 55 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D RTI Control Register (RTICTL)

Addr: $003B

• RTR[6:4] — Real Time Interrupt Prescale Rate Select Bits – These bits select the prescale rate for the RTI. See Table 3-2.

• RTR[3:0] — Real Time Interrupt Modulus Counter Select Bits – These bits select the modulus counter target value to provide additional granularity

– See the next page for the rates (prescale counter) produced ECE 2510 56 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D RTI Rates

Table 6.4 RTI interrupt period (in units of OSCCLK cycle) RTR[3:0] RTR[6:4] 000 001 010 011 100 101 110 111 (off) (210 ) (211 ) (212) (213) (214 ) (215) (216) 0000 (1) off* 210 211 212 213 214 215 216 0001(2) off* 2210 2211 2212 2213 2214 2215 2216 0010 (3) off* 3210 3211 3212 3213 3214 3215 3216 0011 (4) off* 4210 4211 4212 4213 4214 4215 4216 0100 (5) off* 5210 5211 5212 5213 5214 5215 5216 0101 (6) off* 6210 6211 6212 6213 6214 6215 6216 0110 (7) off* 7210 7211 7212 7213 7214 7215 7216 0111 (8) off* 8210 8211 8212 8213 8214 8215 8216 1000 (9) off* 9210 9211 9212 9213 9214 9215 9216 1001 (10) off* 10210 10211 10212 10213 10214 10215 10216 1010 (11) off* 11210 11211 11212 11213 11214 11215 11216 1011 (12) off* 12210 12211 12212 12213 12214 12215 12216 1100 (13) off* 13210 13211 13212 13213 13214 13215 13216 1101 (14) off* 14210 14211 14212 14213 14214 14215 14216 1110 (15) off* 15210 15211 15212 15213 15214 15215 15216 1111 (16) off* 16210 16211 16212 16213 16214 16215 16216 ECE 2510 57 CRG Interrupt Enable Register (CRGINT)

Addr: $0038

• RTIE — Real Time Interrupt Enable Bit. – 1 = Interrupt will be requested whenever RTIF is set. – 0 = Interrupt requests from RTI are disabled. • LOCKIE — Lock Interrupt Enable Bit – 1 = Interrupt will be requested whenever LOCKIF is set. – 0 = LOCK interrupt requests are disabled. • SCMIE — Self Clock Mode Interrupt Enable Bit – 1 = Interrupt will be requested whenever SCMIF is set. – 0 = SCM interrupt requests are disabled.

ECE 2510 58 CRG Block User Guide V02.07, Doc. Number S12CRGV2/D Initialize RTI Code (1)

.area prog(abs) RTICTL = $003B ;RTICTL register address CRGINT = $0038 ;CRGINT register address RTIIV = $3E70 ;RTI D-Bug12 Interrupt Vector address

.text _main:: sei ; disable global interrupts lds #$3c00 ; Load the stack pointer ldx #RTI_isr ;Load start addr of ISR stx RTIIV ;Store in the vector location ldaa #$1F ;RTI Rate is 16 x 2^10 * OSCClock ; OSCclock = 16 MHz (?) staa RTICTL ; approximately 1.024 msec ECE 2510 59 Initialize RTI Code (2)

ldaa CRGINT oraa #$80 ; set the RTIE interrupt staa CRGINT cli ; clear interrupt mask

End: nop ; infinite loop nop bra End

.org $1600 RTI_isr: ldaa CRGFLG ; Reset the RTI interrupt flag oraa #$80 ; “Set to 1” to reset staa CRGFLG nop ; more interrupt routine code goes here … rti

ECE 2510 60 The RTI as Real-Time Monitor

• Every time the interrupt happens, a fixed number of clock cycles have occurred. – If the crystal or external clock is accurate, the interrupts acts like the “time-tick” of a clock. •Pro – Readily available time function interrupt. – RTI is a high-priority interrupt (just below IRQ)

•Con – The divide ratios available are not flexible, 1-15 x 2^ 10-16 – You may be stuck with “strange” clock tick times. Selecting the crystal frequency may provide useful time ticks. (10.24 MHz crystal OSCCLK/ 10 x 2^10 = 1 kHz or (1 msec) ECE 2510 61 The RTI as a Watchdog Timer

• Important control information: A write to the RTICTL register restarts the RTI time-out period.

• Therefore, for real-time processing, make the RTI time greater than the maximum time that is takes one of the infinite software loops – Include all possible times: loop code, interrupt ISR code and time • At the end of every loop, re-write the RTICTL register

• If the RTI interrupt occurs, the software is broken! – Then, the RTI ISR should be an error recovery routine.

ECE 2510 62 SCI_Test.c

/* * SCI_Test Software Modules Header File void main(void){ */ # include "mc9s12dp512.h" // header file for addresses of registers COPCTL=0x00; # include // header file for standard output asm("sei"); # include // header file for strings pll_init(); # include "CRG_sw.h" crg_init(); // You must add the following c-code files to the project init_sci0(); // # include "stdio_hcs.c" // # include "delay.c" asm("cli");

//Function Definitions while(state == 1){ printf("Hello World!\n\r"); void pll_init(void); delayby100ms(2); void crg_init(void); char_in = checkchar(); void rti_isr(void); if (!(char_in ==0)){ state = 2; void delayby100ms(int k); printf("On to state 2.\n\r"); } void init_sci0(void); } int putchar(char cx); int getchar(void); ….. char checkchar(void); int getstr(char *ptr); } int newline(void); char strflip(char *dest, const char *src, int copy_length); ECE 63 4510/5530 CRG_sw.h

/* * CRG Software Modules Header File * * B.J. Bazuin 5/21/2009 * */ // PLL and ECLK Rate Setting // Public Function Prototypes #define BUSRATE 24 #define XTALRATE 16 //16 MHz Xtal, effective 16 MHz OSCCLK void pll_init(void); #define PLLCOMPRATE 1 // Note max(XTAL/PLLC) = 16 void crg_init(void); void rti_isr(void); // Module LED pin access #define LED_PORT PTP // Defines for ECLK access and PLL setup #define LED_PIN PTP7

#ifndef __ECLK_ACCESS // Constant Definitions #define __ECLK_ACCESS #define TRUE 1 #endif #define FALSE 0

#ifndef __SET_PLL #define __SET_PLL #endif

ECE 64 4510/5530 CRG_sw.c (1 of 2)

/* * CRG Software Modules Header File * * B.J. Bazuin 5/21/2009 while((CRGFLG & LOCK) == 0x00) * { */ asm("nop"); # include "mc9s12dp512.h" // header file for addresses of registers asm("nop"); # include "CRG_sw.h“ } void pll_init(void) { CLKSEL |= PLLSEL; PEAR &= ~NECLK; #ifdef __SET_PLL MODE &= 0XEF;

// PLLCLK = 2 * OSCCLK * (SYNR+1)/(REFDV+1) #endif // ECLK = PLLCLK/2 CLKSEL &= ~PLLSEL; #ifdef __ECLK_ACCESS PLLCTL |= PLLON | AUTO | ACQ; REFDV = (XTALRATE/PLLCOMPRATE) -1; // from 1 to 16 PEAR &= ~NECLK; SYNR = (BUSRATE/PLLCOMPRATE) -1; // from 1 to 64 MODE &= 0XEF; asm("nop"); // Allow time for the PLL to start and settle asm("nop"); #endif asm("nop"); asm("nop"); }

ECE 65 4510/5530 CRG_sw.c (2 of 2)

void crg_init(void) { // Port P pin 7 is the Adapt Board LED DDRP |= DDRP7; PTP |= PTP7; // RTI Iniitalization RTICTL = 0x27; // 8 x 2^11 division OSCCLK = 16 MHz -> 1.024 msec CRGINT |= RTIE; // enable the rti interrupt }

#pragma interrupt_handler rti_isr #ifdef __FLASH_LOAD void rti_isr(void) { #pragma abs_address:vrti // Initialize the Interrupt static unsigned int count = 0x0000; Vector address void (*interrupt_vectors[]) (void) = {rti_isr}; // Assign the function pointer CRGFLG |= RTIF; // Reset the interrupt flag #pragma end_abs_address // to the ISR count = count +1; // 500 x 1.024 msec = 0.512 sec #else if(count == 500) { #pragma abs_address:0x3E70 // Initialize the Interrupt PTP ^= PTP7; void (*interrupt_vectors[]) (void) = {rti_isr}; // Assign the function pointer count = 0; #pragma end_abs_address // to the ISR } } #endif

ECE 66 4510/5530 INTERRUPTS

ECE 67 4510/5530 What is an Interrupt?

• An interrupt is a special event that requires the CPU to stop normal program execution and perform some “service related to the event”. – Examples of interrupts include I/O completion, timer time-out, illegal opcodes, arithmetic overflow, divide-by-0, etc. – For most PCs, an interrupt is caused by a real-world event or by something going wrong. – In most “real-time” signal processing almost all events drive interrupts and interrupts are prioritized so the most important interrupt is worked on first. • Interrupt sources – External: an external pin or level causes the interrupt – Internal: an internal microcontroller peripheral device or CPU operation causes the interrupt

ECE 2510 – Software: the swi assembly language instruction is an interrupt 68 Interrupts

• Interrupts Features – Respond to real time hardware, “software events”, or program software initiated interrupts. – Software errors can cause software interrupts, usually referred to as a trap or a fault • Illegal instruction, illegal memory address, etc. • (advanced memory management page fault or segmentation fault) – SWI is a software interrupt • Transfers program execution to D-Bug12 – Activated by: software or IRQ pin if enabled or a peripheral device hardware interrupt if enabled. – Software interrupts happen at defined times in code execution – Hardware interrupts happen at random times during code execution

ECE 2510 69 Functions of Interrupts

• Performing time-critical operations or applications – Real-time data sample systems – Power failure • Coordinate I/O activities and prevent the CPU from being tied up waiting for an event • Providing a graceful way to handle or exit from errors • Reminding the CPU to perform routine tasks – Time-of-Day – Health check and status – Other Periodic Functions – Task Switching for a multitasking operating system

ECE 2510 Example of Real-Time Code Flow

• Sequential Code with Infinite Loop – Process as time is available • Interrupts that must be immediately processed

External Interrupt Priority

Interrupt 1 Interrupt 2 Interrupt M

Int 1 Int 2 Int M Process Process Process

Set Int 1 Set Int 2 Set Int M Flag Flag Flag

RTI RTI RTI

ECE 2510 71 Multi-tasking Operating Systems

• Modern computer systems consists of multiple application programs in the memory – CPU time can be divided into many short time slots of 10 to 20ms – Multitasking operating systems can assign a different program to be executed in each time slot (scheduling) – At end of a time slot (or when program is waiting for the completion of an I/O operation), the operating system takes over and allows the next program to execute. • This technique is called multi-tasking and dramatically improve the CPU performance – Implemented by using periodic timer interrupts (covered later in this course)

ECE 2510 72 Basics of Interrupts (1 of 5)

• Interrupt priority – Allow multiple pending interrupt requests – Resolve the order of service for multiple pending interrupts • Interrupt maskability – Interrupts that can not be ignored by the CPU are called nonmaskable interrupts. (An NMI is usually the highest priority interrupt). – Interrupts that can be ignored by the CPU are called maskable interrupts. – A maskable interrupt must be enabled before it can interrupt the CPU and must be disabled when it is not allowed to interrupt the CPU. – An interrupt is enabled by setting an enable/disable bit or flag.

ECE 2510 Basics of Interrupts (2 of 5)

• Servicing and Interrupt – CPU executes a program called an interrupt service routine (ISR). – A complete interrupt service cycle includes: 1. Saving the current value in the stack 2. Saving the CPU status (including the CPU and some other registers) in the stack 3. Identifying the cause of interrupt 4. Resolving the starting address of the corresponding interrupt service routine (ISR) 5. Executing the interrupt service routine until completed … 6. Restoring the CPU status and the program counter from the stack 7. Return to the interrupted program – An ISR often looks and acts like a subroutine call, except that it is called due to an interrupt. ECE 2510 Basics of Interrupts (3 of 5)

• Interrupt vector – Starting address of the interrupt service routine • Interrupt vector table – A table where all the interrupt vectors are stored • Methods of determining interrupt vectors – Predefined locations (Microchip PIC18, 8051 variants) – Fetching the vector from a predefined memory location (HCS12) – Executing an interrupt acknowledge cycle to fetch a vector number in order to locate the interrupt vector (68000 and families)

ECE 2510 Basics of Interrupts (4 of 5)

• Steps required for interrupt programming – Step 1. Initializing the interrupt vector table – Step 2. Writing the interrupt service routine – Step 3. Enabling the desired interrupts at the appropriate location in the system code.

• The overhead of interrupts – Saving and restoring of CPU status and other registers. (HCS12 needs to save all CPU registers). – Execution time of instructions of the interrupt service routine. • Overhead time required to enter and exit an ISR – The execution of the return-from-interrupt (RTI) instruction that will restore all the CPU registers. ECE 2510 Basics of Interrupts (5 of 5)

• Nasty details when using interrupts – Interrupt happen at random times that may not be predictable. • Plan for the worst – should cleanly transition from normal operation to the interrupt • They typically finish the instruction they are executing and save the address of the next instruction in the stack so that it can resume the program later. – need to identify the cause of the interrupt before it can take appropriate action. This is built into the microprocessor hardware. – Interrupts will force the microprocessor to stop executing an application program briefly • What is the application priority as compared to the interrupt? – Interrupts, if they return, should resume the previous application code as though nothing happened (registers, CCR, etc.). ECE 2510 Global Interrupt Mask

• When none of the interrupts are desirable, the processor can disable all the interrupts by clearing the global interrupt enable bit.

• CCR bit I is the global interrupt mask bit – The I bit enables and disables maskable interrupt sources. – By default, the I bit is set to 1 during reset. – An instruction must clear the I bit to enable maskable interrupts. – While the I bit is set, maskable interrupts can become pending and are remembered, but operation continues uninterrupted until the I bit is cleared. b7 b6 b5 b4 b3 b2 b1 b0

S X H I N Z V C ECE 2510 78 Enabling Global Interrupt

b7 b6 b5 b4 b3 b2 b1 b0

S X H I N Z V C The CCR

• After Reset, the I status bit is set to 1 • To allow interrupts (except NMI) set the bit to 0 ANDCC #$EF ; AND CCR with 1110 1111 or $EF or CLI ; Clear interrupt mask bit Also needed: lower level interrupt enables, interrupt vectors, and ISRs • To disable interrupts reset the bit to 1 ORCC #$10 ; OR CCR with 0001 0000 or $10 or ECE 2510 79 SEI ; Set interrupt mask bit CCR: I Mask Bit

• When an interrupt occurs after interrupts are enabled, the I bit is automatically set to prevent other maskable interrupts during the interrupt service routine. – The I bit is set after the registers are stacked, but before the first instruction in the interrupt service routine is executed. – Normally, an RTI instruction at the end of the interrupt service routine restores register values that were present before the interrupt occurred. • Since the CCR is stacked before the I bit is set, the RTI normally clears the I bit, and thus re-enables interrupts. – Interrupts can be re-enabled by clearing the I bit within the service routine, but implementing a nested interrupt management scheme requires great care and seldom improves system performance.

ECE 2510 80 DEBUGGING TIPS

ECE 81 4510/5530 Tips for Debugging Programs Involving Function Calls

• What to do when the program gets stuck? –Step 1 • Setting a breakpoint immediately before the function call. – Did you successfully get to this point with everything the way it should be –Step 2 • Setting a breakpoint immediately after the function call. – Did the function execute and return – Did the function do the tasks required (function problem)

• Can you separate flow and function? – Code flow (executes, but the answer is wrong) – Code function (logical errors in the algorithm)

ECE 2510 82 Reasons Why Code Flow Fails

• There are some infinite loops in the function. – Are you polling and the result never happens? – If the functions were tested as stand-alone code, do they work? (Can you write test code to test the function? You should! ) • Calling other functions from within the function and they do not return. – If functions are nested, is one of those at fault?

ECE 2510 83 General Debugging Strategy

• Make sure all functions work correctly – Test the function with it’s own special calling program – Work from the bottom up • Debug intermediate functions. Make sure no intermediate function gets stuck. (If you have library code and test code for the library elements, it must be something else.)

• Use “leds” and text to monitor code progress – Use terminal I/O to write progress characters to the screen – Toggle the LED at the beginning of every code segment

ECE 2510 84 C LANGUAGE LIBRARIES EXIST!!

ECE 2510 85 C Language: Character Type Functions

The following functions categorize input according to the ASCII character set. Use #include > before using these functions. int isalnum(int c) returns non-zero if c is a digit or alphabetic character. int isalpha(int c) returns non-zero if c is an alphabetic character. int iscntrl(int c) returns non-zero if c is a control character (for example, FF, BELL, LF). int isdigit(int c) returns non-zero if c is a digit. int isgraph(int c) ) returns non-zero if c is a printable character and not a space. int islower(int c) returns non-zero if c is a lower-case alphabetic character. int isprint(int c) returns non-zero if c is a printable character. int ispunct(int c) returns non-zero if c is a printable character and is not a space or a digit or an alphabetic character. int isspace(int c) returns non-zero if c is a space character, including space, CR, FF, HT, NL, and VT. int isupper(int c) returns non-zero if c is an upper-case alphabetic character. int isxdigit(int c) returns non-zero if c is a hexadecimal digit. int tolower(int c) returns the lower-case version of c if c is an upper-case character. Otherwise it returns c. int toupper(int c) returns the upper-case version of c if c is a lower-case character. Otherwise

ECE 2510 it returns c. 86 C Language: String Functions (1 of 2)

Use #include > before using these functions. The file defines NULL and typedefs size_t, and the following string and character array functions:

void *memchr(void *s, int c, size_t n) searches for the first occurrence of c in the array s of size n. It returns the address of the matching element or the null pointer if no match is found. int memcmp(void *s1, void *s2, size_t n) compares two arrays, each of size n. It returns 0 if the arrays are equal and greater than 0 if the first different element in s1 is greater than the corresponding element in s2. Otherwise, it returns a number less than 0. void *memcpy(void *s1, const void *s2, size_t n) copies n bytes starting from s2 into s1. void *memmove(void *s1, const void *s2, size_t n) copies s2 into s1, each of size n. The routine works correctly even if the inputs overlap. It returns s1. void *memset(void *s, int c, size_t n) stores c in all elements of the array s of size n. It returns s.

ECE 2510 87 C Language: String Functions (2 of 2)

Use #include > before using these functions.

char *strcat(char *s1, const char *s2) concatenates s2 onto s1 . It returns s1. char *strchr(const char *s, int c) searches for the first occurrence of c in s, including its terminating null character. It returns the address of the matching element or the null pointer if no match is found. int strcmp(const char *s1, const char *s2) compares two strings. It returns 0 if the strings are equal, and greater than 0 if the first different element in s1 is greater than the corresponding element in s2. Otherwise, it returns a number less than 0. char *strcpy(char *s1, const char *s2) copies s2 into s1. It returns s1. size_t strlen(const char *s) returns the length of s. The terminating null is not counted.

char *strstr(const char *s1, const char *s2) finds the substring of s1 that matches s2. It returns the address of the substring in s1 if found and a null pointer otherwise.

See: ICC12 On-line Help and then: C LIBRARY AND THE STARTUP FILE

ECE 2510 88