Académique Documents
Professionnel Documents
Culture Documents
Rev. 0, 07/2005
Application Note
This document contains information on a new product. Specifications and information herein
are subject to change without notice.
© Freescale Semiconductor, Inc., 2005. All rights reserved.
Time Base: Time Measurement
MPC5500
Time Base
Crystal sysclk
FMPLL spr TBU spr TBL
8 MHz
Enable
Exercise: Modify the program to record the TBL and TBU at the start of the desired code sequence, and
move their values to SPRG0 and SPRG1. At the end of the measured code, record both again and move
their values to SPRG2 and SPRG3.
1.2 Design
Table 1. Time Base: Time Measurement
Step Code
1.3 Code
# INITIALIZE TIME BASE=0
li r4, 0 # Load immediate data of 0 to r4
mttbu r4 # Move r4 to TBU
mttbl r4 # Move r4 to TBL
# ENABLE TIME BASE
mfhid0 r5 # Move from spr HID0 to r5 (copies HID0)
li r4, 0x4000 # Load immed. data of 0x4000 to r4
or r5, r4, r5 # OR r4 (0x0000 4000) with r4 (HID0 value)
mthid0 r5 # Move result to HID0
# EXECUTE SOME CODE
nop
nop
nop
nop
nop
# RECORD TBL
mftbl r5 # Move TBL to r5 to store TBL value
2 Interrupts: Decrementer
2.1 Description
Task: Use the Decrementer (DEC) exception to generate a periodic interrupt roughly every second. Design
the interrupt handler, including interrupt service routine (ISR) to be written entirely in assembler, without
enabling nested interrupts. The ISR simply counts interrupts and optionally toggles a GPIO pin. Assume
the system clock runs at the default frequency of 1.5 times 8 MHz.
Since the program’s interrupt handler is entirely in assembler, it requires saving and restoring fewer
registers in the interrupt handler’s prologue and epilogue than if it was written in C. Only two registers are
used in the interrupt service routine, so only two need to be saved and restored in the prologue and
epilogue, besides the stack pointer (r1). External Input interrupts, enabled by MSR[EE], are not re-enabled
in the interrupt handler, so SRR0:1 need not be saved in the stack frame.
The DEC interrupt causes the CPU to vector to the sum of the common Interrupt Vector Prefix (IVPR0:16)
plus the FIT interrupt’s individual Interrupt Vector Offset (IVOR15:28).
Exercise: Change the Decrementer timeout to 1 KHz. Do not change the system clock frequency.
Enable
2.2 Design
The overall program flow is shown below, followed by design steps and a stack frame implementation.
main.c file Decrementer interrupt taken
vector to
main {
IVPR0:15 + IVOR1016:28
init IVPR, IVOR(s)
init Decrementer handlers.s file
init GPIO
enable interrupts IVOR10Handler:
wait forever prologue (save registers)
} execute DecISR (increment ctr, clear flag, toggle pin)
epilogue (restore registers, return)
Relevant Bit
Step Pseudo Code
Fields
IVOR10Handler:
prolog: # PROLOGUE
stwu r1, -0x10 (r1) # Create stack frame and store back chain
stw r3, 0x08 (r1)
stw r4, 0x0C (r1)
DECisr:
lis r3, DECctr@ha # Read DECctr
lwz r4, DECctr@l (r3)
addi r4, r4, 0x1 # Increment DECctr
stw r4, DECctr@l (r3) # Write back new DECctr
lis r3, SIU_GPDI205_ADDR@h # Read current GPIO 205 input state
lbz r4, SIU_GPDI205_ADDR@l (r3)
addi r4, r4, 1 # Add one to state for toggle effect
stb r4, SIU_GPDO205_ADDR@l (r3)# Write back "toggled" GPIO 205 (pad A21)
lis r0, 0x0800 # Write "1" clear Dec Interrupt Status (DIS) flag
mtspr 336, r0
epilog: # EPILOGUE
lwz r4, 0x0C (r1) # Restore gprs
lwz r3, 0x08 (r1)
addi r1, r1, 0x10 # Restore space on stack
rfi # End of Interrupt
Enable
1. 8 MHz is the frequency of the crystal used on the MPC5554. Hence the sysclk here will be 12 MHz.
2. The SPE’s accumulator is not saved in the prologue. It is assumed SPE instructions are not used in this example.
3.2 Design
The overall program flow is shown below, followed by design steps and a stack frame implementation.
main.c file
Relevant Bit
Step Pseudo Code
Fields
3.3 Code
3.3.2 handlers.file
# handlers.s - FIT (IVOR11) interrupt example
# Rev 1.0: April 9, 2004, S Mihalik,
# Copyright Freescale Semiconductor, Inc. 2004. All rights reserved
# Compiled with Diab 5.1.2 and CodeWarrior 1.5 b2
# STACK FRAME DESIGN: Depth: 20 words (0xA0, or 80 bytes)
# ************* ______________
# 0x4C * GPR12 * ^
# 0x48 * GPR11 * |
# 0x44 * GPR10 * |
# 0x40 * GPR9 * |
# 0x3C * GPR8 * |
# 0x38 * GPR7 * GPRs (32 bit)
# 0x34 * GPR6 * |
# 0x30 * GPR5 * |
# 0x2C * GPR4 * |
# 0x28 * GPR3 * |
# 0x24 * GPR0 * ___v__________
# 0x20 * CR * __CR__________
# 0x1C * XER * ^
# 0x18 * CTR * |
# 0x14 * LR * locals & padding for 16 B alignment
# 0x10 * padding * |
# 0x0C * padding * |
# 0x08 * padding * ___v__________
# 0x04 * resvd- LR * Reserved for calling function
# 0x00 * SP * Backchain (same as gpr1 in GPRs)
# *************
.text
.globl IVOR11Handler
.globl FitISR # Needed for CodeWarrior compile
.align 16 # Align IVOR handlers on a 16 byte (2**4) boundary
# GHS, Cygnus, Diab(default) use .align 4; Metrowerks .align 16
IVOR11Handler:
prolog: # PROLOGUE
stwu r1, -0x50 (r1) # Create stack frame and store back chain
stw r12, 0x4C (r1) # Store gprs
stw r11, 0x48 (r1)
stw r10, 0x44 (r1)
stw r9, 0x40 (r1)
stw r8, 0x3C (r1)
stw r7, 0x38 (r1)
stw r6, 0x34 (r1)
stw r5, 0x30 (r1)
stw r4, 0x2C (r1)
stw r3, 0x28 (r1)
stw r0, 0x24 (r1)
mfCR r0 # Store CR
stw r0, 0x20 (r1)
mfXER r0 # Store XER
stw r0, 0x1C (r1)
mfCTR r0 # Store CTR
stw r0, 0x18 (r1)
mfLR r0 # Store LR
stw r0, 0x14 (r1)
bl FitISR # Execute Decrementer ISR, but return here
epilog: # EPILOGUE
lwz r0, 0x14 (r1) # Restore LR
mtLR r0
lwz r0, 0x18 (r1) # Restore CTR
mtCTR r0
lwz r0, 0x1C (r1) # Restore XER
mtXER r0
lwz r0, 0x20 (r1) # Restore CR
mtcrf 0xff, r0
lwz r0, 0x24 (r1) # Restore gprs
lwz r3, 0x28 (r1)
lwz r4, 0x2C (r1)
lwz r5, 0x30 (r1)
lwz r6, 0x34 (r1)
lwz r7, 0x38 (r1)
lwz r8, 0x3C (r1)
lwz r9, 0x40 (r1)
lwz r10, 0x44 (r1)
lwz r11, 0x48 (r1)
lwz r12, 0x4C (r1)
addi r1, r1, 0x50 # Restore space on stack
rfi # End of Interrupt
MPC5500
Interrupt
eMIOS Request to
Crystal 12 MHz sysclk Channel 0 INTC
FMPLL
8 MHz as Modulus INTC
Counter (Software
Write to Vector
INTC Mode)
eMIOS Chan. 0 SW IRQ 4
Interrupt
Service Routine
Common
INTC
interrupt request
to CPU core
4.2 Design
The overall program flow is shown below, followed by design steps and a stack frame implementation.
vector to
IVPR0:15 + IVOR416:28
handlers.s file
main.c file
IntcIsrVectors.c file IVOR4Handler:
prologue:
save SRR0:1, main {
ISR Vector Table: fetch ISR vector, init IVPR, IVOR4
... re-enable interrupts init INTC
SW IRQ 4 ISR addr save registers init eMIOS Chan 0
... branch to fetched ISR vector init SW 4 interrupt
eMIOS Ch 0 ISR addr epilogue: enable interrupts
... restore registers wait forever
... disable interrupts }
... write to EOIR
restore SRR0:1 emiosCh0ISR {
return increment counter
invoke SW 4 interrupt
clear flag
}
SW4ISR {
increment counter
clear flag
}
4.2.1 Initialization
Table 8. Initialization: INTC in Software Vector Mode
4.3 Code
MPC5500
Interrupt
eMIOS Request to
Crystal 12 MHz sysclk Channel 0 INTC
FMPLL
8 MHz as Modulus INTC
Counter (Software
Write to Vector
INTC Mode)
eMIOS Chan. 0 SW IRQ 4
Interrupt
Service Routine
Unique
INTC
interrupt request
to CPU core
1. The SPE’s accumulator is not saved in the prologue. It is assumed SPE instructions are not used in this example.
5.2 Design
The overall program flow is shown below, followed by design steps and a stack frame implementation.
INTC vector 51 interrupt taken
vector to
IVPR0:15 + 51*(0x10)
handlers.s file
handler.s file main.c file
emiosCh0Handler:
IntcHandlerBranchTable prologue: main {
b handler_0 save registers init IVPR
... re-enable interrupts init INTC
b handler_1 branch to emiosCh0ISR init SwIrq4
... epilogue: init eMIOS Chan 0
b handler_2 restore registers enable interrupts
... disable interrupts wait forever
b handler_3 write to EOIR }
... return
b SwIrq4Handler emiosCh0ISR {
... SwIrq4Handler: increment counter
... prologue: invoke SW 4 interrupt
b handler_50 save registers clear flag
... re-enable interrupts }
b emiosCh0Handler branch to SwIrq4ISR
... epilogue: SwIrq4ISR {
b handler_52 restore registers increment counter
... disable interrupts clear flag
... write to EOIR }
b handler_307 return
5.2.1 Initialization
Table 13. Initialization: INTC in Hardware Vector Mode
Relevant Bit
Step Pseudo Code
Fields
Relevant Bit
Step Pseudo Code
Fields
5.3 Code
void emiosCh0ISR(void) {
emiosCh0Ctr++; /* Increment interrupt counter */
INTC.SSCIR[4].R = 2; /* Invoke software interrupt 4 */
EMIOS.CH[0].CSR.B.FLAG=1; /* Clear channel's flag */
}
void SwIrq4ISR(void) {
SWirq7Ctr++; /* Increment interrupt counter */
INTC.SSCIR[4].R = 1; /* Clear channel's flag */
}
emiosCh0Handler:
# PROLOGUE
stwu r1, -0x50 (r1) # Create stack frame and store back chain
stw r3, 0x28 (r1) # Store a working register
mfsrr0 r3 # Store SRR0:1 (must be done before enabling EE)
stw r3, 0x0C (r1)
mfsrr1 r3
stw r3, 0x10 (r1)
wrteei 1 # Set MSR[EE]=1(must wait a couple clocks after reading IACKR)
stw r12, 0x4C (r1) # Store rest of gprs
stw r11, 0x48 (r1)
stw r10, 0x44 (r1)
stw r9, 0x40 (r1)
stw r8, 0x3C (r1)
stw r7, 0x38 (r1)
stw r6, 0x34 (r1)
stw r5, 0x30 (r1)
stw r4, 0x2C (r1)
stw r0, 0x24 (r1)
mfcr r3 # Store CR
stw r3, 0x20 (r1)
mfxer r3 # Store XER
stw r3, 0x1C (r1)
mfctr r3 # Store CTR
stw r3, 0x18 (r1)
mflr r3
stw r3, 0x14 (r1) # Store LR
bl emiosCh0ISR
# EPILOGUE
lwz r3, 0x14 (r1) # Restore LR
mtlr r3
lwz r3, 0x18 (r1) # Restore CTR
mtctr r3
lwz r3, 0x1C (r1) # Restore XER
mtxer r3
lwz r3, 0x20 (r1) # Restore CR
mtcrf 0xff, r3
lwz r0, 0x24 (r1) # Restore other gprs except working registers
lwz r5, 0x30 (r1)
lwz r6, 0x34 (r1)
lwz r7, 0x38 (r1)
lwz r8, 0x3C (r1)
lwz r9, 0x40 (r1)
lwz r10, 0x44 (r1)
lwz r11, 0x48 (r1)
lwz r12, 0x4C (r1)
mbar 0 # Ensure store to clear flag bit has completed
lis r3, INTC_EOIR@ha # Load upper half of EIOR address to r3
li r4, 0
wrteei 0 # Disable interrupts for rest of handler
stw r4, INTC_EOIR@l(r3)# Write 0 to INTC_EOIR (address 0xFFF4 8018)
lwz r3, 0x0C (r1) # Restore SRR0
mtsrr0 r3
lwz r3, 0x10 (r1) # Restore SRR1
mtsrr1 r3
lwz r4, 0x2C (r1) # Restore working registers
lwz r3, 0x28 (r1)
addi r1, r1, 0x50 # Delete stack frame
rfi # End of Interrupt
SwIrq4Handler:
# PROLOGUE
stwu r1, -0x50 (r1) # Create stack frame and store back chain
stw r3, 0x28 (r1) # Store a working register
mfsrr0 r3 # Store SRR0:1 (must be done before enabling EE)
stw r3, 0x0C (r1)
mfsrr1 r3
stw r3, 0x10 (r1)
wrteei 1 # Set MSR[EE]=1(must wait a couple clocks after reading IACKR)
stw r12, 0x4C (r1) # Store rest of gprs
stw r11, 0x48 (r1)
stw r10, 0x44 (r1)
stw r9, 0x40 (r1)
stw r8, 0x3C (r1)
stw r7, 0x38 (r1)
stw r6, 0x34 (r1)
stw r5, 0x30 (r1)
stw r4, 0x2C (r1)
stw r0, 0x24 (r1)
mfcr r3 # Store CR
stw r3, 0x20 (r1)
mfxer r3 # Store XER
stw r3, 0x1C (r1)
mfctr r3 # Store CTR
stw r3, 0x18 (r1)
mflr r3
stw r3, 0x14 (r1) # Store LR
bl SwIrq4ISR
# EPILOGUE
lwz r3, 0x14 (r1) # Restore LR
mtlr r3
lwz r3, 0x18 (r1) # Restore CTR
mtctr r3
lwz r3, 0x1C (r1) # Restore XER
mtxer r3
lwz r3, 0x20 (r1) # Restore CR
mtcrf 0xff, r3
lwz r0, 0x24 (r1) # Restore other gprs except working registers
lwz r5, 0x30 (r1)
lwz r6, 0x34 (r1)
lwz r7, 0x38 (r1)
lwz r8, 0x3C (r1)
lwz r9, 0x40 (r1)
lwz r10, 0x44 (r1)
lwz r11, 0x48 (r1)
lwz r12, 0x4C (r1)
mbar 0 # Ensure store to clear flag bit has completed
lis r3, INTC_EOIR@ha # Load upper half of EIOR address to r3
li r4, 0
wrteei 0 # Disable interrupts for rest of handler
stw r4, INTC_EOIR@l(r3)# Write 0 to INTC_EOIR (address 0xFFF4 8018)
lwz r3, 0x0C (r1) # Restore SRR0
mtsrr0 r3
lwz r3, 0x10 (r1) # Restore SRR1
mtsrr1 r3
lwz r4, 0x2C (r1) # Restore working registers
lwz r3, 0x28 (r1)
addi r1, r1, 0x50 # Delete stack frame
rfi # End of Interrupt
1 Note:To allow MMU entries to specify the write mode policy, the cache write mode, L1CSR0[CWM],
must be set to 1.
This program shows how MMU entries are created. However, there is not any memory or I/O at least on
the MPC5554 for the effective address range of this entry, so nothing can be accessed yet. The cache
program later will use this entry to allocate part of cache as SRAM. Accessing the MMU’s TLB entries is
done using sprs MAS0:3 as shown below.
gpr gpr
MPC5500 mtspr mfspr
spr’s MAS1:3 spr’s MAS1:3
tlbwe* *Entry # defined in MAS0[ESEL] tlbre*
MMU TLB Table
Entry 00 V TS TID EPN RPN SIZE Permissions Memory/Cache Attributes User Attributes IPROT
Entry 01 V TS TID EPN RPN SIZE Permissions Memory/Cache Attributes User Attributes IPROT
••• •••
Entry 23 V TS TID EPN RPN SIZE Permissions Memory/Cache Attributes User Attributes IPROT
Exercise: If your debugger supports viewing the MMU TLB table, view the table entries before and after
running the code1. Create a new MMU entry #7 which starts at address 0x4009 0000, with a size of 16 KB.
1. For the Lauterbach debugger, select “MMU TLB1 Table” from the MPC5554 menu.
For the Green Hills debugger, type “target tlbr 0..7” from the command prompt to display TLB entries 0 to 7.
6.2 Design
Below is Figure 6-6 of the e200z6 PowerPC(TM) Core Reference Manual Rev. 0 for reference.
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
MAS0 0 TBSEL 0 ESEL 0 NV
MAS2 EPN 0 W I M G E
MAS3 RPN 0 U0 U1 U2 U3 UX SX UW SW UR SR
Figure 11.
Initialize MMU Select TLB entry # and define MMU R/W & Replacement spr MAS0 =
TLB entry 6 Control: 0x1006 0000
- Select TLB entry #6 MAS0[ESEL] = 6
- Select TLB 1 (required) MAS0[TBLSEL] = 1
- Null replacement MAS0[NVCAM] = 0
Define Descriptor Context and Configuration Control: spr MAS1 =
- Set page as valid MAS1[VALID] = 1 0x8000 0100
- No invalidation protection MAS1[IPROT] = 0
- Use global process ID MAS1[TID] = 0
- Use default translation space MAS1[TS] = 0
- Size = 4KB MAS1[TSIZE] - 0x1
Define EPN and Page Attributes: spr MAS2 =
- EPN = 0x40 0400 for address 0x4004 0000 MAS2[EPN] = 0x40 0400 0x4004 0000
- WIMAGE = all 0’s; use cache inhibit, no write-thru MAS2[W,I,M,G,E] = 0
Define RPN and Access Control (here as RW data) spr MAS3 =
- RPN = 0x40 0400 for address 0x4004 0000 MAS3[RPN] = 0X40 0400 0x4004 000F
- Set user bits to 0 (unused) MAS3[U0:3] = 0
- Disable both user & supervisor execution MAS3[UX, SX] = 0
- Enable both user and supervisor data R and W MAS3[UR, SR, UW, SW] = 1
Write TLB entry fields in MAS1:3 to the entry per MAS0[ESEL] tlbwe1
NOTES:
1
Per Book E, a context synchronizing instruction (CSI), such as an isync, would be needed before the tlbwe instruction if
there were uncompleted preceding storage accesses. Similarly a CSI, such as isync or mbar, would be needed after the
tlbwe to ensure any immediate subsequent storage accesses use the updated TLB entry values.
6.3 Code
/* main.c - MMU - create TLB entry example */
/* Description: Creates a new entry to the TLB table in the MMU */
/* Compiled with Diab v 5.1.2 and CodeWarrior 1.5 beta 2*/
/* Rev 1.0 Sept 28, 2003 S.Mihalik, Copyright Freescale, 2004. All Rights Reserved */
/* Notes: */
/* 1. MMU not initialized; must be done by debug scripts or BAM */
/* 2. L2SRAM not initialized; must be done by debug scripts */
#include "mpc5554.h"
asm void MMU_init_TLB6(void) {
lis r3, 0x1006 /* Select TLB entry #, define R/W replacment control */
mtMAS0 r3 /* Load MAS0 with 0x1006 0000 for TLB entry #6 */
/* Define description context and configuration control:*/
/* VALID=1, IPROT=0, TID=0, TS=0, TSIZE=1 (4KB size) */
lis r3, 0x8000 /* Load MAS 1 with 0x8000 0100 */
ori r3, r3, 0x0100
mtMAS1 r3
/* Define EPN and page attributes: */
/* EPN = 0x4004 0000, WIMAGE = all 0's */
lis r3, 0x4004 /* Load MAS2 with 0x4004 0000 */
mtMAS2 r3
/* Define RPN and access control for data R/W */
/* RPN = 0x4004 0000, U0:3=0, UX/SX=0, UR/SR/UW/SW=1 */
lis r3, 0x4004 /* Load MAS3 with 0x4004 000F */
ori r3, r3, 0x000F
mtMAS3 r3
tlbwe /* Write entry defined in MAS0 (entry 6 here) to MMU TLB */
}
void main (void) {
int i = 0; /* Dummy idle counter */
MMU_init_TLB6(); /* Define 4KB R/W space starting at 0x4004 0000 */
while (1) { i++; } /* Loop forever */
}
MPC5500
Cache Bypassed
1. The CodeWarrior debugger has an Initializaiton File, e.g., MPC5554.mem which defines legal ranges of memory and unused
(“reserved”) ranges. This file must be modified to define the new address range, and has been modified in the Freescale provided
code.
7.2 Design
Table 19. Cache: Configure Part as RAM
Relevant
Step Pseudo Code
Bit Fields
Enable If cache is already being invalidated, wait until done CINV = 0 Wait for L1SCR0[CINV] = 0
cache
Invalidate cache
- Use sync instructions before writing to L1CSR0 msync
iscync
- Set cache invalidation bit CINV = 1 spr L1CSR0[CINV] = 1
Wait until cache invalidation completes CINV = 0 Wait for L1SCR0[CINV] = 0
If cache invalidation was aborted, ABT=1 if L1SCR0[ABT] = 1,
then attempt another cache invalidation. then try to invalidate cache again
Enable cache in copyback mode, keeping other control bits at 0
- Use sync instructions before writing to L1CSR0 msync
isync
- Set mode to copyback CWM=1 L1SCR0 = 0x0010 0001
- Enable cache CE=1
Initialize (See previous example, MMU: Create TLB Entry) spr MAS0 = 0x1006 0000
MMU TLB spr MAS1 = 0x8000 0100
entry 6 spr MAS2 = 0x4004 0000
spr MAS3 = 0x4004 000F
tlbwe1
Lock 4KB Initialize loop counter for 4KB block size / 32B line size = 128 spr CTR = 0x80
in cache
Load a register with start address of new address space r3 = 0x4004 0000
For each 32B cache line in the 4KB space: Locking Loop:
- Establish line address in cache (and zero out line) dcbz instruction for line’s address
- Lock line in cache dcbtls instruction for line’s address
NOTES:
1 Per Book E, a context synchronizing instruction (CSI), such as an isync, would be needed before the tlbwe instruction if
there were uncompleted preceding storage accesses. Similarly a CSI, such as isync or mbar, would be needed after the
tlbwe to ensure any immediate subsequent storage accesses use the updated TLB entry values.
7.3 Code
/* main.c - Configure part of cache as SRAM */
/* Compiled with CodeWarrior 1.5 beta 2, Diab v 5.2.1 */
/* Rev 0.1 Sept 27, 2004 S.Mihalik, Copyright Freescale, 2004. All Rights Reserved */
/* Notes: */
/* 1. MMU not initialized; must be done by debug scripts or BAM */
/* 2. L2SRAM not initialized; must be done by debug scripts */
#include "mpc5554.h"
asm void cache_enable(void) {
WaitForInvalidationComplete1: /* If CINV is already set, wait until it clears */
mfspr r3, l1csr0 /* Get current status of cache from spr L1CSR0*/
li r4, 0x0002 /* In a scratch register set bit 30 to 1, other bits 0 */
and r3, r3, r4 /* Mask out all bits except CINV*/
cmpli r3, 0x0002 /* Compare if CINV, bit 30, =1 */
beq WaitForInvalidationComplete1
InvalidateCache:
msync /* Before writing to L1CSR0, execute msync & isync */
isync
mtspr l1csr0, r4 /* Invalidate cache: Set L1CSR0[CINV]=1; other fields=0*/
WaitForInvalidationComplete2:
mfspr r3, l1csr0 /* Get current status of cache from spr L1CSR0*/
and r3, r3, r4 /* Mask out all bits except CINV */
cmpli r3, 0x0002 /* Compare if CINV, bit 30, =1 */
beq WaitForInvalidationComplete2
/* Branch to error if cache invalidation was aborted */
mfspr r3, l1csr0 /* Get current status of cache from spr L1CSR0*/
li r4, 0x0004 /* In a scratch register set bit 29 to 1, other bits 0 */
and r3, r3, r4 /* Mask out all bits except CABT*/
cmpli r3, 0x0004 /* Compare if CABT, bit 29, = 1 */
beq InvalidateCache /* If there was an aborted invalidation, attempt again */
/* Enable cache */
lis r3, 0x0010 /* In a scratch register set bit 12 = 0 (used to set CWM)*/
ori r3, r3, 0x1 /* Also set bit 31 =1 (used for setting CE) */
msync /* Before writing to L1CSR0, execute msync & isync */
isync
mtspr l1csr0, r3 /* Enable cache with Cache others to 0 */
}
asm void MMU_init_TLB6(void) {
lis r3, 0x1006 /* Select TLB entry #, define R/W replacment control */
mtMAS0 r3 /* Load MAS0 with 0x1006 0000 for TLB entry #6 */
/* Define description context and configuration control:*/
/* VALID=1, IPROT=0, TID=0, TS=0, TSIZE=1 (4KB size) */
lis r3, 0x8000 /* Load MAS 1 with 0x8000 0100 */
ori r3, r3, 0x0100
mtMAS1 r3
/* Define EPN and page attributes: */
/* EPN = 0x4004 0000, WIMAGE = all 0's */
lis r3, 0x4004 /* Load MAS2 with 0x4004 0000 */
mtMAS2 r3
/* Define RPN and access control for data R/W */
/* RPN = 0x4004 0000, U0:3=0, UX/SX=0, UR/SR/UW/SW=1 */
lis r3, 0x4004 /* Load MAS3 with 0x4004 000F */
ori r3, r3, 0x000F
mtMAS3 r3
tlbwe /* Write entry defined in MAS0 (entry 6 here) to MMU TLB */
}
asm void cache_lock_4KB(void) {
li r3, 0x80 /* Load r3 with loop count = 4KB/32B = 128 = 0x80 */
mtCTR r3 /* Move loop count to spr CTR */
lis r3, 0x4004 /* Point r3 to start of desired address (r3=0x40040000)*/
LockingLoop:
dcbz r0, r3 /* Establish address in cache for 32B cache lie of 0's */
dcbtls 0, r0, r3 /* Lock that line in cache */
addi r3, r3, 0x20 /* Increment address pointer by 32 B */
bdnz LockingLoop /* Decrement CTR, and loop back if it is not yet zero */
}
void main (void) {
int i = 0; /* Dummy idle counter */
cache_enable(); /* Invalidate then enable cache in copyback mode */
MMU_init_TLB6(); /* Define 4KB R/W space starting at 0x4004 0000, no transl’n*/
cache_lock_4KB(); /* Lock 4KB R/W space starting at 0x4004 0000 in cache */
while (1) { i++; } /* Loop forever */
}
MPC5500
MFD
FMPLL
Fsys
PFD / Charge Pumps,
(sysclk)
Filter,
Fref Current Controlled RFD
Crystal
8 MHz PREDIV Oscillator
SIU
EBDF clkout
FM Control
8.2 Design
For an 8 MHz crystal (Fref) and a target frequency of 100 MHz (Fsys), derive target values as shown below
using the formala for Fsys:
From this we can see in this case that for Fsys, the target values are: MFD = 6, PREDIV=0, RFD = 0.
Initially software will set the RFD to the next higher value (RFD=1), then lowered in a second step to get
to the target frequency.
Now the bit field values for Frequency Modulation can be determined. The percent depth (P) is 1. For a
target MFD of 6, M = 480. The expected difference value (EXP) is calculated per the formula in the
MPC5554 Reference Manual, 11.4.4.1:
(MFD + 4) x M x P (6 + 4) x 480 x 1
EXP = -------------------------- = ----------------------- = 48
100 100
Loss of lock and loss of clock detection is not enabled in this example. The PLL will not exit reset until it
has locked. Since changing PREDIV, MFD or enabling FM can cause loss of lock, the loss of lock circuitry
and interrupts would not be enabled until after these steps.
Table 20. FMPLL: Frequency Modulation
1. Initalize PLL for less than desired frequency (40 MHz) FMPLL_SYNCR = 0x0308 0030
- EXP value based on calculation = 48 (0x30) EXP = 0x30
- Multiplication Factor Divider = 6 MFD = 6
- PREDIVider= 0 PREDIV = 0 (default)
- Initial Reduced Frequency Divider = 1 RFD = 1
- Keep Frequency Modulation disabled for now DEPTH = 0 (default)
2. Wait for PLL to lock wait for LOCK = 1 wait for FMPLL_SYNSR[LOCK] = 1
3. Enable FM: FMPLL_SYNCR = 0x0308 0430
- Set DEPTH to 1 % DEPTH = 1
- Set RATE RATE = 1 (Fref / 40)
4. Wait for PLL to re-lock (relocks after CALDONE=1) wait for LOCK = 1 wait for FMPLL_SYNSR[LOCK] = 1
5. Verify calibration completed and was successful CALDONE = 1 if ((FMPLL_SYNSR[CALDONE != 1) or
CALPASS = 1 (FMPLL_SYNSR[CALPASS] != 1))
then log an error
6. To go target frequency (80 MHz) RFD = 0 FMPLL_SYNCR = 0x0300 0430
8.3 Code
/* main.c - FMPLL example */
/* Rev 1.0 Sept 21 2004 S. Mihalik
/* Compiled with CodeWarrior 1.5 beta 1, Diab 5.1.2 */
/* Copyright Freescale Semiconductor, Inc. 2004 All rights reserved. */
/* Notes: */
/* 1. ECC in L2SRAM is not initialized here; must be done by debug scripts */
/* 2. Cache is not used */
#include "mpc5554.h"
void errorLog (void){
while (1) {} /* Placeholder for FMPLL error - wait forever */
}
void initFMPLL(void) {
FMPLL.SYNCR.R = 0x03080030; /* Initial setting: 40 MHz for 8 MHz crystal*/
while (FMPLL.SYNSR.B.LOCK != 1) {}; /* Wait for LOCK = 1 */
FMPLL.SYNCR.R = 0x03080430; /* Enable FM */
while (FMPLL.SYNSR.B.LOCK != 1) {}; /* Wait for FMPLL to LOCK again */
if ((FMPLL.SYNSR.B.CALDONE != 1) | (FMPLL.SYNSR.B.CALPASS != 1)) {
errorLog(); /* Error if calibration is not done or did not pass */
}
FMPLL.SYNCR.R = 0x03000430; /* Final setting: 80 MHz for 8 MHz crystal */
}
void main (void){
int i=0; /* Dummy counter */
initFMPLL(); /* Initialize FMPLL for 80 MHz & 1% Frequency Modulation depth */
while (1) {i++; } /* Wait forever */
}
MPC5500
SRAM
eDMA
TCD0
TCD1 Source Array
SRAM
•• XBAR
Transfer
•
Control
Descriptors TCD18
(TCD’s) •• Destination Byte
•
TCDn Other Other
XBAR XBAR
Masters Slaves
9.2 Design
Table 21. DMA: Block Move
9.3 Code
/* main.c - DMA-Block Move example */
/* Compiled with CodeWarrior 1.5 beta 2, Diab v 5.2.1 */
/* Rev 0.1 Sept 30, 2004 S.Mihalik, Copyright Freescale, 2004. All Rights Reserved */
/* Notes: */
/* 1. MMU not initialized; must be done by debug scripts or BAM */
/* 2. L2SRAM not initialized; must be done by debug scripts */
#include "mpc5554.h"
void initTCD18(void) {
EDMA.CR.R = 0x0000E400; /* Use fixed priority arbitration for DMA groups and channels */
EDMA.CPR[18].R = 0x12; /* Channel 18 priorites: group priority = 1, channel priority = 2 */
EDMA.SSBR.R = 18; /* Set channel 18 START bit to initiate first minor loop transfer */
‘Hello World<CR>’
MPC5500
eSCI_A
FMPLL TxDA
Crystal
with 1.5x Data Register Personal
8 MHz
Multiplier XCVR Computer
RxDA COM Port
10.2 Design
The system clock here will be 12 MHz, the default clock for an 8 MHz cystal. Hence for a desired 9600
baud rate, the ideal calculation for SBRn bitfield, eSCIx_CR1[SBRn] is:
Rounding off the the closest whole number, 78 will be used for BR.
Table 22.
Data Init Initialize data string to be transmitted on eSCI_A TransData = “Hello World!<CR>”
Initialize byte used to recieve data from eSCI_A RecData = 0
Init eSCI_A Turn on the eSCI module (in case it was off) MDIS = 0 (default) ESCIA_CR2 = 0x2000
Initialize eSCI control ESCIA_CR1 = 0x004E 000C
- Baud Rate value = 12 M / (16x9600) ~= 78 SBR= 78 (0x4E)
- Word length = 8 bits M = 0 (default)
- Parity is not enabled PE = 0 (default)
- Enable transmitter TE = 1
- Enable receiver RE = 1
Configure pads:
- U24: TxDA PA = primary SIU_PCR[89] = 0x0400
- V24: RxDA PA = primary SIU_PCR[90] = 0x0400
Transmit Data Loop for # characters: Loop for # characters {
- Wait for Transmit Data Register Empty status flag wait for TDRE = 1 wait for ESCIA_SR[TDRE] = 1
- Clear status flag write TRDE = 1 ESCIA_SR = 0x8000 0000
- Write one character ESCIA_DR = next char. }
Read and Echo Wait for Receive Data Register Full status flag wait for RDRF = 1 wait for ESCIA_SR[RDRF] = 1
Back Data
Read byte RecData = ESCIA_DR
Clear status flag write RDRF=1 ESCIA_SR = 0x2000 0000
Ensure Transmit Data Register Empty status flag wait for TDRE = 1 wait for ESCIA_SR[TDRE] = 1
Clear status flag write TRDE = 1 ESCIA_SR = 0x8000 0000
Transmit back (echo) received byte ESCIA_DR = RecData
10.3 Code
/* main.c: Simple eSCI program */
/* Compiled with CodeWarrior 1.5 beta 2, Diab v 5.2.1, Green Hills v 4.0.7 */
/* Rev 0.1 Sept 30, 2004 S.Mihalik, Copyright Freescale, 2004. All Rights Reserved */
/* Rev 1.0 July 14 2005 SM-Cleared TDRE, RDRF flags as required in 5554RevA & later*/
/* Notes: */
/* 1. MMU not initialized; must be done by debug scripts or BAM */
/* 2. L2SRAM not initialized; must be done by debug scripts */
#include "MPC5554.h"
const uint8_t TransData[] = {"Hello World!\n\r"}; /* Transmit string & CR*/
uint8_t RecData; /* Received byte from eSCI */
void initESCI_A (void) {
ESCI_A.CR2.R = 0x2000; /* Module is enabled (default setting ) */
ESCI_A.CR1.R = 0x004E000C; /* 9600 baud, 8 bits, no parity, Tx & Rx enabled */
SIU.PCR[89].R = 0x400; /* Configure pad U24 for primary func: TxDA */
SIU.PCR[90].R = 0x400; /* Configure pad V24 for primary func: RxD A */
}
void TransmitData (void) {
uint8_t j; /* Dummy variable */
for (j=0; j< sizeof (TransData); j++) { /* Loop for character string */
while (ESCI_A.SR.B.TDRE == 0) {} /* Wait for transmit data reg empty = 1*/
ESCI_A.SR.R = 0x80000000; /* Clear TDRE flag */
ESCI_A.DR.B.D = TransData[j]; /* Transmit 8 bits Data */
}
}
void RecieveData (void) {
while (ESCI_A.SR.B.RDRF == 0) {} /* Wait for receive data reg full = 1 */
RecData = ESCI_A.DR.B.D; /* Read byte of Data*/
ESCI_A.SR.R = 0x20000000; /* Clear RDRF flag */
while (ESCI_A.SR.B.TDRE == 0) {} /* Wait for transmit data reg empty = 1 */
ESCI_A.SR.R = 0x80000000; /* Clear TDRE flag */
ESCI_A.DR.B.D = RecData; /* Echo back byte of Data read */
}
void main(void) {
initESCI_A(); /* Enable Tx/Rx for 9600 baud, 8 bits, no parity */
TransmitData(); /* Transmit string of characters on eSCI A */
RecieveData(); /* Recieve and echo character on eSCI A */
while (1) {} /* Wait forever */
}
MPC5500 eMIOS
eMIOS
eMIOS
FMPLL eMIOS Channel 0
Crystal Channel 23
with 1.5x Prescaler (OPWM:
8 MHz (Up counts
Multiplier (Divide by 12) Rising edge at 250
to 1000)
Falling edge at 500)
eMIOS
12 MHz sysclk 1 MHz Channel 1
eMIOS internal clock (OPWM:
(available to all eMIOS channels) Rising edge at 500
Falling edge at 999)
Time Base A
(Counts 1000 1 µsec clocks;
available to all eMIOS channels)
11.2 Design
Table 23. Initialization: eMIOS Output Pulse Width and Frequency Modulation (OPWFM)
11.3 Code
/* main.c - eMIOS OPWM example */
/* Rev 0.1 Sept 9 2004 S.Mihalik
/* Compiled with CodeWarrior 1.5 beta 1, Diab 5.1.2 */
/* Copyright Freescale Semiconductor, Inc. 2004 All rights reserved. */
/* Notes: */
/* 1. ECC in L2SRAM is not initialized here; must be done by debug scripts */
/* 2. Cache is not used */
#include "mpc5554.h"
void initEMIOS(void) {
EMIOS.MCR.B.GPRE= 0xC; /* Divide 12MHz sysclk by 12 for 1MHz eMIOS clk*/
EMIOS.MCR.B.ETB = 0; /* External time base is disabled; Ch 23 drives ctr bus A*/
EMIOS.MCR.B.GPREN = 1; /* Enable eMIOS clock */
EMIOS.MCR.B.GTBE = 1; /* Enable global time base */
EMIOS.MCR.B.FRZ = 1; /* Enable stopping channels when in debug mode */
}
void initEMIOSch23(void) { /* EMIOS CH 23: Modulus Up Counter */
EMIOS.CH[23].CADR.R = 1000; /* Period will be 1000 clocks (1 msec) */
EMIOS.CH[23].CCR.B.MODE = 0x10; /* Mode is Modulus Counter, internal clock */
EMIOS.CH[23].CCR.B.BSL = 0x3; /* Use internal counter */
EMIOS.CH[23].CCR.B.UCPRE=0; /* Set channel prescaler to divide by 1 */
EMIOS.CH[23].CCR.B.FREN = 1; /* Freeze channel counting when in debug mode*/
EMIOS.CH[23].CCR.B.UCPREN = 1; /* Enable prescaler; uses default divide by 1*/
}
void initEMIOSch0(void) { /* EMIOS CH 0: Output Pulse Width Modulation */
EMIOS.CH[0].CADR.R = 250; /* Leading edge occurs when channel counter bus=250*/
EMIOS.CH[0].CBDR.R = 500; /* Trailing edge occurs when channel counter bus=500*/
EMIOS.CH[0].CCR.B.BSL = 0x0; /* Use counter bus A (default) */
EMIOS.CH[0].CCR.B.EDPOL = 1; /* Polarity-leading edge sets output/trailing clears*/
EMIOS.CH[0].CCR.B.MODE=0x20; /* Mode is Modulus Counter, internal clock */
SIU.PCR[179].B.PA = 3; /* Initialize pad AF15 for eMIOS channel. */
SIU.PCR[179].B.OBE = 1; /* Initialize pad AF15 for output */
}
void initEMIOSch1(void) { /* EMIOS CH 1: Output Pulse Width Modulation */
EMIOS.CH[1].CADR.R = 500; /* Leading edge occurs when channel counter bus=500*/
EMIOS.CH[1].CBDR.R = 999; /* Trailing edge occurs when channel counter bus=999*/
EMIOS.CH[1].CCR.B.BSL = 0x0; /* Use counter bus A (default) */
EMIOS.CH[1].CCR.B.EDPOL = 1; /* Polarity-leading edge sets output/trailing clears*/
EMIOS.CH[1].CCR.B.MODE=0x20; /* Mode is Modulus Counter, internal clock */
SIU.PCR[180].B.PA = 3; /* Initialize pad AF15 for eMIOS channel. */
SIU.PCR[180].B.OBE = 1; /* Initialize pad AE15 for output */
}
void main (void) {
int i = 0; /* Dummy idle counter */
initEMIOS(); /* Initialize eMIOS to provide 1 MHz clock to channels */
initEMIOSch23(); /* Initialize eMIOS channel 23 as modulus counter*/
initEMIOSch0(); /* Initialize eMIOS channel 0 as OPWM, using ch 23 as time base */
initEMIOSch1(); /* Initialize eMIOS channel 1 as OPWM, using ch 23 as time base */
while (1) {i++}; /* Wait forever */
}
}
MPC5500
eQADC
CFIFO0 Push Register
CFIFO0 Trigger Mode: Configuration
Single Scan, SW Trigger Commands
CFIFO0
Conversion
AN0 Commands
• • ADC0_CR
• •
• • 40:1 ADC0_TSCR
ADC0
AN17 MUX ADC0_TBCR
• • (BN0)
ADC0_GCCR
• •
• • ADC0_OCCR
AN39
RFIFO0
12.2 Design
Table 24. eQADC Single Software Scan
12.3 Code
/* main.c: performs a simple single ADC conversion of channel 17 using ADC0 */
/* Rev 1.0 Sept 13, 2004 S. Mihalik. */
/* Copyright Freescale, 2004. All Rights Reserved */
/* Compiled with CodeWarrior 1.5 beta 2 and Diab 5.1.2 */
/* Notes: */
/* 1. MMU not initialized; must be done by debug scripts or BAM */
/* 2. L2SRAM not initialized; must be done by debug scripts */
#include "MPC5554.h"
void initADC0(void) {
EQADC.CFPR[0].R = 0x80800001; /* Send CFIFO 0 a ADC0 configuration command to */
/* enable ADC0 & sets prescaler = divide by 2 */
EQADC.CFCR[0].R = 0x0410; /* Trigger CFIFO 0 using Single Scan SW mode */
while (EQADC.FISR[0].B.EOQF !=1) {} /* Wait for End Of Queue flag */
EQADC.FISR[0].B.EOQF = 1; /* Clear End Of Queue flag */
}
void SendConvCmd (void) {
EQADC.CFPR[0].R = 0x80001100; /* Conversion command: convert ch 17 (pad C5) */
/* with ADC0, set EOQ, and send result to RFIFO 0 */
EQADC.CFCR[0].R = 0x0410; /* Trigger CFIFO 0 using Single Scan SW mode */
}
void ReadResult(void) {
static vuint32_t Result;
while (EQADC.FISR[0].B.RFDF != 1){} /* Wait for RFIFO 0's Drain Flag to set */
Result = EQADC.RFPR[0].R; /* Read result in lower 16 bits */
}
int main(void) {
int i = 0; /* Dummy idle counter */
initADC0(); /* Enable ADC0 only on eQADC */
SendConvCmd(); /* Send one conversion command for channel 17 */
ReadResult(); /* Read result */
while (1) {i++; } /* Wait forever */
}
13.2 Design
13.3 Code
/* main.c: performs a single SPI_A transmission to the MC33394 */
/* Rev 1.0 Sept 14 2004 S.Mihalik
/* Compiled with CodeWarrior 1.5 beta 1, Diab 5.1.2 */
/* Copyright Freescale Semiconductor, Inc. 2004 All rights reserved. */
/* Notes: */
/* 1. ECC in L2SRAM is not initialized here; must be done by debug scripts */
/* 2. Cache is not used */
#include "mpc5554.h"
void initDSPI_A(void) {
DSPI_A.MCR.R = 0x80000000; /* Configure DSPI_A as master */
DSPI_A.CTAR[0].R = 0x79000024; /* Configure CTAR0 for MC33394 */
SIU.PCR[93].R = 0x0E00; /* Config pad R26 as DSPI_A SCK, output */
SIU.PCR[94].R = 0x0E00; /* Config pad R25 as DSPI_A SIN */
SIU.PCR[95].R = 0x0E00; /* Config pad R24 as DSPI_A SOUT */
SIU.PCR[101].R = 0x0E00; /* Config pad U25 as DSPI_A PCS5 */
}
void SendCmd (void) {
DSPI_A.PUSHR.R = 0x082000FE; /* Send EOQ + SPI command to PCS5 with data 0x00FE */
}
void ReadData(void) {
static vuint32_t Result;
while (DSPI_A.SR.B.TCF != 1){} /* Wait for Transmit Complete Flag = 1 */
Result = DSPI_A.POPR.R; /* Read data returned from MC33394 */
}
int main(void) {
int i = 0; /* Dummy idle counter */
initDSPI_A(); /* Initialize DSPI_A as SPI, CTAR0 for MC33394 */
SendCmd(); /* Send one command to turn off Vref1 to MC33394 */
ReadData(); /* Read data sent back */
while (1) {i++; } /* Wait forever */
E-mail:
support@freescale.com
Japan:
Freescale Semiconductor Japan Ltd. Information in this document is provided solely to enable system and
Headquarters software implementers to use Freescale Semiconductor products. There are
ARCO Tower 15F no express or implied copyright licenses granted hereunder to design or
1-8-1, Shimo-Meguro, Meguro-ku, fabricate any integrated circuits or integrated circuits based on the
Tokyo 153-0064, Japan information in this document.
0120 191014 or +81 3 5437 9125
support.japan@freescale.com Freescale Semiconductor reserves the right to make changes without further
notice to any products herein. Freescale Semiconductor makes no warranty,
Asia/Pacific: representation or guarantee regarding the suitability of its products for any
Freescale Semiconductor Hong Kong Ltd. particular purpose, nor does Freescale Semiconductor assume any liability
arising out of the application or use of any product or circuit, and specifically
Technical Information Center
disclaims any and all liability, including without limitation consequential or
2 Dai King Street incidental damages. “Typical” parameters that may be provided in Freescale
Tai Po Industrial Estate Semiconductor data sheets and/or specifications can and do vary in different
Tai Po, N.T., Hong Kong applications and actual performance may vary over time. All operating
+800 2666 8080 parameters, including “Typicals”, must be validated for each customer
support.asia@freescale.com application by customer’s technical experts. Freescale Semiconductor does
not convey any license under its patent rights nor the rights of others.
For Literature Requests Only: Freescale Semiconductor products are not designed, intended, or authorized
for use as components in systems intended for surgical implant into the body,
Freescale Semiconductor Literature Distribution Center
or other applications intended to support or sustain life, or for any other
P.O. Box 5405 application in which the failure of the Freescale Semiconductor product could
Denver, Colorado 80217 create a situation where personal injury or death may occur. Should Buyer
1-800-441-2447 or 303-675-2140 purchase or use Freescale Semiconductor products for any such unintended
Fax: 303-675-2150 or unauthorized application, Buyer shall indemnify and hold Freescale
LDCForFreescaleSemiconductor@hibbertgroup.com Semiconductor and its officers, employees, subsidiaries, affiliates, and
distributors harmless against all claims, costs, damages, and expenses, and
reasonable attorney fees arising out of, directly or indirectly, any claim of
personal injury or death associated with such unintended or unauthorized
use, even if such claim alleges that Freescale Semiconductor was negligent
regarding the design or manufacture of the part.