Freescale Semiconductor Application Note Document Number: AN3266 Rev. 1, 5/2006 Getting Started with RS08 by: Vincent Ko Systems Engineering Microcontroller Division This application note is an introduction to the RS08 platform, an ultra low-cost 8-bit MCU core, from Freescale Semiconductor. Section 1 provides information for the user to get started with RS08 and section 2 includes application discussions to demonstrate techniques and concepts, together with working examples. 1 Introduction to RS08 This section covers the RS08 architecture, programming model, and instruction set to help the user to gain a good understanding on the platform. Where necessary, cross references are provided to the popular Freescale HC08 and S08 platforms. In most cases, the MC9RS08KA2 device is used in examples to illustrate concepts. Contents 1 Introduction to RS08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 RS08 Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 RS08 Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3 Paging Memory Scheme . . . . . . . . . . . . . . . . . . . . 15 1.4 MCU Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.5 Wait Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.6 Stop Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.7 Subroutine Call . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.8 Interrupt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2 Emulated ADC Application Example . . . . . . . . . . . . . . . 22 2.1 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.2 Calibration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.3 Measurement Result . . . . . . . . . . . . . . . . . . . . . . . 28 Appendix A Program Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 This document contains information on a new product under development. Freescale reserves the right to change or discontinue this product without notice. (c) Freescale Semiconductor, Inc., 2006. All rights reserved. Introduction to RS08 1.1 RS08 Architecture The RS08 platform is developed for extremely low cost applications. Its hardware size is optimized and the overall system cost is reduced. The smaller hardware size allows the silicon to fit into a smaller package, such as the 6-pin dual flat no lead package (DFN). The RS08 platform retains a similar programming model as in the popular HC08/S08 platforms to allow easy source code migration between the platforms. The main features of the RS08 platform are: * Subset of S08 instruction set * New instructions for shadow program counter (SPC) -- SHA and SLA * New tiny and short addressing modes for code size optimization * Maximum 16K-byte accessible memory space * Eliminated vector fetch mechanism for interrupt and reset service * Eliminated RAM stacking mechanism for subroutine call * Single level hardware stacking for subroutine call * Low power mode supported through the execution of STOP and WAIT instructions * Stop wakeup through internal or external interrupt trigger * Illegal address and opcode detection with reset * Hardware security feature to protect unauthorized access to the non-volatile memory (NVM) area * Debug and NVM program/erase support using single pin interface 1.1.1 CPU Registers The RS08 CPU registers include an 8-bit general purpose accumulator (A), 14-bit program counter (PC), 14-bit shadow program counter (SPC), and a 2-bit conditional code register (CCR). The CCR contains two status flags and are tested for conditional branch instructions such as BCS and BEQ. Figure 1-1 shows the RS08 CPU registers. 7 0 ACCUMULATOR 13 7 PROGRAM COUNTER 13 A 0 PC 0 SHADOW PROGRAM COUNTER SPC CONDITION CODE REGISTER Z C CCR CARRY ZERO Figure 1-1. RS08 CPU Registers Getting Started with RS08, Rev. 1 2 Freescale Semiconductor Introduction to RS08 The 8-bit general purpose accumulator A provides a primary data register for the RS08 CPU. Data can be read from memory into A with the LDA instruction. The data in A can be written into memory with the STA instruction. The new added exchange instructions, SHA and SLA, allow values to be exchanged between accumulator A and shadow program counter (SPC) high byte and low byte respectively. The program counter (PC) contains the address of the next instruction or operand to be fetched as in the HC08/S08 platform. However, the PC in RS08 platform is 14-bit long, which means the maximum addressable space is 16K bytes. In HC08/S08 platform, the return PC value is stacked into RAM during subroutine calls using JSR and BSR instructions. In RS08 platform, RAM stacking mechanism is eliminated, return address is saved into the SPC register. Upon completion of the subroutine, RTS instruction will restore the content of the PC from SPC. SPC only provides a single level of address saving, nested subroutine calls can be performed through software stacking. User firmware can utilize SHA and SLA instructions to swap the high byte and the low byte content of SPC to A, then stack them to RAM. The status bits (Z and C) in condition code register (CCR) indicates the results of previous arithmetic and other operations. The bit definition is identical as in HC08/S08 platform. Please refer to RS08 Core Reference Manual for their detail definition. 1.1.2 Special Registers In additional to the CPU registers, there are two memory mapped registers that are tightly coupled with the core address generation. They are the indirect data register (D[X]) and the index register (X). These registers are located at $000E and $000F respectively. 7 0 INDIRECT DATA REGISTER D[X] (location $000E) 7 0 INDEX REGISTER X (location $000F) Figure 1-2. RS08 Special Registers Registers D[X] and X together perform indirect data access. The register X contains the address which is used when register D[X] is accessed. Figure 1-3 shows the index addressing scheme. The X and D[X] registers are not part of the CPU internal registers, but they are integrated seamlessly with the RS08 generic instruction set to form a pseudo instruction set. Getting Started with RS08, Rev. 1 Freescale Semiconductor 3 Introduction to RS08 $0000 $000E D[X] $000F Register X Register X can specify any location between $0000-$00FF Address indicated in Register X Content of this location can be accessed via D[X] $00FF $0100 Figure 1-3. Index Addressing Scheme 1.1.3 Generic Addressing Mode Whenever the MCU reads data from memory or writes data to memory, an addressing mode is used to determine the exact address whether data is read from or write to. Table 1-1 summarizes the generic addressing mode supported by the RS08 platform. Table 1-1. RS08 Addressing Modes Addressing Mode Example Inherent Addressing CLRA, INCA, SHA, RTS Direct Addressing LDA $20, AND $20 Relative Addressing BRA, BCS, BEQ Immediate Addressing LDA #9 Tiny Addressing INC <$0D Short Addressing CLR <$1D Extended Addressing JMP, JSR Getting Started with RS08, Rev. 1 4 Freescale Semiconductor Introduction to RS08 1.1.3.1 Addressing Modes Common to HC08/S08 Platforms The inherent addressing, direct addressing, relative addressing, immediate addressing, and extended addressing modes in RS08 have identical operation as in the HC08/S08 platform. Inherent addressing is used when the CPU inherently knows all the information needed to complete the instruction and no addressing information is supplied in the source code. Relative addressing is used to specify the offset address for branch instructions relative to the program counter. Immediate addressing is used when an explicit value to be used by the instruction is located immediately after the opcode in the instruction stream. Direct addressing is used to access operands located in direct address space ($0000 through $00FF). Extended addressing is used to specify 2-byte operand to the instructions. This addressing mode is only used in JMP and JSR instructions where the 14-bit target address is specified in the operand. 1.1.3.2 Tiny and Short Addressing Modes Tiny and short addressing modes are introduced in the RS08 platform. These addressing modes have similar operations to direct addressing mode but the addressable space is limited. Only portion of direct address space within $0000-$00FF can be accessed by these addressing modes. However, all instructions associated with these addressing modes are single byte instructions. Maximizing the utilization of these instructions can reduce the overall code size. Tiny addressing mode is capable of addressing only the first 16 bytes in the address map, from $0000 to $000F. This addressing mode is available for increment (INC), decrement (DEC), add (ADD), and subtract (SUB) instructions. Equivalent instructions are also available in direct addressing mode, 2-byte instructions, where the addressable space is from $0000-$00FF. User should add the less than symbol (<) before the operand in the source code as shown below, this forces the assembler to use tiny addressing instructions instead. INC DEC ADD SUB <$0D <$0D <$0D <$0D Short addressing mode is capable of addressing only the first 32 bytes in the address map, from $0000 to $001F. This addressing mode is available for clear (CLR), load accumulator A (LDA), and store accumulator A (STA) instructions. Similar to tiny addressing instructions equivalent instructions are also available in direct address mode. User should add the less than symbol (<) before the operand as shown below to force the assembler to use short addressing instructions. CLR <$1F LDA <$1F STA <$1F 1.1.3.3 Pseudo Addressing Modes Using the special registers, D[X] and X, the RS08 generic instruction set can be used to emulate some of the accumulator X operations in the HC08/S08 architecture. This emulation is supported by the assembler/compiler and it is done during the time of compilation. When zero offset indexing instructions or register X related operations are involved, user can use the same HC08/S08 coding syntax for RS08 programming. During compilation the assembler will convert the pseudo RS08 instructions to equivalent generic RS08 instructions. This operation is transparent to the user. Getting Started with RS08, Rev. 1 Freescale Semiconductor 5 Introduction to RS08 Below summarizes the pseudo addressing modes supported by the RS08 architecture. * Pseudo inherent addressing -- for example, TSTX, DBNZX -- is emulated by equivalent direct addressing operation where the operand is always loaded from register X location ($000F). In some of these operations, such as DECX and INCX, the tiny and short addressing instructions are available. The pseudo instructions become single byte. * Pseudo direct addressing -- for example, LDX $20, STX $20 -- is emulated by move (MOV) direct-direct operation. LDX operation is equivalent to moving operand to register X ($000F). STX operation is equivalent to move the content of register X to operand targeted address. * Pseudo immediate addressing -- for example, LDX #$09 -- is emulated by move (MOV) immediate-direct operation. Register X is loaded by explicit data. * Pseudo zero offset index addressing -- for example, ADD ,X -- is emulated by equivalent direct addressing operation where the operand is always loaded from register D[X] location ($000E). Register D[X] itself holds the indirect data that its address is indicated by register X. Performing operation on register D[X] has equivalent operation as HC08/S08 style zero offset index addressing. RS08 platform preserves the same HC08/S08 style coding syntax which helps user to migrate source code among these platform. Below shows some coding examples. LDA ,X ADD ,X DBNZ ,X, rel NOTE Pseudo instructions are based on emulation, they have equivalent HC08/S08 operations. However in term of CPU cycle count and instruction byte count, they are not the same. Special care is needed for timing critical software before migrating source code from HC08/S08 platform to RS08 platform. 1.2 RS08 Instruction Set The RS08 CPU core can be considered as a reduced version of S08 core. Most arithmetic operations are retained in the RS08 platform such that source code compatibility is maintained as much as possible. However, the RS08 platform is not intended for intensive mathematical calculations, therefore, nibble swap (NSA), multiple (MUL), and divide (DIV) operations were removed from the instruction set. Since the stacking mechanism is removed, instructions involving the stack pointer (SP) that were in HC08/S08 core were removed from the RS08 core. Code condition register (CCR) contains two status flags, Z-bit and C-bit, only conditional branch instructions involving these bits were included. Table 1-2 summarizes the difference between RS08 instruction set and S08 instruction set. Getting Started with RS08, Rev. 1 6 Freescale Semiconductor Introduction to RS08 Table 1-2. RS08 and S08 Instruction Set Comparison Description RS08 S08 Operation Arithmetic Operations: Add with Carry ADC ADC ADC ADC #opr8 opr8 ,X 1 X 1, 2 ADC ADC ADC ADC ADC ADC ADC ADC Add without Carry ADD ADD ADD ADD ADD #opr8 opr8 opr4 ,X 1 X 1, 2 ADD ADD ADD ADD ADD ADD ADD ADD #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP A (A) + (M) + (C) A (A) + (X) + (C) 2 #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP A (A) + (M) A (A) + (X) 2 Add Immediate Value (Signed) to Stack Pointer AIS #opr8 SP (SP) + (16 M) Add Immediate Value (Signed) to Index Register (H:X) AIX #opr8 H:X (H:X) + (16 M) Arithmetic Shift Left (Same as LSL) ASL opr8 ASLA ASLX ASL opr8,X ASL ,X ASL opr8,SP ASLA ASR opr8 ASRA ASRX ASR opr8,X ASR ,X ASR opr8,SP Arithmetic Shift Right Clear CLR opr8 CLR opr5 CLRA CLRX 1 CLR ,X 1 Decimal Adjust Accumulator Decrement DAA DEC opr8 DEC opr4 DECA DECX 1 DEC ,X 1 Divide Increment CLR opr8 CLRA CLRX CLRH CLR opr8,X CLR ,X CLR opr8,SP INC opr8 INC opr4 INCA INCX 1 INC ,X 1 C 0 b7 b0 b7 b0 C M $00 A $00 X $00 (A)10 DEC opr8 DECA DECX DEC opr8,X DEC ,X DEC opr8,SP M (M) - $01 A (A) - $01 X (X) - $01 DIV A (H:A)/(X) H Remainder INC opr8 INCA INCX INC opr8,X INC ,X INC opr8,SP M (M) + $01 A (A) + $01 X (X) + $01 Getting Started with RS08, Rev. 1 Freescale Semiconductor 7 Introduction to RS08 Table 1-2. RS08 and S08 Instruction Set Comparison (continued) Description RS08 S08 Operation Negate (Two's Complement) NEG opr8 NEGA NEGX NEG opr8,X NEG ,X NEG opr8,SP Subtract with Carry SBC SBC SBC SBC #opr8 opr8 ,X 1 X 1, 2 SBC SBC SBC SBC SBC SBC SBC SBC #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP A (A) - (M) - (C) A (A) - (X) - (C) 2 Subtract SUB #opr8 SUB opr8 SUB opr4 SUB ,X 1 SUB X 1, 2 SUB SUB SUB SUB SUB SUB SUB SUB #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP A (A) - (M) A (A) - (X) 2 Logical AND AND AND AND AND AND AND AND AND AND AND AND AND #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP A (A) & (M) A (A) & (X) 2 Clear Bit n in Memory BCLR n,opr8 BCLR n,X 1, 2 BCLR n,D[X] 1, 2 BCLR n, opr8 Mn 0 Xn 0 2 Set Bit n in Memory BSET n,opr8 BSET n,X 1, 2 BSET n,D[X] 1, 2 BSET n, opr8 Mn 1 Xn 1 2 COMA COM opr8 COMA COMX COM opr8,X COM ,X COM opr8,SP M (M)= $FF - (M) A (A) = $FF - (M) X (X) = $FF - (M) EOR EOR EOR EOR EOR #opr8 EOR opr8 EOR opr16 EOR opr8,X EOR opr16,X EOR ,X EOR opr8,SP EOR opr16,SP A (A M) A (A X) 2 M -(M) = $00 - (M) A -(A) = $00 - (A) X -(X) = $00 - (X) Logical Operations: Complement (One's Complement) Exclusive OR Memory with Accumulator Logical Shift Left (Same as ASL) LSLA #opr8 opr8 ,X1 X1, 2 #opr8 opr8 ,X 1 X 1, 2 LSL opr8 LSLA LSLX LSL opr8,X LSL ,X LSL opr8,SP C 0 b7 b0 Getting Started with RS08, Rev. 1 8 Freescale Semiconductor Introduction to RS08 Table 1-2. RS08 and S08 Instruction Set Comparison (continued) Description Logical Shift Right RS08 S08 LSR opr8 LSRA LSRX LSR opr8,X LSR ,X LSR opr8,SP LSRA Nibble Swap Accumulator NSA Inclusive OR Accumulator and Memory ORA ORA ORA ORA ORA ORA ORA ORA Rotate Left through Carry Rotate Right through Carry ORA ORA ORA ORA #opr8 opr8 ,X 1 X 1, 2 ROLA RORA Operation 0 C b7 b0 A (A[3:0]:A[7:4]) #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP ROL opr ROLA ROLX ROL opr,X ROL ,X ROL opr,SP ROR opr RORA RORX ROR opr,X ROR ,X ROR opr,SP A (A) | (M) A (A) | (X) 2 C b7 b0 C b7 b0 Branch Operations: Branch if Carry Bit Clear BCC rel BCC rel PC (PC) + $0002 + rel ? (C) = 0 Branch if Carry Bit Set (Same as BLO) BCS rel BCS rel PC (PC) + $0002 + rel ? (C) = 1 Branch if Equal BEQ rel BEQ rel PC (PC) + $0002 + rel ? (Z) = 1 Branch if Greater Than or Equal To (Signed Operands) BGE opr PC (PC) + $0002 + rel ? (N V) = 0 Branch if Greater Than (Signed Operands) BGT opr PC (PC) + $0002 + rel ? (Z) | (N V) = 0 Branch if Half Carry Bit Clear BHCC rel PC (PC) + $0002 + rel ? (H) = 0 Branch if Half Carry Bit Set BHCS rel PC (PC) + $0002 + rel ? (H) = 1 Branch if Higher BHI rel PC (PC) + $0002 + rel ? (C) | (Z) = 0 BHS rel PC (PC) + $0002 + rel ? (C) = 0 Branch if IRQ Pin High BIH rel PC (PC) + $0002 + rel ? IRQ = 1 Branch if IRQ Pin Low BIL rel PC (PC) + $0002 + rel ? IRQ = 0 Branch if Less Than or Equal To (Signed Operands) BLE opr PC (PC) + $0002 + rel ? (Z) | (N V) = 1 BLO rel PC (PC) + $0002 + rel ? (C) = 1 BLS rel PC (PC) + $0002 + rel ? (C) | (Z) = 1 Branch if Higher or Same (Same as BCC) Branch if Lower (Same as BCS) Branch if Lower or Same BHS rel BLO rel Getting Started with RS08, Rev. 1 Freescale Semiconductor 9 Introduction to RS08 Table 1-2. RS08 and S08 Instruction Set Comparison (continued) Description RS08 S08 Operation Branch if Less Than (Signed Operands) BLT opr PC (PC) + $0002 + rel ? (N V) =1 Branch if Interrupt Mask Clear BMC rel PC (PC) + $0002 + rel ? (I) = 0 Branch if Minus BMI rel PC (PC) + $0002 + rel ? (N) = 1 Branch if Interrupt Mask Set BMS rel PC (PC) + $0002 + rel ? (I) = 1 BNE rel PC (PC) + $0002 + rel ? (Z) = 0 BPL rel PC (PC) + $0002 + rel ? (N) = 0 PC (PC) + $0002 + rel Branch if Not Equal BNE rel Branch if Plus Branch Always BRA rel BRA rel Branch if Bit n in Memory Clear BRCLR n,opr8,rel BRCLR n,X,rel 1, 2 BRCLR n,D[X],rel 1, 2 BRCLR n , opr 8, rel Branch Never Branch if Bit n in Memory Set PC (PC) + $0003 + rel ? (Mn) = 0 PC (PC) + $0003 + rel ? (Xn) = 0 2 PC (PC) + $0002 BRN rel BRSET n,opr8,rel BRSET n,X,rel 1, 2 BRSET n,D[X],rel 1, 2 PC (PC) + $0003 + rel ? (Mn) = 1 PC (PC) + $0003 + rel ? (Xn) = 1 2 BRSET n , opr 8, rel For S08: Branch to Subroutine BSR rel BSR rel For RS08: Compare and Branch if Equal CBEQ opr8,rel CBEQA #opr8,rel CBEQ X rel 1, 2 CBEQ ,X,rel 1, 2 CBEQ opr8,rel CBEQA #opr8,rel CBEQX #opr8,rel CBEQ opr8, X+,rel CBEQ X+,rel CBEQ opr8,SP,rel PC (PC) + $0002; push (PCL) SP (SP) - $0001; push (PCH) SP (SP) - $0001 PC (PC) + rel PC (PC) + 2 Push PC to shadow PC PC (PC) + rel For S08: PC (PC) + $0003 + rel PC (PC) + $0003 + rel PC (PC) + $0003 + rel PC (PC) + $0003 + rel PC (PC) + $0002 + rel PC (PC) + $0004 + rel ? (A) - (M) = $00 ? (A) - (M) = $00 ? (X) - (M) = $00 ? (A) - (M) = $00 ? (A) - (M) = $00 ? (A) - (M) = $00 For RS08: PC (PC) + $0003 + rel ? (A) - (M) = $00 PC (PC) + $0003 + rel ? (A) - (X) = $00 2 A (A) - $0001 or M (M) - $01 or X (X) - $0001 DBNZ opr8,rel DBNZA rel Decrement and Branch if Not Zero DBNZX rel 1 DBNZ ,X,rel 1, 2 Jump JMP opr16 DBNZ opr8,rel DBNZA rel DBNZX rel DBNZ opr8, X,rel DBNZ X,rel DBNZ opr8, SP,rel JMP JMP JMP JMP JMP For S08: PC (PC) + $0003 + rel if (result) 0 for DBNZ direct, IX1 PC (PC) + $0002 + rel if (result) 0 for DBNZA, DBNZX, or IX PC (PC) + $0004 + rel if (result) 0 for DBNZ SP1 For RS08: PC (PC) + $0003 + rel if (result) 0 for DBNZ direct, DBNZX, DBNZ ,X PC (PC) + $0002 + rel if (result) 0 for DBNZA opr8 opr16 opr8,X opr16,X ,X PC Jump Address Getting Started with RS08, Rev. 1 10 Freescale Semiconductor Introduction to RS08 Table 1-2. RS08 and S08 Instruction Set Comparison (continued) Description RS08 S08 Operation For S08: Jump to Subroutine JSR opr16 JSR JSR JSR JSR JSR opr8 opr16 opr16,X opr8,X ,X For RS08: For S08: Return from Subroutine RTS RTS PC (PC) + n (n = 1, 2, or 3) Push (PCL); SP (SP) - $0001 Push (PCH); SP (SP) - $0001 PC Unconditional Address PC (PC) + 3 Push PC to shadow PC PC Unconditional Address SP SP + $0001; Pull (PCH) SP SP + $0001; Pull (PCL) For RS08: Pull PC from shadow PC Data Verification Operations: Bit Test BIT BIT BIT BIT BIT BIT BIT BIT CMP #opr8 Compare Accumulator with Mem- CMP opr8 ory CMP ,X 1 CMP X 1, 2 CMP CMP CMP CMP CMP CMP CMP CMP Complement (One's Complement) CPHX #opr8 CPHX opr8 CPHX opr16 CPHX opr8,SP Compare Index Register (H:X) with Memory CPX CPX CPX CPX CPX CPX CPX CPX Test for Negative or Zero #opr8 opr8 opr116 opr8,X opr16,X ,X opr8,SP opr16,SP #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP #opr8 opr8 opr16 ,X opr8,X opr16,X opr8,SP opr16,SP (A) & (M) (A) - (M) (A) - (X) 2 (H:X) - (M:M + $0001) (X) - (M) TST opr8 1 TSTA 1 TSTX 1 TST opr8 TSTA TSTX TST opr8,X TST ,X TST opr8,SP (A) - $00 (X) - $00 (M) - $00 LDA LDA LDA LDA LDA LDA LDA LDA LDA LDA LDA LDA A (M) Data Movement Operations: Load Accumulator from Memory #opr8 opr8 opr5 ,X 1 #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP Getting Started with RS08, Rev. 1 Freescale Semiconductor 11 Introduction to RS08 Table 1-2. RS08 and S08 Instruction Set Comparison (continued) Description RS08 S08 Load Index Register (H:X) from Memory LDHX #opr16 LDHX opr8 LDHX opr16 LDHX LDHX opr8,X LDHX opr16,X LDHX opr8,SP Load X (Index Register Low) from LDX #opr8 1 LDX opr8 1 Memory LDX LDX LDX LDX LDX LDX LDX LDX Move Store Accumulator in Memory MOV opr8,opr8 MOV #opr8,opr8 MOV D[X],opr8 1 MOV opr8,D[X] 1 MOV #opr8,D[X] 1 MOV MOV MOV MOV STA opr8 STA opr5 STA ,X 1 STA STA STA STA STA STA STA H:X (M:M + $0001) #opr8 opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP opr8,opr8 opr8,X+ #opr8,opr8 X+,opr8 X (M) For S08/RS08: STHX opr STHX opr STHX opr,SP Store X (Index Register Low) in Memory STX STX STX STX STX STX STX (M)destination (M)source For S08 only: H:X (H:X) + $001 in IX+D and DIX+ Modes opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP Store H:X (Index Reg.) STX opr8 1 Operation opr8 opr16 opr8,X opr16,X ,X opr8,SP opr16,SP M (A) (M:M + $0001) (H:X) M (X) Transfer Accumulator to CCR TAP CCR (A) Transfer Accumulator to X (Index TAX 1 Register Low) TAX X (A) Transfer CCR to Accumulator TPA A (CCR) Transfer SP to Index Reg. TSX H:X (SP) + $0001 TXA A (X) TXS (SP) (H:X) - $0001 Transfer X (Index Reg. Low) to Accumulator TXA 1 Transfer Index Reg. to SP Other Operations: Background BGND BGND Clear Carry Bit CLC CLC C0 CLI I0 NOP None Push Accumulator onto Stack PSHA Push (A); SP (SP) - $0001 Push H (Index Register High) onto Stack PSHH Push (H); SP (SP) - $0001 Clear Interrupt Mask Bit No Operation NOP Enter Background Debug Mode Getting Started with RS08, Rev. 1 12 Freescale Semiconductor Introduction to RS08 Table 1-2. RS08 and S08 Instruction Set Comparison (continued) Description RS08 S08 Operation Push X (Index Register Low) onto Stack PSHX Push (X); SP (SP) - $0001 Pull Accumulator from Stack PULA SP (SP + $0001); Pull (A) Pull H (Index Register High) from Stack PULH SP (SP + $0001); Pull (H) Pull X (Index Register Low) from Stack PULX SP (SP + $0001); Pull (X) Reset Stack Pointer RSP SP $FF RTI SP (SP) + $0001; Pull (CCR) SP (SP) + $0001; Pull (A) SP (SP) + $0001; Pull (X) SP (SP) + $0001; Pull (PCH) SP (SP) + $0001; Pull (PCL) Return from Interrupt Swap Shadow PC High with A SHA A SPCH Swap Shadow PC Low with A SLA A SPCL Set Carry Bit SEC Set Interrupt Mask Bit Enable IRQ pin; Stop Osc. STOP SEC C1 SEI I1 Stop Oscillator I bit 0 for S08 only; STOP Software Interrupt SWI PC (PC) + $0001; Push (PCL) SP (SP) - $0001; Push (PCH) SP (SP) - $0001; Push (X) SP (SP) - $0001; Push (A) SP (SP) - $0001; Push (CCR) SP (SP) - $0001; I 1 PCH Interrupt Vector High Byte PCL Interrupt Vector Low Byte Enable Interrupts; Stop Processor WAIT WAIT I bit 0 for S08 only; NOTES: 1 This is pseudo-instruction, the CPU cycle count and the instruction byte count may not be the same as the S08 equivalent instruction. 2 This emulated operation do not have an equivalent operation in S08 instruction set. 1.2.1 Tiny and Short Addressing Mode Instructions Tiny and short addressing mode instructions are single byte instructions. Maximizing the use of these instructions can efficiently improve the overall code density. Given the limited addressable space for these instructions, careful planning to allocate the most frequently used variables to be located within the tiny and short addressable area is recommended. Table 1-3 summarizes the tiny and short instructions support for the RS08 platform. Getting Started with RS08, Rev. 1 Freescale Semiconductor 13 Introduction to RS08 Table 1-3. RS08 Tiny and Short Addressing Mode Instructions Description Tiny/Short Instruction Addressable Space Coding Example Load Accumulator from Memory LDA opr5 $0000 to $001F LDA <$1F LDA <$00 Store Accumulator in Memory STA opr5 $0000 to $001F STA <$1F STA <$00 Clear CLR opr5 $0000 to $001F CLR <$1F CLR <$00 Add without Carry ADD opr4 $0000 to $000F ADD <$0F ADD <$00 Subtract SUB opr4 $0000 to $000F SUB <$0F SUB <$00 Increment INC opr4 $0000 to $000F INC <$0F INC <$00 Decrement DEC opr4 $0000 to $000F DEC <$0F DEC <$00 1.2.2 Pseudo Instructions Using register X located in $000F and register D[X] located in $000E, most HC08/S08 zero offset index addressing instructions and accumulator instructions can be emulated. This index addressing can be performed on virtually all direct addressing mode instructions. Table 1-4 summarizes all of the pseudo instructions supported in RS08 platform and their operations. NOTE Instruction translation is done during time of compilation by the assembler, and is transparent to the user. Table 1-4. Pseudo Instructions in RS08 Platform Operation Pseudo Instruction Emulation Description Bytes Cycles Add with Carry ADC ,X ADC X ADC $0E ADC $0F A (A) + (M) + (C) A (A) + (X) + (C) 2 2 3 3 Add without Carry ADD ,X ADD X ADD <$0E ADD <$0F A (A) + (M) A (A) + (X) 1 1 3 3 Logical AND AND ,X AND X AND $0E AND $0F A (A) & (M) A (A) & (X) 2 2 3 3 Clear Bit n in Memory BCLR n,D[X] BCLR n,X BCLR n, $0E BCLR n, $0F Mn 0 Xn 0 2 2 5 5 Branch if Bit n in Memory Clear BRCLR n,D[X],rel BRCLR n,X,rel BRCLR n, $0E, rel BRCLR n, $0F, rel PC (PC) + $0003 + rel ? (Mn) = 0 PC (PC) + $0003 + rel ? (Xn) = 0 3 3 5 5 Branch if Bit n in Memory Set BRSET n,D[X],rel BRSET n,X,rel BRSET n, $0E, rel BRSET n, $0F, rel PC (PC) + $0003 + rel ? (Mn) = 1 PC (PC) + $0003 + rel ? (Xn) = 1 3 3 5 5 Set Bit n in Memory BSET n,D[X] BSET n,X BSET n, $0E BSET n, $0F Mn 1 Xn 1 2 2 5 5 Compare and Branch if Equal CBEQ ,X,rel CBEQ X rel CBEQ $0E, rel CBEQ $0F, rel PC (PC) + $0003 + rel ? (A) - (M) = $00 PC (PC) + $0003 + rel ? (A) - (X) = $00 3 3 5 5 Getting Started with RS08, Rev. 1 14 Freescale Semiconductor Introduction to RS08 Table 1-4. Pseudo Instructions in RS08 Platform (continued) Operation Pseudo Instruction Emulation Description Bytes Cycles Clear CLR ,X CLRX CLR <$0E CLR <$0F M $00 X $00 1 1 2 2 Compare Accumulator with Memory CMP ,X CMP X CMP $0E CMP $0F (A) - (M) (A) - (X) 2 2 3 3 M (M) - $01 X (X) - $01 PC (PC) + $0003 + rel if (result) 0 3 3 6 6 DBNZ ,X,rel Decrement and Branch if Not DBNZX rel Zero DBNZ $0E, rel DBNZ $0F, rel Decrement DEC ,X DECX DEC <$0E DEC <$0F M (M) - $01 X (X) - $01 1 1 4 4 Exclusive OR Memory with Accumulator EOR ,X EOR X EOR $0E EOR $0F A (A M) A (A X) 2 2 3 3 Increment INC ,X INCX INC <$0E INC <$0F M (M) + $01 X (X) + $01 1 1 4 4 Load Accumulator from MemLDA ,X ory LDA <$0E A (M) 1 3 Load X (Index Register Low) LDX #opr8 from Memory LDX opr8 MOV #opr8, $0F MOV opr8, $0F X (M) 3 3 4 5 Inclusive OR Accumulator and Memory ORA ,X ORA X ORA $0E ORA $0F A (A) | (M) A (A) | (X) 2 2 3 3 Subtract with Carry SBC ,X SBC X SBC $0E SBC $0F A (A) - (M) - (C) A (A) - (X) - (C) 2 2 3 3 Store Accumulator in Memory STA ,X STA <$0E M (A) 1 2 Store X (Index Register Low) STX opr8 in Memory MOV $0F, opr8 M (X) 3 5 Subtract SUB ,X SUB X SUB <$0E SUB <$0F A (A) - (M) A (A) - (X) 1 3 Transfer Accumulator to X (Index Register Low) TAX STA <$0F X (A) 1 2 Test for Negative or Zero TST opr8 TSTA TSTX MOV opr8, opr8 ORA #$00 MOV X, X (M) - $00 (A) - $00 (X) - $00 3 2 3 5 2 5 A (X) 1 3 Transfer X (Index Reg. Low) TXA to Accumulator 1.3 LDA <$0F Paging Memory Scheme The RS08 instruction set does not include extended addressing capability. There is a 64-byte window, known as the paging window, from location $00C0 to $00FF, in the direct page reserved for paging access. A page selection (PAGESEL) register ($001F) determines the corresponding 64-byte block in the memory map for the paging window access. Upper memory access can be done by direct-page access through the paging window area. The entire accessible memory space for RS08 is 16K-bytes, and divided into 256 pages of 64-byte memory. Programming the PAGESEL register ($001F) defines the page to be accessed through the paging window. Figure 1-4 illustrates the paging memory scheme. Getting Started with RS08, Rev. 1 Freescale Semiconductor 15 Introduction to RS08 The PAGESEL register defines the memory page to be accessed, the register X indicates the corresponding location in the paging window that points to the desired upper memory location, CPU access through register D[X] and the paging window can index to the corresponding upper memory location. Most pseudo instructions can utilize this scheme to perform index addressing to the upper memory locations. NOTE Accessing any unimplemented location through the paging window will generate an illegal address reset. $0000 $003F $0040 $007F $0080 $00BF $00C0 PAGE 0 PAGE 1 PAGESEL Register PAGE 2 $00 PAGING WINDOW PAGE 0 $01 PAGE 1 $FF PAGE 255 $00FF $3F40 $3F7F $3F80 PAGE 253 PAGE 254 $3FBF $3FC0 $3FFF PAGE 255 Figure 1-4. RS08 Paging Scheme 1.4 MCU Reset MCU reset provides a way to restart the MCU to a known set of initial conditions. An MCU reset forces most control and status registers to their initial values and the program counter (PC) is started from $3FFD. In the RS08 platform there is no vector lookup mechanism, a JMP instruction (opcode $BC) with a 2-byte operand must programmed into the locations $3FFD-$3FFF. The operand indicates the user defined location to start user program execution. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Reset Vector ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% org $3FFC Security: dc.b $FF ; SECD=1 is unsecured, SECD=0 is secured jmp main Getting Started with RS08, Rev. 1 16 Freescale Semiconductor Introduction to RS08 Similar to the HC08/S08 devices, RS08 has seven sources for reset: * External pin reset (PIN) -- enabled using RSTPE and SOPT * Power-on reset (POR) * Low-voltage detect (LVD) * Computer operating properly (COP) timer * Illegal opcode detect (ILOP) * Illegal address detect (ILAD) * Background debug forced reset via BDC command BDC_RESET The system reset status register (SRS) located in $0200 includes read-only status flags to indicate the source of the most recent reset. 1.5 Wait Mode Wait mode is entered by executing a WAIT instruction. Upon execution of the WAIT instruction, the CPU enters a low-power state in which it is not clocked. The program counter (PC) is halted at the position following the WAIT instruction where it is executed. Exit from wait is done by asserting any reset and any type of interrupt sources that has been enabled. When an interrupt request occurs: 1. MCU exists wait mode and resumes processing. 2. Fetches the following instruction and program flow continues. It is the responsibility of the user program to probe the corresponding interrupt source that woke the MCU because no vector fetching process is involved. 1.6 Stop Mode Stop mode is entered upon execution of a STOP instruction when the STOPE bit in the system option register is set. In STOP mode all internal clocks to the CPU and the modules are halted. Exit from stop is done by asserting any reset, any asynchronous interrupt such as KBI that has been enabled, or the real-time interrupt. When the requests occurs: 1. MCU clock module is enabled. 2. MCU exists stop mode and resumes processing. 3. Fetches the following instruction and program flow continues. It is the responsibility of the user program to poll the corresponding interrupt source that woke the MCU, because no vector fetching process is involved. There are options to enable various modules, such as the internal clock source (ICS) and analog comparator (ACMP), during stop mode. Please refer to the specific device data sheet for more details. NOTE If the STOPE bit is not set when the CPU executes a STOP instruction, the MCU will not enter stop mode and an illegal opcode reset is forced. Getting Started with RS08, Rev. 1 Freescale Semiconductor 17 Introduction to RS08 1.7 Subroutine Call The RS08 platform provides only a single level of hardware stacking. When the instruction, JSR or BSR, is executed, current program counter (PC) value is uploaded to the shadow program counter (SPC) register before the PC is modified with a new location. In the case when the program encounters the instruction RTS, the saved PC value is restored from the SPC register. Program execution resumes at the address that was just restored from SPC register. Single level of subroutine call may not be sufficient for some applications, multi-level software stacking can be emulated with the help of SHA/SLA instructions. These instructions exchange the high byte and the low byte of SPC register with accumulator A respectively. Software stacking can be implemented that place the SPC content for each level of subroutine call in RAM. The following code shows how software stacking can be implemented in macro format. In this example, location $00 is arbitrarily chosen for the stack pointer (STACKPTR) variable and the stack content is placed from address $4F downwards. The code shown provides no stack overflow checking. SPInit FLASHSTART equ equ $4F $3800 ; Stack block allocation ; For MC9RS08KA2 RESETSP: MACRO mov ENDM #SPInit, STACKPTR ; Init Stack pointer PSH_SPC: MACRO ; NOTE: Destructive to X content ldx STACKPTR sha sta ,X sha decx sla sta ,X sla decx stx STACKPTR ENDM ; 20 CPU cycles, 14 bytes code PUL_SPC: MACRO ; NOTE: Destructive to X content ldx STACKPTR incx sla lda ,X sla incx sha lda ,X sha stx STACKPTR ENDM ; 22 CPU cycles, 14 byte code org STACKPTR org TINY_RAM ds.b 1 FLASHSTART ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Load Stack pointer Swap SPC high byte Push high byte to stack Resume A content update stack pointer Swap SPC low byte Push low byte to stack Resume A content update stack pointer Save stack pointer Load Stack pointer Update stack pointer Swap SPC low byte Pull low byte Resume A and SPCL content Update stack pointer Swap SPC high byte Pull high byte Resume A and SPCH content Save stack pointer ; Stack pointer location Getting Started with RS08, Rev. 1 18 Freescale Semiconductor Introduction to RS08 ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Subroutine A ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SubA: PSH_SPC ; Stack SPC ;... ... bsr SubB ; Multi-level subroutine call ;... ... PUL_SPC ; Unstack SPC rts ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Subroutine B ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SubB: PSH_SPC ; Stack SPC ;... ... PUL_SPC ; Unstack SPC rts ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Main ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Main: RESETSP ;... ... jsr SubA ;... ... jsr SubB ;... ... Three macros are defined here. RESETSP is used to reset the stack pointer to the initial position. PSH_SPC pushes shadow PC (SPC) content to stack and decrements STACKPTR variable accordingly. Similarly, PUL_SPC pulls the SPC content from stack and increments STACKPTR variable accordingly. Calling PSH_SPC at the beginning of each subroutine and PUL_SPC before executing RTS would stack up and retrieve the return address (shadow PC) for each level of subroutine calls accordingly. NOTE Both PSH_SPC and PUL_SPC macro are destructive to register X. If X content requires to carry across subroutine calls, enhancements to the macros are required. 1.8 Interrupt RS08 platform is targeted for small applications where usually intensive interrupt servicing is not required. The interrupt request in the RS08 platform is designed to wake the MCU from either wait or stop mode. At the same time the corresponding interrupt flags will also be set to indicate the interrupt events that had happened. If multiple events had happened, it is up to the software to decide the priority of servicing. When the MCU is operating in run mode or active background debug mode (BDM), interrupt events will not affect the software flow. Users can check the interrupt events on a regular basis by polling the corresponding interrupt flag and determine if interrupt service is required. Similar to the HC08/S08 platform, in RS08 each interrupt source is associated with a corresponding interrupt flag and an interrupt enable bit. The wait/stop wakeup capability of an interrupt source can only Getting Started with RS08, Rev. 1 Freescale Semiconductor 19 Introduction to RS08 be enabled when the corresponding interrupt enable bit is set. When the MCU wakes up from wait/stop mode, the program flow is resumed from where it was stopped. At this point, software can determine which interrupt had occurred by polling the interrupt flags and then jump to the service subroutine accordingly. The interrupt flags from individual modules are scattered in several register locations, therefore it is not efficient for the software to poll the corresponding flag among several registers. The RS08 platform implements a system interrupt pending (SIP1) register where it provides a central location for the interrupt sources notification. If hardware interrupt is enabled, the corresponding flag in SIP1 register will be set when the interrupt event occurs. For example, if keyboard interrupt is required, it can be enabled by setting the KBIE bit in KBISC register. When KBI event occurs, KBF flag in KBISC register and KBI flag in SIP1 register are both set. User has a choice to poll either of these bits to determine of the event existence. Writing a logic 1 to KBACK bit in KBISC register will clear both KBF in KBISC and KBI flag in SIP1. 1.8.1 Interrupt Handling Coding Example The interrupt sources associated with the MC9RS08KA2 are shown below: * Low voltage detect (LVD) * Real timer interrupt (RTI) * Modulo timer overflow (MTIM) * Analog comparator (ACMP) * Keyboard interrupt (KBI) First, the priority of servicing should be defined based on the application need. In general, the interrupt that requires the shortest latency should have the highest priority. To illustrate the idea the servicing priority is arbitrarily defined as follows: Table 1-5. Interrupt Servicing Priority Example Highest Lowest MTIM KBI ACMP RTI LVD For many interrupt driven applications the interrupt event period is unknown to the application; most of the time the MCU is in idle state and waiting for an event to trigger. Once it happens, the MCU will wakeup and performs a defined task then returns to its idle state. With the priority table defined in Table 1-5, the interrupt servicing loop can be written as follows: InfLoop: Priority1: Priority2: Priority3: Priority4: Priority5: sta wait brset brset brset brset brset bra SRS ;Bump COP SIP1_MTIM, SIP1, MTIM_ISR SIP1_ACMP, SIP1, ACMP_ISR SIP1_KBI, SIP1, KBI_ISR SIP1_RTI, SIP1, RTI_ISR SIP1_LVD, SIP1, LVD_ISR InfLoop ;5 ;5 ;5 ;5 ;5 bus bus bus bus bus cycles cycles cycles cycles cycles MTIM_ISR: ;... ... Getting Started with RS08, Rev. 1 20 Freescale Semiconductor Introduction to RS08 bra InfLoop ACMP_ISR: ;... ... bra InfLoop KBI_ISR: ;... ... bra InfLoop RTI_ISR: ;... ... bra InfLoop LVD_ISR: ;... ... bra InfLoop The above example illustrates the software priority handling technique. In the example the MCU enters wait mode during the application idle state. RS08 CPU requires typically three bus cycles to wakeup from wait mode, the interrupt latency is mainly due to the software execution time. Assuming a bus frequency of 10MHz (bus period is 100ns) the corresponding latencies are summarized in Table 1-6. User is free to customize the software loop and minimize the interrupt latency according to the application requirement. Table 1-6. Interrupt Latency based on 10MHz Bus Clock Interrupt Latency (s) MTIM 0.8 ACMP 1.3 1 KBI 1.8 1 RTI 2.3 1 LVD 2.8 1 NOTES: 1 Additional delay (typically 2 bus clock cycles) may exist to synchronize the asynchronous interrupt source to the bus clock. NOTE In the above example COP is refreshed before entering wait mode. In order to avoid a COP reset, at least one interrupt event is expected within the COP timeout period. In many applications the interrupt period is much longer, it would be wise to put the MCU in stop mode to minimize the power consumption, particularly in battery operated applications. Because the RS08 CPU can only be waked up from stop by asynchronous interrupt source such as KBI, ACMP, etc., all synchronous interrupt events checking such as MTIM can be eliminated from the interrupt servicing loop. For MC9RS08KA2, all interrupt sources except MTIM has stop wakeup capability (refer to MC9RS08KA2 data sheet for more details). On top of the software execution time the interrupt latency from stop must include the MCU stop recovery time that allows the system clock and internal regulator to wakeup from their standby mode. The stop recovery time varies among product families, it depends on the clock module and internal regulator technology used. Getting Started with RS08, Rev. 1 Freescale Semiconductor 21 Emulated ADC Application Example 2 Emulated ADC Application Example In this section the analog comparator module in the MC9RS08KA2 is used to implement an 8-bit analog-to-digital (ADC). In many applications, precise ADC operation is not needed. With a timer module and a low cost high performance analog comparator module built into the MCU, an ADC can be emulated. The emulated ADC resolution depends on the resolution of the timer. In the case of MC9RS08KA2 an 8-bit modulo timer (MTIM) is included, hence an 8-bit ADC operation can easily be emulated. Comparing with a dedicated ADC module the trade-off is the sampling time and the dynamic range. Emulated ADC usually has longer sampling time, narrower dynamic range, and rail-to-rail operation is not feasible. VDD On-chip Comparator R 4k7 + - ADC In C 47nF MCU Boundary Figure 2-5. Emulated ADC Schematic Figure 2-5 shows the schematic of a simple emulated ADC. The positive terminal of the comparator is connected to a RC network and the negative terminal is the ADC input. Before the comparator function is enabled, both terminals are general I/O ports. The positive terminal is initially set to output low to discharge the RC. When ADC function is required, the comparator is then enabled. The ADC function is emulated by comparing the ADC input to the voltage across the C. Timer is used to monitor the time it takes for the RC to charge up to the ADC input voltage. Since the RC charging profile is not linear, if the ADC dynamic range is small, the timer reading can be used as it is. In general it is more desirable to convert the timer reading back to linear scale using a simple lookup table. 2.1 Implementation The following is the procedure to use the MC9RS08KA2 to perform the emulated ADC function. The complete program is listed in Appendix A. 1. Define the sampling time and timer resolution. The sampling time is the time for the RC to charge up to the maximum ADC input voltage (dynamic range). In this example one millisecond is arbitrarily chosen. When 8-bit timer is used (n=8), the timer resolution is 3.9s (the function is given in Equation 1) and is rounded up to 4s. Maximum timer overflow is assumed, then overflow period becomes 255 times 4s, i.e. 1.02ms. arg eUpTime TimerResolution = Ch --------------------------------------n 2 -1 Eqn. -1 Getting Started with RS08, Rev. 1 22 Freescale Semiconductor Emulated ADC Application Example 2. Define RC time constant. The RC charging profile follows Equation 2. t - -------- RC V = V DD 1 - e Eqn. -2 The capacitor charge level reaches 99% when the time, t, reaches about 4.6 times of the RC constant. To maximize the measurement range, the timer overflow period is expected to be longer than or equal to this value. In this example, with 1.02ms timer overflow period RC constant becomes 2.21E-4. TimerOverflowPeriod RC = ----------------------------------------------------------4.61 Eqn. -3 The value of the resistor, R, is defined by the port sinking capability. Referring to the data sheet of MC9RS08KA2, the sinking current can keep in around 1mA level so that the initial discharged voltage level can maintain to be close to 0V. Assuming VDD of 5V is used, 4700 resistor R is chosen. Then, given 2.21E-4 time constant, capacitor C becomes 47nF. Please note this sinking current will contribute to the overall system IDD consumption. If the ADC function is not used, or before the MCU enters stop mode, it is recommended to configure the port back to input or high impedance to avoid current leakage. 3. Construct the lookup table. Given the timer resolution, 4s in this example, it is possible to construct a lookup table to compensate for the nonlinearity of the charging profile based on Equation 2. The step size for a linear 8-bit ADC is given as: V DD Step = --------255 Eqn. -4 Step $03 CODE Step $02 Step $01 $00 Step/2 3*Step/2 5*Step/2 7*Step/2 ADC in (V) Figure 2-6. ADC Quantization Diagram A linear ADC is expected to quantize the input voltage at step boundary starting from step/2 input voltage as shown in Figure 2-6. The conversion function becomes: Getting Started with RS08, Rev. 1 Freescale Semiconductor 23 Emulated ADC Application Example Step ADCin - ----------- 2 ---------------------------------- +1 Step Code = 0 Step ; ADCin ----------- 2 Eqn. -5 Step ; ADCin < ----------- 2 The lookup table that converts the timer count to linear ADC code is shown in Table 2-7. Table 2-7. Non-Linearity Compensation Lookup Table Time (s) ADC Input (V) (Equation 2) Timer Count Linear ADC Code (Equation 5) 0 0 0 0 4 0.09 1 5 8 0.18 2 10 12 0.26 3 14 16 0.35 4 18 20 0.43 5 23 and so on... 1012 4.95 253 253 1016 4.95 254 253 1020 4.95 255 253 4. Define bus frequency. There is software overhead to enable the timer and the comparator before taking measurements. To avoid software latency error, it is recommended to choose a bus frequency which is at least five times the timer clock frequency. In this example, a 2MHz bus frequency is initially chosen, then timer prescaler is set to divide-by-8 option which gives 250kHz timer clock frequency, i.e. 4s resolution. In applications where the choice of bus frequency cannot be chosen freely, the lookup table can be rebuilt to compensate for the software latency. 5. RS08 coding. The software code can be divided into four parts: declaration, initialization, ADC read, and table lookup. a) First, declare the variables required and the lookup table location. The most frequently used variables should be allocated on the tiny addressable RAM area, i.e. $0000 to $000D, such that the single byte tiny/short instructions can be used for data manipulation. Hence, code density is greatly improved. Lookup table is located in the upper memory, there is no restriction on where to put the table, in this example $3E00 is arbitrarily chosen. All upper memory access is done through the 64-byte paging window located on the first page. Getting Started with RS08, Rev. 1 24 Freescale Semiconductor Emulated ADC Application Example ;========================================================================= ; Application Definition ;========================================================================= RC equ PTAD_PTAD0 mRC equ mPTAD_PTAD0 TableStart equ $3E00 org Tiny_RAMStart ; variable/data section SensorReading ds.b 1 ADCOut ds.b 1 b) Comparator positive terminal must be initialized as output low, so that RC network will start up at a completely discharged state. Coding is shown below: ;------------------------------------------------------; Init RAM ;------------------------------------------------------clr SensorReading clr ADCOut ;------------------------------------------------------; Config GPIO ; RC - init L ;------------------------------------------------------mov #(mDATAOUT), PTAD mov #(mRC|mDATAOUT), PTADD ; Single byte instruction ; Single byte instruction ; RC Initial low ; Set Output pins c) In the ADCRead subroutine, the timer is initialized and started to run before enabling the comparator. Once the comparator is enabled, both of its terminals become analog inputs and the RC network starts to charge up. The MCU then enters wait mode and waiting for interrupt events to trigger. Both timer (MTIM) overflow interrupt and comparator interrupt are enabled since either of these events will wake the MCU up from wait mode. When an interrupt triggers the software flow continues and the following instruction is executed. The timer counter value is read out immediately and save in SensorReading variable. The comparator flag is then checked. If it is clear, it indicates no comparator event occurred. The ADC input could be out of range and the saved SensorReading value is flushed. Otherwise the comparator is disabled, the positive terminal returns to output low and discharges the RC network. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Read Sensor (ADC) Value ; Timer prescalar=8 -> Timer clk~250kHz ; Bus = 2MHz ; Max OF period = 1.02ms ; Timer resolution = 4us ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ADCRead: mov #(MTIM_BUS_CLK|MTIM_DIV_8), MTIM1CLK ;Change Timer resolution mov #255, MTIM1MOD ;OF period mov #(mMTIM1SC_TRST|mMTIM1SC_TOIE), MTIM1SC ;Reset and Start Timer mov #(mACMP1SC_ACME|mACMP1SC_ACIE|ACMP_OUTPUT_RAISING), ACMP1SC ; Enable ACMP, start RC rise bset ACMP1SC_ACF, ACMP1SC ;Clear ACMP Flag wait mov MTIM1CNT, SensorReading brclr ACMP1SC_ACF, ACMP1SC, NoReading Getting Started with RS08, Rev. 1 Freescale Semiconductor 25 Emulated ADC Application Example bset clr mov rts NoReading: mov clr mov rts ACMP1SC_ACF, ACMP1SC ACMP1SC #(mMTIM1SC_TSTP|mMTIM1SC_TRST), MTIM1SC ;Clear ACMP Flag ;disable ACMP ;mask int and clear flag #$FF, SensorReading ACMP1SC #(mMTIM1SC_TSTP|mMTIM1SC_TRST), MTIM1SC ;Biggest Number ;disable ACMP ;mask int and clear flag d) In TableLookup subroutine the two most significant bits (MSB) of the variable SensorReading are extracted and added to the page number that holds the lookup table. The corresponding lookup table content is mapped to the 64-byte paging window, $00C0 to $00FF. Then the six least significant bits (LSB) of the variable SensorReading is used as an index to read out the upper memory content directly from the paging window. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; 8bit Table Lookup ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TableLookup: lda SensorReading ; rola ;Extract 2 MSB rola ; rola ; and #$03 ;Mask all other bits add #(TableStart>>6) ;Add to Lookup table page sta PAGESEL ;High page lda SensorReading ; and #$3F ;Extract 6 LSB add #$c0 ;Index to paging window tax ; lda ,x ;Read upper memory sta ADCOut ;Store lookup table content mov #(HREG), PAGESEL ;Return to register page rts ; ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; ADC Lookup Table - RC charging profile ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% org TableStart dc.b 0, 5, 10, 14, 18, 23, 27, 31, 35, 39, 43, 47, 50, 54, 58, 61 dc.b 65, 68, 71, 75, 78, 81, 84, 87, 90, 93, 96, 99,102,105,107,110 dc.b 113,115,118,120,123,125,127,130,132,134,136,138,141,143,145,147 dc.b 149,150,152,154,156,158,160,161,163,165,166,168,169,171,173,174 dc.b 175,177,178,180,181,182,184,185,186,188,189,190,191,192,193,195 dc.b 196,197,198,199,200,201,202,203,204,205,206,206,207,208,209,210 dc.b 211,211,212,213,214,215,215,216,217,217,218,219,219,220,221,221 dc.b 222,223,223,224,224,225,225,226,226,227,228,228,228,229,229,230 dc.b 230,231,231,232,232,233,233,233,234,234,235,235,235,236,236,236 dc.b 237,237,237,238,238,238,239,239,239,240,240,240,240,241,241,241 dc.b 241,242,242,242,242,243,243,243,243,244,244,244,244,244,245,245 dc.b 245,245,245,246,246,246,246,246,246,247,247,247,247,247,247,247 dc.b 248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249 dc.b 250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251 dc.b 251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252 dc.b 252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253 Getting Started with RS08, Rev. 1 26 Freescale Semiconductor Emulated ADC Application Example 2.2 Calibration The emulated ADC performance depends highly on the RC network time constant accuracy. If the actual RC component values deviates from their specified values, the RC charging profile will be shifted and the timer capture will be inaccurate. In addition, variations in parasitic loading on the PCB layout will also contribute to RC time constant error. Simple calibration can be performed to compensate for the change in RC constant. 264ms VDD/2 Figure 2-7. 2.5V Input R-C Charging Profile To measure the actual RC constant the charging profile must be recorded. This can be done by applying a VDD/2 voltage to the ADC input. The charging profile is recorded as in Figure 2-7. The time taken for the RC network to reach VDD/2 voltage level, 264s in this case. The expected rise time based on the previous calculation listed in Table 2-7 is 152s, which is equivalent to 38 timer counts. There are several ways to do the calibration. * From Equation 2 it is possible to deduce the actual RC constant and rebuild the lookup table. * Instead of using fixed value R or C, variable R or C component can be used. Adjusting the R or the C until the rise time is reduced to the expected value (152s in this case). * Compensation can be done by adjusting the timer resolution. MC9RS08KA2 and many Freescale MCUs include a software programmable clock source (ICS), bus frequency can be fine-tuned by simply reprogramming the content of the TRIM register. In this example, timer resolution is 4s based on the previous calculation with 2MHz bus frequency, 38 timer counts are expected to reach VDD/2 voltage level. So, with 264s measured rise time, new timer resolution should be 264s divided by 38, i.e. 6.94s. With a divide-by-8 prescaler option selected for the timer clock source, compensated bus period should be 6.94s divided by 8, which is 868ns, i.e. 1.15MHz bus frequency. Therefore, if a 1.15MHz bus frequency is used, no hardware adjustment nor lookup table modification is required. For MC9RS08KA2, bus frequency can be changed by reprogramming the TRIM register and bus frequency divider bits in the ICSC2 register. (Refer to MC9RS08KA2 data sheet for more details.) Getting Started with RS08, Rev. 1 Freescale Semiconductor 27 Emulated ADC Application Example 2.3 Measurement Result When ADCRead subroutine is executed, the RC network starts the charging process. Once the ADC input voltage matches the RC voltage, the timer counter value is read out and the comparator is disabled. RC network returns to the discharged state. Figure 2-8 shows the charging and discharging process with various ADC input voltages. ADC IN = 1V ADC IN = 2.5V ADC IN = 5V Figure 2-8. RC Charging Profile Against Different ADC Input Voltages With bus frequency adjusted to 1.15MHz the emulated ADC performance for VDD =5V is shown in Table 2-8 and Figure 2-9. Table 2-8. Emulated ADC Performance ADC Input Voltage (V) Expected ADC code (Decimal) Measured ADC code (Decimal) 1 51 50 1.5 76 75 2 102 99 2.5 127 123 3 153 150 3.5 178 175 4 204 202 4.5 229 234 Getting Started with RS08, Rev. 1 28 Freescale Semiconductor Emulated ADC Application Example Emulated ADC Performance Code (Decimal) 250 200 150 Expected Measured 100 50 0 0 2 4 6 ADC In (Voltage) Figure 2-9. Emulated ADC Performance Getting Started with RS08, Rev. 1 Freescale Semiconductor 29 Emulated ADC Application Example Appendix A Program Listing ;************************************************************** ; ; (c) copyright Freescale Semiconductor, Inc. 2006. ; ALL RIGHTS RESERVED ; ;************************************************************** ;************************************************************** ;* Emulated ADC Coding for MC9RS08KA2 ;* ;* Author: Vincent Ko ;* Date: Jan 2006 ;* ;* PTA0/KBI0/ACMP+ RC network ;* PTA1/KBI1/ACMPADCIN ;* PTA5/KBI5 DATAOUT ;* ;************************************************************** ; include derivative specific macros XDEF Entry include "MC9RS08KA2.inc" ;========================================================================= ; ICS Definition ;========================================================================= ICS_DIV_1 equ $00 ICS_DIV_2 equ $40 ICS_DIV_4 equ $80 ICS_DIV_8 equ $c0 ;========================================================================= ; MTIM Definition ;========================================================================= MTIM_DIV_1 equ $00 MTIM_DIV_2 equ $01 MTIM_DIV_4 equ $02 MTIM_DIV_8 equ $03 MTIM_DIV_16 equ $04 MTIM_DIV_32 equ $05 MTIM_DIV_64 equ $06 MTIM_DIV_128 equ $07 MTIM_DIV_256 equ $08 MTIM_BUS_CLK equ $00 MTIM_XCLK equ $10 MTIM_TCLK_FALLING equ $20 MTIM_TCLK_RISING equ $30 ;========================================================================= ; ACMP Definition ;========================================================================= ACMP_OUTPUT_FALLING equ $00 ACMP_OUTPUT_RAISING equ $01 ACMP_OUTPUT_BOTH equ $03 ;========================================================================= ; RTI Definition ;========================================================================= RTI_DISABLE equ $00 RTI_8MS equ $01 Getting Started with RS08, Rev. 1 30 Freescale Semiconductor Emulated ADC Application Example RTI_32MS RTI_64MS RTI_128MS RTI_256MS RTI_512MS RTI_1024MS equ equ equ equ equ equ $02 $03 $04 $05 $06 $07 ;========================================================================= ; Application Definition ;========================================================================= RC equ PTAD_PTAD0 mRC equ mPTAD_PTAD0 DATAOUT equ PTAD_PTAD5 mDATAOUT equ mPTAD_PTAD5 TableStart equ $3E00 org Tiny_RAMStart ; variable/data section SensorReading ds.b 1 ADCOut ds.b 1 BitCount ds.b 1 org Z_RAMStart ; variable/data section org ROMStart ; code section main: Entry: ;------------------------------------------------------; Config ICS ; Device is pre-trim to 18.4MHz ICLK frequency ; TRIM value are stored in $3FFA:$3FFB ;------------------------------------------------------mov #$FF, PAGESEL mov $FB, ICSSC mov $FA, ICSTRIM mov #ICS_DIV_8, ICSC2 ;------------------------------------------------------;Config System ;------------------------------------------------------mov #HREG, PAGESEL mov #(mSOPT_COPE|mSOPT_COPT|mSOPT_STOPE), SOPT mov #(mSPMSC1_LVDE|mSPMSC1_LVDRE), SPMSC1 mov #(RTI_128MS|mSRTISC_RTIE), SRTISC ;------------------------------------------------------; Init RAM ;------------------------------------------------------clr SensorReading clr ADCOut ;------------------------------------------------------; Config GPIO ; RC - init L ;------------------------------------------------------mov #(mDATAOUT), PTAD mov #(mRC|mDATAOUT), PTADD ; $3FFB ; $3FFA ; Use 1.15MHz bus ; ; ; ; Init Page register SOPT, COP enabled LVI enable 128ms RTI ; Single byte instruction ; Single byte instruction ; RC Initial low ; Set Output pins Getting Started with RS08, Rev. 1 Freescale Semiconductor 31 Emulated ADC Application Example ;------------------------------------------------------; Application Loop ; 1) Wakeup every 128ms ; 2) Read ADC input ; 3) Dump code to serially output port (DATAOUT) ;------------------------------------------------------InfLoop: wait bset SRTISC_RTIACK, SRTISC bsr ReadSensor bsr TableLookup bsr DataDump sta SRS bra InfLoop ; ; ; ; Read Charge up time data Decode 8bit level Dump ADC code Bump COP ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Read Sensor (ADC) Value ; Timer prescalar=8 -> Timer clk~250kHz ; Bus = 2MHz ; Max OF period = 1.02ms ; Timer resolution = 4us ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ADCRead: mov #(MTIM_BUS_CLK|MTIM_DIV_8), MTIM1CLK ;Change Timer resolution mov #255, MTIM1MOD ;OF period mov #(mMTIM1SC_TRST|mMTIM1SC_TOIE), MTIM1SC ;Reset and Start Timer mov #(mACMP1SC_ACME|mACMP1SC_ACIE|ACMP_OUTPUT_RAISING), ACMP1SC ; Enable ACMP, start RC rise bset ACMP1SC_ACF, ACMP1SC ;Clear ACMP Flag wait mov MTIM1CNT, SensorReading brclr ACMP1SC_ACF, ACMP1SC, NoReading bset ACMP1SC_ACF, ACMP1SC ;Clear ACMP Flag clr ACMP1SC ;disable ACMP mov #(mMTIM1SC_TSTP|mMTIM1SC_TRST), MTIM1SC ;mask int and clear flag rts NoReading: mov #$FF, SensorReading ;Biggest Number clr ACMP1SC ;disable ACMP mov #(mMTIM1SC_TSTP|mMTIM1SC_TRST), MTIM1SC ;mask int and clear flag rts ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; 8bit Table Lookup ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TableLookup: lda SensorReading ; rola ;Extract 2 MSB rola ; rola ; and #$03 ;Mask all other bits add #(TableStart>>6) ;Add to Lookup table page sta PAGESEL ;High page lda SensorReading ; and #$3F ;Extract 6 LSB add #$c0 ;Index to paging window tax ; lda ,x ;Read upper memory Getting Started with RS08, Rev. 1 32 Freescale Semiconductor Emulated ADC Application Example sta ADCOut ;Store lookup table content mov #(HREG), PAGESEL ;Return to register page rts ; ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Serial Data dump ; ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DataDump: mov #8, BitCount lda ADCOut bclr bclr cmp nop DATAOUT, PTAD DATAOUT, PTAD 0 ;5 ;5 ;3 ;1 Start bit dummy dummy dummy NextBit: lsla bcc bset bra ClrPort DATAOUT, PTAD BitEnd ;1 ;3 ;5 ;3 bclr bra DATAOUT, PTAD BitEnd ;5 ;3 dbnz BitCount, NextBit ;6 bset rts DATAOUT, PTAD ;5 End bit ClrPort: BitEnd: ByteEnd: ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; ADC Lookup Table - RC charging profile ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% org TableStart dc.b 0, 5, 10, 14, 18, 23, 27, 31, 35, 39, 43, 47, 50, 54, 58, 61 dc.b 65, 68, 71, 75, 78, 81, 84, 87, 90, 93, 96, 99,102,105,107,110 dc.b 113,115,118,120,123,125,127,130,132,134,136,138,141,143,145,147 dc.b 149,150,152,154,156,158,160,161,163,165,166,168,169,171,173,174 dc.b 175,177,178,180,181,182,184,185,186,188,189,190,191,192,193,195 dc.b 196,197,198,199,200,201,202,203,204,205,206,206,207,208,209,210 dc.b 211,211,212,213,214,215,215,216,217,217,218,219,219,220,221,221 dc.b 222,223,223,224,224,225,225,226,226,227,228,228,228,229,229,230 dc.b 230,231,231,232,232,233,233,233,234,234,235,235,235,236,236,236 dc.b 237,237,237,238,238,238,239,239,239,240,240,240,240,241,241,241 dc.b 241,242,242,242,242,243,243,243,243,244,244,244,244,244,245,245 dc.b 245,245,245,246,246,246,246,246,246,247,247,247,247,247,247,247 dc.b 248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249 dc.b 250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251 dc.b 251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252 dc.b 252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253 ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; Reset Vector ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% org $3ffc Security: dc.b $FF jmp main Getting Started with RS08, Rev. 1 Freescale Semiconductor 33 How to Reach Us: Home Page: www.freescale.com E-mail: support@freescale.com USA/Europe or Locations Not Listed: Freescale Semiconductor Technical Information Center, CH370 1300 N. Alma School Road Chandler, Arizona 85224 +1-800-521-6274 or +1-480-768-2130 support@freescale.com Europe, Middle East, and Africa: Freescale Halbleiter Deutschland GmbH Technical Information Center Schatzbogen 7 81829 Muenchen, Germany +44 1296 380 456 (English) +46 8 52200080 (English) +49 89 92103 559 (German) +33 1 69 35 48 48 (French) support@freescale.com Japan: Freescale Semiconductor Japan Ltd. Headquarters ARCO Tower 15F 1-8-1, Shimo-Meguro, Meguro-ku, Tokyo 153-0064 Japan 0120 191014 or +81 3 5437 9125 support.japan@freescale.com Asia/Pacific: Freescale Semiconductor Hong Kong Ltd. Technical Information Center 2 Dai King Street Tai Po Industrial Estate Tai Po, N.T., Hong Kong +800 2666 8080 support.asia@freescale.com For Literature Requests Only: Freescale Semiconductor Literature Distribution Center P.O. Box 5405 Denver, Colorado 80217 1-800-441-2447 or 303-675-2140 Fax: 303-675-2150 LDCForFreescaleSemiconductor@hibbertgroup.com Document Number: AN3266 Rev. 1 5/2006 Information in this document is provided solely to enable system and software implementers to use Freescale Semiconductor products. There are no express or implied copyright licenses granted hereunder to design or fabricate any integrated circuits or integrated circuits based on the information in this document. Freescale Semiconductor reserves the right to make changes without further notice to any products herein. Freescale Semiconductor makes no warranty, representation or guarantee regarding the suitability of its products for any particular purpose, nor does Freescale Semiconductor assume any liability arising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without limitation consequential or incidental damages. "Typical" parameters that may be provided in Freescale Semiconductor data sheets and/or specifications can and do vary in different applications and actual performance may vary over time. All operating parameters, including "Typicals", must be validated for each customer application by customer's technical experts. Freescale Semiconductor does not convey any license under its patent rights nor the rights of others. Freescale Semiconductor products are not designed, intended, or authorized for use as components in systems intended for surgical implant into the body, or other applications intended to support or sustain life, or for any other application in which the failure of the Freescale Semiconductor product could create a situation where personal injury or death may occur. Should Buyer purchase or use Freescale Semiconductor products for any such unintended or unauthorized application, Buyer shall indemnify and hold Freescale 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. FreescaleTM and the Freescale logo are trademarks of Freescale Semiconductor, Inc. All other product or service names are the property of their respective owners. (c) Freescale Semiconductor, Inc. 2006. All rights reserved. RoHS-compliant and/or Pb-free versions of Freescale products have the functionality and electrical characteristics as their non-RoHS-compliant and/or non-Pb-free counterparts. For further information, see http://www.freescale.com or contact your Freescale sales representative. For information on Freescale's Environmental Products program, go to http://www.freescale.com/epp.