About ST
Products
Applications
Support
Buy
News & Events
ST Worldwide
Contact Us
Login
User Manuals
|
Microcontrollers
|
8-bit Microcontrollers
|
ST9 - 8-bit Microcontrollers
ST9 FAMILY, 8/16-BIT MICROCONTROLLER (MCU), USER GUIDE
User Manual
Format:
(1424 kb)
or
(233 kb)
Last Updated: 23/01/2004
Pages: 146
Related Information
Source file for ST9 - ST9+ family, 8/16-bit microcontroller (MCU), user guide
Raw Ascii Text
- (
Hide
)
(Unformatted textual content of the document used by search engines)
ST9
USER GUIDE
1 ABOUT THIS GUIDE
Welcome to the ST9 User Guide. The aim of this book is to help you to get a working knowledge of the ST9 microcontroller family. Using this foundation, you will be in a good position to und erstand and implement any of the ST9 microcontrollers. To make it easier, we have selected the major technical concepts of the ST9 family and will introduce them gradually over seve ral chapters, always supporting theory with practical examples. 1.1 PREREQUISITES Th is book addresses application developers. To fully benefit from the book content, you should be familiar with microcontrollers and their associated development tools. For basic information on microcontrollers and development tools, you should refer to one of the many introductory books available on the subject. 1.2 RESULTS The book will provide you with:
s s s
A basic understanding of the ST9 microcontroller family Knowledge and ready-to-use examples on using ST9 peripherals Useful tips and warnings
Rev. 1.5
January 2004 1/146
1
Table of Contents
1 ABOUT THIS GUIDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 1.2 1.3 1.4 1.5 1.6 P R E R E Q U ISIT ES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 R ESU LT S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 HOW TO USE THIS GUIDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 COMPANION SOFTWARE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 ABOUT THE AUTHORS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 RELATED DOCUMENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 INTRODUCING THE ST9 BASICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.1 2.2 PROCESSOR CORE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 PERIPHERALS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2.1 ST92F124 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2.2 ST92F150 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.2.3 ST92F250 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 PROCESSOR CORE: MAIN CONCEPTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.1 ADDRESS SPACES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.1.1 Register-Oriented Programming Model . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.1.2 Register File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.1.3 Direct access to the Register File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.1.4 Working Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.1.5 Peripheral Register Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.1.6 Working Registers and Register Pointers . . . . . . . . . . . . . . . . . . . . . . . . 16 3.1.7 Memory Management Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 STACK MODES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 INSTRUCTION SET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.3.2 Advantages when Using C Language . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 INTERRUPTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 3.4.1 Interrupt Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3.4.2 Interrupt Priorities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.4.3 External Interrupt Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 DMA CONTROLLER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 3.5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 3.5.2 How the DMA Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 RESET AND CLOCK CONTROL UNIT (RCCU) . . . . . . . . . . . . . . . . . . . . . . . 60 3.6.1 Clock Control Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 3.6.2 Reset and Stop Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
146
3.2 3.3
3.4
3.5
3.6
4 USING THE ON-CHIP PERIPHERALS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 4.1 4.2 PROGRAMMING THE CORE AND PERIPHERALS . . . . . . . . . . . . . . . . . . . . 65 PARALLEL I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
2/146
1
Table of Contents
4.3 STANDARD AND WATCHDOG TIMERS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 4.3.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 4.3.2 Timer Application for Periodic Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . 72 4.3.3 Watchdog Application 1: Generating a PWM . . . . . . . . . . . . . . . . . . . . . 73 4.3.4 Watchdog Application 2: Using the Watchdog . . . . . . . . . . . . . . . . . . . . 74 MULTIFUNCTION TIMER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4.4.1 Generating Two Pulse Width Modulated Waves with One MFT . . . . . . . 79 4.4.2 Generating a Pulse Width Modulated Wave with a Cleaner Spectrum . . 82 4.4.3 Incremental Encoder Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 4.4.4 MFT Application 1: Generating 2 PWMs using Interrupts . . . . . . . . . . . . 86 4.4.5 MFT Application 2: Generating a PWM using DMA . . . . . . . . . . . . . . . . 86 4.4.6 MFT Application 3: Generating a PWM using the DMA Swap Mode . . . 87 SERIAL PERIPHERAL INTERFACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 4.5.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 4.5.2 Static Liquid-Crystal Display Interface Example . . . . . . . . . . . . . . . . . . . 88 4.5.3 EEPROM Serial Interface Example using I²C . . . . . . . . . . . . . . . . . . . . . 91 SERIAL COMMUNICATIONS INTERFACE . . . . . . . . . . . . . . . . . . . . . . . . . . 92 4.6.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 4.6.2 SCI Application 1: Sending Bytes using Interrupts . . . . . . . . . . . . . . . . . 97 4.6.3 SCI Application 2: Sending Bytes using DMA . . . . . . . . . . . . . . . . . . . . . 97 4.6.4 SCI Application 3: Sending and Receiving Bytes using DMA . . . . . . . . . 97 4.6.5 SCI Application 4: Matching Input Bytes . . . . . . . . . . . . . . . . . . . . . . . . . 97 ANALOG TO DIGITAL CONVERTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.7.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.7.2 Analog Watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4.7.3 Interrupt Vectoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4.7.4 ADC Application: A/D Conversions and Analog Watchdog using Interrupts 101 PERIPHERAL INITIALIZATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4.8.1 initialization Header File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4.8.2 Peripheral Function File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
4 .4
4.5
4.6
4.7
4.8
5 USING THE DEVELOPMENT TOOLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 5.1 5.2 5.3 5.4 DEVELOPING IN C LANGUAGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 AVAILABLE TOOLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 INTRODUCING THE DEVELOPMENT TOOLS . . . . . . . . . . . . . . . . . . . . . . 113 PROGRAM CONFIGURATION AND INITIALISATION . . . . . . . . . . . . . . . . . 113 5.4.1 Writing the Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 5.4.2 Writing the Linker Command File using a Script File . . . . . . . . . . . . . . . 119 5.4.3 Writing the Start-Up File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 5.5 GLOBAL INITIALISATION: CORE AND PERIPHERALS . . . . . . . . . . . . . . . 129 5.5.1 Core Initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 5.5.2 Peripheral Initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
3/146
1
Table of Contents
5.5.3 Port Initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 5.5.4 Final Initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 5.6 INTERRUPT CONSIDERATIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 6 DETAILED BLOCK DIAGRAMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 6.7 6 .8 6.9 6 .1 0 6.11 EXTERNAL INTERRUPT CONTROLLER . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 TOP-LEVEL INTERRUPT INPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 WATCHDOG TIMER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 MULTIFUNCTION TIMER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 ADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
7 GLOSSARY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
146
4/146
1
ST9 USER GUIDE
1.3 HOW TO USE THIS GUIDE As a first approach, we recommend that you study each chapter in sequence and carry out the exercises at each step. 1.4 COMPANION SOFTWARE A downloadable file entitled ST9 User Guide Companion Software is available. This file provides all the source text files, listings, object files and any other files mentioned in the docum e n t. You can download the ST9 User Guide Companion Software from the http://www.stmcu.com website product support page. Unless otherwise specified, all the examples can be compiled fo r ST92F124/ST92F150/ST92F250 by modifying the makefile and the "device.h" file, if include d in the application directory. 1.5 ABOUT THE AUTHORS This User Guide has been initially written by Jean-Luc Grégoriadès and Jean-Marc Delaplace and revised for the ST9 by Jean-Luc Crébouw. Jean-Luc Crébouw A signal processing engineer, he has developed a voice synthesizer with an ST9 and conducts ST9 training programs. He acts as a field application engineer consultant for all STMicroelectronics microcontrollers. Jean-Marc Delaplace A former electronics design engineer, he has worked throughout his career for various U.S. co mpa nies involved in lab automation equipment. He has used microprocessors since they first appeared on the market and programmed microcontrollers of various brands in industrial applications using both assembler and high-level languages. Jean-Luc Grégoriadès Teaches automated systems and industrial computer science at the Electrical Engineering department of the University of Cergy-Pontoise. He introduced the STMicroelectronics ST6 as a tea ch ing base for his microcontroller course. On this occasion, he wrote with his friend J.M Delaplace, the book "Le ST6: Etude progressive d'un microcontrôleur" published at "Editions DUNOD".
5/146
1
ST9 USER GUIDE
1.6 RELATED DOCUMENTS The following reference documents should be available for additional information: ST9 Datasheet ST9 Programming Manual ST9 Family GNU Software tools ST9 GNU C Toolchain Release note ST9 Family GNU C Compiler GNU Make Utility You can get a current list of documentation at http://www.stmcu.com.
6/146
ST9 USER GUIDE
2 INTRODUCING THE ST9 BASICS
The ST9 microcontroller family has a common processor core surrounded by a range of powerfu l peripherals for interfacing with many different devices. The peripherals have sufficient built-in intelligence to be able to perform even complex jobs on their own, freeing the core almo s t entirely from I/O handling. The core can thus be fully utilized for classical microprocessing tasks. The ST9 architecture is an original STMicroelectronics design, with the objective of providing an innovative and efficient microcontroller architecture dedicated to real-time control. 2.1 PROCESSOR CORE When you compare different microcontrollers, you can estimate the relative computing power of the core, and also of the peripherals (if they include some intelligence). In some architectu res, the peripherals make heavy use of the core and thus take up a part of its computing po we r. Many microcontrollers available on the market have a relatively powerful core, surrounded by very simple peripherals. This approach has the advantage of making the peripherals easy to use and configure, but at the expense of the overall computing power. The ST9 is an example of a radically different compromise. Its core is among the best 8-bit microprocessors on the market in terms of computing performance and system management capabilitie s. It is assisted (rather than just surrounded) by peripheral blocks of which most can perform complex tasks without the intervention of the core. The net result is a powerful machine that can even perform impressive tasks just using its peripherals. The three applications described in this book give meaningful examples of processes handled solely by the peripherals. Th e ST92F150 is the latest generation of the powerful ST9 microprocessor family. The new ST9 core executes software more than three times faster than the previous ST9 core using optimized instructions and up to double the CPU frequency. The core as well as many peripherals have been enhanced, like for example, the Memory Management Unit (MMU), which is no w more flexible, with a single 4-Mbyte memory space that is directly accessible without using bank switching. Another example is the Reset and Clock Control Unit (RRCU) which has added features for reducing power-consumption. The ST9 is a register-oriented machine. This means that a large number of registers is available in the core; but above all, this implies that the instruction set is tailored to make efficient use of its registers through optimized addressing modes. It is also well suited to the use of C language.
7/146
ST9 USER GUIDE
2.2 PERIPHERALS The ST9 family includes a large number of peripherals. The main ones are:
Acronym Na m e Function All counting and timing functions. Includes auto-reload on condition, interrupt generation, DMA transfer, two inputs for frequency measurement or pulse counting, two outputs that can change on condition, PWM signal generation. Conditions include: overflow/underflow, comparison with one or two compare registers.
MFT
Multi-Function Timer
SCI-M
W DT
I/O port
ADC
Capture registers used to record transitions on inputs with their time of occurrence. Asynchronous transfer with either internal bit-rate generation or Serial Communication In- an external clock. Parity generation/detection. Address recogterface nition feature that can request an interrupt on match of an input character. DMA transfer. Can be used either as a watchdog or as a timer with input and Watchdog timer output capable of pulse counting or waveform generation. Parallel input/output ports. Each bit individually configurable as input, output, bi-directional, or alternate function. Inputs can be Parallel input/output port high impedance or with pull-up, CMOS or TTL-level. Outputs can have open drain or push-pull configuration. 10-bit analog to digital converter. One to sixteen channels can be converted in series. On each of two of the sixteen channels, Analog to digital converter. an Analog Watchdog function is used to define two thresholds. When exceeded, an interrupt is generated.
These peripherals are available with the standard variants. More peripherals are available on custo m devices on request, e.g. a videotext decoding logic. The ST9 family includes so many variants it would go beyond the scope of this book to describe them all. They are all made up of the same ST9 core surrounded by a set of peripherals, ROM and/or RAM and/or EEPROM and/or FLASH being optional. This book has chosen to show the three most generic variants and provide a basis for understanding all the others.
8/146
ST9 USER GUIDE
2.2.1 ST92F124
Figure 1.ST92F124R9 Block Diagram
F L A SH 64 Kbytes E3 TM 1 Kbyte RA M 2 Kbytes NMI 256 bytes Register File 8/16 bits CPU I N T [ 5 :0 ] WKU P[13 :0] OSCIN O SC O U T R E S ET CL OCK2 /8 INTC LK C K _ AF STOU T Interrupt Ma nagem ent ST9 CORE WAT CHD OG RC CU W DOU T HW0SW1 I2C BUS SDA SCL MEMORY BUS Ful ly Prog. I/Os
P0[7:0] P1[2:0] P2[7:0] P3[7:4] P4[7:4] P5[7:0] P6[5:2,0] P7[7:0]
T IN PA 0 T OUT A 0 T IN PB 0 T OUT B 0 T IN PA 1 T OUT A 1 T IN PB 1 T OUT B 1
REGISTER BUS
ST. TIMER
S PI
MIS O MOS I SCK SS
MF TIMER 0
A DC
AVDD AVSS AIN[15:8] EXTRG TX CLK RX CLK SIN DC D SO UT CL KOUT RT S
MF TIMER 1
S CI M
VREG
VOLTAGE RE GULA TOR
The alternate functions (Italic characters) are mapped on Port 0, Port 1, Port2, Port3, Port4, Port5, Port6 and Port7.
9/146
ST9 USER GUIDE
Figure 2. ST92F124V1 Block Diagram
F L A SH 128 Kbytes E3 TM 1 Kbyte RA M 4 Kbytes 256 bytes Register File 8/16 bits CPU Interrupt Ma nagem ent ST9 CORE MEMORY BUS
Ext. MEM. ADDRESS D A TA Port0 Ext. MEM. ADDRESS Ports 1,9
A[7:0] D[7:0]
A[10:8] A[21:11] P0[7:0] P1[7:3] P1[2:0] P2[7:0] P3[7:4] P3[3:1] P4[7:4] P4[3:0] P5[7:0] P6[5:2,0] P6.1 P7[7:0] P8[7:0] P9[7:0] SD A SC L W D O UT HW0S W1 MI SO MO SI SC K SS AVDD A VS S AIN[15:8] AIN[7:0] EXT RG TXCL K RXCL K SIN DCD SOUT CLKO UT RTS RDI TDO
AS DS RW W AIT NMI DS2 RW
Ful ly Prog. I/Os
INT[6:0] WK UP[1 5:0] OSCIN O SC O U T R E S ET CL OCK2 /8 INTC LK C K _ AF STOU T ICAP A0 O C M P A0 ICAP B0 O C M P B0 E X T C L K0 ICAP A1 O C M P A1 ICAP B1 O C M P B1 E X T C L K1 T IN PA 0 T OUT A 0 T IN PB 0 T OUT B 0 T IN PA 1 T OUT A 1 T IN PB 1 T OUT B 1 VREG
RC CU
I2C BUS
EF TIMER 0
REGISTER BUS
ST. TIMER
WA TCHD OG
SPI
EF TIMER 1
ADC
MF TIMER 0
SCI M
MF TIMER 1 SC I A VOLTAGE RE GULA TOR
The alternate functions (Italic characters) are mapped on Port 0, Port 1, Port2, Port3, Port4, Port5, Port6, Port7, Port8 and Port9.
10/146
ST9 USER GUIDE
2.2.2 ST92F150
Figure 3.ST92F150C(R/V)1/9 Block Diagram
F L A SH 128/64 Kbytes E3 TM 1 Kbyte RA M 2/4 Kbytes 256 bytes Register File 8/16 bits CPU Interrupt Ma nagem ent ST9 CORE MEMORY BUS
Ext. MEM. ADDRESS D A TA Port0 Ext. MEM. ADDRESS Ports 1,9*
A[7:0] D[7:0]
A[10:8] A[21:11]* P0[7:0] P1[7:3]* P1[2:0] P2[7:0] P3[7:4] P3[3:1]* P4[7:4] P4[3:0]* P5[7:0] P6[5:2,0] P6.1* P7[7:0] P8[7:0]* P9[7:0]* SD A SC L W D O UT HW0S W1 MI SO MO SI SC K SS AVDD A VS S AIN[15:8] AIN[7:0]* EXT RG TXCL K RXCL K SIN DCD SOUT CLKO UT RTS RDI TDO R X0 T X0
AS DS RW WA IT N MI D S2 R W* IN T[5:0] INT6 * W KUP [13:0] W K U P [ 1 5 :1 4 ] * OSCIN O SC O U T R E S ET CL OCK2 /8 INTC LK C K _ AF STOU T ICAP A0 O C M P A0 ICAP B0 O C M P B0 E X T C L K0 ICAP A1 O C M P A1 ICAP B1 O C M P B1 E X T C L K1 T IN PA 0 T OUT A 0 T IN PB 0 T OUT B 0 T IN PA 1 T OUT A 1 T IN PB 1 T OUT B 1 VREG
Ful l y Prog. I/Os
RC CU
I2C BUS
EF TIMER 0 *
REGISTER BUS
ST. TIMER
WA TCHD OG
SPI
EF TIMER 1 *
ADC
MF TIMER 0
SC I M
MF TIMER 1 SCI A* VOLTAGE RE GULA TOR CAN_ 0
* Not available on 64-pin version. The alternate functions (Italic characters) are mapped on Port 0, Port 1, Port2, Port3, Port4, Port5, Port6, Port7, Port8* and Port9*.
11/146
ST9 USER GUIDE
Figure 4. ST92F150JDV1 Block Diagram
FLASH 128 Kbytes FLAS H 128 Kbytes E3 TM 1K byte MEMORY BUS RAM 6 Kbytes
Ext. MEM. ADDRESS D A TA Port0 Ext. MEM. ADDRESS Ports 1,9
A[7:0] D[7:0]
A[21:8] P0[7:0] P1[7:0] P2[7:0] P3[7:1] P4[7:0] P5[7:0] P6[5:0] P7[7:0] P8[7:0] P9[7:0] V PW I V PW O S DA S CL W DOU T HW0SW1 MIS O MO SI SCK SS AVDD AVSS AIN[15:0] EX TRG TXCLK RXCLK SIN DCD SOU T CLK O UT RTS RDI TDO
AS DS RW WA IT NM I DS 2 RW INT[6:0] WKU P[15: 0] OSCIN O SC O U T RESE T CLO C K2 /8 CLOCK2 I NT CL K CK_A F S T OU T IC APA 0 OC MPA 0 IC APB 0 OC MPB 0 EXT CLK 0 IC APA 1 OC MPA 1 IC APB 1 OC MPB 1 EXT CLK 1 T IN PA 0 TO UTA 0 T IN PB 0 TO UTB 0 T IN PA 1 TO UTA 1 T IN PB 1 TO UTB 1 VR E G
Fully Prog.
256 bytes Register File 8/16 bit CPU In terrup t Management ST9 CORE
I/Os
J1850 J B L PD I2C BUS
RC CU WAT CHD OG REGISTER BUS
ST. TIMER
SPI
EF TIMER 0
A DC
EF TIMER 1
S CI M
MF TIMER 0 S CI A
MF TIMER 1
C AN _ 0
RX 0 TX 0 RX1 TX 1
VOL T AG E REGU LAT O R
CAN_1
The alternate functions (Italic characters) are mapped on Port0, Port1, Port2, Port3, Port4, Port5, Port6, Port7, Port8 and Port9.
12/146
ST9 USER GUIDE
2.2.3 ST92F250
Figure 5. ST92F250CV2 Block Diagram
FLASH 256 Kbytes E3 TM 1K byte MEMORY BUS RAM 8 Kbytes
Ext. MEM. ADDRESS D A TA Port0 Ext. MEM. ADDRESS Ports 1,9
A[7:0] D[7:0]
A[21:8] P0[7:0] P1[7:0] P2[7:0] P3[7:0] P4[7:0] P5[7:0] P6[7:0] P7[7:0] P8[7:0] P9[7:0] S D A0 SCL0 S D A1 SCL1 W DOU T HW0SW1 MIS O MO SI SCK SS AVDD AVSS AIN[15:0] EX TRG TXCLK RXCLK SIN DCD SOU T CLK O UT RDI TDO RX 0 TX 0
AS DS RW WA IT NM I DS 2 RW INT[6:0] WKU P[15: 0] OSCIN O SC O U T RESE T CLO C K2 /8 CLOCK2 I NT CL K S T OU T IC APA 0 OC MPA 0 IC APB 0 OC MPB 0 IC APA 1 OC MPA 1 IC APB 1 OC MPB 1 T IN PA 0 TO UTA 0 T IN PB 0 TO UTB 0 T IN PA 1 TO UTA 1 T IN PB 1 TO UTB 1 VR E G
Fully Prog.
256 bytes Register File 8/16 bit CPU In terrup t Management ST9 CORE
I/Os
I2C BUS _0
I2C BUS _1 RC CU REGISTER BUS
WAT CHD OG
ST. TIMER
SPI
EF TIMER 0 A DC
EF TIMER 1 S CI M MF TIMER 0 S CI A MF TIMER 1 C AN _ 0 VOL T AG E REGU LAT O R
The alternate functions (Italic characters) are mapped on Port0, Port1, Port2, Port3, Port4, Port5, Port6, Port7, Port8 and Port9.
13/146
ST9 USER GUIDE
3 PROCESSOR CORE: MAIN CONCEPTS
The term ST9 designates a family of components. Each component shares the same core, surrounded by a particular configuration of memory and peripherals that make up the specific va riant. The ST9 core has a unique and powerful structure. This chapter explains the main build ing blocks that you need to get familiar with to be able to make full use of its capabilities. The main features of the core architecture are: Register-Oriented Programming Model Single-Space memory addressing System and User Stacks Interrupt system with fully integrated controller Built-in DMA mechanism Reset and Clock Control Unit (RCCU) with PLL 3.1 ADDRESS SPACES Th e ST9 provides two different address spaces: Register Space and Memory Space. The Reg ister Space draws its power from its size: 256 registers of which 224 are uncommitted, and from the fact that it can hold data or pointers to data that reside in any of the two spaces. The Memory spaces can address up to 4 Mbytes. This address space is arranged as 64 segments of 64 Kbytes to address Programs and as 256 segments of 16 Kbytes to address Data when the DMA is not used. 3.1.1 Register-Oriented Programming Model The usual microprocessor core structure is based on an accumulator. The accumulator is the one register that holds the data to work on and the results of the arithmetic or logical operation s applied to it. This structure has become a classic - for its simplicity - the internal data pa th s of the microprocessor all converge to the accumulator. The instruction set is simple, sin ce you need to specify only one memory address in a data move instruction, the other being implicit: the accumulator itself. This simplicity has its own drawbacks: the accumulator is the computation bottleneck, since to move data from one place in memory to another place, you have to do it through the accumulator. The simplest transfer involves at least two instructions: one to get the data, the other one to store it. Re gister-Oriented models, in contrast, allow you to move data directly from one place to another in a single instruction. Data can come from a register or from a memory address and can go to either to a register or a memory address. You can code the addresses in the instruction, or store them in registers referenced by the instruction. This allows you to optimize your code
14/146
ST9 USER GUIDE
by choosing to store frequently used data in registers, leaving less frequently used data in memory. 3.1.2 Register File Th e ST9 has a special addressing space for registers, providing 256 different register addre sses. This large amount of registers gives you considerable flexibility in allocating variables. Register addresses are coded using one byte. You can use any of these registers to hold data or as a pointer either to other registers or to bytes in memory(1). Contrast this with processors that feature a certain number of registers, but in which some of these registers are meant to be only pointers or indexes, and some others not. These processors only allow transfers between memory and registers. The register organization of the ST9 gives you a real advantage you can make use of. 3.1.3 Direct access to the Register File The entire Register File can be accessed directly by its address prefixed by an "R" except for register group D (13) that can only be addressed through the Working Register mechanism. For example to address the register at the address 73, address it as R73, R49h or R1001001b in decimal, hexadecimal or binary. For a double register (16 bits) you can use the "RR" prefix to address any data with an even address. Any register can be given a user-defined name. In C language: #pragma register_file data1 char data1; #pragma register_file data2 60 int data2; and accessed with: data1=13; data2=0x12 34; data1 is automatically allocated in the register file by the linker as no register number is provided . data2 is manually allocated in register RR60. This pragma should be repeated in each file where the variable is made visible through an external declaration. However using these registers needs an additional byte with the instruction mnemonic. Using Working Registers is more efficient, because it avoids using this address byte.
(1)
Exce pt for group E (14) reserved for the system registers and group F (15) reserved for the peripherals.
15/146
ST9 USER GUIDE
3.1.4 Working Registers To further improve coding efficiency, a special mechanism has been created: the concept of wo rking registers. This reduces to just 16 bytes the register space accessible by the instructions in the so-called working register addressing mode. Only four bits are required to address this space, allowing both the source and the destination of a data move to be coded in a single byte, thus saving both code size and execution time. 256 registers, when split into groups of 16, give 16 groups. The group used is indicated in a special register, called the Working Register Pointer. The register address is made up of the group number and the register address within the group, as follows:
Figure 6. Register Group Addressing Scheme Register Address 7 6 5 4 3 2 1 0
Group Number (16 Register Groups)
Register Number within Group Number
3.1.5 Peripheral Register Pages All internal peripherals are mapped into the register space. Most of them have a multitude of features and can be configured in different ways. This implies that they have a large number of registers. Since only the last group of 16 registers is allocated for peripherals, a special sche me must be used to overcome this problem. It is called paging. The last group of registers actually addresses one pack of sixteen registers that belongs to the peripheral itself. Which pack of which peripheral depends on the value of a register called the Page Pointer Register. There can be as many as 64 different pages, providing plenty of space for accessing peripherals. Here are more details on these two mechanisms. 3.1.6 Working Registers and Register Pointers Th e working registers offer a workspace of 16 bytes. This is sufficient for most applications, and much more convenient than a single accumulator. However, in some applications, this is still not enough. In this case you can easily allocate more than one register group to a particular program module. Since any register can be accessed directly, it is up to you to decide whether you want to switch working register groups or not to access the other groups of registers. Since changing the current group involves only one instruction, the concept of working registers can greatly reduce context switching time, for example in the case of an interrupt service
16/146
ST9 USER GUIDE
rou tine. Doing this preserves the contents of the whole group, and the reverse operation restores them, as in the example: ; The main program uses the working register group 0 InterruptR outine: p ushw RPP ; Keep track of current group s rp #2 ; Switch to group 1 (see text below for details) . .. . .. ; Body of the interrupt service routine . .. p opw RPP ; Restore whatever group was active i ret ; Return from interrupt Supposing we could not switch working registers, we would have to push 16 bytes to the stack to ensure that the contents of the working area have been preserved, and pop them back before returning. Obviously the example above is more efficient, both in code and data memory size, and also in execution time. You use register pointers to allocate the working registers in a particular group. When writing in C or assembly language, you must position the working registers before you use them(2). Switching groups involves the RPP register pair, made of the two registers RP0 and RP1. These registers are directly accessible, but since their bits are laid out in a non-trivial manner, it is recommended that you set them using only one of the srp, srp0 or srp1 instructions. The registers are considered as sixteen groups of sixteen registers each. This is the way they are represented in the register number summary table (See Table 1.). Use the numbers in this table to refer to a register directly, e.g. when writing R35, this designates the fourth register of group 2. 3.1.6.1 Switching the 16 Groups of Working Registers This is done using the srp instruction. In spite of what we have explained up until now, and how it is usually represented, the core does not actually divide the registers in 16 groups of 16 re giste rs, but 32 blocks of 8 registers. This is why the srp instructions require arguments ranging from 0 to 31 instead of 0 to 15. Here is how the Register Pointers select the desired register group among 16 such groups.
(2)
Device Datasheet; Address spaces of the register file § 2.2.1 and following, system registers § 2.3.
17/146
ST9 USER GUIDE
Figure 7. Selecting a 16-Register Working Group
R255 Group F Paged Registers
R240 R2 39 Group E System Registers R232 Register Pointer 0 (RP0R) R224 R223 Groups 2 to D RP0R loaded using instruction code srp #2
R32 R31 General Purpose Registers G r oup 1 as Working Register Group R16 R15 Group 0 r0 r15
R00
Using srp defines one group of sixteen working registers named r0 to r15, and occupying 16 contiguous registers in the register file. The lower case r for the register number indicates that it is a working register number, in contrast to upper case R registers that indicate an absolute register number. For example, accessing r3 is the same as accessing R19 if the current group is group 1: s rp #2 i nc r3 ; Switch to group 1 ; increment 4th register of the group
18/146
ST9 USER GUIDE
i nc R19 ; increment the same register again The following table summarizes the use of the srp instruction and its effect in terms of group selection.
Table 1. Register Page Number Summary Hexadecimal register number F0-FF E 0-E F D0-DF C0-CF B 0-B F A 0-A F 90-9F 80-8F 70-7F 60-6F 50-5F 40-4F 30-3F 20-2F 10-1F 00-0F Notes: Deci m al register number 240 -255 224 -239 208 -223 192 -207 176 -191 160 -175 144 -159 128 -143 112 -127 96-111 80 -95 64 -79 48 -63 32 -47 16 -31 00 -15 Function Paged registers System registers Register group decimal (hexadecimal) 15 (F) 14 (E) 13 (D) 12 (C) 11 (B) 10 (A) 9 8 7 6 5 4 3 2 1 0 srp #n instruction to select a group to provide r0-r15 srp #30 srp #28 srp #26 srp #24 srp #22 srp #20 srp #18 srp #16 srp #14 srp #12 srp #10 srp #8 srp #6 srp #4 srp #2 srp #0
G eneral purpose registers
Though it is possible, it normally makes no sense to set the working register group either to group E (14) or F (15), since the registers in these groups have pre-defined meanings. You cannot use them to store intermediate values of calculations without greatly affecting the behavior of the microcontroller in an unpredictable way. However, bit-level instructions are only available using working register addressing, so when you need to do bit manipulations in these groups, setting the register pointer to either 28 or 30 is an efficient way of programming when accessing these two groups.
The srp instruction is the only one you have to use to switch register groups, and is the way working registers are used in most programs. However, the working register scheme includes a subtlety that is seldom used, but that could give you even more flexibility in some cases. This is what is described in the next paragraph. The same register group number can be selected by an odd or even number. In fact, the formula is: s rp or s rp 2*n ; for group n 2*n+1 ; for group n
19/146
ST9 USER GUIDE
3.1.6.2 Defining Two Separate Groups of Eight Working Registers In this mode, the srp instruction is not used. Instead, we use the pair of instructions srp0 and sr p1 . When using a working register, r0 to r7 address the first to the eighth register of the whole group selected by half the value in RP0 i.e. all the registers of the half group selected by RP0. Registers r8 to r15 relate to the first to the eighth register of the group pointed to by RP1. Here is how the two blocks are selected:
Figure 8. Register Numbers
R25 5 Group F paged registers R24 0 R239
Group E system registers
R233 Register pointer 1 (RP1R) R232 Register pointer 0 (RP0R) R22 4 R22 3 R21 6 R215 R208 R207 R32 R31 General Purpose Registers R24 R23 R16 R15 r15 r8
Upper part of Group D as working register group Lower part of group D Groups 2 to C
RP1R loaded using the instruction code srp1 #27
RP0R loaded using the instruction code srp0 #2
Upper part of group 1 Lower part of Group 1 as working register group Grou p 0 r7 r0
R00
20/146
ST9 USER GUIDE
As an example, if RP0 is set to half group 2 (lower part of whole group 1) and RP1 to half group 27 (upper part of whole group 13), r0 will designate R16 (2 x 8 + 0) while r15 designates R223 (27 x 8 + 7). Using either method depends on the organization of the data in the register file. You may find it convenient to use two 8-register blocks if you need to make quick calculations on pairs of data that are far apart in the register file. The page numbering and switching instructions are summarized below:
Table 2. Register Page Number Summary Hexadecimal register number F8-FF F0-F7 E8-EF E0-E7 D8-D F D 0-D7 C8-C F ... 78-7F ... 2 0-27 18-1F 1 0-17 08-0F 0 0-07 Deci m al register number 248-255 240-247 232-239 224-231 216-223 208-215 200-207 ... 120-127 ... 32-39 24-31 16-23 08-15 00-07 Eight-Register block decimal (hexadecimal) 31 (1F) 30 (1E) 29 (1D) 28 (1C) 27 (1B) 26 (1A) 25 (19) ... 15 (0F) ... 4 3 2 1 0 srp0 #n (or srp1) #n instructions to select a block to provide r0-r7 and r8-r15 respectively srp0 or srp1 #31 srp0 or srp1 #30 srp0 or srp1 #29 srp0 or srp1 #28 srp0 or srp1 #27 srp0 or srp1 #26 srp0 or srp1 #25 ... srp0 or srp1 #15 ... srp0 or srp1 #4 srp0 or srp1 #3 srp0 or srp1 #2 srp0 or srp1 #1 srp0 or srp1 #0
Function Paged registers Paged registers System registers System registers
General purpose registers
When you use an 8- or 16-register group, you may very likely have a subroutine or an interrupt routine that uses a different set of working registers. You must save (push) the pair of register pointers RPP that include RP0 and RP1 at the beginning of the routine and restore them on exit. 3.1.6.3 Peripheral Register Paging G rou p F of the 16-register groups is paged so that as many as 64 different groups can be mapped to this address range. This large space is used to accommodate the registers related to the peripherals. The paging technique allows you to add any number of peripherals and still be able to handle them without using up more addresses in the register space. When you access a register in group 15, first set the Page Pointer Register to the number of the page that contains the register you want. Here is how a page is selected:
21/146
ST9 USER GUIDE
Figure 9. Selecting Page Registers
R255 Group F Paged Registers Page 3 R240 R2 39 Group E System Registers R234 R224 Page Pointer Register (PPR) PPR loaded using instruction code spp #3.
Groups 0 to D R00
As with the working registers, if a subroutine or an interrupt routine needs to access a periphe ra l that uses paged registers (which is very likely), you must save (or push) the register pointer PPR at the beginning of the routine and restore it on exit.
Notes: In both assembly and C languages, include files are supplied with symbolic names pre-defined for all the peripherals. These names are unique for each peripheral; however several different names relate to the same register, but in a different page. You must bear in mind that writing for example (in C language):
S_ISR = 0; /* clear serial peripheral error register */
does not automatically select the proper page; this statement must be preceded by another one that selects the SCI page. Since no predefined C statement exists for this, a convenient way is to define an assembler statement under the form of a macro that will read nicely in the C source.
An example of the correct way to access the SCI register is: #define SelectPage(Page) asm ("spp %0":: "i" (Page)) ; /* pseudo function to select a page */ S electPage( SCI1_PG ); S _ISR = 0 ; 3.1.7 Memory Management Unit Like most microcontrollers, the ST9 has a bus for interfacing internal and external memories. This allows you to store both programs and data. A special feature of the ST9 is that it can address a 4 Mbyte single space to address ROM, RAM, EPROM, EEPROM, FLASH. /* Select the serial peripheral page */ /* Clear serial peripheral error register */
22/146
ST9 USER GUIDE
To address the 4 Mbytes of memory, the address bus is 22 bits wide. To manage the 22-bit address with 16-bit direct or indirect addressing, the memory mechanism adds extra bits to the 16-bit address and then works with segments (see Figure 10) or pages (see Figure 13). The memories are arranged in 64 segments of 64 Kbytes for the program and in 256 segments of 16 Kbytes for data. A set of special registers is used to extend the 16-bit address. Programs use the CSR, DMA uses the DMASR or ISR and interrupts use the ISR or CSR register to provide the 6 Most Significant Bits to make a 22-bit address. Data uses a set of four registers (DPR0-3) to provide the 8 Most Significant Bits to make a 14-bit address. Data can be addressed in the Program segment by using special move instructions: lddp, ldpp, ldpd, lddd. It is easier from a hardware point of view to use only one address space for Program and Data .
Figure 10. Addressing via CSR, ISR and DMASR 16-bit Virtual Address
MMU Registers
C SR
D M AS R
ISR
1 1
Fetching program instruction
2
3
6 bits
2
Data Memory accessed in DMA Fetching interrupt instruction or DMA access to Program Memory
3
22-bit Physical Address
23/146
ST9 USER GUIDE
3.1.7.1 Program Segment We can consider this memory as linear since we can jump anywhere in memory space using the special JPS, CALLS and RETS instructions. The 6-bit CSR register is used to extend the 16-bit address to a 22-bit address by concatenation (see Figure 10). To make a fast branch in the same segment, use the common JP, CALL and RET instructions. To branch to another segment using a far call, the use of CALLS saves the current PC value and the CSR value (Code Segment Register) in the stack, before loading the PC and the CSR registers with the new values. Every time the segment changes you have to use the far branch e v e n if you branch from address (n)FFFFh to (n+1)0000h. This is because the program doe sn 't manage the 6 high-order bits of the 22-bit program addresses if you don't use a far branch to change the CSR register value. The script file (described in the Development Tools chapter) allows you to place all your program modules anywhere in a single segment. The far branch instruction adds only 2 to 4 additional cycles compared to a near branch instr u ctio n .
Note: In C language, using the small code model (this means only one 64 Kbyte segment is used), all calls use local branches. If more than one segment is used, the large code model is required and all calls use far branches even when branching locally. To avoid far calls in the same segment, the segment to be called has to be declared as static if it is not called from another segm ent .
3.1.7.1.1 Segment and Offset in Assembler Mode or C Language The Offset represents the address in the segment with 16 bits. If the Segment and the Offset are known, the following syntax is used for the far branches: j ps j ps c alls c alls c alls c alls r ets segment,offset symbol segment ,offset symbol (R),(rr ) (r),(rr) ; 6 bits + 16 bits ; 22 bits ; 6 bits + 16 bits ; 22 bits ; 6 bits + 16 bits ; 6 bits + 16 bits ; 22 bits
Th e assembly tools accept a set of directives which retrieves the elements of a function address or of a label. The operator SEG (stands for SEGment) allows you to extract the segment number of a label; similarly, the operator SOF (stands for Segment OFfset) allows you to extract the offset of a label within its segment.
24/146
ST9 USER GUIDE
These operators are especially useful when applied to a function or instruction label, although the macro-assembler and assembler do not verify the type of the label. E xa m p l e : ld l dw c alls r0,#SEG Function rr2,#SO F Function (r0),(r r2) ; extract the 6-bit segment ; extract the 16-bit offset
The same functions exist in C language: SEG(Function); SOF(Function). 3.1.7.2 Interrupt Service Routine Segment One program segment is reserved for storing the Interrupt Service Routines. All the interrupt routines start in this segment. To obtain a 22-bit address, the 16-bit address is concatenated with 6 bits from the ISR register (the 6 bits from the ISR register are the high-order bits of the address). To offer compatibility with the previous ST9 versions and to have a new powerful address mechanism, you can select "ST9" mode using the EMR2 bit in the ENCSR register. Both modes use the concatenation of the ISR register value and the 16-bit address as shown in Figure 10 to address the interrupt vector. Then, in "ST9" mode, only the ISR register value is used during the interrupt routine. So it's not possible to jump to another segment from the Interrupt Service Routine because the CSR register value is not saved with the FLAGR value and the current PC value when the interrupt occurs. The advantage of "ST9" mode is to reduce stack memory usage and CPU cycles by not saving the CSR value (see Figure 11). This figure shows you the different mechanisms that are used when an interrupt occurs, when a branch or a call is executed during the interrupt routine and when the return from interrupt instruction (RETI) is executed.
25/146
ST9 USER GUIDE
Figure 11. Interrupt Processing in "ST9" Mode
6-bit 6-bit I SR 22-bit 22-b i t 16-bit Inte rrupt Vector Interrupt Se rvice Ro utine Ad dress 16-bit Address of any branch 16-bit 22 -bit ISR CS R
6-bi t
6-bit ISR
22-bit
8 bits at '0' 8-bit IVR
16-bit
PC MSB STAC K FL AG PC MSB PC LSB When an interrupt occurs, the 8-bit IVR address is extended to 22-bits to obtain the address of the Interrupt Service Routine as shown above. PC LSB ST ACK FLA G PC MSB PC LSB
Only the PC value is saved for a CALL instruction
FLAG PC MSB PC LSB
FLAGR register
ST ACK
Addresses of local branches (within the same segment as the Interrupt Service Routine, using the CALL instruction) are extended to 22-bits as shown above.
Return from interrupt. The current PC value saved in the stack and the CSR value are concatenated to make the 22-bit return address.
In "ST9" mode, saving the CSR value allows you to change its value to branch to another segm e n t . When the interrupt occurs and when the current PC, CSR and FLAGR values are save d, the ISR register value is stored in the CSR register (see Figure 12).
26/146
ST9 USER GUIDE
Figure 12. Interrupt Processing in "ST9" Mode
Next segment for a far branch 6-b i t ISR 6-bit C SR 6-bit ISR 22-b i t 16-bit Inte rrupt Vector 22-b i t In terru pt Service R outin e Address 22-b i t 22 -bit CSR CSR 6-bi t
8 bits at '0' 8-bit IVR
16-bit Address of any branch 16-bit 16-bit
C SR STAC K FLAG CS R PC MSB PC LSB PC MSB CS R+P C represent the 22-bit current address sa ved. PC LSB STA C K FLA G C SR PC MSB PC LSB When an interrupt occurs, the 16-bit Interrupt Vector is extended to 22-bits as shown above. Before loading the CSR register with the ISR value, the CSR value is saved in the stack. Addresses of local and far branches (to any segment) are extended to 22-bits as shown above. For a far CALL, the CSR value is saved with the current PC value in the stack and the CSR register is loaded with the new segment to jump to. Return from interrupt. The current PC value and the CSR value saved in the stack are concatenated to make the 22-bit return address. FL AG CSR PC MSB PC LSB S T AC K FLAGR register
3.1.7.3 DMA Segment To address the total 4 M b yt e s of memory in a DMA transaction, the DMASR points to a 64-Kbyte segment. Since there is no need to have more than one segment at the same time for the transaction, the DMA uses a single 64-Kbyte segment instead of 4 pages like a Data Segme nt (see below). To use the DMASR register, the DP bit in the DMA Address Register (DAPR) must be set. If DP is reset, the DMA uses the ISR register instead of the DMASR register.
27/146
ST9 USER GUIDE
3.1.7.4 Data Segment Data uses the page mechanism to address the 4 Mbytes of memory. To authorize data coming from different 64-Kbyte segments, a set of 4 Data Page Registers (DPR0 to DPR3) allows you to address 16 Kbytes per register (see Figure 13). The DPR is selecte d with the 2 high-order bits of the 16-bit data address: DPR0: from 0000h to 3FFFh (b15-b14=00) DPR1: from 4000h to 7FFFh (b15-b14=01) DPR2: from 8000h to BFFFh (b15-b14=10) DPR3: from C000h to FFFFh (b15-b14=11) After you select the DPR, the 8-bit value of the selected DPR register is used to extend the 14 remaining bits of the address to 22 bits. For example, if DPR0 equals 20h and DPR1 equals 2h, each memory access in the range of 00 00 h to 3FFFh uses the DPR0 page and addresses data from 080000h to 083FFFh, and ea ch memory access in the range of 4000h to 7FFFh uses the DPR1 page and addresses data from 008000h to 00BFFFh (see Figure 13). For example: 16-bit address = 0010 0101 1010 0101 = 25A5h 0000h < 25A5h < 3FFFh
DPR0 is selected, so the 6 high-order bits are equal to 20h 22-bit address = 0010 0000 10 0101 1010 0101 DPR0 value, 14 LSB of the 16-bit address = 00 1000 0010 0101 1010 0101 = 0825A5h With this mechanism, if the 16-bit addresses are different only on the 2 highest bits and if all the DPR registers selected with these two bits have the same value, the resulting 22-bit address will be the same. Four pages of 16Kbyte of data memory are enough for many applications and allow you to use data from different segments without costing additional CPU cycles. With four DPRs, you can acce ss up to 64K (4 x 16K) of data without changing the DPR values. Data can be variables stored in RAM or constants stored in program ROM. The four DPR registers are located in the MMU register page (page 21 of register group F). If you use them frequently, you can relocate them to register group E, by programming bit 5 of the EMR2 register (R246 in page 21). This prevents you from having to switch to the MMU register page from another peripheral register page in order to change a DPR register value.
28/146
ST9 USER GUIDE
Figure 13. Addressing via DPR0-3 MMU Registers 16-bit Virtual Address
D PR 0
D PR 1
DPR2
D PR 3
00
01
10
11
8 bits
14 LSB
22-bit Physical Address
3.1.7.4.1 Accessing the Page and the Offset in Assembler or C Language The assembly tools implement a set of operands which allows you to extract the components of a data address. The PAG operator (stands for PAGe) extracts the page number of an address; similarly, the POF operator (stands for Page OFfset) extracts the offset of the address within the page. S yn t a x : PAG label POF label Be careful that directly using the data label and using the POF operator on a data label are not equivalent: the data label gives the 16 bits of the logical label address; the POF operand gives the 14 lowest bits of the label's physical or logical address. E xa m p l e : Assuming data is mapped at address 0x129876: l dw l dw rr2,#POF data rr4,#data ; rr2 = 0x1876 ; rr4 = 0xD876 (with DPR3=0x4A)
Rem em ber that you must take care of which data pointer has to be set before accessing a variable .
2
M
SB
29/146
ST9 USER GUIDE
E xa m p l e : Assuming that data has been mapped in a page aligned on address 0xC000, this means that DPR3 will be used, therefore the following code is correct: ld l dw ld DPR3,#PAG data rr2,data r4,(rr2)
In assembly language, it is possible to access data through another DPR: E xa m p l e : Still using data at an address aligned with 0xC000, following code is correct: ld l dw DPR2,#P AG data ; if data address=0x01C765, DPR2=7 ; #(POF data) to reset bit 15 and 14 ; and 0x8000 to use DPR2 ld . .. ld r4, (POF data)+0x8000 ; direct addressing mode It is important to look at the explicit usage of the immediate addressing mode (#) to get the page number and the offset; it is consistent with the ST9 assembly syntax shown in the following example: l dw ld . .. ld r4, Var The same functions exist in C language: PAG(data); POF(data); rr2,#Va r r4,(rr2 ) r4,(rr2 ) ; indirect addressing mode
rr2, #(POF data)+0x8000; rr2=0x8765
30/146
ST9 USER GUIDE
3.2 STACK MODES The ST9 allows you to have two separate stacks: a system stack and a user stack. The core uses the system stack in interrupt routines and subroutines to save return addresses, the flag reg ister and the CSR depending on option (EMR2 register bit Enable Code Segment Register). You can also use it under program control to save data, using the push and pop instructions. The user stack works exactly the same way, using the pushu and popu instructions but only under program control, which means that the user stack is not changed by the system. You may choose to use a separate space for your data, or to store them in the same stack as the return addresses. Both stacks can independently be located either in RAM or in the register file. You select this using the SSP and USP bits in the MODER register (R235) for the system stack and the user stack, respectively. A low bit value selects a RAM stack, and a high bit value selects a Register File stack. Since the stacks grow towards low addresses, the stack pointers must be initialized to the highest location plus one (3) of the space reserved to it. This location becomes the "bottom" of th e stack. When the stack is located in the register file, take care that it does not overwrite other data, in particular the registers located in groups 14 (0EH) and 15 (0FH). For this reason it is advisable to set the system stack pointer to the end of group 13 (0DH). The last register of this group being R223, the instruction that sets the stack pointer will be: ld
Note 1:
sspr, #224 ; set stack pointer to one above end of group 13
Using two separate stacks in the same kind of storage (memory or register) area is likely to consume more space than if a single stack is used. So most of the time, only one stack will hold both return addresses and arguments for functions. You can then use pushu and popu instructions to manipulate data with the convenience of auto incrementing or decrementing the pointer after each access. As an example, refer to the C language start-up files which initialize both the user and system stacks.
The following diagram illustrates the two options for locating the stack: in the register file or in memory.
(3)
The push instruction decrements the stack pointer before writing the data, so this location would never be used if set to the top location.
31/146
ST9 USER GUIDE
Figure 14. Stack Location Options
R 255 G r oup F Paged Registers R 240 R 239 Stack Pointer Low Stack Pointer High Group E System Registers
R25 5 G r oup F Paged Registers R24 0 R23 9 Stack Pointer Low Stack Pointer High G r oup E System Registers Data Memory (RA M )
Bottom of Stack Stack Bottom of Stack S t ac k
R 00 System or User Stack in Register Space High byte of pointer irrelevant
R00 System or User Stack in Data Memory Space
3.3 INSTRUCTION SET The ST9 is said to be an 8/16-bit microcontroller. This means that although the size of the internal registers and the width of the data bus are 8 bits, the instruction set includes instructions that handle a pair of registers or a pair of bytes in memory at once. These instructions represent roughly one half of the total instructions, which means that the ST9 can be programmed with the same ease as if it were advertised as a full 16-bit device. This is why it is well suited for C programming, as illustrated in this book.
32/146
ST9 USER GUIDE
3.3.1 Overview For a complete description of the instruction set, you should refer to the ST9 Programming Man ual. The aim here is to give you an introduction to the ST9 instruction set and highlight some of its best features in terms of power and ease of programming. Most instructions of the ST9 exist in both byte and word forms. That is, they can operate on either 8 (byte) or 16-bits (word). The mnemonics of the word-instructions all end with a "w", as in the following examples:
Load ld l dw Ad d add addw Subtract s ub s ubw Logical and and andw Logical or or orw Compare cp c pw Push pus h pus hw Pop p op po pw
The new powerful instructions added to the ST9 are the CALLS, RETS, JPS instructions for far branching to change the program segment and the instructions used for C language applicatio ns, LINK, LINKU, UNLINK and UNLINKU. Moreover, all instructions have been optimized compared to Previous ST9. 3.3.1.1 Load Instructions Beside the classical load instructions found on most microprocessors, there are four special load instructions for moving data between two locations in memory. One instruction to move data from data segment to data segment; lddd. This instruction allows you to post-increment the destination and the source index register at the same time. The ld instruction needs two instructions to do this. An example for moving a block of data would be: ld ld ld loop: ld ld d jnz r4,(rr0)+ (rr2)+,r4 r5,loop ; transfer of one byte rr0,#Source rr2,#Destination r5,#Num_loop ; initialisation of the pointers ; number of elements to move
The two ld instructions are coded using 6 bytes and executed in 24 cycles. The same program with the lddd instruction: ld ld rr0,#Source rr2,#Destination ; initialisation of the pointers
33/146
ST9 USER GUIDE
ld loop: l ddd d jnz
r5,#Num_loop (rr2)+, (rr0)+ r5,loop
; number of elements to move ; transfer of one byte
The lddd instruction is coded using 2 bytes and executed in 14 cycles. Here are the four possible data transfers:
Instruction lddd ldpp lddp ldpd Moves data from... data segment (uses the DPR0-DPR3 registers) program segment (uses the CSR register) program segment data segment ...to data segment program segment data segment program segment
Th ese four instructions improve the performance of data block moves (frequently used in C programs). As you can see in the table above, the data move can be between data and program segments. Here's an example of a data move from a Data segment using the DPR register to a Prog ram segment using the CSR register: ld ld ld loop: l dpd d jnz (rr2)+, (rr0)+ r5,loop ; transfer of one byte rr0,#Source rr2,#Destination r5,#Num_loop ; initialisation of the pointers ; number of elements to move
The data load with rr0 comes from the data segment selected by one of the four DPR register value s depending on the rr0 value and then are stored in the program segment selected by the CSR register value. (Please refer to the MMU Section 3.1.7 for an explanation of data and program segments). 3.3.1.2 Test Under Mask The se instructions, tm and tmw, perform a logical (bitwise) AND between the two operands, but do not store the result. They only set the Z and S bits of the flag register for a later conditional jump on zero or sign. The mask is a value in which the bits that are set to 1 select the corresponding bits of the value to be tested for non-zero. As an example, in the following instr u ctio n : t m value, mask
34/146
ST9 USER GUIDE
If the mask is a byte whose binary value is 110 0 00, only the left-most two bits of the unkn ow n value will be tested, and a later branch if zero will be taken or not according only to these bits. As shown below, the same mask is used for two values that differ only by one bit:
000110101 110 0 000 0 0 00000 jump taken Byte to be tested Mask used for testing Result of the logical AND operation Result of the "jump if zero" 1 1 1 0 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0
jump not taken
Two more instructions, tcm and tcmw, work essentially the same way, but they take the complement of the value to be tested before ANDing it with the mask, as follows: t cm value, mask The same two cases will provide the following results:
000110101 111001010 110 0 000 110 0 000 jump not taken Byte to be tested Complement of the byte to be tested Mask used for testing Result of the logical AND operation Result of the "jump if zero" 1 0 1 0 0 1 1 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0
jump not taken
The jump would be taken if the byte to be tested had two 1's in its most significant two bits, for example 11110101. 3.3.1.3 Push and Pop Since there are two stacks, there are two kinds of push and pop instructions. The mnemonics push, pushw, pop and popw act on the system stack, which can be either in the register space or in the memory space. The mnemonics pushu, pushuw, popu and popuw act on the user stack, that can also be either in the register space or the memory space. The stack pointer used in each case is the SSPR or the USPR register pair respectively. The stack pointers are alwa ys decremented before writing on pushing, and they are incremented after reading on popping. Thus the stack pointer always points to the last byte written. This is worth knowing if you need to manipulate the stack contents. The operands to be pushed can be a register, a pair of registers or an immediate value:
35/146
ST9 USER GUIDE
p ush r6 p ush (R120) p ush #80 p ushw RR100 p ushw #1500 Pushing an immediate value is especially useful when you are programming in C. A special push instruction is Push Effective Address. This instruction does not push the data itself, but the memory address of the data. For example: p ea 5(rr2) This takes the contents of rr2, adds 5 and pushes the result onto the stack. This is widely used in C programming. 3.3.1.4 Multiply and Divide The multiply instruction takes two byte operands and provides a word result. All numbers are treated as unsigned numbers (operands 0 to 255, result 0 to 65535). Though both operands are bytes, the first one must address a word to receive the result. The first operand should then reside in the low byte of the word, and the high byte, not used in the operation, will be overwritte n. The flag register is affected but the state of the flags after the operation is meaningle ss. To multiply a signed number (operands -128 to 127) by an unsigned number (operands 0 to 255) with a result in the range of -32768 to 32767, refer to the example given below: ld ld b tjt m ul jp neg: m ul s ub end With the signed operand equal to 226=0E2h (means -30 for signed data) and the second unsigne d operand equal to 0Fh (+15) the result will be -450 (0FE3Eh). rr0,r4 r0,r4 ; rr0 = r1*r4, with r1 value a negative signed ; number ; rr0=rr0-100h*r4 r1,#signed_data r4,#unsigned_data r1.7,ne g rr0,r4 end ; rr0 = r1*r4, with r1 value a positive signed ; number
36/146
ST9 USER GUIDE
This "eight bits signed by eight bits unsigned" multiplication with a "sixteen bits signed" result takes a maximum of 36 cycles. There are two divide instructions. The div instruction divides a word by a byte, and returns the quotient and the remainder as the low and the high bytes of the destination respectively. For example: l dw ld d iv rr0,#31184 r2,#201 rr0,r2 ; rr0=#31184 ; r2=#201 ; rr0=1D9Bh, 1Dh=#29 and 9Bh=#155
This puts the value 155 in r1 (the quotient) and the value 29 (the remainder) in r0, and r2 still contains 201. If the divider is greater than the dividend, nothing is done. If the divisor is zero, a trap is triggered that acts like an interrupt request, and uses the vector at locations 2 and 3 in program memory. It is up to you to write the appropriate code to handle this trap. Finally, the numbers to be divided should be such that the quotient be less than 256, that is, can be stored in a single byte. Otherwise, the results are undefined. The usable result is only the data stored in r1 which is 155 (for the previous example), the remainder must be divided by the divisor (201) to give more precision (16-bits precision). l dw ld d iv ld c lr d iv ld rr0,#31184 r2,#201 rr0,r2 r4,r1 r1 rr0,r2 r0,r4 ; rr0=#31184 ; r2=#201 ; rr0=1D9Bh, 1Dh=#29 the remainder and ; 9Bh=#155 the quotient ; r4=9Bh=#155 ; rr0=1D00h ; rr0=0BC24h, 0BCh=#188 the remainder and ; 24h=#36 the quotient ; rr0=09B24h, 09B24h means in fix-point ; with the point in the 16-bits middle ; 09B24h=155.140625 instead of ; #31184/#201=155.1442786 In the best case, the number of cycles required to divide a word by a byte with 16-bits precision is 80 cycles. This program has to manage overflow and divide by zero functions in order to be able to be used. The divws instruction performs one of the sixteen partial divides required to divide a double word by a word, so you need to write a subroutine to perform the division completely. An example subroutine is given in the ST9 Programming Manual.
37/146
ST9 USER GUIDE
3.3.1.5 Bit Operations Microcon trollers are often used for controlling inputs and outputs on a single-bit basis, in order to read the state of a contact, switch a relay on or off, etc. Because of this and because the data is stored in bytes, instructions for bitwise manipulation of data are welcome. The ST9 provides instructions to load, and, or, exor, set, clear, complement and test single bits. These are bld, band, bor, bxor, bset, bres, bcpl, btset. To designate a single bit in a byte, the notation .n is used. For example, r0.3 means bit 3 of r0. Here are examples of bit manipulation instructions: b ld b ld b and b or b set r0.2, r6.4 r0.3, !r6.0 r0.2, r0.3 r0.2, r2.7 r0.0 ; bit 0 or r0 set to 1 ; bit 4 of r6 copied to bit 2 of r0 ; complement of bit 0 of r6 copied to bit 3 of r0 ; r0.2 contains now (r6.4) and not (r6.0)
b cpl r0.1; bit 1 of r0 is complemented All the above instructions act on single working registers. If the source operand is preceded by `!', the complement of the source bit is used. To test a bit, to condition a later jump, we have already described the tm and tcm instructions. There is another instruction, btset, that can act on either a single or a double working register, and that sets the Z bit of the FLAGR register if the designated bit is zero. After which, the bit is set to one. You can use this instruction in an interrupt service routine to test for a request and acknowledge it in a single instruction. Warning. Don't use the bit manipulation instructions directly on bidirectional ports. To avoid unwante d modifications to the port output register contents, use a copy of the port register, th en transfer the result with a load instruction to the I/O port. (Refer to the Input/Output Bit Configuration section in the Device Datasheet for more details.) 3.3.1.6 Test and Jump Th e btjf and btjt instructions test if a bit is set or cleared respectively and branch to another program location if true. For example: b tjt b set Lampon: . .. ; continuation of the program Two instructions are well-suited for implementing lookup tables. These are cpjfi and cpjti. They compare a byte in a register with a byte pointed to by a register pair, and increment the pointer r1.5,Lampon r1.5 ; switch lamp on
38/146
ST9 USER GUIDE
if the condition is not met. If the condition is met, the pointer is not incremented and the branch is taken. Example: ; Find the position of a letter in a text. Message: .a scii "This is a trial" ld ld Search: c pjfi . .. . .. 3.3.1.7 Far Branch As explained in Section 3.1.7, the 4-Mbyte memory is a segmented memory. It is not possible to reach another segment with the common CALL, RET and JP instructions because they do not manage the CSR (Code Segment Register) register. This is managed by the three new CALLS, RETS and JPS instructions. Only 2 to 4 cycles are added to the common instructions. 3.3.1.8 Optimized C Instructions In C functions when a function is called, the compiler needs to push the variables in the user/ system stacks and to keep the return address location of the function inside the stack. Therefore, a frame pointer is used, and 2 pieces of code named prologue and epilogue need to be added by the C Compiler at the beginning and at the end of the function respectively. The LINK and UNLINK instructions (LINKU, UNLINKU to use the user stack) are used to reduce the code overhead generated by the compiler inside the function. These instructions are automatically added by the C Compiler instead of prologue and epilogue (if option -mlink is specified). The number of cycles gained by using these instructions is about 34 to 42 cycles and 8 bytes per called function. r2,(rr0),Search ; this is the search loop rr0,#Message r2,#'t' ; where to search ; the character to search for
; here rr0 points to the 11th character of message ; continuation
39/146
ST9 USER GUIDE
3.3.2 Advantages when Using C Language The ST9 has been designed with high-level languages in mind. In particular, the instructions describ ed above are of special interest to C programmers. First, as a structured language, C typically uses the stack to pass arguments to functions, return values from functions, and store the local variables of the functions. An instruction such a s: p ushw #1500 pushes a constant integer value as the constant argument of a function. This is used in the following example: /* define a function that has a single argument of int type */ void MyFunction ( int Param ) ; { / * body of the function */ } void main ( void ) ; { / * some code ... */ M yFunction ( 1500 ) ;/* invoke this function with a constant argument */ / * more code ... */ } Since C makes heavy use of pointers, the instruction: p ea 4(rr2) pushes the address of the 5th byte of a structure. For example: /* define a structured type */ struct sMyStruct { i nt N1 ; i nt N2 ; c har C1 ; }; struct sMyStruct MyStruct ;/* create a variable of the above defined type */
40/146
ST9 USER GUIDE
/* define a function that has a single argument of type pointer to character */ void MyFunc ( char * Arg ) ; { / * body of the function */ } void main ( void ) ; { / * some code */ / * invoke the function with the address of the character element of the structure */ M yFunc ( &MyStruct.C1 ) ;/* &MyStruct.C1 = 4(rr2) if rr2 contains the address of MyStruct */ / * more code */ } The lddd, ldpp, lddp, ldpd instructions are used for block copies such as assignments of structures, etc. Po we rful addressing modes such as indirect, indirect with increment or decrement and indexed shorten the code needed to access data even in structures or arrays. They also facilitate access to local variables created on the stack on entering functions. Working registers that benefit from the most powerful instructions and addressing modes are heavily used by the compiler. In fact, the GNU9 compiler does not always translate the source code as suggested a bo v e . There are optimization schemes that save execution time and/or memory by judiciously allocating the working registers, so that in many cases arguments are not pushed to the stack, but merely to an available working register. 3.4 INTERRUPTS Th e interrupt system of the ST9 is very powerful, and, in consequence, requires some thorough study to get the most out of it. However, it is worth learning since it allows you to build very efficient programs with excellent interrupt response times. The ST9 interrupt system works the same as that of any microcontroller, except for two points that call for special attention: the vector mechanism and the priority mechanism(4).
(4)
Device Datasheet; Interrupts § 4.
41/146
ST9 USER GUIDE
3.4.1 Interrupt Vectors Unlike most microcontrollers, the ST9 uses a two-level indirect interrupt vector system. This m ea n s that each peripheral able to generate interrupt requests has a vector register that points to a location in program memory (the vector array). This location contains the address of the start of the interrupt service routine. This allows each peripheral to generate several differen t interrupt requests: the peripheral vector register points to an array of pointers to rout in e s, each routine responding to a different interrupt cause. All pointers to interrupt processing routines, except the Reset, must be located in the first 256 bytes of the Interrupt Service Routine (ISR) segment (one of the 64 code segments). The trap for divide by zero with the associated far call to the Interrupt Service Routine has to be repeated in all memory segm e n t s containing programs that perform division. Code may also reside in this 256-byte space, provided that it does not overlap with the interrupt vectors. Figure 15 shows the complete mechanism of the 22-bit address construction from the interrupt which provides the Interrupt Vector Register value to the return from interrupt. For each peripheral, the layout of the vector array is specified in the section related to its own Interrupt Vector Register.
42/146
ST9 USER GUIDE
Figure 15. Interrupt Vectors
(2)
22-bit C SR
Memory Space
CSR from stack
At the end of the Interrupt Service Routine, the IRET instruction returns to the program in the segment selected by CSR (CSR_5 to CSR_0)
PC from stack Interrupt Program
22-b it ISR Segment ISR or CSR(1) 22-bit
6-bit 00 ISR
8-bit
Interrupt Service Routine Address
16-bit
8-bit
ISR Address of Divide by Zero Trap ISR 0002 ISR 0000 XX FFFF
Paged Registers
01 0000 00 FFFF
Segment 0
R25 5 Interrupt Vector Register (IVR)
Divide by zero trap repeated at each segment
ISR Address of Divide by Zero Trap 00 0002 ISR Address of Only for the first R E S ET 00 0000 se gmen t
Bit D0 of IVR is always 0 since the addresses of the interrupt service routine start at even addresses
R240
(1) If the ENCSR bit of EMR2 is set (Enable Code Segment Register), the CSR is saved in the stack and then loaded by the ISR. If it's reset, the CSR is not saved and only the ISR is used. (2) If the ENCSR is set, the CSR is reloaded with the value saved in the stack when the interrupt occurs. If it's reset, CSR is used instead of ISR when the RETI instruction occurs (Return from interrupt).
As an example, let's take the ST92F150 Multifunction Timer 0. The registers that define the MFT0 functions are all contained in pages 9 and 10 of register group 15 (0FH). Register 242, called the Interrupt Vector Register (IVR), holds the address of the beginning of the vector array in program memory. The IVR has the following bit layout:
43/146
ST9 USER GUIDE
T0_IVR (R242 page 9)
V4 V3 V2 V1 V0 W1 W0 '0'
Where V4-V0 (fixed by software) are the high bits of the low byte address memory where the vector for the first interrupt cause is located. Since there are three different interrupt causes, and the address of each interrupt service routine occupies two bytes, the IVR must be loaded with an address between 8 and 250 that is a multiple of 8 (i.e. the lower three bits are zero). The layout above shows two bits W1 and W0 (fixed by hardware), and a third bit that is permanently set to zero. The two W1-W0 bits code four different possible interrupt causes, as in the following table:
W1 0 0 1 1 W0 0 1 0 1 Interrupt Source Overflow/ Underflow event interrupts Not available Capture event interrupts Compare event interrupts
Wh en an interrupt occurs, the resulting value is an address that is the value written in IVR (here 40H), plus the value coded by the cause (if the cause is a capture event, W1-W0 are 10, thus the value is 4). This gives an even number, since the least significant bit is zero, as follows:
V4 0 V3 1 V2 0 V1 0 V0 0 W1 1 W0 0 0 0
So IVR points to address XX 0044H (with XX the ISR segment number), which must contain a word that is equal to the address in the ISR segment of the Interrupt Service Routine for that ca u s e . An example of the code for setting the IVR is: void ConfigTimer0 ( void ) { / * setting other registers... */ S electPage (T0C_PG) ; T 0_IVR = (unsigned char)INTRELOADVECT ;/* Array of pointers to service routines in ROM */ / * setting other registers, continued... */ }
44/146
ST9 USER GUIDE
Figure 16. Interrupt Vectors: Example with Multifunction Timer 0
Memory (16-bit address space)
65535
Group F Paged Registers (8-bit address space)
R255
I SR on compare event I SR on captur e event I SR on OV F/ UNF event
R242 R240
Interrupt vector register (IVR) contents = 40h
page 09
The value 40h as the base address of the interrupt vector table is chosen arbitrarily by the programmer
47h 46h 45h 44h 43h 42h 41h 40h
ISR address on compare event ISR address on capture event Interrupt Vector Table
No t available I SR address on OV F/ UNF
00h
The corresponding source code could be: ; This program uses the 3 interrupt possibilities of MFT0 ; Constants IT_MFT0_VE CT = 40h ; Vector table . section.tex t . org 00h ; (default address) . word Reset ; reset vector ; if needed divide by zero, NMI vectors -
45/146
ST9 USER GUIDE
. org IT_MFT0_VECT . word isr_ovf_unf; ISR address on OVF /UNF . fill 1,2,0xffff ; does not exist in MFT0 interrupt ; skip one vector . word isr_capt ; ISR address on capture event . word isr_comp ; ISR on compare event ; somewhere in the initialisation code... ;MFT0 initialisation mft0_init: s pp #T0C_PG ; select MFT0 control register page ; setting of some other registers... ld T0_IVR, #IT_MFT0_VECT; pointer for the vector table ; continuation of the program... A similar scheme applies for all other peripherals, though the number of interrupt causes may vary, and thus the size of the pointer table.
Note: To summarize, the table of vectors to an interrupt service routine in ROM for a given peripheral is itself pointed to by the Interrupt Vector Register of this peripheral that must be set to the proper value. This gives you an unusual degree of flexibility: a peripheral may have different interrupt service routines at different times, without the need to add tests at the beginning of the interrupt service routine. Let's consider for example that we want to transfer a string of data from a peripheral. When the first byte of data comes in, we must initialise some variables to handle the string. Then, all subsequent transfers merely copy the data from the peripheral to memory and increment the pointer. Switching between these two modes is very easy. Initially, the IVR of the peripheral is set to the block of vectors that point to the interrupt service routine that serves the first time. This interrupt service routine changes the value of the IVR to another block of vectors and returns. The next interrupt will be automatically re-routed to the other, lighter, interrupt service routine. This reduces the execution time of this routine, since we do not need to test whether this is the first time that the interrupt service routine is called or not.
46/146
ST9 USER GUIDE
3.4.2 Interrupt Priorities In any microprocessor-based system, there is a trade-off between the computational power of the main program and the interrupt latency time. Expressed simply, the less the main program is disturbed, the sooner it finishes its job. On the other hand, we often need to serve interrupt re qu e sts generated by the peripherals as quickly as possible. Since this is a trade-off, we n e e d to find a compromise that gives both enough power to the main program while still ke eping it as responsive as possible to interrupts. It is likely that we will need to modify this compromise according to the current status of the program. If we define that some interrupt requests are more urgent than others, we can define a priority or a hierarchy of interrupt requests. The main program itself, if given a priority level, should be considered as having the lowest priority (except sometimes when interrupts are undesirable). In most cases, when the main program is running, it can be interrupted by any interrupt request. But once a request is being served, it most likely needs to continue undisturbed, unless a request from a higher priority level occurs. Then, the higher priority request is served until comple tion. The service routine then returns to the lower priority interrupt service routine, that te rm in a te s and eventually returns to the main program. In the ST9, this behavior is called Nested Mode. Othe r types of behavior may be required depending of the kind of processing. For this, the ST9 interrupt system has two Boolean parameters to select the way interrupts are handled, which allow four basic choices. The priority mechanism is driven by the Current Priority Level parameter. At a given time, the part of the program being executed runs under a certain level. You can change this CPL by writing a different value in the core's Central Interrupt Control Register (CICR). You can assign Priority Level (PL) to each interrupt source. At initialisation time, this value is written in one of the control registers specific to the corresponding peripheral.
Note: The PL is a three-bit word that ranges from 0 to 7. Note that 0 stands for a high priority and 7 for a low priority. These bits belong to one of the configuration registers of each peripheral.
When a peripheral requests an interrupt, the built-in interrupt controller compares the priority level of the interrupt request to the Current Priority Level. The interrupt is only acknowledged if its priority level value is strictly less than (higher priority) than the Current Priority Level value . This allows you to filter out interrupt requests according to their degree of importance or of urgency according to the current activity of the program. The Non-Maskable Interrupt input (NMI) is hard wired with a higher priority than any level, and thus is acknowledged immediately in all circumstances. The ST9 offers two modes for managing interrupt priorities: Concurrent Mode Nested Mode
47/146
ST9 USER GUIDE
The difference between them is explained below. 3.4.2.1 Global Interrupt Enable Flag In both modes, when an interrupt request is acknowledged, the Interrupt ENable (IEN) bit is cleared, preventing the interrupt service routine from being interrupted again until it is finished. If required, you may prefer to keep it cleared for the duration of the routine or to set IEN at some place in the routine using the ei instruction. In the first case, if an interrupt request of a sufficient priority level is received, it will only be serviced as soon as the service routine currently running returns. In the second case, the same interrupt request is serviced as soon as both it occurs and the IEN bit is set. In short, interrupt service routines may be re-interrupted or not, at will. 3.4.2.2 Concurrent Mode versus Nested Mode Selecting either Concurrent Mode (automatically chosen on reset) or Nested Mode changes the way the Current Priority Level is managed. In Nested Mode, the CPL is automatically set to the priority of the current interrupt service routine, and is reset to the previous value on return. This allows you handle the interrupt request acco rding to priority at all times, since during the execution of the service routine for a given interrupt, only those interrupts whose priority is strictly higher than that of the one currently being serve d will be taken into consideration. Then if, as must normally be done, the IEN bit is set during the current service routine, it will be interrupted at once if an interrupt request of higher priority occurs. If the IEN remains cleared for the whole duration of the service routine, those interrupt requests will be served first after the current routine has returned.
48/146
ST9 USER GUIDE
Figure 17. Example with Nested Interrupts Enabled
0 1 Prior i ty Level Interrupt #2 is requested and served Interrupt #2 CPL = 2 Nested mode: IAM bit ="1" IEN is set to "1" by the programmer
2
3 Interrupt #6 is requested but not served because its priority is lower than the current CPL Interrupt #5 CPL = 5 ei Interrupt #2 has priority level 2 Interrupt #5 has priority level 3 Interrupt #6 has priority level 6 Main program has priority level 7 Interrupt #6 ei 7 Main program CPL is ( a u to m a t i c a l l y ) e i di set to 7 CPL = 6 ei Main program CPL = 7 (Interrupt #5 can be served)
4
5 Interrupt #5 is requested
Interrupt #5 CPL = 5
6
Figure 18. Example with Nested Interrupts Disabled
0 Pr iority Le vel Nested mode: IAM bit ="1" IEN is not set to "1" by the programmer
1
2 Interrupt #2 is requested Interrupt #6 is requested
Interrupt #2 C PL = 2
3
4
5 Interrupt #5 is requested
Interrupt #5 CPL = 5
Interrupt #2 has priority level 2 Interrupt #5 has priority level 3 Interrupt #6 has priority level 6 Main program has priority level 7 Interrupt #6 CPL = 6
6
7
Main program CPL is (automatically) (Interrupt #5 set to 7 ei can be served) di
Main program CP L = 7
49/146
ST9 USER GUIDE
In Concurrent Mode, the CPL is set exclusively by the programmer. You can change it if you need to shift the compromise mentioned above either towards main program efficiency, or towards short interrupt latency times. So you can have a high-priority service routine that is reinterrupted by a low-priority interrupt request, if the CPL has been set to a low priority and the IEN bit is set. This mode gives you maximum flexibility, but it is the most difficult to use since you must keep track of every combination of interrupt requests to achieve the efficiency you expect from your program.
Figure 19. Example with Concurrent Interrupts Enabled
0 1 2 3 4 5 6 7 Main program CPL is set to 7 Interrupt #5 is requested Interrupt #5 CPL=7 ei Interrupt #2 and #6 are requested. T he Interrupt #2 is served first because it's priority is higher than the interrupt #6
Interrupt #4 is requested Interrupt #4 is served first because it's priority is higher than the interrupt #6
Interrupt #2 CPL=7 ei
Interrupt #2 CPL=7
Interrupt #4 CPL=7 ei Interrupt #6 CPL=7
Interrupt #4 CPL=7 Interrupt #5 CPL=7
Main Interrupt #2 has priority level 2 Interrupt #4 has priority level 4 Interrupt #5 has priority level 5 Interrupt #6 has priority level 6 Main prog has priority level 7 CPL=7
Concurrent mode does not look like a reasonable way to handle interrupts if you enable interrupts in your interrupt service routine. It should be thought of as a way to fully control priorities through programming, if nesting priorities cannot meet your processing requirements. For example, let us consider the case when a timer produces a periodic interrupt that outputs some data on an external digital to analog converter. The requirement is that the new data be output at the very time of the interrupt, so as to reduce the jitter (or parasitic frequency modulation) that would compromise the spectral purity. Then, once the data is output, the interrupt service routine does some processing to make or get the data for the next interrupt. The latter part of the processing is much less critical in terms of execution time, provided it is finished before the next timer interrupt. Using Concurrent mode, you can assign that interrupt the highest priority so that it will be served immediately, then re-enable the interrupts and, if needed, give it a pri-
50/146
ST9 USER GUIDE
ority level as appropriate. The service routine will then allow other interrupts to gain control, at the expense of delaying its own completion.
Note 1: In practice, Concurrent mode does not differ much from nested mode if the interrupts are not reenabled during an interrupt service routine. Concurrent Interrupts Disabled looks like Nested Interrupt Disabled with the difference that the CPL is changed only by software when necessary. The interrupt requests pending while the interrupt service routine is executing, will only be serviced after the current service routine returns. An interrupt with priority level 7 will never be served.
Note 2:
3.4.3 External Interrupt Unit This is a functional block that can receive interrupt requests from up to eight external pins, and also from some internal devices such as the Watchdog Timer, the Serial Peripheral Interface, etc. It is used to select the active edge for pin or device, and define the priority for each of the four pairs. In addition, an NMI pin can be programmed as being maskable or non-maskable. It is maskable on reset, and once set to non-maskable, it cannot again be set to maskable until the next reset. This works as explained below. 3.4.3.1 Maskable External Interrupt Pins These are eight external inputs you can set individually to rising-edge or falling-edge sensitive, and masked. You assign priorities by pairs, making four groups with different priorities. Within each group, the two interrupt requests have two successive priorities. For example, if you set group C to priority 2, the INT4 input will have priority 2 and INT5 will have priority 3 (which is lower).
51/146
ST9 USER GUIDE
The simplified block diagram is the following:
Figure 20. External Interrupts Simplified Block Diagram
External Interrupt pin (INT0 to INT7)
Edge trigger event selection: one bit of EITR Internal interrupt
Only for: A0: INT0 or WDT interrupt B0 INT2 or SPI interrupt (Device dependent)
Internal/External source selection
Pending Bit
One bit of EIPR
One bit of EIMR
M ask Bit
Current priority level (CPL) Bit IEN of CICR Interrupt enable
3
P r iority Comparator
3
External interrupt priority level
A detailed block diagram is provided in Section 7 Interrupt to the core
3.4.3.2 Top-Level Interrupt The Top Level Interrupt can have two sources: either the NMI pin, or the watchdog end-ofcount(5). This interrupt level has a special feature that allows you to mask it like any other interrupt, or to make it a real non-maskable interrupt. For this, the TLNM bit (see Figure 21) can remove the effect of the mask. Once set, it cannot be reset, thus preventing this interrupt from
(5)
See Section 4.3 on the Watchdog Timer.
52/146
ST9 USER GUIDE
being accidentally masked even in the case of a program failure. In any case, the Top Level Interrupt uses the third fixed vector at addresses 4 and 5 in program memory. As the name implies, it has a fixed priority that is higher than any other interrupt request. Though it does not cle ar the IEN bit when acknowledged, unlike all other interrupt requests, its service routine cannot be interrupted by any cause, including the Top Level Interrupt itself. The simplified block diagram is the following:
Figure 21. Top-Level Interrupt Simplified Block Diagram
NMI pin
Edge trigger event selection: one bit of EIVR Watchdog timer End of Count
Two bits of CICR
Interrupt bit Interrupt enable:
Watchdog/NMI source selection: one bit of EIVR Pending Bit One bit of CICR
One bit of NICR
Top Level not maskable
A detailed block diagram is provided in Section 7 Top Level Interrupt to the core
53/146
ST9 USER GUIDE
3.4.3.3 External Interrupt Vectors There are eight external interrupt causes. They are each connected to an external input that is the alternate function of an I/O port. Some of these are shared with other causes in an exclusive manner, i.e., the INT0 pin is multiplexed with the Watchdog/Timer interrupt request, and t h e INT5 pin is multiplexed with the Serial Peripheral Interface interrupt request (on the ST92 F150). Each cause is associated with a separate vector in Program Memory. All vectors are contiguous, generating an array of 8 vectors starting with the INT0 vector, and ending with the INT7 vector. This array may be freely located in program memory between addresses 8 to 240 (0F0h) in program memory. Th ese interrupt causes are grouped by pairs, and are given new names inside the interrupt controller, as shown in the following table:
Interrupt Source INT 0 INT 1 INT 2 INT 3 INT 4 INT 5 INT 6 INT 7 Interrupt Cause INT A0 INT A1 INT B0 INT B1 INT C0 INT C1 INT D0 INT D1
You can independently assign a priority to each pair (A, B, C, D), with levels that are multiple of two, i.e. you can set them to priority levels 0, 2, 4, or 6. In each pair, the cause bearing the fig ure zero assumes this priority, and the cause bearing the figure 1 assumes the next level above. For example, if you assign level 4 to pair C, this means that INTC0 will have level 4 and INTC 1 level 5. You set this in register EIPLR (R245 page 0), where each group of two bits gives the level of the corresponding interrupt cause. The interrupt vectoring is summarized in the table below:
54/146
ST9 USER GUIDE
Figure 22. External Interrupt Vectors EIVR (R246, Page 0) External Interrupt Vector Register V5
7
0
V7 V6
V4 TLTEV TLIS IAOS EWEN
11 11b Lo ISR address for INTD1 1110b H i
V7
V6
V5 V4
01 11b Lo ISR address for INTB0 01 10b H i 0011b Lo ISR address for INTA1 00 10b H i 00 01b Lo ISR address for INTA0 00 00b H i
Vector Table: (Addresses less than FFh)
MSB of the Vector Table address for the 8 external interrupts (Software fixed)
LSB of the Vector Table address for the 8 external interrupts (Hardware fixed)
55/146
ST9 USER GUIDE
3.5 DMA CONTROLLER 3.5.1 Overview One of the most important advantages of the ST9 is its ability to handle input/output data flows witho ut using core instruction cycles. This is made possible by the built-in DMA controller. Once properly initialized, it allows peripherals to exchange data either with memory or the register file, with no more use of the core resources than the stolen memory cycles strictly needed to transfer the data. To see how much faster DMA is than the simplest interrupt service routine, let us compare the execution times. Let us assume that the data comes from the serial port. The simplest interrupt routine is the following: GetOneByte :; interrupt latency: p ush p ushw s pp l dw ld l dw p opw p op i ret ; Total: PPR rr0 #SCI_PG rr0, POINTER (rr0)+, S_RXBR POINTER, rr0 rr0 PPR ; save current page ; save rr0 ; change register page ; get pointer ; move data ; store pointer ; restore rr0 ; restore current page ; return 22 cycles 8 10 4 12 12 14 10 8 16 116
; ------------------------------------------With an internal clock of 24 MHz, this corresponds to an execution time of 4.8364 s. In contrast, the DMA cycle time for the transfer of one byte from a register to a register file takes only 8 cycles (16 cycles to the memory), that is 0.33 s. The DMA feature saves you from using valua ble core processing power for simple tasks like storing an input byte to memory. For example, if a continuous flow of data is input at 19200 bits per second, the interrupt service routine would consume 1.11% of the total cycles of the core, as compared to the 0.0767% with the DMA solution. Since the DMA is built-in and works with most of the peripherals, it is a good idea to use it even for slow transfers. The DMA uses the Segment mechanism to address 64 Kbytes along the linear 4 MBytes. See Section 3.1.7 for more details.
56/146
ST9 USER GUIDE
3.5.2 How the DMA Works The DMA consists of a transfer between a memory or register file and a peripheral, in either direction. Assuming the peripheral is configured to handle externally supplied data or to provide data to external circuits, two steps are needed for a transfer to occur. The transfer must be requested by some event or condition. A mechanism must handle reading the data from one part and writing to the other part. The term DMA transfer represents the transfer of a single byte of data. Usually, more than one byte is transferred and the transfer occurs in bursts. Thus, a third step is involved: A mechanism that counts the transfers and stops them when the count is finished. To the programmer, these mechanisms appear as registers to be properly initialized. The three steps are handled as follows (see Figure 23). 3.5.2.1 Transfer Requests The DMA transfer is requested in exactly the same way as an interrupt is requested. According to its type, the peripheral concerned sends a request based on an external event such as a character received or transmitted by the Serial Channel Interface. You configure this in the registers belonging to the peripheral involved. Special bits in the registers indicate that the peripheral ready status, instead of requesting an interrupt, requests a DMA transfer. 3.5.2.2 Transfer Execution A DMA transfer can involve a memory location or a register in the register file. In any case, the transfer requires an address and a counter. This address and counter are stored in registers which you can define anywhere in the register file. The address register value is automatically incremented after each transfer and the counter register value is decremented so that the next tra n sfe r will involve the next address and this mechanism will continue until the counter is equal to 0. Depending on whether the transfer addresses memory or the register file, there are two cases. If the transfer addresses the register file, the address register and the counter register are single registers (a byte is enough to address 256 registers). The address of this address register is stored in one of the peripheral's registers, named DCPR. The low bit (RM) of this register is set to zero indicating that the register file is involved in the transfer. The address registe r must have an even address to address the DMA address, the next register storing the DMA transaction counter. If the transfer addresses the memory, the registers that hold the address and the counter must be two double registers. In this case, the DMA address is pointed by the DAPR pointer register and the DMA transaction counter is pointed by the DCPR pointer register. The low bit of the
57/146
ST9 USER GUIDE
DA P R indicates whether the memory segment is pointed by DMASR or ISR (see Section 3.1.7). The DMA address and the DMA transaction counter are not necessarily consecutive. 3.5.2.3 Transfer Termination A burst terminates when the count of transfers reaches a predefined value. To set this up, you set a counter register in the register file that holds the count of transfers to execute at the start of a burst. Each transfer decrements it, and the DMA mechanism is stopped when the counter reaches zero. The way DMA controller terminates the transfer differs from one peripheral to another, but typically it consists of resetting the bit in the configuration register that tells the peripheral to issue DM A requests instead of interrupt requests. Then, on the last transfer, when the transfer counter reaches zero, it toggles the DMA/Interrupt request bit so that the peripheral issues an interrupt request again. If this request is unmasked, you should vector it to an interrupt service routine that handles the DMA termination.
To summarise:
For register transfers, the DCPR of the peripheral points to a user-defined pair of registers that holds the address and the count. Register DAPR is unused. For memory transfers, the DAPR points to the user-defined register pair that holds the address. The DCPR register points to the user-defined register pair that holds the count. Some peripherals, such as the Multifunction Timer, even have a double pair of DAPR/DCPR registers. Only one pair is used at a time. In so-called Swap Mode, this allows the timer to use one data buffer for output and another buffer for input. The pair of registers used is automatically changed when one transfer burst terminates, allowing a continuous data flow between the program and the peripheral, with minimum data handling overhead. In addition, the MFT has 16-bit registers. Transfers imply two byte transfers for each register. Th is is ensured by a mechanism that gives the DMA the highest priority as soon as the first b y t e is transferring. This guarantees that the second byte will also be transferred in the shortest delay, even if other DMA requests become pending while the transfer is in progress.
58/146
ST9 USER GUIDE
Figure 23. DMA Data Transfer
REGISTER FILE DF REGISTER FILE OR MEMORY REGISTER FILE COUNTER ADDRESS PERIPHERAL Current COUNTER value Decrease after each transfer Current ADDRESS
DATA peripheral
0
Start ADDRESS
59/146
ST9 USER GUIDE
3.6 RESET AND CLOCK CONTROL UNIT (RCCU) The RCCU is composed of the Clock Control Unit (CCU) and the Reset and Stop Manager. 3.6.1 CLOCK CONTROL UNIT The CCU generates the peripheral clock INTCLK and the CPU clock CPUCLK. It is a useful clock generator with low power function and low external frequency oscillator to reduce electromagnetic emissions. The diagram can be reduced as in Figure 24.
Figure 24. CCU Simplified Block Diagram 1 Quartz Oscillator 3 Clock Multiplier 4
[1/32 to 14]
5 Prescaler CP UCLK
CK _A F S ourc e 2 INTCLK
The CCU is composed of 5 main blocks:
B L OC K 1 2 3 4 5 COMMENTS Quartz oscillator gives the main frequency generator. The frequency is in the range of 3 to 5 MHz. External clock for very low power consumption with a very low frequency. The Clock Multiplier can reduce or increase the input frequency by using prescaler and PLL.The increase is for the normal use and the decrease for low power consumption. The selector aims the clock coming from the Clock Multiplier for normal or low power use or aims the clock CK_AF for a very low power consumption. The prescaler is used also for low power consumption. The INTCLK is not change giving a high frequency to the internal peripheral. This allows the user to slow down program execution during non processor intensive routines.
60/146
ST9 USER GUIDE
3.6.1.1 Clock Multiplier The Clock Multiplier is a part of the Figure 26. The advantage of the Clock Multiplier is that it can produce a variable clock frequency depending on the needs of the CPU. Since the input clock to the PLL circuit requires a 50% duty cycle for correct operation, the divide by two should be enabled (DIV2 bit of MODER register set) if the PLL is enabled. It is necessa ry when a crystal oscillator is used, or when the external clock generator does not provide a 50% duty cycle. In practice, the divide-by-two is virtually always used in order to ensure a 50% duty cycle signal to the PLL multiplier circuit. The Clock Multiplier output is one of the CLOCK2, CLOCK2/16 or CLOCK2*PLLMUL/(DX+1) (PLL MUL is the PLL multiplier coefficient) frequencies. The two frequencies CLOCK2 and CLOCK2/16 are for low power consumption or reduce po wer consumption, depending on the Wait For Interrupt instruction (refer to the flow chart Figure 25). The PLL has four clock multiplier factors (6,8,10 and 14) controlled by the two bits MX0 and M X1 in the PLLCONF register. The clock divider is controlled by three bits DX0:2 in the PLLCONF register for seven rates which are 1/(DX+1). Setting DX2:0=7 turns OFF the PLL to reduce consumption. When you switch on the PLL, you have to allow a delay for the PLL to lock.
61/146
ST9 USER GUIDE
Figure 25. INTCLK and CPUCLK Flow Chart
Yes
No W FI Instruction No CKAF_SEL==0 Ye s No CK _AF Present No Yes XT_DIV16==0 No C S U _ C K S EL = = 0 No DX2:0==7 Yes Ye s DX2:0==7 No Yes
No LPOWFI==0 CS U_CK SEL =0 No W F I_CK SEL ==0 No C K _ AF Present Yes Yes
Ye s
Yes
CK AF_S EL= 0 CK AF_S T=0
CK AF_S EL=1 CK AF_S T=1
CSU_CKSEL=0
CSU_CKSEL=0
INTCLK=
CLOCK2/16 CK_AF CLOCK2/16 Previous CK_AF CLOCK PL L-CL OCK CLOCK2 CLOCK2 (PLL OFF) (PLL ON) CLOC K2/1 6 (PLL OFF)
Fast mode LOW POWER PLL is OFF Reduced power consumption Slow mode Reduced power consumption
CPUCLK Stopped
CPUCLK=INTCLK/N
62/146
ST9 USER GUIDE
Figure 26. Clock Control Unit Programming
X T ST O P
(CLK_F LAG)
DIV 2
(MODER)
CSU_CKSEL
(CLK_FLAG)
CK AF_S EL
(CLKCTL)
CLOCK MULTIPLIER 1/16
0 0 Quartz oscillator
1/2 CLO C K1
1
CLO C K2
PLL x 6/8/10/14
0
0 1
INTCL K
to Peripherals and CPU Clock Prescaler
1
1/N
1
CK_AF source
CK _AF
MX (1:0) Wait for Interrupt and Low Power Modes:
DX (2:0)
XT_DIV16
CKA F_ST
(PLLCONF)
(CLK_FLAG)
LPOWFI (CLKCTL) selects Low Power operation automatically on entering WFI mode. WFI_CKSEL (CLKCTL) selects the CK_AF clock automatically, if present, on entering WFI mode. XTSTOP (CLK_FLAG) automatically stops the Xtal oscillator when the CK_AF clock is present and selected.
3.6.1.2 CK_AF Source When you execute a Wait For Interrupt (WFI) instruction using the Clock Multiplier with output clock CLOCK2/16, the power is put in Low Power mode. To reduce this power further you have the possibility of slowing down the INTCLK frequency by using an external clock source CK_AF. The CK_AF clock will be selected if the WFI_CKSEL bit in the CLKCTL register is set and if CK_AF is present. The CK_AF source can also be used in Run mode (no WFI) to reduce power consumption if CKAF_ SEL is set and CK_AF is present.
63/146
ST9 USER GUIDE
3.6.1.3 Low Power with Frequency Slow Down When the PLL has been frozen by a WFI instruction you need a delay after the interrupt to wait for the PLL to lock. To avoid this delay but not to lose the Low Power consumption, you have two choices which are: To use a WFI instruction with LPOWFI reset and initialize INTCLK to CLOCK2 with XT_DIV16 bit set (CSU_CKSEL register). When the WFI occurs, CPUCLK is stopped and INTCLK doesn't change. To not use the WFI instruction. Set XT_DIV16 bit of CSU_CKSEL register. Initialize DX2:0 of PLLCONF to 6 to divide the PLL output clock by 7 which is the maximum. Initialize the CPUCLK clock prescaler to 7 to divide INTCLK by 8. 3.6.2 Reset and Stop Manager RE S E T normally means restarting from the beginning with everything initialized. However sometime s it's necessary to know the context of the ST9 before the RESET and if it was an external or internal RESET. Two bits, SOFTRES and WDGRES in the CLK_FLAG register indicate the previous context. Table 3. shows the three cases to manage.
Table 3. Three Types of RESET RESET Type External RESET Watchdog RESET Software RESET SOFTRES bit 0 0 1 W DGRES bit 0 1 0 Meaning H igh to low level on RESET pin. The Watchdog Timer is activated and the Timer has reached 0. The HALT instruction is executed, waiting for an external Reset to restart (if the SRESEN bit in the CLKCTL register is set).
These bits are read-only and change with each Reset.
64/146
ST9 USER GUIDE
4 USING THE ON-CHIP PERIPHERALS
Th is chapter introduces the main peripherals of the ST9 family. Each variant includes none, one or several peripherals of each type. This allows you to select the variant that best fits your requirements. For high-volume markets, you can order custom versions with exactly the type and number of peripherals required, including the relatively exotic ones not described here but available on request, such as videotext decoders etc. 4.1 PROGRAMMING THE CORE AND PERIPHERALS In addition to describing how each peripheral works, we give examples of the code needed to use them in several configurations. This code is available on the Companion software. You can experiment with the original code or modify it to do the functions you require. Configuring and using the core and the peripherals involves a considerable amount of bit man i p u l a t io n in the registers. Many variables that drive microcontroller states are Boolean value s. To reduce the use of addressable space in registers, bits have been logically grouped in bytes, so the majority of the control registers have their eight bits fully used. To properly program these registers, you need to track the exact position of each bit in each register. You can do this by referring systematically to the appropriate Data Sheet, and commenting the source text so that it can be easily read and understood later. See the following e xa m p l e : ld R235,#1110 0 0B ; R235 is register MODER ; |||||||+-- HIMP : no foreign access to bus ; ||||||+--- BRQEN : no foreign access to bus ; |||+++---- PRS2,1,0 : processor at full speed ; ||+------- DIV2 : crystal frequency divided by 2 ; |+-------- USP : user stack pointer in registers ; +--------- SSP : system stack pointer in registers #0 ; SPI page R254,#10 0 001B ; |||||||+-- SPR0 : SPR1, SPR0 = 01: clock divided by 16 ; ||||||+--- SPR1 : ; |||||+---- CPHA : Input sampled on rising edge ; ||||+----- CPOL : Rest level of serial clock = 0 ; |||+------ BUSY : Set to ready ; ||+------- ARB : No I²C arbitration ; |+-------- BMS : SPI used as a shift register (not I²C) ; +--------- SPEN : SPI enabled
s pp ld
65/146
ST9 USER GUIDE
Th is style has the advantage of clarity. However, there is still a problem that it does not address: the variety of the different products of the ST9 family. The different products available in the ST9 family are very diverse and as a result it is not always the case for all products that a given function is performed by the same bit of the same register. The location of a register in one peripheral may be different in another. To avoid this problem, the GNU9 programming tool chain provides a set of include files that define the physical location of every bit and register, by their symbolic name. These files correspond to the appropriate variant of the ST9. Using them guarantees that switching to another member of th e family will not need more than changing the Include statement at the beginning of the source text. The same example as above, using the predefined symbols reads as follows: . include "system.inc" ; System register ld s pp ld MODER,#MOm_sspm+MOm_uspm+MOm_div2m; Both stacks in ;reg isters, clock divided by 2 #SPI_PG ;SPI page ; configuration, Clock/16 This notation is more compact, and is independent of changes either between variants in the same family, or by changes made globally to the family in the future. This writing style is recommended for this reason. 4.2 PARALLEL I/O The parallel input-outputs have a basically very straightforward functionality. Once initialized, they appear as a register that can be written or read. However in many cases, direct byte-wide input-output is not sufficient. Bit-oriented I/O is often what is used in microcontroller systems. A powerful feature of the ST9 is that you can address the eight bits of each port individually. The ST9, like most microcontrollers also provides the external pins of the other peripherals (timers, UARTs, etc.) by diverting some bits from the parallel I/O ports. The ST9 parallel I/O has an additional very flexible feature. You can independently configure each bit as: An input with two variants (TTL or CMOS levels) An output with also two variants (open-drain or push-pull) A bi-directional port with either a weak pull-up or an open-drain output side An alternate function output (that is, the output pin of an internal peripheral), with also either open-drain or push-pull output driver. SPICR,# SPm_spen+SP m_SP_16 ; Enable SPI,1st clock
66/146
ST9 USER GUIDE
Analog Input (see note)
Note: On the port that accommodates the inputs of the Analog to Digital Converter, there is a special feature. In all other peripherals that require an input, you only need to configure the corresponding pin as an input. However, when using the ADC you can put the input pins to any voltage level from ground to Vcc. This is normally badly handled by standard logic gates that dissipate considerable power when the voltage reaches the limit range. To avoid this, the port that provides the input pins of the ADC has a special Alternate Function mode. Unlike the other ports it is used for input. This mode disconnects the input buffer from the pin and shorts the buffer input to the ground. The output buffer is put in high-impedance mode. The pin is permanently connected to the input of the ADC, thus allowing its voltage to be read at any time.
To handle all these capabilities, each port requires three configuration registers, PxC1, PxC2 and PxC3, where x is the port number. Once configured, a port exchanges data with the core through the PxDR data register. The configuration registers are placed in various pages of the register group 15, as well as the da ta registers, except for the first six ports. These six belong to the system register group (group 14) for easy access. Some ports also include DMA capability, configurable to work with the Multi-Function Timer.
67/146
ST9 USER GUIDE
4.3 STANDARD AND WATCHDOG TIMERS You can use this timer both as a regular timer and as a watchdog timer. 4.3.1 Description The block diagram of the Watchdog Timer is the following:
Figure 27. Watchdog Timer Simplified Block Diagram
I N T C L K /4 WDIN Pin
Input Modes and Clock Control Logic
3 bits of WDTCR
Prescaler (8-bit)
2 bits of WDTCR
16-bit Downcounter
WDOUT Pin
Output Control L ogic
3 bits of WDTCR 1 bit of W CR
INT0 Pin NMI Pin Reset and Interrupt Control Logic
Reset and interrupt request to the core
2 bits of EIVR
A detailed block diagram is provided in Section 7
In Counter/Timer mode, the WDT can count pulses coming either from an input pin (WDIN; in the ST92F150, alternate function of P5.3) or from the internal clock divided by 4. When the internal clock is used, the external pin, if enabled, can either gate the clock, start the counter, or
68/146
ST9 USER GUIDE
reload it with its initial value. You select these modes using three bits in the WDT Control Register, as follows:
INEN 1 1 1 1 0 INMD1 0 0 1 1 X INMD2 0 1 1 0 X Mode Event counter mode Gated mode Retriggerable input mode Triggerable input mode Input section disabled. Internal clock selected.
4.3.1.1 Event Counter Mode The counter value is decremented at each falling edge on the WDTIN pin if ST_SP is high (bit 7 of WDTCR).
Figure 28. Timer in Event Counter Mode WDTIN Pin ST_SP Counter Value
4.3.1.2 Gated Input Mode The counter value is decremented by WDTCLK (INTCLK / 4) if the WDTIN pin and ST_SP are high.
Figure 29. Timer in Gated Input Mode WDTIN Pin ST_SP
Counter Value
69/146
ST9 USER GUIDE
4.3.1.3 Retriggerable Input Mode The counter value is decremented by WDTCLK (INTCLK / 4) if ST_SP is high. The initial value is reloaded either at the rising edge of ST_SP or at each falling edge of the WDTIN pin if ST_SP is high.
Figure 30. Timer in Retriggerable Input Mode WDTIN Pin ST_SP
Counter Value
Initial Value
4.3.1.4 Triggerable Input Mode The counter value is decremented by WDTCLK (INTCLK / 4) if ST_SP is high and falling edge of WDTIN occurs. The initial value is reloaded at the first falling edge of the WDTIN pin if ST_SP is high.
Figure 31. Timer in Triggerable Input Mode WDTIN Pin
S T _S P Initial Value
Counter V al ue
70/146
ST9 USER GUIDE
4.3.1.5 Single/Continuous Mode On counter underflow (End Of Count), the counter is always reloaded with the value of the latch that is actually accessed when writing to the WDTHR and WDTLR register pair. The counter has two modes: Single-shot or Continuous, selected by the S_C bit of WDTCR. In Single-shot mode, the End Of Count also resets the ST_SP bit of the WDTCR, which stops the counter after one cycle. In Continuous mode on reaching the End Of Count condition, the counter reloads the constant and restarts. When the ST_SP bit is set, the contents of the latch are written again to the counter, allowing the initial count value to be changed before starting the counter. You restart the down counter by setting the ST_SP bit. The constant value can be either the initial value or a new one as shown on the following diagram:
Figure 32. Timer in Single Mode ST_SP Initial Value Counter Value
End of Count
A new value may be written in the counter latches at any time. It will be transferred into the counter on end of count or on various conditions on WDTIN and ST_SP.
4.3.1.6 Output Pin Another pin, WDOUT (alternate function of P5.1 for ST92F150), when enabled by the OUTEN bit, can change its state in two ways on the end of count of the main counter. Basically, each time the counter overflows, it updates the output value. This can produce two different effects, selected by the OUTMD bit: either the state of the WROUT bit is copied to the output at that time, or the output is complemented.
71/146
ST9 USER GUIDE
Figure 33. Output Pin Block Diagram
WDTCR (R251 page 0) Timer/Watchdog Control Register
7 0
ST_SP S_C INMD1 INMD2 INEN OUTMD WR OUT OUTEN Logical level user definable while counter is running
1 D 0 EOC
WDTOUT Pin
4.3.2 Timer Application for Periodic Interrupts In this application, the clock is internal and the input and output pins are unused. The counter is set to Continuous mode, and the value of the reload registers chosen so that the overflow occu rs exactly every 128 microseconds. 4.3.2.1 Initialisation of the WDT for a Periodic Interrupt Very few registers are involved when you use the WDT for this purpose, since there is no input apart from the internal clock and no output. However, the WDT interrupt handling is a little different from most other peripherals in that it borrows the interrupt circuit named INTA0 that is normally assigned to external interrupt pin INT0. So you configure the WDT in two steps: initializing the WDT itself, and also the external interrupt INTA0. In this example application, the internal frequency is 24 MHz and the interrupt rate must be 8192 Hz. The timer starts with the preset count on the low-to-high transition of the ST_SP bit of the WDT Control Register. The initialisation routine for the WDT is then:
72/146
ST9 USER GUIDE
/* * * ** * ** Configure Watchdog for Periodic Interrupt * * ** * ****/ void ConfigWDT ( void ) { S electPage( WDT_PG ) ;/* select Watchdog page */ W DTPR = 0 ;/* 122 us = 366 ticks */ W DTR = 365 ;/* preset is nb ticks-1 (WDTR is the pair WDTLR and WDTHR) */ W DTCR = (WDTm_stsp) ;/* WDT is set to continuous mode, no inputs, no o utputs */ / * Interrupt must be connected to intA0 in the EIVR register */ } The initialisation routine for INTA0 follows. In this example application, interrupt A0 is the only "external" interrupt enabled, and it is assigned priority level 2: /* * * ** * **Initialise Interrupt A0 and Cu