<<

EMBEDDED SYSTEMS AN INTRODUCTION USING THE RENESAS RX62N MICROCONTROLLER

James M. Conrad University of North Carolina at Charlotte

Alexander G. Dean North Carolina State University Micri␮m Press 1290 Weston Road, Suite 306 Weston, FL 33326 USA www.micrium.com

Designations used by companies to distinguish their products are often claimed as trademarks. In all instances where Micri ␮m Press is aware of a trademark claim, the product name appears in initial capital letters, in all capital letters, or in accordance with the vendor’s capitalization preference. Readers should contact the appropriate companies for more complete information on trademarks and trademark registrations. All trademarks and registered trademarks in this book are the property of their respective holders.

Copyright © 2011 by James M. Conrad and Alexander G. Dean except where noted otherwise. Published by Micri␮m Press. All rights reserved. Printed in the United States of America. No part of this publication may be reproduced or dis- tributed in any form or by any means, or stored in a database or retrieval system, without the prior written permission of the publisher; with the exception that the program listings may be entered, stored, and executed in a system, but they may not be reproduced for publication.

The programs and code examples in this book are presented for instructional value. The programs and examples have been carefully tested, but are not guaranteed to any particular purpose. The publisher and content contributors do not offer any warranties and does not guarantee the accuracy, adequacy, or completeness of any information herein and is not responsible for any errors or omissions. The publisher and content contributors assume no liability for damages resulting from the use of the information in this book or for any infringement of the intellectual property rights of third parties that would result from the use of this information.

Library of Congress subject headings:

1. Embedded computer systems 2. Real- time data processing 3. Computer software—Development

For bulk orders, please contact Micrium Press at: ϩ1 954 217 2036

ISBN: 978-1-935772-99-6 NOTICE 1. All information included in this document is current as of the date this document is issued. Such information, however, is subject to change without any prior notice. Before purchasing or using any Renesas products listed herein, please confirm the latest product information with a sales office. Also, please pay regular and careful attention to additional and different information to be disclosed by Renesas Electronics such as that disclosed through our website. 2. Renesas Electronics does not assume any liability for infringement of patents, copyrights, or other intellectual property rights of third parties by or aris- ing from the use of Renesas Electronics products or technical information described in this document. No license, express, implied or otherwise, is granted hereby under any patents, copyrights, or other intellectual property rights of Renesas Electronics or others. 3. You should not alter, modify, copy, or otherwise misappropriate any Renesas Electronics product, whether in whole or in part. 4. Descriptions of circuits, software and other related information in this document are provided only to illustrate the operation of semiconductor products and application examples. You are fully responsible for the incorporation of these circuits, software, and information in the design of your equipment. Renesas Electronics assumes no responsibility for any losses incurred by you or third parties arising from the use of these circuits, software, or information. 5. When exporting the products or technology described in this document, you should comply with the applicable export control laws and regulations and follow the procedures required by such laws and regulations. You should not use Renesas Electronics products or the technology described in this doc- ument for any purpose relating to military applications or use by the military, including but not limited to the development of weapons of mass de- struction. Renesas Electronics products and technology may not be used for or incorporated into any products or systems whose manufacture, use, or sale is prohibited under any applicable domestic or foreign laws or regulations. 6. Renesas Electronics has used reasonable care in preparing the information included in this document, but Renesas Electronics does not warrant that such information is error free. Renesas Electronics assumes no liability whatsoever for any damages incurred by you resulting from errors in or omis- sions from the information included herein. 7. Renesas Electronics products are classified according to the following three quality grades: “Standard”, “High Quality”, and “Specific”. The recom- mended applications for each Renesas Electronics product depends on the product's quality grade, as indicated below. You must check the quality grade of each Renesas Electronics product before using it in a particular application. You may not use any Renesas Electronics product for any application categorized as “Specific” without the prior written consent of Renesas Electronics. Further, you may not use any Renesas Electronics product for any application for which it is not intended without the prior written consent of Renesas Electronics. Renesas Electronics shall not be in any way liable for any damages or losses incurred by you or third parties arising from the use of any Renesas Electronics product for an application categorized as “Spe- cific” or for which the product is not intended where you have failed to obtain the prior written consent of Renesas Electronics. The quality grade of each Renesas Electronics product is “Standard” unless otherwise expressly specified in a Renesas Electronics data sheets or data books, etc. “Standard”: ; office equipment; communications equipment; test and measurement equipment; audio and visual equipment; home electronic appliances; machine tools; personal electronic equipment; and industrial robots. “High Quality”: Transportation equipment (automobiles, trains, ships, etc.); traffic control systems; anti-disaster systems; anti-crime systems; safety equipment; and medical equipment not specifically designed for life support. “Specific”: Aircraft; aerospace equipment; submersible repeaters; nuclear reactor control systems; medical equipment or systems for life support (e.g. artificial life support devices or systems), surgical implantations, or healthcare intervention (e.g. excision, etc.), and any other applications or purposes that pose a direct threat to human life. 8. You should use the Renesas Electronics products described in this document within the range specified by Renesas Electronics, especially with respect to the maximum rating, operating supply voltage range, movement power voltage range, heat radiation characteristics, installation and other product characteristics. Renesas Electronics shall have no liability for malfunctions or damages arising out of the use of Renesas Electronics products beyond such specified ranges. 9. Although Renesas Electronics endeavors to improve the quality and reliability of its products, semiconductor products have specific characteristics such as the occurrence of failure at a certain rate and malfunctions under certain use conditions. Further, Renesas Electronics products are not subject to radiation resistance design. Please be sure to implement safety measures to guard them against the possibility of physical injury, and injury or dam- age caused by fire in the event of the failure of a Renesas Electronics product, such as safety design for hardware and software including but not lim- ited to redundancy, fire control and malfunction prevention, appropriate treatment for aging degradation or any other appropriate measures. Because the evaluation of software alone is very difficult, please evaluate the safety of the final products or system manufactured by you. 10. Please contact a Renesas Electronics sales office for details as to environmental matters such as the environmental compatibility of each Renesas Elec- tronics product. Please use Renesas Electronics products in compliance with all applicable laws and regulations that regulate the inclusion or use of controlled substances, including without limitation, the EU RoHS Directive. Renesas Electronics assumes no liability for damages or losses occurring as a result of your noncompliance with applicable laws and regulations. 11. This document may not be reproduced or duplicated, in any form, in whole or in part, without prior written consent of Renesas Electronics. 12. Please contact a Renesas Electronics sales office if you have any questions regarding the information contained in this document or Renesas Electron- ics products, or if you have any other inquiries. (Note 1) “Renesas Electronics” as used in this document means Renesas Electronics Corporation and also includes its majority-owned subsidiaries. (Note 2) “Renesas Electronics product(s)” means any product developed or manufactured by or for Renesas Electronics.

Preface

This book is the results of a long relationship the authors have enjoyed with Renesas Electronics America, Inc. (and one of its predecessors, Mitsubishi Electronics). We origi- nally worked with this company because of their commitment to providing a low-cost eval- uation board and free development software that students could purchase and use in classes and senior design projects. Over the years the boards have remained as affordable (and popular) as ever, and the tools available have added more function- ality while still remaining available for free to our students. We have been teaching embedded systems courses for over twelve years (and working in the field even longer). We had not been able to find a book suitable for using in an un- dergraduate course that would lend itself to the theoretical and applied nature of embedded systems design. Renesas had been asking us to create a book for several years, and the in- troduction of the new RX62N microcontroller offered a wonderful opportunity to work with this powerful device and integrate it into our classes. This book also has a radical feature not seen in many books currently on the market (if any). It is freely available for download and is also provided with the Renesas RX62N evaluation board. It is also available for purchase in hardcopy form for a modest price. This book can be used on its own for an Introduction to Embedded Systems class or an Introduction to /Microcontrollers. It can also be used as a supplement in many different types of classes. This book would not have been possible had it not been for the assistance of numerous people. Several students and educators contributed to some of the chapters, including: Adam Harris (1, 2), Suganya Jebasingh (2, 6), Vikram Gill (3,4), Archana Subramanian (4), Onkar Raut (5, 7), Steven Erdmanczyk (8,9), Sunil Gurram (8,11), Aswin Ramakrishnan (11), Vivek Srikantan (12), and Paul Mohan Das (12). Stephanie Conrad heavily edited versions of the chapters. Michael McLain helped create the solutions for the homework assignments. Thanks go to the compositor, Linda Foegen, and especially to June Hay-Harris, Rob Dautel, and Todd DeBoer of Renesas for their help in getting this book produced and published (and for their patience!). Many, many thanks go to the reviewers who offered valuable sugges- tions to make this book better, especially Jerry Zacharias, Mitch Ferguson, Mike Wilkinson, and students from my UNC Charlotte Embedded Systems course. Jim Conrad: I would like to personally thank my parents, the Conrads, and my in-laws, the Warrens, for their continued assistance and guidance through the years while I worked on this and other books. Also, I would especially like to thank my children, Jay, Mary Beth, and Caroline, and my wife Stephanie, for their understanding when I needed to spend more time on the book than I spent with them.

v vi PREFACE

Alex Dean: I would like to thank Bill Trosky and Phil Koopman for opening the doors into so many embedded systems through in-depth design reviews. I would like to thank my students in my NCSU embedded systems courses for bringing their imagination, excite- ment, and persistence to class projects. I would also like to thank my wife Sonya for shar- ing her passion of seeking out and seizing opportunities, and our daughters Katherine and Jacqueline for making me smile every time I leave work to head home.

James M. Conrad and Alexander G. Dean September 2011 Foreword

The world of MCU-based embedded designs can be divided into those that take advantage of existing code and MCUs, and those that require leading edge MCU architectures and implementations. Dr. Conrad, with assistance from Dr. Dean, spent more than a year inter- nalizing the inner workings and surrounding ecosystem of the newly-developed RX archi- tecture, and have generated a book showcasing the RX line which has a level of integration that has not been seen before. Indeed, by taking the best DNA of both CISC and RISC architectures, and combining them into a new breed of MCU, the RX line enables design approaches that were previously spread across the CISC and RISC camps and inac- cessible in one device line. The authors leverage the capabilities of the RX and demonstrate their own expert grasp of all the dynamics that differentiate successful end solutions from those of the “me-too” variety. They recognize that successful embedded systems require more than just good hardware and software engineering. Jim and Alex have masterfully applied RX capabilities to real world challenges using examples, applications, and approaches that will surely em- power individuals and teams of designers. Readers aspire to find books that have the right balance between depth and breadth. Where there is too much detail, the relevance can be obscured; while a broad brush ap- proach may trivialize the essence of key topics. This is especially true of books relating to embedded designs that must achieve a utilitarian purpose. Here, Jim and Alex skillfully navigate from topic to topic, knowing exactly when to throttle for maximum utility. Whether you are a university student preparing for the real world, a design looking for leading edge approaches to time-critical processes, or a manager attempting to further your risk management techniques, you will find their approach to embedded sys- tems to be stimulating and compelling.

Ali Sebt Renesas September 8, 2011

vii

Contents

Preface iii Foreword v

CHAPTER ONE Introduction to Embedded Systems 1

1.1 Learning Objectives 1 1.2 Concepts 1 1.2.1 Economics and Microcontrollers 1 1.2.2 Embedded Networks 2 1.3 Typical Benefits of Embedded Systems 2 1.3.1 Greater Performance and Efficiency 3 1.3.2 Lower Costs 3 1.3.3 More Features 4 1.3.4 Better Dependability 4 1.4 Functions 4 1.5 Attributes of Embedded Systems 5 1.6 Constraints on Embedded Systems 6 1.7 Designing and Manufacturing Embedded Systems 6 1.8 An Example of an Embedded System: The EIN GreenEval Zigbee Module 7 1.9 Summary of Book Contents 8 1.10 Recap 9 1.11 References 9

CHAPTER TWO Concepts of Microcontrollers 11

2.1 Learning Objectives 11

ix x CONTENTS

2.2 Interfacing with Digital Signals 11 2.2.1 General Purpose Digital I/O 11 Data Direction Register (DDR) 12 Data Register (DR) 13 Port Register (PORT) 14 Check State of Switch1 (Port 4 bit 0) and Turn On LED1 (Port D bit 0) 15 Input Buffer Control Register (ICR) 15 Open Drain Control Register (ODR) 15 Pull-Up MOS Control Register (PCR) 16 2.2.2 Example 1: to Control LEDs 16 Using LEDs as Outputs 16 Using Switches as Inputs 17 2.2.3 Driving Motors and Coils 20 2.2.4 Scanning Matrix Keypads 22 2.3 Interfacing with Analog Signals 24 2.3.1 Analog to Digital Converters 24 2.3.2 Analog Comparator 25 2.3.3 Digital to Analog Conversion 26 Resistor Networks 26 Binary Weighted DACs 26 R- 2R DAC 27 Pulse Width Modulation 28 2.4 Infrastructure: Power, Clock, and Reset 28 2.4.1 Power Supply 28 2.4.2 Generation 30 2.4.3 Reset Circuit 31 2.5 Recap 32 2.6 References 32 2.7 Exercises 32 CONTENTS xi

CHAPTER THREE Organization and Architecture of the Renesas RX62N Microcontroller Board 35

3.1 Learning Objectives 35 3.2 Basic Concepts 35 3.2.1 Introduction to Computer Organization & Architecture 35 3.2.2 Architecture of the Renesas RX62N 38 CPU 42 Register Set 42 3.2.3 Data Types 52 3.2.4 55 3.2.5 Data Arrangement 56 3.2.6 Specification 57 Description of Buses 58 Bus Error Monitoring Section 63 Types of Bus Error 63 3.3 Basic Examples 64 3.4 Advanced Concepts 65 3.4.1 Pipelining 65 Pipeline Basic Operation 67 3.4.2 Operating Modes 71 3.4.3 Memory Organization 75 Byte Addressing vs. Word Addressing 75 3.4.4 Memory Map 76 3.4.5 I/O Registers 76 3.5 Advanced Examples 79 3.6 References 81 3.7 Exercises 82 xii CONTENTS

CHAPTER FOUR Software Development Tools 85

4.1 Learning Objectives 85 4.2 Basic Concepts 85 4.2.1 Compilation Mechanism 85 4.2.2 for Embedded Systems 87 4.2.3 RX Package 87 Features of RX Family /Cϩϩ Compiler 88 4.2.4 Tools 89 4.2.5 Introduction to HEW 89 Creating or Opening a Project in HEW- IDE 90 Windows in HEW 92 Concept of Configuration and Session 93 Configuration 94 Session 94 4.2.6 Concepts of Header Files 94 Header Files Used in RX Family C/Cϩϩ Compiler 95 Header Files Associated with RX62N 95 4.3 Basic Examples 96 4.4 Advanced Concepts 106 4.4.1 Advanced Debugging Concepts 106 4.4.2 The J- Link 117 Features 118 4.4.3 Description of the Header Files Used in the RX Family 118 4.5 Advanced Examples 130 Window Configuration 130 Changing the Register Display Radix 131 Setting the Layout 131 Choosing a Register to be Displayed 133 Modifying the Register Contents 133 Setting the Flag Value 134 CONTENTS xiii

Screenshot 134 Saving Register Contents 135 4.6 References 136 4.7 Exercises 137

CHAPTER FIVE Software Engineering for Embedded Systems 141

5.1 Learning Objectives 141 5.2 Introduction 141 5.2.1 Risk Reduction 141 5.3 Software Development Stages 142 5.3.1 Development Lifecycle Overview 142 5.3.2 Requirements 145 5.3.3 Design Before Coding 146 5.3.4 Peer Reviews of Design Artifacts 147 5.3.5 System Architecture and Design Approach 147 Time-Critical Processing 148 Safety-Critical Processing 149 5.3.6 Detailed Design 149 5.3.7 Implementation 151 5.3.8 Software Testing 152 Do We Know How the System is Built? 153 How Many Modules Do We Test at a Time? 153 How Do We Keep from Breaking Old Bug Fixes? 154 5.4 Software Development Lifecycle Models 155 5.4.1 Waterfall 155 5.4.2 Iterative Process 156 5.4.3 Spiral Process 156 5.4.4 Agile Development Methods 157 5.4.5 Prototyping 158 xiv CONTENTS

5.5 Recap 158 5.6 References 158 5.7 Exercises 159

CHAPTER SIX Converting Between the Analog and Digital Domains 161

6.1 Learning Objectives 161 6.2 Basic Concepts 161 6.2.1 Analog to Digital Conversion by Successive Approximation 163 6.2.2 Conversion Speed 165 6.2.3 Transfer Function Calculation 165 6.3 Basic Examples 167 6.3.1 Conversion Speed 167 6.3.2 Digital Value for a Given Analog Value 167 6.3.3 Step Size 168 6.4 Advanced Concepts 168 6.4.1 12-Bit A/D Converter 168 Registers 170 A/D Data Registers n (ADDRn) (n ϭ A to H) 170 A/D Control Register (ADCSR) 170 A/D Channel Select Register (ADANS) 171 A/D- Converted Value Addition Mode Select Register (ADADS) 171 A/D- Converted Value Addition Count Select Register (ADADC) 172 A/D Control Extended Register (ADCER) 173 A/D Start Trigger Select Register (ADSTRGR) 173 Operation 175 Single-Cycle Scan Mode 175 Continuous Scan Mode 178 6.4.2 10-Bit A/D Converter 178 Registers 178 A/D Data Register (ADDRn) (n ϭ A to D) 178 CONTENTS xv

A/D Control/ (ADCSR) 178 A/D Control Register (ADCR) 180 A/D Data Placement Register (ADDPR) 181 A/D Self- Diagnostic Register (ADDIAGR) 181 Operation 182 6.4.3 D/A Converter 183 D/A Registers 183 D/A Data Register (DADRm) (m ϭ 0, 1) 184 D/A Control Register (DACR) 184 D/A Data Placement Register (DADPR) 184 Operation 184 6.5 Advanced Examples 186 6.5.1 12-Bit ADC 186 Output 188 6.5.2 10-Bit ADC 188 Output 190 6.5.3 DAC 190 6.6 Recap 191 6.7 References 192 6.8 Exercises 192

CHAPTER SEVEN Serial Communications 193

7.1 Learning Objectives 193 7.2 Basic Concepts of Serial Communications 193 Terminologies 194 7.2.1 Introduction to the RX62N Interfacing 196 7.2.2 Universal Asynchronous Receiver and Transmitter 198 Registers Related to the SCI in UART Mode 200 Serial Mode Register (SCIX.SMR) 201 Serial Control Register (SCIx.SCR) 202 xvi CONTENTS

Serial Status Register (SCIx.SSR) 203 Bit Rate Register (SCIx.BRR) 204 Transmit Data Register (SCIx.TDR) 205 Receive Data Register (SCIx.RDR) 205 Variations to the UART 205 7.2.3 Renesas Serial Peripheral 205 General Working of SPI Modules 207 Configurations of the Renesas SPI 208 Registers Related to the Renesas Serial Peripheral Interface 208 Configuring the RSPI to Function in Single Master Single Slave Mode 220 7.2.4 Renesas Inter Bus 221 I2C Bus Protocol 221 I2C Communication Modes 222 Registers Related to the RIIC Interface 224 7.3 Basic Examples 236 7.3.1 Basic Transmission/Receiving of Serial Data via UART 236 Explanation of Initialization Code 239 Explanation of Transmission Code 240 Explanation of Reception Code 241 Explanation of Main Program 241 7.3.2 Basic Transmission of Data Using Serial Peripheral Interface Bus 242 Explanation of Initialization Code 244 Transmission Code 246 Explanation of Transmission Code 246 Main Code 247 Explanation of Main Code 247 7.3.3 Basic Transmission and Reception of Data Using the Renesas I2C Bus 248 7.4 Advanced Concepts 262 7.4.1 Applying FIFO Data Structures for Transmission and Reception Using the UART Serial Communications Interface 262 7.4.2 Multiprocessor Communication Using the Renesas Serial Peripheral Interface 264 Master Algorithm 266 Slave Algorithm 267 CONTENTS xvii

7.4.3 Transfer of Data Between Connected on the I2C Bus Using FIFOs 268 7.5 Advanced Examples 276 7.5.1 FIFO Data Structures for Transmission and Reception Using the UART Serial Communications Interface 276 Setting Up Service Routines 276 Main Program 279 7.5.2 Multiprocessor Communication Using Queues and the Renesas Serial Peripheral Interface 280 Setting Up Interrupt Service Routines 280 Setting Up Function Definitions for Operating on the Queues 281 Setting Up All the Function Details Related to the Functioning of the UART and FIFO Queues 282 Main Program 285 7.5.3 Transfer of data between peripherals connected on the I2C bus using FIFOs 286 7.6 Recap 297 7.7 References 299 7.8 Exercises 299

CHAPTER EIGHT Event Counters, , and the Real Time Clock 301

8.1 Learning Objectives 301 8.2 Basic Concepts 301 8.2.1 and Event 301 Timer 301 Event Counter 302 8.2.2 Cascading Timers 310 8.2.3 Pulse Output Operation 311 8.3 Real Time Clock 313 8.3.1 RTC Registers 314 8.3.2 Setting the RTC 321 8.3.3 Reading the RTC 322 xviii CONTENTS

8.4 Basic Examples 323 8.4.1 Setting Up Cascaded Timers 323 8.4.2 Setting Up a Timer for Pulse Output 327 8.4.3 Setting and Reading from the Real Time Clock 328 8.5 Advanced Concepts 333 8.5.1 Using a Cascaded Timer with 16-Bit Timer Constant Registers 333 8.5.2 Calculating and Programming Pulse Frequency and Duty Cycle in Pulse Output Mode, and Controlling a Servo Motor 334 8.5.3 Using the Real Time Clock’s Alarm and Periodic 336 8.6 Advanced Examples 337 8.6.1 Using a Cascaded Timer with 16-Bit Timer Constant Registers 337 8.6.2 Setting Up Pulse Output Mode to Control a Servo Motor 340 8.6.3 Using the Real Time Clock’s Alarm and Periodic Interrupts 343 8.7 Recap 347 8.8 References 347 8.9 Exercises 347

CHAPTER NINE Using Interrupts with Peripherals 349

9.1 Learning Objectives 349 9.2 Basic Concepts 349 9.2.1 Using Interrupts for Tasks versus Other Methods 349 9.3 Interrupts 350 Interrupt Request Register n (IRn) (n ϭ interrupt vector number) 351 IR Flag (Interrupt Status Flag) 354 Interrupt Priority Register m (IPRm) (m ϭ 00 to 8Fh) 355 Fast Interrupt Register (FIR) 356 Software Interrupt Activation Register (SWINTR) 356 IRQ Control Register i (IRQCRi) (i ϭ 0 to 15) 357 Non- Maskable Interrupt Enable Register (NMIER) 357 Non- Maskable Interrupt Status Register (NMISR) 358 CONTENTS xix

Non- Maskable Interrupt Clear Register (NMICLR) 359 NMI Pin Interrupt Control Register (NMICR) 360 9.3.1 Interrupt Vector Table 360 9.3.2 Interrupt Operation 360 Edge Detection 361 Level Detection 362 9.3.3 Setting Up an Interrupt for a Peripheral 363 Setting Up an Interrupt 363 Registers Set in the ICU for an Interrupt 365 9.3.4 How an Interrupt Operates 369 9.4 Basic Examples 370 9.4.1 Polling a for Input versus Using an Interrupt 370 9.4.2 Setting up the ADC with an Interrupt 373 9.5 Advanced Concepts 377 9.5.1 Minimizing the Amount of Code in Interrupts 377 9.5.2 Brief Introduction to State Machines 378 9.5.3 State Machines and Using Them with Interrupts 379 9.6 Advanced Examples 380 9.6.1 Using an ADC Interrupt with Flags to Process Data 380 9.6.2 A Simple State Machine Controlled by Interrupts 383 9.7 Recap 389 9.8 References 389 9.9 Exercises 389

CHAPTER TEN Floating Point Unit and Operations 391

10.1 Learning Objectives 391 10.2 Basic Concepts 391 10.2.1 Floating Point 391 Floating Point Representation 391 IEEE 754 Floating Point Standard 392 xx CONTENTS

The IEEE 754 Floating Point Standard 393 Single Precision (32 bits) 393 Double Precision (64 bits) 395 10.2.2 Pipelining Basics 397 Instruction Fetch 397 Instruction Decode 398 Execution 398 Memory Access 398 Write- Back 398 10.2.3 Floating Point in RX62N 398 Floating Point Unit 399 Floating Point Registers 399 Floating Point Instructions 401 FADD 401 FSUB 401 FCMP 403 Floating Point Exceptions 403 Overflow 403 Underflow 404 Inexact 404 Divide- By- Zero 404 Invalid Operation 404 10.3 Basic Examples 404 10.3.1 Operations Explaining Floating Point Exceptions 404 10.4 Advanced Concepts of RX62N Floating Point Unit 408 10.4.1 FPSW in Detail 408 Rounding- Modes 409 Cause Flags 409 Exception Flags 410 Exception Handling Enable Bits 410 Denormalized Number Bit 410 Floating Point Error Summary Flag 411 Reserved Bits 411 CONTENTS xxi

10.4.2 Floating Point Exception Handling Procedure 411 Acceptance of the Exception 411 Hardware Pre- Processing 412 Processing of User- Written Program Code 412 Hardware Post- Processing 414 10.5 Advanced Examples 414 10.5.1 Fixed- Point and Floating- Point Operation Time Calculation 414 Int 417 Float 417 Double 417 10.5.2 Matrix Multiplication Time Calculation 418 Int 422 Float 422 Double 422 10.6 Recap 422 10.7 References 423 10.8 Exercises 423

CHAPTER ELEVEN and Brown- Out Detector 425

11.1 Learning Objectives 425 11.2 Basic Concepts of Watchdog Timer 425 11.2.1 Watchdog Timer (WDT) 426 11.2.2 Register Descriptions 426 Timer Counter Register (TCNT) 428 Explanation of the Code 428 Timer Control/Status Register (TCSR) 428 Bit Description of TCSR 429 Explanation of the Code 431 Reset Control/Status Register (RSTCSR) 431 xxii CONTENTS

Bit Description of RSTCSR 431 Explanation of the Code 432 11.2.3 Operation of WDT 432 11.3 Basic Code Examples 434 11.3.1 Example 1: Setting Up Watchdog Timer Mode 434 Explanation of the Code 434 11.3.2 Example 2: Application of a Watchdog Timer 434 Explanation of the Code 435 11.4 Advanced Concepts of the Watchdog Timer 436 11.4.1 Interval Timer Mode 436 11.4.2 Inde pen dent Watchdog Timer (IWDT) 436 Bit Description for IWDTCR 438 Bit Description of IWDTSR 441 Operation of Inde pen dent Watchdog Timer 441 11.5 Complex Examples 443 11.5.1 Example 1: Interval Timer Mode of a Watchdog Timer 443 Explanation of the Code 443 11.5.2 Example 2: Setting Up of IWDT 444 Explanation of the Code 444 11.6 Brownout Condition 444 11.6.1 How Brownout Occurs 444 11.6.2 Automatically Detecting a Brownout Condition 444 11.7 Recap 445 11.8 References 445 11.9 Exercises 445

CHAPTER TWELVE Designing Responsive andReal- Time Systems 447

12.1 Learning Objectives 447 12.2 Motivation 447 12.3 Scheduling Fundamentals 449 CONTENTS xxiii

12.3.1 Task Ordering 449 12.3.2 Task 451 12.3.3 Fairness and Prioritization 452 12.3.4 Response Time and Preemption 453 12.3.5 Stack Memory Requirements 454 12.3.6 Interrupts 455 12.4 Task Management 456 12.4.1 Task States 456 12.4.2 Transitions between States 457 12.4.3 Context Switching for Preemptive Systems 458 12.5 Sharing Data Safely 460 12.5.1 Data Shared Objects 460 12.5.2 Function Reentrancy 461 12.5.3 High- Level Languages and Atomicity 462 12.5.4 Shared-Data Solutions and Protection 464 Disable Interrupts 464 Use a Lock 465 RTOS- Provided Semaphore 466 RTOS- Provided Messages 467 Disable Task Switching 467 12.6 Nonpreemptive Dynamic Scheduler 467 12.6.1 Concepts 467 12.6.2 Implementation 470 Task Table 470 Managing Tasks 471 Tick Timer Configuration and ISR 473 Scheduler 474 12.6.3 Example Application using RTC Scheduler 474 12.7 References 475 12.8 Exercises 476

Appendix A 479 Index 487

Chapter One

Introduction to Embedded Systems

1.1 LEARNING OBJECTIVES

In this chapter the reader will learn:

Ⅲ What an embedded system is Ⅲ Why to embed a computer Ⅲ What functions and attributes embedded systems need to provide Ⅲ What constraints embedded systems have

1.2 CONCEPTS

An embedded system is an application- specific computer system which is built into a larger system or device. Using a computer system rather than other control methods (such as non- programmable logic circuits, electro- mechanical controls, and hydraulic control) offers many benefits such as sophisticated control, precise timing, low unit cost, low de- velopment cost, high flexibility, small size, and low weight. These characteristics can be used to improve the overall system or device in various ways:

Ⅲ Improved per for mance Ⅲ More functions and features Ⅲ Reduced cost Ⅲ Increased dependability

Because of these benefits, billions of microcontrollers are sold each year to create embed- ded systems for a wide range of products.

1.2.1 Economics and Microcontrollers

Microcontrollers are remarkably inexpensive yet offer tremendous per for mance. The mi- croprocessor for a may cost $100 or more, while microcontrollers typi- cally cost far less, starting at under $0.25. Why is this so?

1 2 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Microcontrollers provide extremely inexpensive processing because they can leverage economies of scale. MCUs are programmable in software, so a chipmaker can design a single type of MCU which will satisfy the needs of many customers (when combined with their application- specific software). This reduces the per- chip cost by amortizing the de- sign costs over many millions of units. The cost of an integrated circuit (such as a microcontroller or a ) depends on two factors: non- recurring engineering (NRE) cost and recurring cost. The NRE cost includes paying to design the integrated circuit (IC) and verify through and prototyping that it will work properly. The recurring cost is in- curred by making each additional IC, and includes raw materials, processing, testing, and packaging. The IC’s area is the major factor determining this recurring cost. The smaller the IC, the more will fit onto a silicon wafer and the lower the recurring cost. Microcontrollers are much smaller than microprocessors for personal computers, so they will cost less (given the same number of ICs sold). The NRE cost must be divided across each IC sold. As the number of ICs sold rises, the NRE falls, and so each IC’s price falls as well. Low- volume chips are more expensive than high- volume chips.

1.2.2 Embedded Networks

Some embedded systems consist of multiple embedded computers communicating across an embedded network, and offer further benefits. Each computer on the network uses a communication protocol to share the same set of wires to communicate, rather than dedicating one set for each possible communication route. Several advantages come from having fewer wires:

Ⅲ Lower parts cost, as fewer wires are needed Ⅲ Lower labor costs, as it is faster to assemble Ⅲ Greater reliability, as it has fewer connections to fail

Other advantages come from allowing separate nodes to share information. New features may be possible, or the system efficiency may be improved through better coordination of activities among different nodes.

1.3 TYPICAL BENEFITS OF EMBEDDED SYSTEMS

As an example, let’s examine how embedded systems have affected automobiles. A typical modern car has dozens of microcontrollers embedded within it. Let’s see why. CHAPTER 1 / INTRODUCTION TO EMBEDDED SYSTEMS 3

1.3.1 Greater Performance and Efficiency

Computer control of automobile engines lowers pollution and increases fuel efficiency, re- ducing operating costs. Burning gasoline with air in spark ignition engines is a tricky business if we want to max- imize efficiency, yet minimize pollution. The main factor affecting emissions is the ratio of air mass to fuel mass. The ideal ratio is 14.7 to 1, and the catalytic converter is designed to op- erate most efficiently at this ratio. If there is too little air (a rich mix), then excessive carbon monoxide (CO) and hydrocarbons (HC) will be produced. If there is too much air (a lean mix), then large amounts of oxides of nitrogen (called NOx) will be created. So we would like for each fuel injector to add just the right amount of fuel. This depends on the mass of the air inside the cylinder, which depends on factors such as air temperature and air pressure. These in turn depend on altitude and weather, as well as whether the engine is warmed up or not. Another factor is the timing of the sparkplug firing. If it fires early, then there is more time for combustion within the cylinder before the exhaust valve opens. This raises the av- erage temperature within the cylinder and changes the combustion process, affecting CO, HC, and NOx concentrations. It would be quite impractical to design a mechanical to consider all of these factors and squirt the fuel injectors at just the right instant for the right amount of time. Thankfully, an inexpensive microcontroller is quite effective at these kinds of calcu- lations and control.

1.3.2 Lower Costs

There are various ways in which an embedded system can reduce the costs associated with a device.

Ⅲ Component costs: can compensate for poor signal quality, al- lowing the use of less- expensive components. For example, a low- cost pressure may be very temperature- de pen dent. If ambient temperature information is already available, then it is a simple matter to compensate for the temperature- induced error. Ⅲ Manufacturing costs: Many vehicles use the Control Area Network (CAN) pro- tocol to communicate across an in- car network. The embedded network reduces assembly and parts costs because of the simpler wiring harness. Ⅲ Operating costs: As mentioned above, an embedded system enables automobile engines to operate more efficiently, reducing the amount of gasoline needed and hence lowering operating costs. Ⅲ Maintenance costs: Some vehicles predict oil life by monitoring engine use his- tory, notifying the driver when an oil change is needed. 4 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

1.3.3 More Features

An MCU running application- specific software offers tremendous opportunities for fea- tures and customization. These features can make your company’s products stand out from the competition.

Ⅲ Cruise control keeps the car running at the same speed regardless of hills, wind, and other external factors. Ⅲ Smart airbags reduce injuries by adjusting inflation speed based on passenger weight. Ⅲ Power seats move to each driver’s preferred position automatically, based on whose keyless entry fob was used to open the car. Ⅲ Headlights and interior lights shut off automatically after a time delay if the car is not running and prevents the lights from draining the battery.

1.3.4 Better Dependability

Embedded systems and networks offer many opportunities to improve dependability.

Ⅲ An engine (and other controllers) can provide various “limp- home modes” to keep the car running even if one or more or other devices fail. Ⅲ A warning of an impending failure can be provided. Ⅲ Diagnostic information can be provided to the driver or ser vice personnel, saving valuable trouble- shooting time.

1.4 EMBEDDED SYSTEM FUNCTIONS

There are several common functions which embedded systems typically provide.

Ⅲ Control systems monitor a process and adjust an output variable to keep the process running at the desired set point. For example, a cruise control system may increase the throttle setting if the car’s speed is lower than the desired speed, and reduce it if the car is too fast. Ⅲ There is often sequencing among multiple states. For example, a car engine goes through multiple states or control modes when started. During Crank and Start, the fuel/air mix is lean and depends on the engine coolant temperature. Once the engine has started, the controller switches to the Warm- Up mode, in order to raise the engine and exhaust system temperatures to their ideal levels. Here the fuel/air CHAPTER 1 / INTRODUCTION TO EMBEDDED SYSTEMS 5

mixture and ignition timing are adjusted, again based in part on the engine coolant temperature. When the engine has warmed up it can switch into Idle mode. In this mode the controller seeks to minimize the engine’s speed, yet still run smoothly and efficiently despite changes in loads due to air conditioning, power steering, and the electrical system. Ⅲ Signal processing modifies input signals to eliminate noise, emphasize signal components of interest, and compensate for other factors. For example, a hands- free speakerphone interface may use multiple microphones, beam- forming, and active noise cancellation to filter out low- frequency road noise. Other sensors may have spark- plug noise filtered out. Ⅲ Communications and networking enable different devices on the same network to exchange information. For example, the engine controller may need to send a message indicating speed. To do this, the speed value must be formatted according to the communication protocol and then loaded into the network interface periph- eral for transmission.

1.5 ATTRIBUTES OF EMBEDDED SYSTEMS

Embedded systems are designed so that the resulting device behaves in certain desirable ways.

Ⅲ Embedded systems need to respond to events which occur in the environment, whether a user presses a button or a motor overheats. A system which is not suffi- ciently responsive is not likely to be a successful product. For example, when we press a channel select button for the radio, we would like for it to respond within some reasonable time. Ⅲ For real-time systems, the timing of the responses is critical because late answers are wrong answers. Igniting the fuel in a cylinder is time- critical because bad tim- ing can damage or destroy engine components (to say nothing of reducing power, or the efficiency and pollution concerns mentioned previously). Ⅲ Embedded systems typically require sophisticated fault handling and diagnos- tics to enable safe and reliable operation. Often the fault handling code is larger and more complex than the normal operation code. It is easy to design for the “everything goes right and works fine” case. It is far more difficult to determine methods to handle the exceptional cases. What is likely to fail? Which failures can lead to dangerous conditions? How should the system handle failures? How will you test that the system handles the failures correctly? Ⅲ Embedded systems may be expected to operate indepen dently for years with- out operator attention such as adjustment or resetting. The system is expected to 6 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

operate robustly and always work. Given that it is very difficult and expensive to write perfect, bug- free software, developers build in mechanisms to detect faulty behavior and respond, perhaps by restarting the system.

1.6 CONSTRAINTS ON EMBEDDED SYSTEMS

Embedded systems often have constraints which limit the designer’s options, and can lead to creative and elegant solutions. These constraints are typically different from those for general- purpose computers.

Ⅲ Cost is a common constraint. Many applications which use embedded systems are sold in very competitive markets, in which price is a major factor. Often a manu- facturer will hire subcontractors to design and build individual sub- systems. This allows the manufacturer to pit potential subcontractors against each other, keeping prices down. Ⅲ There may be size and weight limits for portable and mobile applications. An em- bedded system for an automotive remote keyless entry transmitter must fit into a small fob on a key ring which fits easily into a pocket. Similarly, the receiver must not be too heavy. A heavier car will have worse acceleration, braking, cornering, and fuel efficiency. Aircraft and spacecraft are especially sensitive to weight since a heavier craft requires more fuel to achieve the same range. Ⅲ There may be limited power or energy available. For example, a battery has a lim- ited amount of energy, while a solar cell generates a limited amount of power. High temperatures may limit the amount of cooling available, which will limit the power which can be used. Ⅲ The environment may be harsh. under the hood of a car need to operate across a wide range of temperatures (Ϫ40°C to 125°C, or Ϫ40°F to 193°F), while withstanding vibrations, physical impact, and corroding salt spray. Spark plugs generate broadband radio frequency energy which can interfere with electronics.

1.7 DESIGNING AND MANUFACTURING EMBEDDED SYSTEMS

Embedded systems are designed with a central microcontroller and other supporting elec- tronic components mounted on a (PCB). PCBs provide the means to connect these integrated circuits to each other to make an operational system. The PCB pro- vides structural support and the wiring of the circuit. The individual wires on the PCB are called traces and are made from a flat copper foil. While many circuit designs may use the same standard components, the PCB is often a custom component for a given design. Designing a PCB requires a completed schematic for the circuit. This schematic is sometimes different than the schematic seen in textbooks. It often contains extra informa- CHAPTER 1 / INTRODUCTION TO EMBEDDED SYSTEMS 7

Figure 1.1 EIN GreenEval Zigbee Module.

tion about the components and construction of the board. For example, a textbook schematic may only show a battery for the power supply, while the production schematic would show the battery case, the number of cells, the rating of the battery, and the manu- facturers of the components. From the schematic, a designer will use their computer- aided design tools to identify the size of the PCB, and then place the electronic components on their board drawing. The designer will also place the wiring between the components on the PCB. The physical PCB is manufactured from a fiberglass- resin material that is lightweight and inexpensive. A manufacturer will add copper wiring traces to the surfaces of the board and the appropriate insulation and white silk screening. The final manufacturing steps are applying solder, placing the components, and heating/cooling the solder. Figure 1.1 shows an example of a finished board. The completed boards are electrically tested for functionality. Any board failing the test is inspected in more detail to find the problems. These boards are repaired to increase the passing rate acceptable to the manufacturer. The boards are wrapped in anti- static ma- terials and shipped to the next location for the next stage of production, or immediately in- stalled in a mechanical enclosure (like the mechanical shell of a ).

1.8 AN EXAMPLE OF AN EMBEDDED SYSTEM: THE EIN GREENEVAL ZIGBEE MODULE

The EIN GreenEval Zigbee (Envisionnovation, http://www.eininc.net/products.html) mod- ule is one example of a Renesas MCU- based embedded system. This device has thirty- four digital I/O lines that are controlled by a Zigbee radio. 8 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Figure 1.1 shows the main board of the EIN GreenEval Zigbee Module. As seen in this example, taking off the shielding provides a good look at the internal circuitry. Six of the main components are visible. Starting from left to right; the large cylindrical device hang- ing off the left edge of the board is an antenna for the 2.4 GHz radio. The chip labeled 5PE20V (http://www.micron.com//get-document/?documentId= 5965&file=M25PE20_10.pdf) (the small 8-pin chip at the top left of the image) is a page- erasable serial FLASH chip. This chip communicates with the Renesas MCU through the SPI bus. This chip is also used to hold more data than the MCU. Since the MCU can only handle 8 k of data, it is quickly filled. This extra FLASH chip can hold an additional 2 Mbits. The square chip on the lower left is a Skyworks 2.4 GHz Front- End Module (FEM) (SKYWORKS Solutions, Inc., http://www.skyworksinc.com/Product.aspx?ProductIDϭ752), which simply boosts radio signals sent from the MCU. It is controlled by three output pins of the MCU. One pin controls putting the FEM to sleep to save power, another pin selects whether the FEM will send or receive data, and the last pin actually transmits and receives data to and from the FEM. The large chip in the center is a Renesas R5FF36B3 from the M16C family of chips with 256 K ϩ 24 K of ROM, 20 k RAM, and 8 k of data (Renesas Electronics America, Inc., RENESAS MCU: M16C Family/M16C/60 SERIES, http://am.renesas.com/products/ mpumcu/m16c/m16c60/m16c6b/m16c6b_root.jsp). Thirty-four I/O pins are used to inter- face with external pins on the module. This is running at 4 MHz (controlled by the small metal chip which is actually a temperature compensated crystal oscillator). This chip has an RF radio built in. The pins at the far right are a programming and interface header. They are used to com- municate with and program the Renesas MCU.

1.9 SUMMARY OF BOOK CONTENTS

This book is structured as follows:

Ⅲ Chapters 2 and 3 present basic microcontroller concepts and the specifics of the RX62N. Ⅲ Chapters 4 and 5 show how software is built. At the low level they show how pro- grams are compiled and downloaded. At the high level they show software engi- neering concepts and practices. Ⅲ Chapters 6 through 8 present how to use peripherals to interface with the environ- ment and simplify programs. Ⅲ Chapter 9 presents how to use interrupts to improve response times and program structure. CHAPTER 1 / INTRODUCTION TO EMBEDDED SYSTEMS 9

Ⅲ Chapter 10 presents how to use the floating- point math support in the RX62N. Ⅲ Chapter 11 presents how to increase system robustness using the watchdog timer and voltage brownout detector. Ⅲ Chapter 12 presents how to structure multi- threaded software so the resulting sys- tem is predictably responsive.

1.10 RECAP

An embedded system is an application- specific computer system which is built into a larger system or device. Using a computer system enables improved perfor mance, more functions and features, lower cost, and greater dependability. With embedded computer systems, manufacturers can add sophisticated control and monitoring to devices and other systems, while leveraging the low- cost microcontrollers running custom software.

1.11 REFERENCES

Envisionnovation. EININC Products. Ontario: Envisionnovation, 2010. Web. Accessed at http://www.eininc. net/products.html Numonyx MP25PE20 datasheet http://www.micron.com//get-document/?documentId=5965&file=M25PE20_ 10.pdf RENESAS MCU: M16C Family/M16C/60 SERIES. Renesas Electronics America, Inc., 2010. Web. Accessed at http://am.renesas.com/products/mpumcu/m16c/m16c60/m16c6b/m16c6b_root.jsp SKYWORKS Solutions, Inc. SKYWORKS Products: SKY65352–11. Woburn, MA: SKYWORKS Solutions, Inc., 2009. Web. Accessed at http://www.skyworksinc.com/Product.aspx?ProductIDϭ752

Chapter Two

Concepts of Microcontrollers

2.1 LEARNING OBJECTIVES

Embedded systems consist of computers embedded in larger systems. Additional circuitry such as power supplies, clock generators, and reset circuits, is required for the computer to work. Transducers (devices that convert one type of energy into another) are also used to connect microcontrollers to the outside world. There are two classes of transducers: inputs and outputs. Inputs are also known as “sensors” and contain such things as switches, key- pads, and buttons. Output transducers include devices such as LEDs, motors, and coils. In this chapter the reader will learn general information about:

Ⅲ Connecting LEDs Ⅲ Connecting motors and coils Ⅲ Connecting switches and buttons Ⅲ Connecting keypads Ⅲ Analog to digital conversion Ⅲ Digital to analog conversion Ⅲ Power supplies for embedded systems Ⅲ Clock generation options Ⅲ Reset circuitry

2.2 INTERFACING WITH DIGITAL SIGNALS

2.2.1 General Purpose Digital I/O

Embedded systems consist of computers embedded in larger systems. The processor needs to sense the state of the larger system and environment, and control output devices. The most basic way to do this is through one or more discrete signals, each of which which can be in one of two states (on or off). General purpose digital I/O ports are the hardware which can be used to read from or write to the system outside the microcontroller.

11 12 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The RX62N has eleven I/O ports (Port 0 to 5, A to E). Each port has eight pins, and on most ports all eight pins can be selected as inputs or outputs. However, on some ports some pins are reserved. The reserved pins cannot be configured as I/O pins. Each port has a Data Direction Register (DDR), Data Register (DR), Port Register (PORT), and Input Buffer Control Register (ICR). The pins of a port may serve several purposes; for example, Port 4 pin 0 can be used as a general purpose I/O pin, as an A/D converter input, or as an interrupt input. Depending on the purposes these pins serve, they might have extra regis- ters. Ports A through E have an extra register called the Pull- up MOS Control Register (PCR), and Ports 0 to 3 (P30 to P34) and C have Open Drain Control Register (ODR). All of these registers are 8 bits long. Certain other registers called Port Function Registers are also present. These registers are associated with special features of the RX62N board such as USB, CAN, etc.

Data Direction Register (DDR) This register, as the name suggests, is used to set the data direction (input or output) of a pin. DDR is a read/write register. Each bit of the Data Direction Register represents a pin.

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 0 0 0 0 0 0 0 0

Figure 2.1 Data Direction Register. Source: Kuphaldt, T. R. “Successive Approximation ADC,” in All about Circuits, page 765.

The ‘iodefine_RX62N.h’ file has C code constructs that make it easy to access each port with C code. Each port is defined as a structure and each register of the port is defined as a union of variables within that structure. An example of how the DDR is defined inside a port structure follows:

1. struct st_port4 { 2. union { 3. unsigned char BYTE; 4. struct { 5. unsigned char B7:1; 6. unsigned char B6:1; 7. unsigned char B5:1; 8. unsigned char B4:1; CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 13

9. unsigned char B3:1; 10. unsigned char B2:1; 11. unsigned char B1:1; 12. unsigned char B0:1; 13. } BIT; 14. } DDR; 15. }

Line 1 shows that port0 has been defined as a structure. Lines 2 to 14 suggest that Data Direction Register (DDR) has been defined as a union with the variable BYTE and a struc- ture called BIT. This organization helps in easy access of the bits of the DDR. Unsigned char Bn:1(n 0 to 7) indicates that the character variable is assigned one bit. To select a particular pin as the input pin, the corresponding bit of the DDR has to be set to ‘0’; and to select a pin as output, the corresponding bit of the DDR has to be set to ‘1.’ The general syntax to set a bit of the DDR is PORTx.DDR.BIT.Bn (x 0 to 5, A to E; and n 0 to 7) since ports are defined as structures and accessing structure members is done so this way. To configure multiple pins at the same time, the char variable BYTE can be used. All pins are configured as inputs at reset, by default.

EXAMPLE 1

Set Switch 1 (Port 4 bit 0) as Input PORT4.DDR.BIT.B1 =0;

When a pin is selected as an input from a peripheral, the Input Buffer Control Register (ICR) has to be enabled. The ICR will be explained a little later. Selecting a pin as an output involves setting the Data Register (DR) and the Data Direction Register (DDR).

Data Register (DR) The Data Register is used to store data for pins that have been configured as output pins. This register is similar to the DDR in that each bit of the register represents a pin and certain bits of certain ports are reserved. 14 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 0 0 0 0 0 0 0 0 Figure 2.2 Data Register.

The Data Register (DR) is also defined as a union of variables inside the port structure, in the ‘iodefine_RX62N.h’ file. It is presented just like the DDR. Unsigned char: 1 is used to represent reserved pins. The syntax to access the bits of the Data Register (DR) is PORTx.DR.BIT.Bn (x 0 to 5, A to E; and n 0 to 7). To select a pin as an output pin, first set the Data Register (DR) to a known value, preferably 0, so that changes in the output can be easily observed. The char variable BYTE can be used to set multiple pins as output at the same time.

EXAMPLE 2

Set LED1 (Port D bit 0) as Output 1. PORTD.DDR.BIT.B0 = 1; 2. PORTD.DR.BIT.B0 = 0;

Line 1 sets LED1 as an output and line 2 switches on the LED.

Sets LEDs 1, 2, and 3 (Port D bit 0, 1, and 2) as Outputs 1. PORTD.DDR.BYTE = 0x07; 2. PORTD.DR.BYTE = 0xF8;

Line 1 sets LED1, 2, and 3 as outputs and line 2 switches on the LEDs.

Port Register (PORT) Port register is also defined as a union of variables inside the port structure in the ‘iodefine_RX62N.h’ file. PORTx.PORT.BIT.Bn (x 0 to 5, A to E; and n 0 to 7) is used to read the state of a pin and the state is stored in the Port Register regardless of the value in the Input Buffer Control Register (ICR). This register also has some reserved bits. These bits are read as 1 and cannot be modified. CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 15

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: x x x x x x x x Figure 2.3 Port Register.

Check State of Switch1 (Port 4 bit 0) and Turn On LED1 (Port D bit 0) 1. if(PORT4.PORT.BIT.B0 == 1){ 2. PORTD.DR.BIT.B0 = 1; 3. }

Input Buffer Control Register (ICR) This register is used to buffer the input values for pins that have been configured as input from peripheral modules.

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 0 0 0 0 0 0 0 0 Figure 2.4 Input Buffer Control Register.

Before configuring a pin as an input from a peripheral, the ICR must be enabled. To enable the ICR set PORTx.ICR.BIT.Bn (x 0 to 5, A to E; and n 0 to 7) to 1. If a pin has to be configured as an output pin, set PORTx.ICR.BIT.Bn (x 0 to 5, A to E; and n 0 to 7) to 0. Setting ICR to 0 disables the ICR. While setting the ICR, make sure that the correspon- ding pin is not in use. For example, when setting IRQi (i 0 to 15) as input, first disable the interrupts, next enable ICR and then enable interrupts. It is necessary to follow the above steps to avoid unintended operations from taking place.

Open Drain Control Register (ODR) Most output pins function as CMOS but some output pins can operate as CMOS or NMOS open- drain pins. Since NMOS circuits are faster compared to the CMOS circuits, which consist of the slower p- channel , using NMOS open- drain pins as outputs would be similar to a wired- OR connection. All of the pins of port 0, 1, 2, C and pins 0 to 4 of port 3 are capable of functioning as NMOS open- drain output pins. Setting PORTx.ODR.BIT.Bn (x 0 to 5, A to E; and n 0 to 7) to 1, selects the pin as an NMOS open- drain pin. 16 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Pull-Up MOS Control Register (PCR) Some devices have limited signal swing. When such a device is interfaced with the RX62N board, the signal from the device has to be pulled up so that it is in the valid voltage range of the board (this is not the typical usage, the typical usage is the external de- vice is only capable of pulling down; or there is nothing attached and you do not want the port to float). To simplify this kind of interfacing, pull- up MOS circuitry is available for ports A to E. To enable pull- up MOS for a particular pin of a port, set PORTx.PCR.BIT.Bn (x 0 to 5, A to E; and n 0 to 7) to 1. To disable pull- up MOS, set PORTx.PCR.BIT.Bn (x 0 to 5, A to E; and n 0 to 7) to 0. The PCR is automatically disabled for pins configured as outputs. To enable or disable pull- up MOS for multiple pins use PORTx.PCR.BYTE command. The value of the PCR after reset is 0x00.

2.2.2 Example 1: Reading Switches to Control LEDs

Using LEDs as Outputs LEDs require a current- limiting resistor so that they do not draw too much current from the I/O pin to which they are connected. Most microcontrollers can sink more current than they can supply, so generally LEDs are connected with the cathode to the microcontroller pin, and a current- limiting resistor between the anode and supply voltage. Formula 2.1 shows how to calculate the value of the current limiting resistor. Figure 2.5 shows the two ways of connecting LEDs to a microprocessor.

R (VOutput VLED)/ILED Formula 2.1

R5F211A1DD 5 VSS/AVSS LED2 R2 18 P1_0/AN9/KI01/CMP0_0

17 GND P1_1/AN8/KI0/CMP0_0 15 P1_2/AN10/K12/CMP0_2 14 P1_3/ANN11/KI3/TZOUT 13 P1_4/TXD0 12 P1_5/RXD0/CNTR01/INI11 11 P1_6/CLK0/SSIO1 10 P1_7/CNTR00/INI10 19 P3_3/TCIN/INI3/SSI00/CMP1_0

Figure 2.5A The microprocessor is sourcing current to an LED. Turning on this LED requires a logical HIGH signal on the output pin. If the LED is attached to Port D, Pin 0, and that pin is set to an output; then the code needed to turn the LED on would be: PORTD.DR.BIT.B0 = 1; CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 17

R5F211A1DD 5 VSS/AVSS R2 18 P1_0/AN9/KI01/CMP0_0

17 VCC P1_1/AN8/KI0/CMP0_0 15 LED1 P1_2/AN10/K12/CMP0_2 14 P1_3/ANN11/KI3/TZOUT 13 P1_4/TXD0 12 P1_5/RXD0/CNTR01/INI11 11 P1_6/CLK0/SSIO1 10 P1_7/CNTR00/INI10 19 P3_3/TCIN/INI3/SSI00/CMP1_0

Figure 2.5B The microprocessor is sinking current from the LED. Turning on the LED requires a logical LOW on the output pin. If the LED is attached to Port D, Pin 0, and that pin is set to an output; then the code needed to turn the LED on would be: PORTD.DR.BIT.B0 =0;

Using Switches as Inputs A simple interfacing design can include using a pull- up resistor on a pin that is also con- nected to ground through a button or switch. The resistor will pull the voltage on that pin to logic HIGH until the button connects to ground. When the button is pressed, the voltage at that pin will drop to zero (logic LOW). Figure 2.6 shows a schematic of this approach. If the switch in Figure 2.6 is connected to Port D pin 0, the code to check this switch would be:

1. if(PORTD.PORT.BIT.B0 == 0){ 2. //Conditional code goes here 3. }

VCC

R5F211A1DD

5 R19 VSS/AVSS 18 P1_0/AN9/KI01/CMP0_0 17

P1_1/AN8/KI0/CMP0_0 2 15 P1_2/AN10/K12/CMP0_2 14 P1_3/ANN11/KI3/TZOUT 1 13 S1 P1_4/TXD0 12 P1_5/RXD0/CNTR01/INI11 11 P1_6/CLK0/SSIO1 10 P1_7/CNTR00/INI10 19 GND P3_3/TCIN/INI3/SSI00/CMP1_0 20 P3_4/SCS/SCA/CMP1_1

Figure 2.6 Basic button connection to a microprocessor input pin. 18 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Contact bounce is a worry with any mechanical switch. When the switch is closed, the mechanical properties of the metals in the switch cause the contacts to literally bounce off of one another. This can cause false signals to be read as inputs. Your design should take this into account with either a hardware or software debouncing solution. Hard- ware debouncing circuits often require digital logic as well as some resistors and ca- pacitors. Hardware debouncing circuits are very useful for interrupt pins. Software de- bouncing is accomplished by setting up a timer to check the state of the switch at a set interval, such as every 1 ms. If the value of the input has been the same for the duration of the timer (1 ms in this case) the input can be considered valid. This method helps to ignore false input values. To better understand configuring I/O pins let us look at an example. The RX62N board has three push buttons and twelve LEDs (six red and six green). Switches and LEDs are simple I/Os and in the following program we will see how to set up switches as inputs and LEDs as outputs. According to this program, when switch1 is pressed, green LEDs will glow, when switch2 is pressed, red LEDs will glow, and when switch3 is pressed, all the LEDs will glow.

1. #include “iodefine_RX62N.h” 2. #ifdef YRD_RX62N 3. #define LED1 PORTD.DR.BIT.B0 4. #define LED2 PORTD.DR.BIT.B1 5. #define LED3 PORTD.DR.BIT.B2 6. #define LED4 PORTD.DR.BIT.B3 7. #define LED5 PORTD.DR.BIT.B4 8. #define LED6 PORTD.DR.BIT.B5 9. #define LED7 PORTD.DR.BIT.B6 10. #define LED8 PORTD.DR.BIT.B7 11. #define LED9 PORTE.DR.BIT.B0 12. #define LED10 PORTE.DR.BIT.B1 13. #define LED11 PORTE.DR.BIT.B2 14. #define LED12 PORTE.DR.BIT.B3 15. #define LED1_DDR PORTD.DDR.BIT.B0 16. #define LED2_DDR PORTD.DDR.BIT.B1 17. #define LED3_DDR PORTD.DDR.BIT.B2 18. #define LED4_DDR PORTD.DDR.BIT.B3 19. #define LED5_DDR PORTD.DDR.BIT.B4 20. #define LED6_DDR PORTD.DDR.BIT.B5 21. #define LED7_DDR PORTD.DDR.BIT.B6 22. #define LED8_DDR PORTD.DDR.BIT.B7 23. #define LED9_DDR PORTE.DDR.BIT.B0 24. #define LED10_DDR PORTE.DDR.BIT.B1 CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 19

25. #define LED11_DDR PORTE.DDR.BIT.B2 26. #define LED12_DDR PORTE.DDR.BIT.B3 27. #define LED_ON 1 28. #define LED_OFF 0 29. #define ALL_LEDS_ON {LED1 = LED2 = LED3 = LED4 = LED5 = LED6 = LED7 = LED8 = LED9 = LED10 = LED11 = LED12 = LED_ON;} 30. #define ALL_LEDS_OFF {LED1 = LED2 = LED3 = LED4 = LED5 = LED6 = LED7 = LED8 = LED9 = LED10 = LED11 = LED12 = LED_OFF;} 31. #define ENABLE_LEDS {LED1_DDR = LED2_DDR = LED3_DDR = LED4_DDR = LED5_DDR = LED6_DDR = LED7_DDR = LED8_DDR = LED9_DDR = LED10_DDR = LED11_DDR = LED12_DDR = 1;} 32. #endif 33. #define SW1 PORT4.PORT.BIT.B0 34. #define SW2 PORT4.PORT.BIT.B1 35. #define SW3 PORT4.PORT.BIT.B2 36. #define ENABLE_SWITCHES {PORT4.DDR.BIT.B0 = PORT4.DDR.BIT.B1 = PORT4.DDR.BIT.B2 = 0;} 37. void main(void){ 38. ENABLE_LEDS; 39. ENABLE_SWITCHES; 40. while(1){ 41. if(SW1 == 0){ 42. LED12 = LED11 = LED10 = LED6 = LED5 = LED4 = LED_ON; 43. } else if(SW2 == 0){ 44. LED9 = LED8 = LED7 = LED3 = LED2 = LED1 = LED_ON; 45. } else if(SW3 == 0){ 46. ALL_LEDS_ON; 47. } else { 48. ALL_LEDS_OFF; 49. } 50. } 51. }

In line 1, the file ‘iodefine_RX62N.h’ has been included. It is a custom header file created by Renesas for easy access and manipulation of data. The RX62N board has two sets of LEDs: RSK_RX62N LEDs which are used to indicate basic functions like power on, and YRD RX62N LEDs which are used to simulate a motor. This program uses the YRD RX62N LEDs to demonstrate the use of digital I/O pins. Line 2 and line 32 are used to indicate that the statements between them should be executed only for YRD RX62N LEDs. All pins of Port D and pins 0 to 3 of Port E are the LED pins. The three switches are at Port 4 bits 0 to 2. 20 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

In main, first the LEDs have been enabled (line 38). ENABLE_LEDS is a macro de- fined earlier in the program (line 31) to set the Data Direction Register (DDR) of the LEDs to 1; i.e., set up the LED pins as output pins. Next, the switches have been enabled (line 39). ENABLE_SWITCHES is another macro defined earlier (line 36) to set the Data Direction Register (DDR) of the switches to 0; i.e., set up the switch pins as output pins. The next part of the program is an important part of many embedded systems—the while (1) loop (line 40). This loop makes the microcontroller execute all the statements within the loop repeatedly until the microcontroller is stopped by an external force (e.g., power off). In this program, the conditions for LED operation are given within the while (1) loop using if- else statements (lines 41 to 47). Even though use of the switch statement will result in much better code, the if- else statement has been used for easy understanding.

Ⅲ If switch 1 is pressed (state of switch 1 is low), all the green LEDs are turned on (line 42). The state of the switch is checked using the macro defined in line 33 us- ing the PORT register. From the schematic of the board it can be seen that green LEDs are LED 12, 11, 10, 6, 5, and 4. They are turned on by setting the Data Register (DR) of the LED pins to 1 (active high) which has been defined using the macro LED_ON in line 27. Ⅲ If switch 2 is pressed (state of switch 2 is low), all the red LEDs are turned on (line 44). The state of the switch is checked using the macro defined in line 34 us- ing the PORT register. From the schematic of the board it can be seen that red LEDs are LED 9, 8, 7, 3, 2, and 1. They are turned on by setting the Data Register (DR) of the LED pins to 1 (active high) which has been defined using the macro LED_ON. Ⅲ If switch 3 is pressed (state of switch 3 is low), all the LEDs are turned on (line 46) using the macro LED_ON. Ⅲ If none of the switches are pressed (line 47) all the LEDs are turned off using the macro LED_OFF (line 48).

2.2.3 Driving Motors and Coils

Input/Output (I/O) pins on a microcontroller have specific limits to the amount of current each pin can sink or source. These limits are found in the datasheet. Voltage levels can also be different between sensors and the microcontroller. Both of these constraints must be taken into account when designing interfaces for the actuator. Because of their large coils, motors draw a lot of current. For Direct Current (DC) mo- tors, simple drivers or H- bridges (shown in Figure 2.7) can be used to interface them with a microcontroller. If the left input of the circuit in Figure 2.7 is connected to CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 21

Port D pin 0 and the right input of this circuit is connected to Port D pin 1, the code to turn the motor one direction would be:

1. PORTD.DDR.BYTE = 0x03; //Sets pins 0 and 1 on Port D as outputs 2. PORTD.DR.BYTE = 0x02; //Sets one pin as HIGH and the other as LOW

Stepper motors can use transistors or stepper motor driver ICs. Some ICs such as the L293 or the 754410 are specifically designed to drive the DC motors and interface directly with a microcontroller. Servos are gearboxes that have motor control circuitry built in. These devices can often connect their control pins directly to a microprocessor as their in- ternal circuitry handles driving the motor itself. Other large coils such as coils should be treated similarly to motors. Figure 2.8 shows a basic coil driving circuit. Code to drive the coil is the same as it is to drive an LED.

Vout

Q2 Q4 R17 2N3906 2N3906 R18

MOTOR

Q1 Q3 2N3904 2N3904

GND

Figure 2.7 H- bridge motor driver. Two if the microprocessor’s outputs are connected to the resistors. Note: Both inputs should not be the same value for the motor to turn. 22 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Vout

R5F211A1DD R20 5 VSS/AVSS L1 2 18

P1_0/AN9/KI01/CMP0_0 D1 1N4004 17 P1_1/AN8/KI0/CMP0_0 15 P1_2/AN10/K12/CMP0_2 14 T2 P1_3/ANN11/KI3/TZOUT 1 13 2N3904 P1_4/TXD0 12 P1_5/RXD0/CNTR01/INI11 11 P1_6/CLK0/SSIO1 R16 10 P1_7/CNTR00/INI10 19 P3_3/TCIN/INI3/SSI00/CMP1_0 20 P3_4/SCS/SCA/CMP1_1 1 P3_5/SSCK/SCL/CMP1_2 2 GND P3_7/CNIR0/SSO/IXD1

Figure 2.8 A simple coil driver.

There are other methods of controlling large loads with a microprocessor, such as using re- lays or triacs. The overall concept with all load driving circuits is to keep the source and sink currents of the microprocessor within the manufacturer’s recommendations. Some sensors may require different voltages than what the microprocessor requires. Care should be taken when interfacing these sensors. If the microprocessor runs at 5 V and the sensor runs at 1.8 V, the microprocessor will not be able to read a HIGH logic signal on the sensor output. Circuits for interfacing with higher voltage sensors can be designed us- ing transistors or by using level converter ICs, which convert the signals between the mi- crocontroller and the sensor either uni- directionally or bi- directionally (in case the micro- processor needs to communicate to the sensor.) The use of a flyback diode is very important when interfacing inductive loads, to safely dissipate the voltage spike when the voltage to the load is removed.

2.2.4 Scanning Matrix Keypads

Keypads work as a matrix of buttons. For instance, Figure 2.9 shows an example keypad matrix. The top three output pins are used as the columns of the matrix. The three pins con- nected as the rows of the matrix are all input pins. A button is placed in the circuit at each intersection of a column and row. One at a time, the output pins turn on and each of the in- put pins is read. If an input is detected, the microprocessor can determine which button on the keypad had been pressed. For example, if the microprocessor noted an input on the CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 23 middle row pin at the time in which the middle output was logic HIGH, then the center button must have been pressed. If the columns in Figure 2.9 are connected to Port D bits 0, 1, and 2 respectively, and the rows are connected to Port E bits 0, 1, and 2 respectively; code to read the keypad values of the first column would be:

1. PORTD.DR.BIT.B0 = 1; //Set the output of the first column to 1 2. PORTD.DR.BIT.B1 = 0; //Set the output of the second column to 0 3. PORTD.DR.BIT.B2 = 0; //Set the output of the third column to 0 4. 5. if(PORTE.PORT.BIT.B0 == 0){ 6. //Conditional code for Row 0 7. } 8. 9. if(PORTE.PORT.BIT.B0 == 0){ 10. //Conditional code for Row 1 11. } 12. 13. if(PORTE.PORT.BIT.B0 == 0){ 14. //Conditional code for Row 2 15. }

R5F211A1DD 5 VSS/AVSS 18 P1_0/AN9/KI01/CMP0_0 17 P1_1/AN8/KI0/CMP0_0 15 P1_2/AN10/K12/CMP0_2 14 P1_3/ANN11/KI3/TZOUT 13 P1_4/TXD0 1 2 1 2 1 2 12 P1_5/RXD0/CNTR01/INI11 S2 S7 S8 11 P1_6/CLK0/SSIO1 10 P1_7/CNTR00/INI10 19 P3_3/TCIN/INI3/SSI00/CMP1_0 1 2 1 2 1 2 20 P3_4/SCS/SCA/CMP1_1 1 S3 S6 S9 P3_5/SSCK/SCL/CMP1_2 2 P3_7/CNIR0/SSO/IXD1 P4_2/VREF 16 1 2 1 2 1 2 P4_5/INI0/HXD1 9 P4_6/XIN 6 S4 S5 S10 P4_7/XOUT 4

MODE 8

Figure 2.9 Keypad button matrix. 24 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

2.3 INTERFACING WITH ANALOG SIGNALS

The world is not digital; it is analog. Microphones, thermometers, speakers, light sensors, and even video cameras are all analog sensors. As a result, the signals from these sensors must be converted to digital values so that the microcontrollers can process them.

2.3.1 Analog to Digital Converters

To read the value of an analog sensor, Analog to Digital Converters (also referred to as ADC, A/D, A- to- D, and A2D) are used. This circuit produces a multi- bit binary number based on a voltage scale. The number of bits in the multi- bit binary number helps determine the resolution or precision of the reading; 8-bit, 10-bit, and 12-bit converters are commonly used. ADCs also require a reference voltage. This is a stable voltage to which the current reading will be com- pared to produce the binary output. The analog reference voltage is scaled by the resolution. Most ADCs use linear scales, so converting the values is straightforward. Figure 2.10 shows the transfer function which is used to convert an analog voltage (measured on the horizontal axis) to its digital output code representation (on the vertical axis). Each step on the transfer function represents one least- significant bit. Figure2.11 shows an example input analog volt- age which is sampled over time.

The resolution of the conversion is determined by Formula 2.2.

Nbits Resolution VLSB Vref /2 Formula 2.2

“3.0V” 11 1 LSB “2.0V” 10

“1.0V” 01 Output Code

“0.0V” 00 1.0V 2.0V 3.0V 4.0V

Input Voltage

Figure 2.10 2-bit ADC conversion chart. The stair step line shows the ADC’s output code. CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 25 Digital Value

Time

Figure 2.11 ADC readings over time.

If Vref 5 V, and there is an 8-bit resolution, the volts per ADC raw value step 5 V/256 0.01953 V/step. To determine the value of the conversion, Formula 2.3 can be used:

Nbits ADC output code int (((2 1) * (Vin /Vref) 1/2 Formula 2.3

For example:

Vref 5 V, Vin 2.26295 V, with a 10-bit resolution; int ((1023 * (2.26295 V/5 V)) 1/2) 463 ADC raw value steps.

Once the raw ADC value is known, the application software should reverse the formula to calculate the actual voltage on that pin. Since the datasheet for most sensors provides a for- mula for converting the voltage to the unit the sensor is measuring (be it degrees Celsius, distance in centimeters, pressure in kilopascals, etc.), this formula can be inserted into the firmware to make sense of the data. More advanced sensors use a communication protocol such as RS- 232, RS- 485, I2C, and SPI. These sensors generally take an analog value, convert it to digital, and then send it to the microcontroller for processing using a communication protocol. These protocols sometimes allow for multiple sensors to be connected to the same pins of the microcontroller.

2.3.2 Analog Comparator

Some microcontrollers may contain one or more comparator circuits. This circuit can be thought of as a simple 1-bit analog to digital converter. It compares an analog voltage input with an analog reference voltage, and then determines which is larger. 26 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

2.3.3 Digital to Analog Conversion

Just as we must convert analog signals to digital to process them, sometimes there is a need to convert digital signals to analog. In systems that control audio, speed, or even light lev- els; digital output from a microprocessor must be converted into an analog signal. There are several different methods for converting digital signals to analog.

Resistor Networks Resistor networks allow a very simple solution for converting digital signals to analog. There are many methods of using resistor networks for DACs, but two designs are pre- dominantly used.

Binary Weighted DACs Resistor networks are another simple method for DAC conversion. Several different methods are available for using resistor networks, and again it is up to the designer to

R5F211A1DD 5 VSS/AVSS 18 P1_0/AN9/KI01/CMP0_0 17 P1_1/AN8/KI0/CMP0_0 R4 15 P1_2/AN10/K12/CMP0_2 14 P1_3/ANN11/KI3/TZOUT 13 P1_4/TXD0 R5 12

P1_5/RXD0/CNTR01/INI11 Vout 11 P1_6/CLK0/SSIO1 10 P1_7/CNTR00/INI10 R6 19 P3_3/TCIN/INI3/SSI00/CMP1_0 20 P3_4/SCA/SCD/CMP1_1 R7 1 P3_5/SSCK/SCL/CMP1_2 2 P3_7/CNIR0/SSO/IXD1 P4_2/VREF 16 P4_5/INI0/HXD1 9 P4_6/XIN 6 P4_7/XOUT 4

MODE 8 RESET 3 VCC/AVCC 7 IC5

Figure 2.12 4-bit binary weighted network DAC design. Source: Kester, W. A., and Analog Devices, Inc., Data Conversion Handbook, 2005, page 153–159. CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 27 decide which method is best for a particular design. Voltage- Mode Binary Weighted DACs are commonly used with microcontroller circuits. In this design, resistors are connected together on one end (the analog output), and the other ends are connected di- rectly to the pins of a microcontroller port. The values of the resistors are based on bi- nary bit place- values (R, 2R, 4R, 8R, etc.; with R being the least significant bit or LSB). When the pins of the microcontroller are set to HIGH, then the sum voltage of the ana- log output are related to the value on that port. Figure 2.12 shows an example of a 4-bit Binary Weighted DAC.

R- 2R DAC Another method of using resistor networks to design a DAC is called the R- 2R or R/2-R Net- work. It consists of resistors of only two values. One value is twice the value of the other. For instance, if the R resistors are one kilo- ohm, then the 2R resistors must equaltwo kilo- ohms. Figure 2.13 shows an example R- 2R network (Kuphaldt, T. R., “The R2-R,”).

R5F211A1DD GND 5 VSS/AVSS

18 R15 P1_0/AN9/KI01/CMP0_0 17 P1_1/AN8/KI0/CMP0_0 R8 15

P1_2/AN10/K12/CMP0_2 R9 14 P1_3/ANN11/KI3/TZOUT 13 P1_4/TXD0 R10 12 P1_5/RXD0/CNTR01/INI11 11 R11 P1_6/CLK0/SSIO1 10 P1_7/CNTR00/INI10 R12

19 R13 P3_3/TCIN/INI3/SSI00/CMP1_0

20 Vout P3_4/SCS/SCD/CMP1_1 R14 1 P3_5/SSCK/SCL/CMP1_2 2 P3_7/CNIR0/SSO/IXD1 P4_2/VREF 16 P4_5/INI0/HXD1 9 P4_6/XIN 6 P4_7/XOUT 4

MODE 8 RESET 3 VCC/AVCC 7 IC6 Figure 2.13 R- 2R network. R9, R11, and R13 are considered “R” resistors and all 1kohm while R8, R10, R12, R14, and R15 are considered “2R” and all 2kohm. Source: “The R2-R,” in Kuphaldt, T. R., All about Circuits, http://www.allaboutcircuits.com/vol_4/chpt_13/2.html 28 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Figure 2.14 An example PWM signal. If this were controlling an active- high LED, the LED would be brighter during the first half of the graph, and dimmer over the second half.

As with the binary weighted DAC, the output voltage corresponds to the binary value on the port. The following example is valid for both R- 2R as well as Binary Weighted DACs: If the Vref is 5 V and there is a 4-bit binary value 1001 (decimal number 9) on the mi- crocontroller pins, we would expect the output voltage to be:

N Vout (Vref /(2 )) * (binary value of microcontroller output) Formula 2.4

For example: (5 V / 16 bits) * (9) 2.8125 V.

Pulse Width Modulation A common method for controlling the speed of a simple DC motor or the brightness of an LED is Pulse Width Modulation. Pulse Width Modulation works as a DAC by changing the duty cycle of an oscillating digital output as shown in Figure 2.14. In the case of an LED, the more time the duty cycle is HIGH, the brighter the LED. This method works in cases where the oscillating frequency is so fast that the resulting output seems smooth. The LED is actually turning on and off several times per second; however, the human eye can- not detect the inde pen dent flashes of the LED due to their speed. Motor speed can be con- trolled this way because the inertia of the spinning armature carries the motor forward through the moments when no power is applied.

2.4 INFRASTRUCTURE: POWER, CLOCK, AND RESET

2.4.1 Power Supply

When designing the power supply for an embedded system, the designer must determine how to power peripherals and whether or not they will use a separate supply. This decision will affect the overall design requirements of the power supply. This chapter only ad- dresses the power supply for the microprocessor itself. CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 29

Voltage and current ratings for the microprocessor can be found in the manufacturer’s datasheet for the chip, often under the title of Recommended Operating Conditions or Electrical Characteristics. Another section in the datasheet also shows Absolute Maximum Ratings, which should be considered but not confused with the recommended values. To be assured that the chip will operate as expected, a system should never be designed to operate too close to the absolute maximum or minimum power ratings. Fluc- tuations in the power supply may cause the values to go over the absolute maximum ratings of the chip, which can damage the microprocessor. The power supply should be designed with a safety factor to account for these fluctuations, hence the recommended values. Once the requirements are determined, the source of the power must be determined. Whether the design plugs into the wall or if it uses batteries will determine the type of power supply circuit. If the design uses mains power, then a standard design method for a power supply cir- cuit can be used. This design will require a transformer to drop the voltage to an acceptable range for a voltage regulator chip. Capacitors will be required to smooth out any ripple or noise. If batteries are to be used, then the type of battery (NiCad, NiMH, LiPo, etc.) must be selected based on the current rating each battery type can supply, and whether the design will need to be rechargeable. The length of time a battery will last can be calculated based on the capacity of the bat- tery and the amount of current the circuit uses using Formula 2.5.

Battery Life (hours) Capacity (amp- hours) / current (amps) Formula 2.5

An 800 mAh battery will power a device that draws 200 mA for;

800 mAh / 200 mA 4 hours

Putting batteries in parallel adds their current capacities. Putting them in series adds their voltages. For two batteries with each 1.5 V and 2000 mAh:

Series: 1.5 V 1.5 V 3.0 V at 2000 mAh Parallel: 2000 mAh 2000 mAh 1.5 V at 4000 mAh

If the batteries need to be recharged, then a battery charging circuit as well as battery level monitor will also need to be designed. Regardless of which batteries are chosen, a voltage regulator of some type is generally required. The use of linear or switch- mode voltage regulator integrated circuits (ICs) is a standard practice. 30 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

2.4.2 Clock Signal Generation

Microprocessors are synchronous circuits that require a clock to work. This clock allows data to be pushed through the stages of the instruction pipeline and helps the microproces- sor coordinate tasks. When selecting a clock generator, the microcontroller datasheet must be used. This datasheet gives the values of the different clocks that a particular micro- processor can accept. There are two major types of clock signal generators: those that work on purely electrical principles, and those that work on mechanical vibration (resonance of a quartz element). The signal generators for the electrical driven clock can be simple resistor- capacitor (RC) or inductor- capacitor (LC) circuits. Generally, these clocks aren’t very accurate on their own, and their design can become quite complicated when precision is required. Many microprocessors offer signal generators with an internal clock that consists of an RC circuit inside the chip, which can be configured. These clocks should not be used when precision is required. Figure 2.15 shows the connection of an RC oscillator to the clock input of a microprocessor.

19 VCC P3_3/TCIN/INI3/SSI00/CMP1_0 20 P3_4/SCS/SCA/CMP1_1 1 P3_5/SSCK/SCL/CMP1_2 2 P3_7/CNIR0/SSO/IXD1 P4_2/VREF 16 P4_5/INI0/HXD1 9

P4_6/XIN 6 R3 P4_7/XOUT 4 C1 MODE 8 RESET 3 VCC/AVCC 7 U3

GND Figure 2.15 RC clock generator.

Clock signal generators that are mechanically driven use a quartz crystal to produce a steady signal. These oscillators rely on the piezoelectric effect of the crystal. This method of clocking is accurate (around 30 parts per million or about 0.003% error), cheap, and widely available. Generally, two small load capacitors are required between each lead of the crystal and ground. The values of these capacitors are based on the crystal characteris- tics and are listed in the crystal’s datasheet. CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 31

19 P3_3/TCIN/INI3/SSI00/CMP1_0 20 P3_4/SCS/SCA/CMP1_1 1 P3_5/SSCK/SCL/CMP1_2 2 P3_7/CNIR0/SSO/IXD1

P4_2/VREF 16 C3

P4_5/INI0/HXD1 9 GND

P4_6/XIN 6 Y1 P4_7/XOUT 4

MODE 8

RESET 3 C2

VCC/AVCC 7 GND U4 Figure 2.16 Connection of a crystal clock generator chip.

Ceramic resonators are growing in popularity for use as a clock generator. The res- onators use a piezoelectric ceramic element that is not as accurate as quartz, yet more ac- curate than RC circuits. They also contain the appropriate load capacitors built in so they do not require any additional components to work. External clock generator integrated circuit chips can also be used. These clocks use a quartz or RC circuit as a resonant oscillator, but also contain an amplifier. The frequency can be changed by reprogramming the clock generator. The duty cycle is also selectable for use in cases where a 50 percent duty cycle cannot be used. These circuits are usually more expensive when compared to other oscillators.

2.4.3 Reset Circuit

Resetting a microprocessor starts the processor off in a predictable state. When a reset is detected, the microprocessor loads predefined values into the system control registers. These registers are useful in case of a catastrophic event, such as if the power supply were to drop below a certain threshold. All microprocessors designate a pin that is solely used for resetting the chip. A reset circuit controls this pin to assure a reset is valid if it is used. The requirements of a reset circuit is specific to the microprocessor being used and can be found in the manufacturer’s datasheet. Some microcontrollers contain reset logic inter- nally; however, the manufacturer’s datasheet should be consulted to make sure it meets the specifications for your application. Alternatively, reset controller chips can be used which contain all the parts necessary for the circuit. Even though they are generally more expen- sive in some cases, such as low- volume productions, it may be best to use reset controller chips. 32 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

2.5 RECAP

It should now be easier to understand how the embedded systems you encounter in your everyday life actually operate and communicate with the outside world. It should also be easier to break some of these systems down into their component parts, given the knowl- edge of sensor and actuator interfacing presented in this chapter.

2.6 REFERENCES

Kester, W. A., and Analog Devices, Inc. Data Conversion Handbook. Lawrence, KS: Newnes, 2005: pp. 153–159. Print. Kuphaldt, T. R. “Successive Approximation ADC,” in All about Circuits. Electronic publication. Accessed at http://www.allaboutcircuits.com/vol_4/chpt_13/6.html “The R2-R,” in Kuphaldt, T. R., All about Circuits. Electronic publication. Accessed at http://www. allaboutcircuits.com/vol_4/chpt_13/2.html

2.7 EXERCISES

1. Name ten devices that use an embedded system. 2. Write the C code to set port 4, bits 0 through 3 to be input pins, and port 4, bits 4 through 7 to be output pins. 3. Write the C code to read the data on port 4, bits 0 through 3 and write the read data to port 4, bits 4 through 7. 4. How long will a 2500 mAh battery last if the circuit using it runs at 600 mA? 5. You have a wireless whose current drain is 50 mA for one minute every one hour and 0.001 mA the rest of the time. I am using a single 5000 mAh cell as the power supply for this device. How long will my device run in hours, days, and years? 6. What are the different kinds of clock generators? Define their base technologies. 7. What resistor value should be used to connect an LED with a forward voltage of 3.1 volts and a forward current of 20 mA to the input pin of a microcontroller that outputs 5 volts? 8. Is it generally safe to connect a coil or motor directly to a microcontroller I/O pin? Why or why not? 9. Is it generally safe to connect a servo control input directly to a microcontroller I/O pin? Why or why not? CHAPTER 2 / CONCEPTS OF MICROCONTROLLERS 33

10. How many volts per ADC step are in a system with an ADC resolution of 10-bits, and a reference voltage of 3.3 V? 11. How many volts per ADC step are in a system with an ADC resolution of 12-bits, and a reference of 5 V? 12. An analog input has a voltage of 1.37860. What value will the ADC return if it has an 8-bit resolution and a reference of 4.25 volts? 13. An analog input has a voltage of 7.61245. What value will the ADC return if it has a 12-bit resolution and a reference of 10 volts? 14. Using a binary- weighted DAC, using 8 bits and a reference of 4.35 volts, what is the voltage of the output if the 8-bit value is 01011010?

Chapter Three

Organization and Architecture of the Renesas RX62N Microcontroller Board

3.1 LEARNING OBJECTIVES

In this chapter the reader will learn about:

Basic organization of computers Architecture of the Renesas RX62N board Endianness, data arrangement, and bus specification in RX62N CPU Date types, operating modes, and memory map of RX62N CPU

3.2 BASIC CONCEPTS

3.2.1 Introduction to Computer Organization & Architecture

A computer is a complex digital system. The best way to look at it is by looking at its hierar- chical nature. Hierarchical systems are best described as a series of subsystems that are inter- connected at various levels to form a complete computer system. At each level is a set of components whose behavior depends on the characteristics and functions of the next lower level. A designer focuses on structure and function within each level. The computer has four basic functions to perform (see Figure 3.1):

1. Data processing 2. Data storage 3. Data movement 4. Data control

Computers process data with the help of the data processing facility. During and after pro- cessing, storage is required for this data. During processing, the data needs a temporary or short term storage area. After processing, the data will be stored in long- term storage area. The Data Movement Block provides a data path between the outside environment and the computer. This block is also responsible for the data flow between various subcomponents

35 36 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Data storage facility

Data source Data Control & movement mechanism destination

Data processing facility

Figure 3.1 A generalized view: Building blocks of a computer.

within the computer. The Control Mechanism takes care of controlling and managing var- ious subcomponents and their interactions with each other.

Computers have four basic structural components (See Figure 3.2):

1. CPU: Processes the data and controls the operation of computer. 2. Memory: Stores data. 3. I/O: Moves the data between the computer and the external environment. 4. System Interconnection: Provides a mechanism for transferring data or communi- cating between components such as the CPU, main memory, and I/O.

I/O Memory

System interconnection

CPU

Figure 3.2 A top level view of a computer.

The (CPU) is the most complex component out of the four basic com ponents. The structure of the CPU is illustrated in Figure 3.3. The components that make up a CPU are: CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 37

1. : Controls the operation of the CPU. 2. Arithmetic and Logic Unit (ALU): Performs the computer’s data processing functions. 3. Registers: Provides internal storage for the CPU. They store ALU operands. 4. Interconnections: Provides a mechanism for transferring data or communicating between components such as the Control Unit, ALU, and registers.

Registers ALU

Interconnection

Control unit

Figure 3.3 A top level view of a CPU.

The IAS* computer, which is a prototype of general- purpose computers, is based on the stored- program concept. This idea was developed by John von Neumann and is known as the von Neumann Machine. As shown in Figure 3.4, the von Neumann machine has a main

CPU

ALU I/O Main memory

Control unit

Figure 3.4 Structure of a von Neumann machine.

* Institute for Advanced Study, Princeton, NJ 38 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

memory for storing the instructions and data the same as an IAS computer. It also has an ALU, which processes the binary data. A control unit decodes the instructions and forwards them to the ALU for execution. The Input/Output unit interacts with the external environ- ment and is controlled by the Control Unit.

3.2.2 Architecture of the Renesas RX62N

The RX62N microcontroller architecture has the following components:

1. CPU: The CPU contains two main modules or functions: CPU: It is a 32-bit RX CPU with maximum operating frequency of 100 MHz. Floating Point Unit (FPU): This unit is a single precision (32-bit) floating point unit which supports data types and floating- point exceptions in confor- mance with IEEE 754 standard. 2. Memory: The Memory contains three main modules: ROM: Its capacity is 512 Kbytes (max) and it supports two on-chip pro- gramming modes and one off- chip programming mode. RAM: Its capacity is 96 Kbytes (max). Data Flash: Its capacity is 32 Kbytes. 3. Clock generation circuit: The clock generation circuit consists of two circuits, namely a main clock oscillator and a sub clock oscillator. The CPU and other bus masters run in synchronization with the system clock (ICLK): 8 to 100 MHz; the peripheral modules run in synchronization with the peripheral module clock (PCLK): 8 to 50 MHz; while devices connected to the external bus run in syn- chronization with the external bus clock (BCLK): 8 to 50 MHz. 4. Reset: There are various reset sources available for different modules in the MCU such as pin reset, power- on reset, voltage- monitoring reset, watchdog timer reset, inde pen dent watchdog timer reset, and deep software standby reset. 5. Voltage detection circuit: When the voltage available on VCC falls below the voltage detection level (Vdet), an internal reset or internal interrupt is generated. 6. External bus extension: The external address space is divided into nine areas: CS0 to CS7 and SDCS. The capacity of each area from CS0 to CS7 is 16 Mbytes, and for SDCS the capacity is 128 Mbytes. A chip- select signal (CS0# to CS7#, SDCS#) can be output for each area. Each area is specifiable as an 8-, 16-, or 32-bit bus space; however, only 176-pin versions support 32-bit bus spaces. 7. Direct Memory Access (DMA): The DMA system consists of three different controllers which are explained below. The activation sources for all three con- trollers are software trigger, external interrupts, and interrupt requests from pe- ripheral functions: DMA controller: It has four channels and three transfer modes. These modes are normal transfer, repeat transfer, and block transfer. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 39

EXDMA controller: It has two channels and four transfer modes. These modes are normal transfer, repeat transfer, block transfer, and cluster transfer. Data transfer controller: It has three transfer modes. These modes are normal transfer, repeat transfer, and block transfer. 8. I/O ports: The main modules of I/O ports are programmable I/O ports. There are several I/O ports available on the 176-pin LFBGA, 145-pin TFLGA, 144-pin LQFP, 100-pin LQFP, and 85-pin TFLGA packages. 9. Timers: There are seven timer units available for controlling the sequence of an events or processes. Multi- function timer pulse unit: It has two units each supporting six channels and each channel has 16 bits. It provides time bases for the twelve 16-bit timer channels by way of up to 32 pulse- input/output lines and six pulse- input lines. Port output enable: It controls the high- impedance state of the MTU’s waveform output pins. Programmable pulse generator: It has two units, each supporting four groups and each group has four bits. It outputs MTU pulse as a trigger. The maxi- mum output possible is 32-bit pulse output. 8-bit timers: It has two units, each supporting two channels and each channel has 8 bits. The clock signal can be selected from seven internal clock signals (PCLK, PCLK/2, PCLK/8, PCLK/32, PCLK/64, PCLK/1024, and PCLK/8192) and one external clock signal. These are capable of outputting pulse trains with desired duty cycles or of PWM signals. Compare match timer: It has two units, each supporting two channels and each channel has 16 bits. The clock signal can be selected from four internal clock signals (PCLK/8, PCLK/32, PCLK/128, and PCLK/512). Watchdog timer: It has one channel of 8 bits. The clock signal can be selected from eight counter- input clock signals (PCLK/4, PCLK/64, PCLK/128, PCLK/512, PCLK/2048, PCLK/8192, PCLK/32768, and PCLK/131072). It is switchable between watchdog timer mode and interval timer mode. Indepen dent watchdog timer: It has one channel of 14 bits. It requires counter- input clock which is available from dedicated on- chip oscillator. 10. Communication function: For communicating with the outside world, the MCU provides several controllers: controller: The data rate it supports is either 10 or 100 Mbps. It sup- ports both full and half duplex modes. DMA controller for Ethernet: It supports transmission and reception FIFO of 2 Kbytes each. USB 2.0 host/function module: It includes a USB device controller and trans- ceiver for USB 2.0. It incorporates 2 Kbytes of RAM as a transfer buffer and supports data rate of 12 Mbps. 40 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Data Flash

WDT

IWDT

CRC

SCI 6 ch

USB (up to 2 ports)

RSPI (unit 0)

RSPI (unit 1)

CAN

Port 0 MTU 6 channels (unit 0)

MTU 6 channels (unit 1) Port 1

Port 2 POE

Port 3 PPG (unit 0)

PPG (unit 1) Port 4 Internal 1 to 6 main bus ETHERC Port 5 TMR 2 channels (unit 0)

TMR 2 channels (unit 1) Port 6 EDMAC

Port 7 CMT 2 channels (unit 0) ICU ROM Internal 2 main bus CMT 2 channels (unit 1) Port 8

DTC Port 9 RTC RAM Port A DMACA RIIC 2 channels

Port B 12-bit A/D converter 8 channels RX CPU MPU Port C 10-bit A/D converter 4 channels (unit 0)

Port D Clock 10-bit A/D converter 4 channels (unit 1) generation circuit Port E 10-bit D/A converter 2 channels

Port F Internal 1 main bus

EXDMAC External bus Port G BSC

Figure 3.5 Block diagram. Source: Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series, Renesas Electronics America, Inc., 2010, Figure 1.2, page 1–12. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 41

Serial communication interfaces: It has six channels and supports several serial communication modes such as asynchronous, clock synchronous, and smart- card interface. The desired baud rate is selected by on- chip baud rate generator. I2C bus interfaces: The communication formats supported are I2C bus for- mat/SMBus format and Master/slave selectable. CAN module: It supports one channel and 32 mailboxes. Serial peripheral interfaces: It supports two channels and MOSI (master out, slave in), MISO (master in, slave out), SSL (slave select), and RSPI clock (RSPCK) signals. They enable serial transfer through SPI operation (four lines) or clock- synchronous operation (three lines). It is capable of handling serial transfer as a master or slave. 11. A/D converter: MCU supports two A/D converters, specifically 12-bit and 10-bit. The conversion time is 1.0 ms per channel. The selectable operating modes are single mode and scan mode. 12. D/A converter: It supports two channels and 10-bit resolution. The output volt- age ranges from 0V to Vref. 13. CRC : CRC code generator generates code for arbitrary amount of data in 8-bit units. It is capable of selecting any of three generating polynomials:

X8 X2 X 1, X16 X15 X2 1, or X16 X12 X5 1.

One can also generate CRC codes for use with either LSB- first or MSB- first communications.

DEFINITION OF TERMS:

ETHERC: Ethernet Controller WDT: Watchdog timer

EDMAC: DMA controller for Ethernet controller IWDT: Inde pen dent watchdog timer

ICU: Interrupt control unit CRC: Cyclic redundancy check calculator

DTC: Data transfer controller MPU: Memory- protection unit

DMACA: DMA controller SCI: Serial communications interfaces

EXDMAC: EXDMA controller USB: USB 2.0 host/function module

BSC: Bus controller RSPI: Serial peripheral interfaces 42 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

DEFINITION OF TERMS:

CAN: CAN module TMR: 8-bit timer

MTU: Multi- function timer pulse unit CMT: Compare match timer

POE: Port output enable RTC: Real time clock

PPG: Programmable pulse generator RIIC: I2C bus interface

CPU The RX CPU being used in RX62N/RX621 group of MCU’s supports high- speed and high -performance. The instruction set architecture (ISA) of RX CPU has a variable- length instruction for- mat. The most commonly used instructions have been allocated shorter instruction lengths, making it possible to develop efficient programs that occupy less memory. The ISA of RX62N/RX621 group has ninety instructions, out of which seventy- three are basic instruc- tions, eight are floating- point operation instructions, and nine are DSP instructions. It achieves high- speed operation by executing instructions in a single cycle. It includes an in- ternal multiplier and divider for high speed multiplication and division. These operations now take less time and hence add to the efficiency of the processor. The RX CPU has a five- stage pipeline for processing instructions.

1. Instruction fetching stage 2. Instruction decoding stage 3. Execution stage 4. Memory access stage 5. Write- back stage

In cases where pipeline processing is drawn- out by memory access, subsequent operations may in fact be executed earlier. By adopting “out- of- order completion” of this kind, the ex- ecution of instructions is completed in fewer clock cycles.

Register Set The RX CPU has sixteen general- purpose registers, nine control registers, and one accu- mulator used for DSP instructions.

General-Purpose Registers (R0 to R15): The RX CPU has sixteen general- purpose reg- isters (R0 to R15). R0 can function as a stack pointer (SP) and R1 to R15 can be used as data or address registers. The stack pointer can be made to operate either as an Interrupt CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 43

TABLE 3.1 Features of CPU.

FEATURES DESCRIPTION High instruction execution rate One instruction in one clock cycle. Address space 4-Gbyte linear address space. Register set of the CPU There are sixteen 32-bit general purpose registers and nine 32-bit control registers. It has a 64-bit register . Basic instructions It has seventy- three basic instructions such as arithmetic/logic instructions, data- transfer instructions, branch instructions, bit- manipulation instructions, string- manipulation instructions, and system- manipulation instructions. Floating- point operation It is an optional function that can be used. There are eight such instructions operations. DSP instructions It is an optional function that can be used. There are nine such instructions. It supports 16-bit 16-bit multiplication and multiply- and- accumulate operations. It rounds the data in the accumulator. Addressing modes There are ten addressing modes. Five-stage pipeline It has a five- stage pipeline and allows out- of- order completion. Processor modes A supervisor mode and a user mode are supported. Floating- point operation unit It supports single-precision (32-bit) floating point operations and supports data types and exceptions in conformance with the IEEE 754 standard. Data arrangement The data can be selected either as little endian or big endian.

stack pointer (ISP) or user stack pointer (USP). The required stack pointer can be selected by the value of the stack pointer select bit (U) in the processor status word (PSW).

Control Registers: This CPU has the following nine control registers:

1. Interrupt stack pointer (ISP) 2. User stack pointer (USP) 44 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

General-purpose register

b31 b0

R0 (SP)

R1

R2

R3

R4

R5

R6

R7

R8

R9

R10

R11

R12

R13

R14

R15

Control register

b31 b0

ISP (interrupt stack pointer)

USP (User stack pointer)

INTB (Interrupt table register)

PC (Progam counter)

PSW (Process status word)

BPC (Backup PC)

BPSW (Backup PSW)

FINTV (Fast interrupt vector register)

FPSW (Floating point status word) DSP

b63 b16 b15 b0

ACC (Accumulator)

Figure 3.6 Register set of CPU. Source: Hardware Manual, Figure 2.1, page 2–2. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 45

3. Interrupt table register (INTB) 4. (PC) 5. Processor status word (PSW) 6. Backup PC (BPC) 7. Backup PSW (BPSW) 8. Fast interrupt vector register (FINTV) 9. Floating- point status word (FPSW)

The section below explains each control register briefly. It mainly focuses on the bit con- figuration and the functionality of each register.

1. Interrupt Stack Pointer (ISP)/User Stack Pointer (USP): After reset, all the bits of the register hold the value zero. The register is configured with 32 bits. The reg- ister can be made to operate either as Interrupt stack pointer (ISP) or user stack pointer (USP). The decision is made by the value of the stack pointer select bit (U) in the processor status word (PSW). Depending on the value of the bit, the stack pointer operates either as ISP or USP. Setting the value of ISP or USP to a multiple of four reduces the numbers of cycles required to execute interrupt se- quences and instructions. 2. Interrupt table register: The interrupt table register (INTB) points to an address where the relocatable vector table starts and is configured with 32 bits. After reset, value of the register is Undefined. 3. Program counter: Value after reset: Contents of addresses FFFFFFFCh to FFFFFFFFh. The program counter (PC) points to the address of the instruction that will be executed next. As soon as that instruction’s execution starts, PC value is in- cremented and it points to the next instruction. The PC is configured with 32 bits. 4. Processor Status Word (PSW):

b31 b30 b29 b28 b27 b26 b25 b24 b23 b22 b21 b20 b19 b18 b17 b16

— — — — IPL[2:0] IPL[2:0] IPL[2:0] IPL[2:0] — — — PM — — U I b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0

————————————O S Z C

Figure 3.7 PSW. Source: Hardware Manual, page 2–5. 46 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

After reset, all the bits of the register hold the value zero.

C Flag (Carry Flag): Whenever an operation results in a carry, borrow, or shift- out, this flag is set. The bit position of the carry flag is b0 and when it is set as 1, it means a carry has occurred. When it is 0, it means no carry has occurred. The sym- bol of the flag is C and it can be read and written by the CPU. Z Flag (Zero Flag): Whenever an operation results in a zero, this flag is set. The bit position of the zero flag is b1 and when it is set as 1, it means the result of an op- eration is zero. When it is 0, it means the result is non- zero. The symbol of this flag is Z and it can be read and written by the CPU. S Flag (Sign Flag): This flag indicates that the result of an operation was negative. The bit position of the sign flag is b2 and when it is set as 1, it means the result of an operation is negative. When it is 0, it means the result is non- negative. The sym- bol of this flag is S and it can be read and written by the CPU. O Flag (Overflow Flag): This flag indicates that an overflow occurred during an operation. Whenever an operation results in an overflow, this flag is set. The bit po- sition of the overflow flag is b3 and when it is set as 1, it means the result of an op- eration resulted in an overflow. When it is 0, it means there was no overflow. The symbol of this flag is O and it can be read and written by the CPU. I Bit (Interrupt Enable): Whenever this bit is set, an interrupt can occur. If this bit is disabled, then even if an interrupt occurs an exception will not be accepted. The bit position of interrupt enable is b16 and when it is set as 1, it means interrupt is enabled which means interrupt requests will be accepted. When it is 0, then inter- rupt requests will not be accepted. The symbol of this flag is I and it can be read and written by the CPU. U Bit (Stack Pointer Select): This bit specifies the stack pointer as either the ISP or USP. When an interrupt occurs and the interrupt enable bit is set to 1, an exception request is accepted. When this happens this bit is set to 0 and then this register acts as an interrupt stack pointer. When the processor mode is switched from supervi- sor mode to user mode, this bit is set to 1. Now the register acts as a user stack pointer. The bit position of the stack pointer select is b17. The symbol of this flag is U and it can be read and written by the CPU. PM Bit (Processor Mode Select): This bit specifies the processor mode. When an interrupt occurs and the interrupt enable bit is set to 1, an exception request is ac- cepted. When an exception is accepted, supervisor mode is selected and the bit is set as 0. When user mode is selected then this bit is selected as 1. The bit position of the processor mode select is b20. The symbol of this flag is PM and it can be read and written by the CPU. IPL [3Ϻ0] Bits (Processor Interrupt Priority Level): The IPL [3Ϻ0] bits specify the processor interrupt priority level. There are in total sixteen levels from CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 47 zero to fifteen, wherein priority level fifteen is the highest. When the priority level of a requested interrupt is higher than the processor interrupt priority level, the interrupt is enabled; and when the priority level of a requested inter- rupt is lower than the processor interrupt priority level then the interrupt request is not accepted. So if the IPL [3Ϻ0] bits is set to a level fifteen (Fh) then it will disable all interrupt requests. The only case where IPL [3Ϻ0] bits are set to level fifteen (Fh) is when a non- maskable interrupt is generated. When inter- rupts in general are generated, the bits are set to the priority levels of accepted interrupts. The bit positions of the processor interrupt priority level are from b27 to b24. The symbol of this flag is IPL [3Ϻ0] and it can be read and written by the CPU.

The following list shows sixteen priority levels. b27 b26 b25 b24 0 0 0 0: Priority level 0 (lowest) 0 0 0 1: Priority level 1 0 0 1 0: Priority level 2 0 0 1 1: Priority level 3 0 1 0 0: Priority level 4 0 1 0 1: Priority level 5 0 1 1 0: Priority level 6 0 1 1 1: Priority level 7 1 0 0 0: Priority level 8 1 0 0 1: Priority level 9 1 0 1 0: Priority level 10 1 0 1 1: Priority level 11 1 1 0 0: Priority level 12 1 1 0 1: Priority level 13 1 1 1 0: Priority level 14 1 1 1 1: Priority level 15 (highest)

Reserved Bits:

The following bits are reserved in the PSW register. These bits are always read as 0. The write value should be 0.

b15 to b4; b19, b18; b23 to b21; b31 to b28 48 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

5. Backup PC (BPC): After reset, the value of the register is Undefined. The register is configured with 32 bits. The Backup PC (BPC) register assists in speeding up the response to interrupts. After a fast interrupt has been generated, the contents of the program counter (PC) are saved in the Backup PC register. 6. Backup PSW (BPSW): After reset, the value of the register is Undefined. The register is configured with 32 bits. After a fast interrupt has been generated, the contents of the processor status word (PSW) are saved in the Backup Processor status word (BPSW) register. The allocation of bits in the BPSW register corre- sponds to that in the PSW register. 7. Fast Interrupt Vector Register (FINTV): After reset, the value of the register is Undefined. The register is configured with 32 bits. As the name suggests, this reg- ister assists in speeding up the response to interrupts. As soon as a fast interrupt is generated, the FINTV register specifies a branch destination address. 8. Floating- Point Status Word (FPSW):

b31 b30 b29 b28 b27 b26 b25 b24 b23 b22 b21 b20 b19 b18 b17 b16

FS FX FU FZ FO FV — — — — — — — — — —

b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0

— EX EU EZ EO EV — DN CE CX CU CZ CO CV RM[1:0] RM[1:0]

Figure 3.8 FPSW. Source: Hardware Manual, page 2–9.

After reset, all the bits of the register hold the value zero. The floating- point status word (FPSW) indicates the results of floating- point oper- ations. The register can be broadly classified into three types of bit configuration. One type is enable bits, another type is flag bits, and the third type is cause bits. So for every exception that occurs, there exists an enable bit (Ej), a flag status bit (Fj), and an exception cause bit (Cj). When an exception handling enable bit (Ej) is en- abled, which means when Ej 1, corresponding Cj flag indicates the cause. If the exception handling is masked (Ej 0), then the state of the Fj flag at the end of a series of instructions indicates whether an exception occurred. The Fj flag is the accumulation type flag where j represents X, U, Z, O, or V. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 49

TABLE 3.2 Description of FPSW

BIT SYMBOL BIT NAME DESCRIPTION R/W b1, b0 RM Floating- Point b1 b0 [1Ϻ0] Rounding- Mode 0 0 : Rounding to the nearest value. R/W Setting 0 1 : Rounding to 0. 1 0 : Rounding to ϱ. 1 1 : Rounding to ϱ. b2 CV Invalid Operation 0 : No invalid operation has been R/W*1 Cause Flag encountered. 1: Invalid operation has been encountered. b3 CO Overflow Cause 0 : No overflow has occurred. R/W*1 Flag 1: Overflow has occurred. b4 CZ Division- by- Zero 0 : No division- by- zero has occurred. R/W*1 Cause Flag 1: Division- by- zero Overflow has occurred. b5 CU Underflow Cause 0 : No underflow has occurred. R/W*1 Flag 1: Underflow has occurred. b6 CX Inexact Cause 0 : No inexact exception has been generated. R/W*1 Flag 1: Inexact exception has been generated. b7 CE Un- Implemented 0 : No un- implemented processing has been R/W*1 Processing Cause encountered. Flag 1: Un- implemented processing has been encountered.

Source: Hardware Manual, page 2–9.

Notes: 1. Writing 0 to the bit clears it. Writing 1 to the bit does not affect its value. 2. Positive denormalized numbers are treated as 0, negative denormalized numbers as 0. 3. When the EV bit is set to 0, the FV flag is enabled. 4. When the EO bit is set to 0, the FO flag is enabled. 5. When the EZ bit is set to 0, the FZ flag is enabled. 6. When the EU bit is set to 0, the FU flag is enabled. 7. When the EX bit is set to 0, the FX flag is enabled. 8. Once the bit has been set to 1, this value is retained until it is cleared to 0 by software.

(Continued) 50 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 3.2 Description of FPSW—Continued

BIT SYMBOL BIT NAME DESCRIPTION R/W b8 DN 0 Flush Bit of 0: A denormalized number is handled as a R/W Denormalized denormalized number. Number 1: A denormalized number is handled as 0.*2

b9 — (Reserved) This bit is always read as 0. The write value R/W should be 0. b10 EV Invalid Operation 0: Invalid operation exception is masked. R/W Exception Enable 1: Invalid operation exception is enabled. b11 EO Overflow 0: Overflow exception is masked. R/W Exception Enable 1: Overflow exception is enabled. b12 EZ Division- by- Zero 0: Division- by- zero exception is masked. R/W Exception Enable 1: Division- by- zero exception is enabled. b13 EU Underflow 0: Underflow exception is masked. R/W Exception Enable 1: Underflow exception is enabled. b14 EX Inexact Exception 0: Inexact exception is masked. R/W Enable 1: Inexact exception is enabled. b25 — (Reserved) These bits are always read as 0. The write R/W to b15 value should be 0. b26 FV*3 Invalid Operation 0: No invalid operation has been R/W Flag encountered. 1: Invalid operation has been encountered.*8 b27 FO*4 Overflow Flag 0: No overflow has occurred. R/W 1: Overflow has occurred.*8 b28 FZ*5 Division- by- Zero 0: No division- by- zero has occurred. R/W Flag 1: Division- by- zero has occurred.*8 b29 FU*6 Underflow Flag 0: No underflow has occurred. R/W 1: Underflow has occurred.*8 CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 51

TABLE 3.2 Description of FPSW—Continued

BIT SYMBOL BIT NAME DESCRIPTION R/W b30 FX*7 Inexact Flag 0: No 0: No inexact exception has been R/W generated. 1: Inexact exception has been generated.*8 b31 FS Floating- Point This bit reflects the logical OR of the FU, FZ, R/W Flag Summary FO, and FV flags.

RM [1Ϻ0] bits: These bits specify the floating- point rounding- mode. Explanation of Floating- Point Rounding Modes ▫ Rounding to the nearest value (the default behavior): An inaccurate result is rounded to the available value that is closest to the re- sult which would be obtained with an infinite number of digits. If two avail- able values are equally close, rounding is done to the even alternative. ▫ Rounding towards 0: An inaccurate result is rounded to the smallest available absolute value. ▫ Rounding towards ϱ: An inaccurate result is rounded to the nearest available value in the direction of positive infinity. ▫ Rounding towards ϱ: An inaccurate result is rounded to the nearest available value in the direction of negative infinity.

The default mode is to round off to the nearest value in order to return the most accurate value. The other modes, such as rounding towards 0, rounding towards ϱ, and rounding towards ϱ, are used to ensure precision.

Cj (Cause flag): The five floating- point exceptions based on IEEE 754 standard are overflow, underflow, inexact, division- by- zero, and invalid operation. The bit is set to 1 until and unless FPU instruction is executed. After that the bit is set to 0. When instructions like MVTC and POPC instructions write 0 to the bit, the bit is set to 0; and when they write 1, the bit retains the previous value. DN Flag: When this bit is set to 0, a denormalized number is handled as a denormal- ized number; and when this bit is set to 1, a denormalized number is handled as 0. Ej (Exception handle bit): When any of the five floating- point exceptions is gener- ated by the FPU instruction, this bit then decides whether the CPU will handle the exception or not. When the bit is set to 0, the exception handling is masked and the 52 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

CPU will not handle the exception; when the bit is set to 1, the exception handling is enabled and CPU will handle the exception. Fj: While the exception handling enable bit (Ej) is 0 (exception handling is masked), if any of the five floating- point exceptions specified in the IEEE 754 standard is generated, the corresponding bit is set to 1. When Ej is 1 (exception handling is en- abled), the flag retains its value. When the corresponding flag is set to 1, it remains 1 until it is cleared to 0 by software. (Accumulation flag) FS bit (Floating- point flag summary bit): This bit reflects the logical OR of the FU, FZ, FO, and FV flags.

Accumulator (ACC):

Range for reading by MVFACMI b63 b48 b47 b32 b31 b16 b15 b0

Range for reading and writing by Range for reading by MVTACLO MVTACHI and MVFACHI

Figure 3.9 ACC. Source: Hardware Manual, page 2–12.

This register is configured with 64 bits and is mainly used for DSP instructions. It is also used for the multiply and multiply- and- accumulate instructions, where the prior value in the accumulator is modified by the execution of instruction. The examples of such instruc- tions are EMUL, EMULU, FMUL, MUL, and RMPA. To write to the accumulator, MVTACHI and MVTACLO instructions are used. These instructions write data to the higher- order 32 bits (bits 63 to 32) and the lower- order 32 bits (bits 31 to 0). To read from the accumulator, MVFACHI and MVFACMI instructions are used. The MVFACHI and MVFACMI instructions read data from the higher- order 32 bits (bits 63 to 32) and the middle- order 32 bits (bits 47 to 16), of the accumulator.

3.2.3 Data Types

The RX CPU supports four types of data: integer, floating- point, bit, and string. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 53

1. Integer:

b7 b0 Signed byte (8-bit) Integer b7 b0 Unsigned byte (8-bit) Integer b15 b0 Signed word (16-bit) Integer b15 b0 Unsigned word (16-bit) Integer b31 b0 Signed longword (32-bit) Integer b31 b0 Unsigned longword (32-bit) Integer

Figure 3.10 Integer. Source: Hardware Manual, Figure 2.2, page 2–14.

2. Floating-Point: The IEEE standard defines four different types of precision for floating point operations. They are single precision, double precision, single- extended precision, and double- extended precision. Most of the floating- point hardware follows IEEE 754 standard’s single and double precision for floating point computations. RX family supports single precision floating- point computation. There are in total eight operations that can be done with such floating- point operands: FADD, FCMP, FDIV, FMUL, FSUB, FTOI, ITOF, and ROUND. b31 b0

S

E F

Figure 3.11 Floating point. Source: Hardware Manual, Figure 2.3, page 2–14.

Single- precision floating- point S: Sign (1 bit) E: Exponent (8 bits) F: Mantissa (23 bits)

Value (1)S (1 F 223) 2(E127) 54 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The floating- point format supports different values for exponent and mantissa. When the value of E is between 0 and 255 (i.e., 0 E 255), then the number is considered as a normal number. For a signed zero number, the value of E and F should be 0. For denormalized numbers, the value of E is 0 and the value of F is greater than 0. When the value of E is 255 and the value of F is 0, then the number is considered as infinity. When the value of E is 255 and the value of F is greater than 0, then the number is not a number.

NOTE: The number is treated as 0 when the DN bit in FPSW is 1. When the DN bit is 0, an unimplemented processing exception is generated.

3. Bitwise Operations: There are five different types of bit- manipulation instructions for bitwise opera- tions: BCLR, BMCnd, BNOT, BSET, and BTST. The register is a 32-bit register so the bits range from 0 to 31. In the Figure 3.12, notation looks like “#bit, Rn”; which means ‘corresponding bit in register n.’ Here the value of ‘n’ ranges from 0 to 15. So notation “#30, R1” suggests 30th bit in R1 register. For bitwise opera- tion in memory, the notation is “#bit, mem.” For instance, #2, [R2] means address [R2] and bit 2. The bit value ranges from 0 to 7. The addressing modes available to specify addresses are register indirect and register relative.

Register b31 b0 #bit, Rn Example #30, R1 (Bit:31 to 0, n:0 to 15) (register R1, bit 30

Memory

Example #bit, mem #2, [R2] (Bit:7 to 0) (address [R2], bit 2) b7 b0

Figure 3.12 Bitwise Operation. Source: Hardware Manual, Figure 2.4, page 2–15.

4. Strings: The string data type consists of an arbitrary number of consecutive byte (8-bit), word (16-bit), or longword (32-bit) units. To work with strings there are seven string manipulation instructions: SCMPU, SMOVB, SMOVF, SMOVU, SSTR, SUNTIL, and SWHILE. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 55

String of byte (8-bit) data

8

String of word (16-bit) data

16

String of longword (32-bit) data

32

Figure 3.13 Strings. Source: Hardware Manual, Figure 2.5, page 2–15.

3.2.4 Endianness

Endianness refers to the arrangement of sub- units such as bytes within a longer data word, while storing it in memory. Basically there are two types of endianness: big endianness and little endianness.

Big endian: The most significant byte (MSB) is stored at the lowest byte address of the memory. Little endian: The least significant byte (LSB) is stored at the lowest address of the memory.

As arrangements of bytes, the RX62N/RX621 Group supports both big endian, where the most significant byte (MSB) is stored at the lowest byte address of the memory; and little endian, where the least significant byte (LSB) is stored at the lowest address of the mem- ory. For the RX CPU, instructions are always little endian, but the way the user wants to handle data decides endianness. Therefore, if a wants to change the endian- ness, it can be changed. 56 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Register

AB CD EF 12 Memory

A AB

A 1 1 CD

A 1 2 EF

A 1 3 12

Big endian

Register

AB CD EF 12 Memory

A 12

A 1 EF

A 2 CD

A 3 AB

Little endian

Figure 3.14 Endianness: Arrangement in memory.

3.2.5 Data Arrangement

1. Data Arrangement in Registers: Figure 3.15 shows the relation between the sizes of registers and bit numbers. 2. Data Arrangement in Memory: Data in memory have three sizes: byte (8-bit), word (16-bit), and longword (32-bit). According to the requirement, the data arrangement can be selected as lit- tle or big endian. Figure 3.16 shows the arrangement of data in memory. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 57

b7 b0 Byte (8-bit) data b15 b0 Word (16-bit) data b31 b0 Longword (32-bit) data MSB LSB

Figure 3.15 Data arrangement in registers. Source: Hardware Manual, Figure 2.6, page 2–21.

Data type Address Little endian Big endian

b7 b0 b7 b0

1-bit data Address L 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0

Byte data Address L MSB LSB MSB LSB

Address M LSB MSB Word data Address M 1 MSB LSB

Address N LSB MSB Address N 1 Longword data Address N 2 Address N 3 MSB LSB

Figure 3.16 Data arrangement in memory. Source: Hardware Manual, Figure 2.7, page 2–21.

3.2.6 Bus Specification

In total, there are five different types of buses in RX62N microcontroller board. The fol- lowing section lists various bus specifications. It describes whether the bus operates in syn- chronization with a clock or not.

1. CPU bus: Instruction bus: It is connected to the CPU and to the on- chip memory such as on- chip RAM and on- chip ROM. It operates in synchronization with the system clock (ICLK). 58 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Operand bus: It is connected to the CPU and to the on- chip memory such as on- chip RAM and on- chip ROM. It operates in synchronization with the system clock (ICLK). 2. Memory bus: Memory bus 1: It is connected to on- chip RAM. Memory bus 2: It is connected to on- chip RAM. 3. Internal main bus: Internal main bus 1: It is connected to the CPU and operates in synchroniza- tion with the system clock (ICLK). Internal main bus 2: It is connected to the DMACA, DTC, and EDMAC. Also, it is connected to on- chip memory, namely on- chip RAM and on- chip ROM. It operates in synchronization with the system clock (ICLK). 4. Internal peripheral bus: Internal peripheral bus 1: It is connected to peripheral modules and operates in synchronization with the system clock (ICLK). Internal peripheral bus 2: It is connected to peripheral modules, on- chip ROM (for programming and erasure), and data- flash memory. It operates in synchro- nization with the peripheral- module clock (PCLK). Internal peripheral bus 3: It is connected to peripheral modules (USB) and it operates in synchronization with the peripheral- module clock (PCLK). Internal peripheral bus 4: It is connected to peripheral modules (EDMAC and ETHERC) and it operates in synchronization with the system clock (ICLK). Internal peripheral bus 5: It is connected to peripheral modules and it operates in synchronization with the system clock (ICLK). Internal peripheral bus 6: It is connected to on- chip ROM (for programming and erasure) and data- flash memory. It operates in synchronization with the peripheral- module clock (PCLK). 5. External bus: CS area: It is connected to the external devices and it operates in synchroniza- tion with the external- bus clock (BCLK). External bus SDRAM area: It is connected to the SDRAM and it operates in synchronization with the SDRAM clock (SDCLK).

Description of Buses 1. CPU Buses: The CPU buses consists of instruction and operand buses, which are connected to internal main bus 1 as shown in Figure 3.17. The instruction bus is used to fetch in- structions for the CPU, while the operand bus is used for operand access. These buses are connected to on- chip RAM and on- chip ROM and therefore the CPU can directly access these areas. Direct access refers to that access which is not by way of internal main bus 1. In contrast to access through internal main bus 1, direct ac- CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 59

cess allows only reading the on- chip ROM by the CPU. Programming and erasure are handled by way of an internal peripheral bus. Internal main bus 1 handles bus requests for instruction fetching and operand access. The operand access has a higher priority than instruction fetching. The bus- access operations can proceed si- multaneously, irrespective of whether the instruction fetching and operand access need different buses or not. For example, parallel access to an on- chip ROM and on- chip RAM or to an on- chip ROM and external space is possible. 2. Memory bus: There are two memory buses; namely memory bus 1 and memory bus 2. On- chip RAM is connected to memory bus 1 and on- chip ROM is connected to memory bus 2. Bus requests from the CPU buses and internal main bus 2 are handled through memory buses 1 and 2. Internal memory bus 2 has a higher priority than the CPU bus. 3. Internal main bus: The internal main bus consists of two buses; one is internal main bus 1, which is used by the CPU; and internal main bus 2, which is used by the other bus- master modules such as the DTC, DMACA, and EDMAC. Bus requests for instruction fetching and operand access are handled through internal main bus 1. Operand ac- cess has higher priority than instruction fetching. Bus requests from the DTC, DMACA, and EDMAC are handled by internal main bus 2. The order of priority is EDMAC, DMACA, and then DTC, as shown in Table 3.3. The bus access opera- tions can proceed simultaneously. For instance, if the CPU and another bus master are requesting access to different buses; in this case, the respective bus- access op- erations will take place simultaneously. Internal main bus 2 has a higher priority than internal main bus 1. However, when the CPU executes the XCHG instruction, the only request that can access bus is the request from CPU, until and unless data transfer for the XCHG instruction is completed. If data transfer for the XCHG is completed, requests for bus access from other masters will be accepted. Further- more, during reading and writing back of control information, the only bus master which has access is DTC. Bus requests from other masters are not accepted.

TABLE 3.3 Priority of Bus Masters.

PRIORITY BUS MASTER High EDMAC DMACA DTC CPU Low

Source: Hardware Manual, Table 12.3, page 12–5. 60 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

ICLK Synchronization

CPU

Instruction bus

Operation bus

On- On- chip chip RAM ROM Bus error monitoring section

Internal main bus 1

DTC DMACA(m) EDMAC

Internal main bus 2

1* PCLK Synchronisation 2* 3* 4*

EXD D MAC Peripheral M Peripheral Peripheral Peripheral Peripheral On-chip Data Flash module A module module module module ROM Memory C A BCLK Synchronisation

External bus control

Write buffer

SDCLK BCLK 1: Internal peripheral bus 1 Synchronisation Synchronisation 2: Internal peripheral buses 2 and 3 3: Internal peripheral buses 4 and 5 4: Internal peripheral bus 6

SDRMAC CSC

External bus

Figure 3.17 Bus Configuration. Source: Hardware Manual, Figure 12.1, page 12–2. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 61

NOTES: BCLK (external- bus clock): The maximum frequency of the clock is 100 MHz. The CSC (CS area controller) and the EXDMAC operate in synchronization with the BCLK. SDCLK (SDRAM clock): The maximum frequency of the clock is 50 MHz. The SDRAMC (SDRAM area controller) operates in synchronization with the SDCLK. BCLK: The frequency is the same as the BCLK as default. 1/2 BCLK can be supplied by setting the BCLK pin output select bit (BCLKDIV) in the system clock control register (SCKCR). The BCLK and the SDCLK should be operated with the same frequency (50 MHz as a maximum) when the SDRAM is in use.

4. Internal peripheral buses: The following table lists various peripheral buses and the peripheral modules to which they are connected:

TABLE 3.4 Connection of Peripheral Modules.

TYPES OF BUS PERIPHERAL MODULES Internal peripheral bus 1 DMACA EXDMAC Interrupt controller Bus error monitoring section Internal peripheral bus 2 Peripheral modules other than those connected to internal peripheral buses 1, 3, 4, and 5 Internal peripheral bus 3 USB Internal peripheral bus 4 EDMAC and ETHERC Internal peripheral bus 5 Reserved area Internal peripheral bus 6 Data flash memory

Source: Hardware Manual, Table 12.4, page 12–5.

Bus mastership requests from the CPU (internal main bus 1) and other bus masters (internal main bus 2) are handled through internal peripheral buses 1 to 6. Internal main bus 2 has higher priority than internal main bus 1. 62 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

5. External Bus: This section lists various specifications of the external bus. Bus masters such as in- ternal main bus 1, internal main bus 2, and EXDMAC keep requesting bus master- ship. In such a scenario, the external bus controller arbitrates various requests and decides the master. The order of priority determines which bus master will handle mastership first, if all of them request at the same time. The order of priority is EXDMAC, internal main bus 2, and then internal main bus 1. The various areas of external bus and their specifications are as follows: External address space: An external address space is divided into two specific areas. One area is fur- ther divided into eight areas (CS0 to CS7) and the other area is the SDRAM area (SDCS). This is how external address space is or ga nized for better man- agement. For each area the chip select signals can be output, an 8/16/32-bit bus space can be selected, and an endian mode can be specified. CS area controller: The CS area controller deals with the read and write controls associated with CS areas (CS0 to CS7). In the controller, recovery cycles can be inserted. In read recovery up to fifteen cycles, and in the write recovery up to fifteen cycles can be inserted. The cycle wait function can wait up to thirty- one cycles. In the page access, wait function takes up to seven cycles. The controller uses wait control to set up timing of assertion and negation for chip- select signals (CS0# to CS7#) and for read signal (RD#) and write signals (WR0# to WR3#). It also sets up the timing with which data output starts and ends. It has two write ac- cess modes; one is single write strobe mode and other is byte strobe mode. SDRAM area controller: The SDRAM Controller is a part of external bus. Several features are available in the SDRAM area controller. The SDRAM controller is capable of self- refresh and auto-refresh. It supports multiplexing output of row address/column address (8, 9, 10, or 11 bits). The CAS latency can be specified from one to three cycles. Write buffer function: Write buffer function is used when there is data to be written to a buffer. When write data from the bus master has been written to the write buffer, the write access by the bus master is completed. Frequency: As mentioned earlier, the CS area controller (CSC) operates in synchroniza- tion with the external- bus clock (BCLK), while the SDRAM area controller (SDRAMC) operates in synchronization with the SDRAM clock (SDCLK).

NOTE: When different bus- master modules request access to different slave modules, then all of the different masters can be given access to different peripheral modules. This is known as paral- lel operation as all of the accesses are taking place at the same time. Consider the case where CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 63 the CPU is fetching an instruction from on- chip ROM and at the same time an operand is needed from on- chip RAM. What will happen in such a scenario? Here the master module CPU wants to gain access to on- chip ROM as well as on- chip RAM. The DMACA simulta- neously handles transfer between a peripheral bus and the external bus. In this example, the CPU uses instruction and operand buses for simultaneous access to on- chip ROM and RAM, respectively. So, with the help of instruction bus and operand bus, the CPU is able to fetch in- structions and access an operand, both at the same time. Moreover, the DMACA simultane- ously uses internal main bus 2 or the external bus to achieve parallel operation.

Bus Error Monitoring Section Whenever an error occurs in a bus, the bus- error monitoring system comes into play. It monitors each individual area and whenever it detects an error, it generates an interrupt. Usually, two types of error occur in a bus, illegal address access error and timeout error. Whenever the bus- error monitoring system detects illegal access to an area, an illegal ad- dress access error is said to have occurred. Similarly, when the bus- error monitoring sys- tem detects any bus- access operation that is not being completed within 768 cycles, then a time out error is said to have occurred.

Types of Bus Error As said earlier, there are mainly two types of error that can occur in a bus. The following section explains them briefly.

1. Illegal Address Access: To detect illegal access to an area, first of all a bit in a register has to be set up. The bit is called an illegal address access detection enable bit (IGAEN) and is usually set to 1 in the bus error monitoring enable register (BEREN). If that happens, ac- cesses of the following types lead to illegal address access errors: Access to those external areas for which operation has been disabled. The space area is disabled by setting up the value of registers CSnCNT.EXENB and SDCCR.EXENB as ‘0.’ With respect to areas other than those described above, access to illegal ad- dress ranges. 2. Time out: To detect time out error, first of all a bit in a register has to be set up. The bit is called a timeout detection enable bit (TOEN) and is usually set to 1 in the bus er- ror monitoring enable register (BEREN). After setting up that bit, if any bus access is not completed within 768 cycles, then it leads to a timeout error. In the RX62N/RX621, a timeout error occurs only for access to CS areas. During access to any of the CS areas from CS0 to CS7, it might lead to timeout error if bus access is not completed (the WAIT# signal is not negated) within 768 external bus clock 64 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

(BCLK) cycles from the start of the access. When timeout error occurs, accesses to bus are prohibited. In fact, accesses from the bus master are rejected for 256 BCLK cycles. If a single bus request from bus master also contains generated multiple external bus accesses, then the bus access cannot be stopped by the time- out. At this time, timeout errors may occur repeatedly. The CPU is aware of the er- rors that are occurring in the bus section and whenever an error occurs the CPU is informed. The CPU does not poll for errors on the bus. Whenever there is an error, an interrupt is generated. The interrupt generated gives an indication to CPU that there is an error in the bus section. The IEN register in the ICU decides whether to generate an interrupt in the case of a bus error or not.

3.3 BASIC EXAMPLES

EXAMPLE 1

What is the difference between computer organization and architecture? A computer’s architecture is its abstract model and is the programmer’s view in terms of instructions, addressing modes, and registers. A computer’s organization expresses the realization of the architecture. Architecture describes what the computer does and organi- zation describes how it does it. The architecture is like a blue print which mentions all the components and how they are connected, while the organization is an implementation of that blue print. Each vendor will have their own version of organization, and their own way of implementing the blue print. computer organization (what the machine looks like) instruc- tion set architecture (how you talk to the machine).

EXAMPLE 2

What is the difference between a microcontroller and a microprocessor? The main difference is that a microcontroller incorporates features of a microprocessor (CPU, ALU, Registers) along with the presence of added features like RAM, ROM, I/O ports, counter, etc. In addition, microcontrollers are usually designed to perform a small set of spe- cific functions; for example, the case of a which performs a small set of signal processing functions, whereas microprocessors tend to be designed to perform a wider set of general purpose functions. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 65

EXAMPLE 3

1. Can you, the user, store a value at memory location 0008 C067h? Why or why not? No, because address 0008 C067h corresponds to the memory area that stores special func- tion registers. In the RAM, the memory addresses from 0000 0000h to 0001 8000h are re- served for special function registers and cannot be used by the user to save his data. 2. What area of Flash is available for the user program on the RX62N board? List the range of addresses and the exact size in bytes (not Kbytes). In RX62N, the memory addresses of the on- chip ROM or data flash ranges from 0010 0000h to 0010 8000h.The total number of bytes available for user program is 32768 bytes.

3.4 ADVANCED CONCEPTS

3.4.1 Pipelining

Pipelining is an important technique used to make fast CPUs. It is implemented to increase the instruction throughput (i.e., the number of instructions that can be executed in a unit of time) but it does not reduce the time taken to execute an individual instruction. The execu- tion time of an individual instruction actually increases due to overhead caused by imple- menting the pipeline. The overhead in the pipeline is from register delay (setup time) and clock skew. Improvement in instruction throughput means programs run faster and have lower execution time, though no single instruction runs faster. The perfor mance will be re- duced if there is an imbalance between the stages. For instance, if execution stage takes more time than memory access stage or, in other words, an instruction stays in execution stage longer than memory access stage, then the perfor mance degrades because the clock cannot be faster than the slowest stage. Pipelining would provide optimal CPU per for- mance CPU if every instruction was indepen dent of every other instruction but, unfortu- nately, most of the instructions are de pen dent on each other. The RX CPU is based on the classical five- stage pipeline. During the execution of an instruction, it is converted into various micro- operations. The five stages of the pipeline are described below. Only the Instruction Fetch (IF) stage is executed in the terms of instruc- tions while others are executed in terms of micro- operations. The operation of pipeline and respective stages is described as follows:

1. Instruction Fetch Stage (IF Stage): In the IF stage, the CPU fetches 32/64 bit instructions from the memory. The Program counter (PC) fetches the instruction and then the PC is incremented by 66 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

4 or 8 since the instructions are 4 or 8 bytes long. The RX CPU has four 8-byte in- struction queues. The RX CPU keep fetching instructions until the queues are filled. 2. Instruction Decode Stage (ID Stage): The main function of this stage is decoding. Instructions are decoded in the ID stage and are converted into micro- operations. In addition to the decoding of the instructions, the values of registers (operands) are also read from the register file. If the value of a register needed is the result of the preceding instruction, then the CPU executes a bypass process (BYP). This process is also called forwarding. 3. Execution Stage (E Stage): Two main types of calculation take place in this stage. One is normal ALU opera- tions and the other is memory address calculations for memory access stage. Normal ALU operations are register to register operations which includes add, subtract, compare, and logical operations. The other calculations are memory ref- erence operations which includes all load operations from the memory. During the execute stage, the ALU adds the two arguments; i.e., a register and a constant off- set given in the instruction to produce an address by the end of this stage. 4. Memory Access (M Stage): Memory is accessed either for fetching an operand from the memory or storing an operand in the memory. The address of an operand is calculated in the precious ex- ecution stage. This stage (M Stage) is divided into two sub- stages, M1 and M2. The RX CPU enables respective memory accesses for M1 and M2. M1 stage (memory- access stage 1): In this sub- stage, operand memory accesses OA1 and OA2 are processed. A store operation is processed when a write request is received via the bus. During the Load operation, the operation proceeds to the M2 stage only when a read request is received via the bus. In addition to the request, if the load data is received at the same timing (i.e., no- wait memory access), then the opera- tion proceeds to the WB stage. M2 stage (memory- access stage 2): In this sub- stage operand memory access OA2 is processed. In this sub- stage the CPU waits for the load data, and once received the operation proceeds to the WB stage. 5. Write- back stage (WB stage): The last stage of the pipeline writes data into the register file. In this stage, the op- eration result calculated in the execution stage and the data read from memory in the memory access stage are written to the register (RW). The data read from memory and the other type of data, such as the operation result, can be written to the register in the same clock cycles. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 67

One cycle M stage Pipeline stage IF stage D stage E stage M1 stage M2 stage WB stage

BYP Execution processing IF DEC OP RW OA1 RF OA2

Figure 3.18 Pipeline Configuration and its Operation. Source: Hardware Manual, Figure 2.10, page 2–26.

Pipeline Basic Operation Ideally, each pipeline stage should take the same amount of time to process the instruction. Unfortunately, ideal conditions are hard to achieve and hence stalls are created in the pipeline and perfor mance is degraded. The slowest stage which takes the maximum amount of time becomes the bottleneck. Once the pipeline is filled, each instruction will come out of the pipeline after one clock cycle. In a non- pipelined processor, if there are n tasks to handle and each task takes m clock period , then total time taken to process n tasks is n*m clock periods. In a pipelined processor, when it has m stages, ideally n tasks will take (m (n 1)) clock periods. So, if we calculate the speed- up gained in this sce- nario, it will be n * m/{m (n 1)}. Hazards prevent the next instruction from executing at the next cycle. They reduce the perfor mance and speed- up gained by pipelining. There are three types of hazards:

1. Structural hazard: It arises from resource conflicts when the hardware is not capable of supporting multiple instructions simultaneously in an overlapped manner. 2. Data hazard: It arises when an instruction depends on the result of previous instruction. For in- stance, in the pipeline, an instruction I 1 depending on the result of instruction I will cause a data hazard because one of the operands of the instruction I 1 is the result of instruction I. In such a case, instruction I 1 cannot execute, as the data is not available. 3. Control hazard: It arises from pipelining of branches and other instructions that change the pro- gram counter; i.e., when a set of instructions are control de pen dent on the branch condition, and what value the PC will take is not known until the execution stage or decode stage. 68 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Hazards in the pipeline cause stalls in the pipeline which simply means stalling the pipeline. Allowing some instructions to proceed and delaying other instructions helps in avoiding the stall. When an instruction is stalled, the instructions issued (from the instruction stream) later than the stalled one are also stalled. And the ones which were issued earlier than the stalled instruction are allowed to proceed, so that the hazard goes away with time. The following figures show typical cases that can occur in the pipeline. (In the follow- ing section, the abbreviation “mop” stands for micro- operations.)

1. Pipeline flow with stalls: In Figure 3.19 the first instruction is a division operation and its execution stage takes more than one cycle to complete. The other instructions, such as the ‘ADD’ instruc- tion, if allowed to execute will complete execution before the division operation. Since out of order completion might create a problem, the pipeline has to be stalled.

DIV R1, R2 IF D E E ...... E WB (mop) div

ADD R3, R4 IF D stall ...... stall E WB (mop) add

ADD R5, R6 IF stall ...... stall D E WB (mop) add

Figure 3.19 Stalls created due to an Instruction that requires multiple cycles to execute in the E Stage. Source: Hardware Manual, Figure 2.20, page 2–32.

In Figure 3.20, the first instruction is a load instruction which takes more than one cycle to complete its operand access from memory. Again since in- order comple- tion is important, therefore the later instructions have to be stalled and no more fetching of instructions takes place. As soon as the memory access completes, the pipeline is no longer stalled and instructions are passed to their next stage.

Other than no-wait memory access

MOV [R1], R2 IF D E MM ...... M WB (mop) load

MOV [R3], R4 IF D E stall ...... stall M WB (mop) load

ADD R5, R6 IF D stall ...... stall E WB (mop) add

Figure 3.20 Stalls created due to an Instruction that requires more than one cycle for its operand access to execute in the E stage. Source: Hardware Manual, Figure 2.21, page 2–32. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 69

Figure 3.21 shows how control dependencies in the code cause stalls in the pipeline. For instance, consider a simple “if statement.”

Branch instruction is executed

Branch IF D E (mop) jump instruction Branch penalty Two cycles

IF D E WB

Figure 3.21 Stalls created due to control dependency on a Branch Instruction. Source: Hard- ware Manual, Figure 2.22, page 2–33.

Code0 ...... if(Cond1){ Code1 } Code2 ......

Code1 is control depen dent on cond1. Code1 will only execute if Cond1 becomes true or is satisfied. Code2 is also control depen dent on Cond1. When this code is converted into assembly code, a branch instruction such as jump executes. As the branch instruction goes into the instruction decode stage, it’s time to fetch the next instruction. But which instruction should be fetched, Code1 or Code2? Since the decision is de pen dent on cond1 (branch instruction), and the result of the branch instruction will be available after execute stage (E stage), therefore the pipeline has to be stalled for two cycles. By the end of two cycles the address of next instruc- tion is available in the program counter (PC), and then the next instruction will be fetched. 70 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

2. Pipeline flow with no stall: Forwarding/Bypass Process: Forwarding is a simple hardware technique used to minimize data hazard stalls. It is also called a bypass process. The result of an ‘ADD’ instruction is not needed until decode stage, or in extreme cases until execution stage. When the D stage of ‘SUB’ instruction needs the operand, it is not available since the result of ‘ADD’ instruction is not yet written into register, so a stall is created. If the result can be moved from the execution stage of ‘ADD’ instruction to the start of the execution stage of the ‘SUB’ instruction, then the need for a stall can be avoided. To achieve this, ‘ALU result’ from both the E stage and M stage is fed back to the ALU in- puts. If the forwarding hardware detects that the previous ALU operation gener- ated a result which is going to be one of the inputs of a current ALU operation, then the control logic selects the forwarded result as the ALU input instead of reading from the register file.

ADD R1, R2 IF D E E (mop) div

Bypass process

SUB R3, R2 IF D E WB (mop) sub

Figure 3.22 Forwarding done to reduce the number of stalls. Source: Hardware Manual, Figure 2.24, page 2–33.

When WB stages of two instructions are overlapped: In this example, the first instruction is a ‘MOV’ instruction and the other instruc- tion is an ‘ADD’ instruction. In Figure 3.23, the ADD instruction is more likely to create a structural hazard in the WB stage. But this does not happen; instead, both cause a write operation in the same cycle. In the first half of the cycle ‘MOV’ in- struction writes and in the second half of the cycle ‘ADD’ instruction writes into the register.

Mov [R1], R2 IF D E M WB (mop) load Executed at the same timing even when the WB stages are ADD R5, R3 IF D E WB (mop) add overlapped

Figure 3.23 When WB Stages of two instructions are overlapped. Source: Hardware Manual, Fig- ure 2.25, page 2–33. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 71

When subsequent instructions write to the same register before the end of memory load: In the following example, even when the subsequent instruction writes to the same register before the end of memory load the operation processing is pipelined, because the WB stage for the memory load is canceled.

X

MOV [R1], R2 IF D E MMW. . . B(mop) load

(Canceled when the register IF D EWB number matches either of them)

IF D EWB

IF D EWB

Figure 3.24 When subsequent Instruction writes to the same register before the end of Memory Load. Source: Hardware Manual, Figure 2.26, page 2–34.

When the load data is not used by the subsequent instruction: Out of order com- pletion is allowed in pipelining if the correctness of the program is maintained. As in the following situation, when the load data is not used by the subsequent in- struction, the subsequent operations are not stalled and in fact are allowed to exe- cute. So, subsequent instructions are executed earlier and instructions are processed out- of- order.

MOV [R1], R2 IF D E MM ...... M WB (mop) load

ADD R4, R5 IF D EWB (mop) add

SUB R6, R7 IF DEWB (mop) sub

Figure 3.25 When Load Instruction data is not used by the subsequent Instruction. Source: Hardware Manual, Figure 2.27, page 2–34.

3.4.2 Operating Modes

Operating Mode Types and Selection: There are five types of operating modes in the RX62N/RX621 Group of MCUs. To specify the type of operating mode, the system con- trol register 0 (SYSCR0) has to be set first. The bits that are set in the system control reg- ister are MD1, MD0, ROME, and EXBE. The MDE pin specifies the endianness. 72 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 3.5 Selection of Operating Modes by the Mode Pins.

MD1 MD0 ROME EXBE OPERATING MODE ON- CHIP ROM EXTERNAL BUS 0 1 1 0 Boot mode Enabled Disabled 1 0 1 0 USB Boot mode Enabled Disabled 1 1 1 0 Single chip mode Enabled Disabled

Source: Hardware Manual, Table 3.1, page 3–1.

TABLE 3.6 Selection of Operating Modes by Register Setting.

ROME EXBE OPERATING MODE ON- CHIP ROM EXTERNAL BUS 0 0 Single chip mode Disabled Disabled 1 0 Single chip mode Enabled Disabled 0 1 On- chip ROM enabled extended mode Disabled Enabled 1 1 On- chip ROM enabled extended mode Enabled Enabled

Source: Hardware Manual, Table 3.2, page 3–1.

TABLE 3.7 Selection of Endianness.

MDE ENDIAN 0 Little endian 1 Big endian

Source: Hardware Manual, Table 3.3, page 3–1.

TABLE 3.8 Registers Related to Operating Modes.

REGISTER NAME SYMBOL ACCESS SIZE Mode monitor register MDMONR 16 Mode status register MDSR 16 System control register 0 SYSCR0 16 System control register 1 SYSCR1 16

Source: Hardware Manual, Table 3.4, page 3–2. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 73

1. Description of operating modes: Single-Chip Mode: In this mode, on- chip ROM can be either disabled or en- abled, but external bus is always disabled and all I/O ports are accessible. The on- chip ROM is enabled when the microcontroller is started. When ROME bit is set to 1 in SYSCR0, then on- chip ROM is enabled and it is again disabled when ROME bit is set to 0. The same is not true in reverse operation. While the on- chip ROM is disabled (i.e., ROME bit is set to 0 in SYSCR0), it cannot be enabled by setting the ROME bit in SYSCR0 to 1. On-chip ROM Enabled Extended Mode: In this mode, on- chip ROM is en- abled and the external bus is always enabled. The on- chip ROM is enabled when the ROME bit is set to 1 in SYSCR0. The external bus is available as ex- ternal extended mode when EXBE bit is set to 1 in SYSCR0. This mode al- lows some I/O ports to be used as data bus input/output, address bus output, or bus control signal input/output. The transition from this mode to single- chip mode (on- chip ROM enabled) is possible if 0 is written to EXBE, and a transi- tion to on- chip ROM disabled extended mode is possible if 0 is written to ROME bit. On-chip ROM Disabled Extended Mode: In this mode, on- chip ROM is dis- abled and external bus is always enabled. The on- chip ROM is disabled when ROME bit is set to 0 in SYSCR0. The external bus is available as external ex- tended mode when EXBE bit is set to 1 in SYSCR0. This mode allows some I/O ports to be used as data bus input/output, address bus output, or bus control signal input/output. It allows transition from this mode to single- chip mode (on- chip ROM enabled) which is possible if 0 is written to EXBE. The transi- tion to on- chip ROM enabled extended mode is not possible. Boot Mode: Boot mode is provided for the flash memory. This mode functions in the same manner as single- chip mode except for data write/erase function to the flash memory. USB Boot Mode: USB boot mode is provided for the flash memory. This mode functions in the same manner as single- chip mode except for data write/erase function to the flash memory. 2. Transitions of Operating Modes: Operating Mode transitions according to Mode Pin Setting: Figure 3.26 shows operating mode transitions according to the setting of pins MD1 and MD0. Operating modes can shift in the direction of arrows. Operating Mode Transitions according to Register Setting: Figure 3.27 shows operating mode transitions according to the setting of the ROME and EXBE bits in SYSCR0. Operating modes can shift in the direction of arrows. 74 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Reset* state RES# 0

Reset* generated Reset* generated Reset* generated

Reset* released Reset* released Reset* released MD1 0 MD1 1 MD1 1 MD0 1 MD0 0 MD0 0

Boot mode USB boot mode Single-chip mode

Mode can shift

Figure 3.26 Operating mode transitions according to Mode Pin Setting. Source: Hardware Man- ual, Figure 3.1, page 3–8.

Single-chip mode On-chip ROM enabled extended mode On-chip ROM: Enabled* EXBE 0 External bus: Disabled On-chip ROM: Enabled EXBE 1 External bus: Enabled ROME 1 EXBE 0 ROME 1 EXBE 1

ROMF 0 ROME 0 ROME 0 EXBE 1 ROME 0 EXBE 0 On-chip ROM disabled On-chip ROM: Disabled EXBE 0 extended mode External bus: Disabled On-chip ROM: Disabled EXBE 1 External bus: Enabled ROME 0 EXBE 0 ROME 0 EXBE 1

Mode can shift

Figure 3.27 Operating mode transitions according to Mode Pin Setting. Source: Hardware Man- ual, Figure 3.1, page 3–8. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 75

3.4.3 Memory Organization

This section discusses some of the basic concepts of memory organization. The basic mem- ory unit is or ga nized into an array of addressable units. In a byte- addressable memory, each memory location contains one byte (8-bits) of data. Another way of addressing the memory is by grouping the bytes into a larger block called words or longwords and addressing that block. Consider a memory unit having k locations (bytes). If, for addressing every location (byte) a unique n -bit identifier is used, then the number of locations that can be addressed would be 2n. So, k is equal to 2n which is equal to the size of the memory. If each location stores m - bit value then the memory is said to be or ga nized into an array of k m stored bits. The address of each memory location will be a unique n -bit identifier andthe content at each location will be an m - bit value. Figure 3.28 shows the basic arrangement of memory unit. In this figure the memory unit is a byte- addressable memory and, as can be seen, each location is addressed by 4-bits; therefore the size of memory is 24 or 16 bytes.

Byte Addressing vs. Word Addressing By using N address lines we can address 2N distinct addresses, numbered 0 through 2N 1. Most of the modern computers use byte addressing but there are other cases possible, such as word addressing. Consider the computer having 16-bit address space; if the addressing scheme is byte- addressing, then the addressable entities would be 216 bytes with byte ad- dresses from 0, 1, 2 . . . .216 1. If the addressing scheme is word- addressing then the ad- dressable entities would be 215 words with byte addresses from 0, 2, 4 . . . .216 2.

216 bytes with byte addresses from 0, 1, 2, to 216 1 215 words with byte addresses 0, 2, 4, to 216 2

0000 0001 0010 0011 00101101 0100 0101 0110 . . 1101 10100010 1110 1111

Figure 3.28 Logical layout of a block of memory. 76 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

0 8 bits of data 1 8 bits of data 2 8 bits of data 3 8 bits of data 4 8 bits of data 5 8 bits of data 6 8 bits of data

Figure 3.29 Byte addressing.

0 16 bits of data 2 16 bits of data 4 16 bits of data 6 16 bits of data

Figure 3.30 Word addressing.

3.4.4 Memory Map

The following figure shows a memory map in various operating modes. The accessible areas will differ according to the operating mode and the states of control bits. This microcontroller has a 4-Gbyte address space, which ranges from 0000 0000h to FFFF FFFFh. The reserved ar- eas shown in all three operating modes are not accessible by users/programmers. In Figure 3.32, External Address Space is shown. It consists of CS areas (CS0 to CS7) and SDRAM area (SDCS). The CS area is further divided into eight areas (CS0 to CS7), each corresponding to the CSi signal output from a CSi (i 0 to 7) pin.

3.4.5 I/O Registers

This section focuses on preventive measures that should be taken while using I/O registers. In some cases, after writing into I/O registers, you must check whether the write operation is completed. In some cases, a CPU behaves differently and could lead to unpredictable re- sults. In such cases, the CPU starts executing subsequent instructions before the write op- eration is over. If the next instruction deals with the same I/O register, and it tries to read from the same register, then the subsequent instruction reads the value of an I/O register that is not yet updated. So, in such scenarios where the updated value of an I/O register is required in the future, or where a subsequent instruction must execute after the value in the I/O register is changed, special care must be taken. Examples of such situations could be where the subsequent instruction must be executed while an interrupt request is disabled, or where a WAIT instruction is executed immediately after the preprocessing for causing a CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 77

On-chip ROM enabled On-chip ROM disabled Single-chip mode*2 extended mode extended mode

0000 0000h On-chip RAM 0000 0000h On-chip RAM 0000 0000h On-chip RAM

0001 8000h Reserved area*1 0001 8000h Reserved area*1 0001 8000h Reserved area*1 0008 0000h 0008 0000h 0008 0000h Perpheral I/O registers Perpheral I/O registers Perpheral I/O registers

0010 0000h On-chip ROM 0010 0000h On-chip ROM 0010 0000h (data flash) (data flash) 0010 8000h 0010 8000h Reserved area*1 Reserved area*1

007F 8000h FCU-RAM3 007F 8000h FCU-RAM3 007F A000h 007F A000h Reserved area*1 Reserved area*1

007F C000h Perpheral I/O registers 007F C000h Perpheral I/O registers Reserved area*1 007F C500h 007F C500h Reserved area*1 Reserved area*1

007F FC00h Perpheral I/O registers 007F FC00h Perpheral I/O registers 0080 0000h 0080 0000h Reserved area*1 Reserved area*1

00F8 0000h On-chip ROM (program ROM) 00F8 0000h On-chip ROM (program ROM) (write only) (write only)

0100 0000h 0100 0000h 0100 0000h ϷϷExternal address space External address space (CS area) ϷϷ(CS area)

0800 0000h 0800 0000h External address space External address space (SDRAM) (SDRAM)

1000 0000h 1000 0000h

Ϸ Reserved area*1 Ϸ

Ϸ Reserved area*1 Ϸ Ϸ Reserved area*1 Ϸ

FEFF E000h FEFF E000h On-chip ROM (FCU )*3 On-chip ROM (FCU firmware)*3 (read only) (read only) FF00 0000h FF00 0000h FF00 0000h Reserved area*1 Reserved area*1

FF00 C000h On-chip ROM (user boot) FF7F C000h On-chip ROM (user boot) (read only) (read only) FF80 0000h FF80 0000h Extend address space Reserved area*1 Reserved area*1

FFF8 0000h On-chip ROM (program ROM) FFF8 0000h On-chip ROM (program ROM) (read only) (read only) FFFF FFFFh FFFF FFFFh FFFF FFFFh

Note: 1. Reserved areas should not be accessed, since the correct operation of LSI is not guaranteed if they are accessed. 2. The address space in boot mode and user boot mode is the same as the address space in single-chip mode. 3. For details on the FCU, see section 37, ROM ( for Code Storage) and section 38, Data Flash (Flash Memory for Data Storage) in the Hardware Manual. Figure 3.31 Memory map in each operating mode. Source: Hardware Manual, Figure 4.1, page 4–1. 78 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

0000 0000h On-chip RAM 0100 0000h

0001 8000h Reserved area*1 CS7 (16 Mbytes) 0008 0000h Peripheral I/O registers 01FF FFFFh 0200 0000h 0010 0000h

CS6 (16 Mbytes)

02FF FFFFh Ϸ Reserved area*1 Ϸ 0300 0000h

CS5 (16 Mbytes)

03FF FFFFh 0400 0000h 0100 000h

CS4 (16 Mbytes)

Ϸ External address space Ϸ 04FF FFFFh (CS area) 0500 0000h

CS3 (16 Mbytes)

0080 0000h External address space 05FF FFFFh (SDRAM area) 0600 0000h

1000 0000h CS2 (16 Mbytes)

06FF FFFFh 0700 0000h

CS1 (16 Mbytes)

07FF FFFFh 0800 0000h

Ϸ Reserved area*1 Ϸ

SDCS (128 Mbytes)

0FFF FFFFh

FF00 0000h FF00 0000h

*2 External address space CS0 (16 Mbytes) (CS area)

FFFF FFFFh FFFF FFFFh

Note: 1. Reserved areas should not be accessed, since the correct operation of LSI is not guaranteed if they are accessed. 2. The CSO are is disabled in on-chip ROM enabled extended mode. In this node, the address spare for addresses above 1000 0000h is as shown in Figure 3.1.

Figure 3.32 Correspondence between External Address Spaces, CS Areas (CS0 to CS7), and SDRAM area (SDCS) (In On- chip ROM Disabled Extended Mode). Source: Hardware Manual, Figure 4.2, page 4–2. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 79

transition to the low power consumption state. The correct way to handle such situations is by waiting until the write operation is completed and following a debugging procedure. Follow these steps:

1. Write to an I/O register. 2. Read the value from the I/O register to a general register. 3. Execute the operation using the value read. 4. Execute the subsequent instruction.

Consider a situation where multiple registers need to be written first before subsequent in- struction can execute. In other words, subsequent instructions should be executed after the write operations are completed. In such a case only read the I/O register that was last writ- ten to, and execute the operation using that value. Do not read or execute operation for all the registers that were written to.

3.5 ADVANCED EXAMPLES

EXAMPLE 1

Show how the C arrays are laid out in memory for the Renesas board and compiler. Remember to pay attention to endianness, indicating which byte is located where. Assume the space for “a” starts in the first available space of user RAM (lowest address), and “b” starts 100 bytes (decimal) after where a starts.

a) int a [5] ADDRESS ARRAY ELEMENT WHICH BYTE? 400 a[0] Lower 401 a[0] Upper 402 a[1] Lower 403 a[1] Upper 404 a[2] Lower 405 a[2] Upper 406 a[3] Lower 407 a[3] Upper 408 a[4] Lower 409 a[4] Upper 80 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

b) unsigned char b [4] [2] ADDRESS ARRAY ELEMENT WHICH BYTE? 464 b[0][0] 465 b[0][1] 466 b[1][0] 467 b[1][1] 468 b[2][0] 469 b[2][1] 46A b[3][0] 46B b[3][1]

EXAMPLE 2

What is the speedup gained by implementing pipeline stages on a normal process? Consider a normal process with n number of tasks, taking k number of clock periods to execute one task. Then, the time taken by the process to complete n tasks n * k clock periods. If k pipeline stages are implemented for the above scenario, then the time taken (k (n 1)) clock periods. Therefore,

nk speedup d . k n 1 1 1 22

EXAMPLE 3

What are the various technologies used to implement embedded systems? Compare them on the basis of various parameters such as design cost, unit cost, upgrades and bug fixes, size, weight, power consumption, and system speed. CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 81

UPGRADES IMPLEMEN- DESIGN UNIT AND BUG SYSTEM TATION COST COST FIXES SIZE WEIGHT POWER SPEED

Discrete Low Mid Hard Large High ? Very fast logic

ASIC High Very Hard Tiny Very low Low Obscenely ($500K/ low fast mask set)

Programmable Low Mid Easy Small Low Medium Very fast logic- FPGA,PLD to high

Microprocessor Low to Mid Easy Small to Low to Medium Moderate memory peripherals mid medium moderate

Microcontrollers Low Mid Easy Small Low Medium Slow to (including memory to moderate and peripherals) low

Embedded PC Low High Easy Medium Moderate Medium Moderate to high to high

3.6 REFERENCES

Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print. Hennesy, J. L. and Patterson, D. A. Computer Architecture: A Quantitative Approach. San Francisco, CA: Morgan Kaufmann Publishers, c2003. Print. Parhami, B. Computer Architecture: From Microprocessors to . Oxford, New York: Oxford University Press, 2005. Print. Stallings, W. Computer Organization & Architecture: Designing for Performance. Upper Saddle River, NJ: Pearson/Prentice Hall, c2006. Print. Tomek, I. Introduction to Computer Architecture. Rockville, MD: Press, c1981. Print. 82 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

3.7 EXERCISES

1. What are the benefits of a microprocessor/microcontroller- based embedded sys- tem over an ASIC- based embedded system? 2. Consider a college food court which involves five steps before you select and eat your food. Look at the following figure for solving the problem.

Show ID Get token Place the order Cashier Take the meal

Suppose that in the food court pipeline the latency varies at each window. It varies from one to two minutes. When a student is done at each window he or she waits until the next window is available. Assume that there is no overhead in- volved while a student passes from one window to another window. a. How should this pipeline be used to maximize its throughput? b. Is the method of part ‘a’ applicable to a processor’s data path? c. What would be the throughput of the scheme in part ‘a’ if the latency of each window were uniformly distributed? d. Discuss a method other than ‘c’ for improving throughput? 3. Which memory is the fastest? a. Level 2 b. Registers c. RAM d. Disk storage e. Level 1 cache 4. Consider 4 Kbyte SRAM chips having a data width of 4 bits. How many chips will be required to build a 32 MB memory unit with the word width of 8-bits? 5. The double word 0x AC35 FA34 is stored in memory addresses N through N 3. Which of the following represents storage using little endianness?

a. N 43 b. N AC N 1 AF N 1 35 N 2 53 N 2 FA N 3 CA N 3 34 CHAPTER 3 / ORGANIZATION AND ARCHITECTURE ... 83

c.N 34 d. N FA N 1 FA N 1 34 N 2 35 N 2 AC N 3 AC N 3 35

6. How many bits wide is the program counter register? a. 32 bits b. 16 bits c. 8 bits d. 10 bits e. 12 bits 7. What will happen if you try to write to an array element larger than your array? a. An error will be reported. b. The program won’t compile. c. Nothing. d. You don’t know, but it will most likely be bad. e. The array will redefine itself bigger. 8. What is the total address space for our RX62N microcontroller? a. 31 Kbytes b. 384 Mbytes c. 4 Kbytes d. 4 Gbytes e. 1024 Kbytes 9. What are the benefits of a microprocessor/microcontroller- based embedded sys- tem over an FPGA- based embedded system? 10. What is the number of address bits required to address any byte in a memory that contains 4096 address spaces? a. 2 b. 8 c. 12 d. 16 e. 32 11. MCU can run in three modes: single chip, memory expansion, microprocessor modes. If used in single- chip mode, what areas in memory could be addressed? a. Only internal areas (SFR, internal RAM, internal ROM) b. Internal areas (SFR, internal RAM, internal ROM) and external memory areas c. SFR, internal RAM, and external memory d. SFR, external memory e. Only external memory 84 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

12. What is the number of address bits required to address any byte in a memory that contains 65536 address spaces? a. 2 b. 8 c. 12 d. 16 e. 20 13. Which of the following buses is not a valid bus? a. Instruction bus b. Internal main bus 1 c. Internal peripheral bus 1 d. External bus e. External operand bus 14. Out of the following which bus request has the highest priority? a. DMACA b. DTC c. CPU d. EDMAC Chapter Four

Software Development Tools

4.1 LEARNING OBJECTIVES

In this chapter the reader will learn about:

Ⅲ Process of compilation Ⅲ Features of the RX family compiler Ⅲ Debugging tools Ⅲ Features of the High-performance Embedded Workshop Ⅲ Various header files associated with C/C Compiler and the RX family

4.2 BASIC CONCEPTS

4.2.1 Compilation Mechanism

There are several steps involved from the stage of writing a C program to the stage of exe- cution. Figure 4.1 shows these different steps. In this process, a program written in C language gets translated into an assembly level program which the computer can understand. It can be seen from Figure 4.1 that the pro- gram passes through several processors before it is ready to be executed. The functions of each of these processors are:

Ⅲ The preprocessor performs text replacement according to preprocessor directives. There are two main preprocessor directives—macro expansion (e.g. #define SIZE 30) and file inclusion (e.g. #include “config.h”). Ⅲ The compiler transforms source code, written in a such as C, or C (source language) into another target language (object code) which is of binary form. Ⅲ The linker is a program that takes one or more objects generated by a compiler and combines them into a single executable program.

85 86 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

C Source and Header Files

C Preprocessor

Compiler

Source Code Analysis Symbol Table Target Code Synthesis

Library Linker Object Files

Executable Image

Figure 4.1 Compilation process for a C program.

The input and output to each of these processing stages is shown in Table 4.1.

TABLE 4.1 Input and Output to each Processor.

PROCESSOR INPUT OUTPUT Preprocessor C source code file Source code file with processed preprocessor commands Compiler Source code file with processed Re- locatable object code preprocessor commands Linker Re- locatable object code and the Executable code in machine standard C library functions language CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 87

4.2.2 Compilers for Embedded Systems

Compilers for embedded systems differ from compilers for general-purpose processors (GPPs). Minimizing code and data size is often critical for embedded systems since memory sizes are limited due by price pressures. This makes compiler code and data size optimiza- tions extremely important. The tongue-in-cheek “Software Gas Law” states that a program will eventually grow to fill all available resources. Embedded system software evolves as fea- tures are added and defects are fixed, while the hardware changes much more slowly. It is much easier to reprogram an MCU than redesign the hardware. As a result there is great value in compiler optimizations which can squeeze more code and data into the available resources. Speed optimization is also often critical. However, it is done differently for embedded systems and GPPs. First, GPP instruction sets have evolved over time to enable extremely high clock rates ( 2 GHz) and deep instruction processing pipelines. Embedded proces- sors with their lower clock rates do not need such deep pipelines, which leads to different code optimization trade-offs. Second, a lower means that embedded systems have a smaller performance penalty than GPPs for accessing memory instead of registers. This has two interesting effects. First, the compiler makes different optimization trade-offs with data allocation. Second, instruction sets for embedded systems can support memory- memory and bit-level operations rather than being forced into a load/store model.

4.2.3 RX Compiler Package

The RX compiler package includes the following embedded system development tools.

Ⅲ C/C؉؉ Compiler The compiler translates source code into assembly code, and typically also invokes the assembler and linker to create an executable file. The Compiler is ANSI-compliant and supports exception processing and template functions. It supports C or C and generates compact and high-speed object code. It offers general optimization tech- niques such as deletion of common expression and register allocation. There are addi- tional non-ANSI features which are helpful or necessary for embedded systems. Ⅲ Assembler The Assembler translates assembly code into object (machine) code. It also pro- vides pre-processor functions such as the file inclusion, conditional assembly, and macros, in order to simplify programming. Ⅲ Optimizing Linkage Editor The Linkage Editor processes object files generated by the compiler and assembler to create load modules and library files. Ⅲ Standard Library Generator The Standard Library Generator creates customized versions of the standard li- brary files based on the user-specified options. 88 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Ⅲ Simulator/Debugger This Simulator/Debugger provides the capability for debugging in targetless system. It is also a highly accurate simulator, supporting program performance evaluation . Ⅲ Utilities The RX package contains various utility tools. Call Walker shows stack use corre- sponding to the C/C function call tree. Moreover, function allocation editing by drag & drop is available. Map Viewer provides a GUI display of the various sections in a map file (output by the Optimizing Linkage Editor). Ⅲ IDE (Integrated Development Environment): HEW (High-performance Embedded Workshop) High-Performance Embedded Workshop provides a GUI-based integrated devel- opment environment on Windows operating systems for the development and de- bugging of embedded applications for the Renesas microcontrollers. It supports seamless integration and easy access to all tools for coding, compiling, linking, and debugging. All the tools in the package together offer a variety of functions and increase productivity greatly.

Features of RX Family C/C؉؉ Compiler 1. Easy optimization setting and the optimization features Ⅲ Compiler Optimization: It provides an easy selection of optimization as in the selection of size, speed, priority, and also in the selection of the optimization level (optimize level: 0, 1, 2, or max). Ⅲ Supports wide-ranging optimization when compiling; function’s inline- expansion between files and symbol access optimization which uses external symbol allocation information from the optimization linker. Ⅲ Has a detailed setting of optimization that is useful in loop expansions, in- structions order, optimization range specification, register allocation, etc. 2. Linker optimization Ⅲ Handles inter-module optimization such as the removal of an unreferenced symbol, optimization for branch order, and provides a detailed setting of par- tially disabled optimization. 3. Optimization of standard library Ⅲ Application of compiler optimization: A standard library is targeted on opti- mization and a compact code is generated with the entire program. 4. Easy translation environment from the existing product Ⅲ Supports the option of controlling different language specifications. Ⅲ Language specification of another compiler is checked by the RX compiler. Ⅲ RX supports Bi-endian operation. The compiler can select between big endian and little endian. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 89

4.2.4 Debugging Tools

There are two primary tools for debugging embedded real-time systems:

a. Debugger: The debugger allows a developer to observe and control a program’s execution and data. The execution can be started, paused and stopped, or advanced by a single instruction or program statement. Breakpoints can typically be in- serted. Data stored in variables as well as raw memory and register values can be examined and modified. b. Monitor: The monitor allows a developer to examine the program’s temporal be- havior. The most common monitors are oscilloscopes and logic analyzers con- nected to the embedded system. For instance, , while implementing interrupts in serial communication, one can measure useful information such as the duration of the transmit ISR and the receive ISR, or the delay between sending a character and receiving a reply. This information can be used to find maximum latency, and max- imum frequency. Hence the monitor tool is helpful in giving you insights about the timing of various operations happening inside the system.

4.2.5 Introduction to HEW

This section deals with the concepts and functionalities associated with the High- performance Embedded Workshop V.4.08 (HEW).

Overview: HEW organizes your work with the concepts of workspaces and projects.

Ⅲ Workspace: This is the largest unit which contains programs written in the HEW workshop. It can have several projects. A project is automatically created when we create the workspace. Ⅲ Project: The project is where you write your program. In fact, creating a new proj- ect is making a new program. You can also make hierarchical levels between sev- eral modules. It, along with other projects, will be included in the workspace.

A simple diagram below shows the relationship between a project and the workspace.

Figure 4.2 Relationship file project between a project and the file workspace. workspace project

project 90 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Creating or Opening a Project in HEW-IDE To launch HEW, open the start menu, select program, select Renesas, select HEW, and then select the shortcut of the High- per for mance Embedded Workshop.

Figure 4.3 Launching of HEW. Source: RX62N RDK Renesas toolchain quick start guide.

Look for the dialog box just like this:

Figure 4.4 Welcome dialog box in HEW. Source: HEW User Manual V.4.08, page 15.

To create a new workspace:

Ⅲ Select the Create a new project workspace option from the Welcome! dialog box, and click the OK button or select [File V New Workspace]. The New Project Workspace dialog box will be displayed. Ⅲ Enter the name of the new workspace into the Workspace Name field. To select the directory in which you would like to create the workspace, use the Browse but- ton or type the directory into the Directory field manually. Ⅲ Select the CPU family and Tool chain upon which you would like to base the workspace. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 91

Ⅲ When a new workspace is created, the HEW will also automatically create a proj- ect and place it inside the new workspace. From the project types list, select the type of project that you want to create from this list. The project types are of mainly three types: tool chain- only, debug- only, and a full project generator that contains both the debugger and tool chain aspect of the HEW. Ⅲ Click the OK button to create. This then launches the HEW window.

To open a new workspace:

Ⅲ Select Browse to another project workspace option from the dialog box shown in Figure 4.4 and then click the OK button or select [File V Open Work- space]. The Open Workspace dialog box will be displayed. Select the workspace file (“.HWS” file) that you want to open. Ⅲ Click the Select button to open the Properties dialog box to open the workspace. Click the Cancel button to stop opening the workspace.

To open a recently used workspace:

Ⅲ Select Open a recent project workspace in the dialog box: select the name of the workspace from the dropdown list, and then click the OK button.

Figure 4.5 HEW workspace showing various windows. Source: HEW User Manual V.4.08, page 2. 92 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Windows in HEW There are three main windows in HEW:

Workspace Window: Shows the projects and files that are currently in the workspace. It has four tabs: Projects, Templates, Navigation, and Test.

Figure 4.6 Workspace window in HEW. Source: HEW User Manual V.4.08, page 6.

Output Window: Shows the results of a various processes (e.g., build). By default, it has seven tabs (Build, Debug, Find in Files 1, Find in Files 2, Macro, Test, and Version Control) on display.

Figure 4.7 Output window in HEW. Source: HEW User Manual V.4.08, page 9. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 93

Editor Window: Provides file viewing and editing facilities. It is in this window where you will edit files of your project. It allows you to have many files open at one time, so you can switch between them. You can edit them in whichever order you want. Each file has a separate tab associated with it, and you can navigate easily to any tab you want.

Figure 4.8 Editor window in HEW. Source: HEW User Manual V.4.08, page 9.

Concept of Configuration and Session

Figure 4.9 Configuration and session selection in HEW. Source: HEW User Manual V.4.08, page 20.

By looking at the Standard toolbar you will know your current configuration and session. You can also select your session and configuration by looking into the drop- down list box. For instance, Figure 4.9 shows that the selected debugger is “SH- 4 Simulator” which works along with Renesas SuperH Standard toolchain. Before going any further, let me clarify the concept of configuration and session. 94 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Configuration After selecting a toolchain, you will create a project. Once the project is created, the HEW will automatically create configurations “Debug” and “Release.” As shown in Figure 4.9, configurations “SimDebug_SH- 4,” “Debug,” and “Release” are available. At the time of the creation of the project, if you have selected a target debugger HEW will automatically create a configuration best suited for that debugger. For in- stance, if you have selected “SH-4 Simulator” in the Target tab while creating a proj- ect, configuration “SimDebug_SH- 4” is created. Configurations are the settings that have to be set before the building process starts. It can also be referred to as “build configuration.”

Session Sessions are the units basically used to manage various settings. For instance, they may refer to the settings associated with debugging options of a specific debugger and data values on the memory and register windows. The term “session” is also referred as “de- bugger session.” If you look at the figure of the Standard toolbar (Figure 4.9), sessions “SimSessionSH- 4” and “Default Session” are available. Information on each session is saved in an individual file in the HEW project. Just like a configuration is created as you create a project after selection of the toolchain, a session called “Default Session” is also created. Also, if you select a target debugger at the creation of project, a session is created for connecting the debugger. For example, if you have selected “SH- 4 Simu- lator” in “Target” at the creation of a project, session “SimSessionSH- 4” is automati- cally created.

4.2.6 Concepts of Header Files

Most of the programming languages (for instance C and C) use header files. These files hold certain elements (program’s source code) which are reusable. Header files contain common repeatable elements such as forward declarations of classes, sub- routines, structure, unions, variables, and other identifiers. Declaring the same stan- dardized identifiers in more than one source file can be a cumbersome task for a programmer. The solution to this is declaring that identifier in a single header file and when there is a need for that identifier in some other source file, a programmer can just include that header file in order to include all declarations. The C standard library and C standard library traditionally declare their standard functions in header files that implement standard processing operations such as input/output and string handling. They can be used by in- cluding the standard include files which contain declarations for the corresponding li- braries and definitions of the macro names necessary to use them. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 95

Header Files Used in RX Family C/C؉؉ Compiler C and C are the most famous programming languages that implement the concept of header files. Table 4.2 lists the various library types, and their corresponding standard include files. Some include files consist only of macros, as seen in Table 4.3, to improve the program efficiency.

Header Files Associated with RX62N Some of the header files used in the demo program can be seen in Table 4.4.

TABLE 4.2 Library Types and Their Corresponding Header Files.

STANDARD LIBRARY INCLUDE TYPES DESCRIPTION FILES Program diagnostics Outputs program diagnostic information. Character handling Handles and checks characters. Mathematics Performs numerical calculations such as trignometric functions. Non- local jumps Supports transfer of control between functions. Variable arguments Supports access to variable arguments for functions with such arguments. Input/output Performs input/output handling. General utilities Performs C program standard processing such as storage area management. String handling Performs string comparison, copying, etc. Complex arithmetic Performs complex numeric operations. Floating- point environment Supports access to floating- point environment. Integer type format Manipulates greatest- width integers and converts conversion integer format. Multibyte and wide Manipulates multibyte characters. characters

Source: Compiler Package User Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Table 9.26, page 328. 96 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 4.3 Header Files that Contain Macros.

STANDARD INCLUDE FILE DESCRIPTION Defines macro names used in common by the standard include files. Defines various limit values relating to the compiler internal processing. Defines the value to be set in errno when an error is generated in a library function. <float.h> Defines various limit values relating to the limits of floating- point numbers. Defines alternative spellings of macro names. Defines macros relating to logical types and values. Declares integer types with specified width and defines macros. Defines type- generic macros.

Source: Compiler Package User Manual, Table 9.27, pg. 329.

TABLE 4.4 Header Files Used in Demo Program of RX62N Microcontroller Board.

STANDARD INCLUDE FILE DESCRIPTION Defines macros relating to the font size. Defines external constants, typedef enumerations and structures, prototype for minimum, and full access for glyph API library. Defines basic definitions of all simple constants and types. Defines prototypes that are required by the LCD driver in the glyph API. Defines prototypes for the glyph communication API. Defines aliases of Integer Type. Defines macro relating to size of area managed by sbrk. Defines vector table. Defines macros that refer to setting of stack area. Define various input and output registers.

4.3 BASIC EXAMPLES

(Source: High- per for mance Embedded Workshop V.4.08, User’s Manual. Renesas Elec- tronics America, Inc., 2010.) CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 97

EXAMPLE 1

This is an example demonstrating how to Build, Debug, and Run a Project on the HEW- IDE. If you are testing your board for the first time, you will test it with the demo code that comes with the package. After launching the main window, you probably want to down- load and run it on the board. Follow these steps to acquaint yourself with the whole process:

Step 1: Ensure that ‘SessionRX600_E1_E20_SYSTEM’ session in the right- hand drop- down list on the tool bar is selected.

Step 2: Click the button on the ‘debug’ toolbar.

When you click on the connect button, an initial settings window will appear. Ensure that you select the right MCU group and device. Select the debugging mode as shown in Figure 4.10.

Figure 4.10 Initial setting window while connecting the board. 98 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

After clicking OK, a window will pop up which will show the status as connecting. This window indicates whether an initial configuration has been done or not. See Figure 4.11 to get an idea.

Figure 4.11 Window showing the status as connecting.

This window will show up for just a few seconds, and after that a configuration properties window will appear. You can see various configuration properties associated with MCU, system, Internal flash memory overwrite, and external flash memory. You can select any of them and edit the properties as your application demands. If you go to the MCU tab on the same window, you need to select one of three operating modes; i.e., on chip ROM enabled extended mode, on chip ROM disabled extended mode, or single chip mode. For the demo application, you can go on with the settings shown in the Figure 4.12.

Figure 4.12 Window showing configuration properties. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 99

Once connected, you can see the status in the output window (Figure 4.13) as ‘connected.’ Also, you can see the status of the platform tab of other component windows. Here is the snapshot:

Figure 4.13 Window showing the status after the board has connected.

Step 3: The next step is building the program to check for any compiling error. Typically, in build process, each phase of the build takes a set of project files and builds them. If every file builds successfully, then the next phase is executed. Let me shed some light on the build process. The building process takes place in three phases: the Compiler is the first phase, the Assembler is the second phase, and the Linker is the third and final phase. During the Com- piler phase, the C/C source files from the various projects are compiled in turns. During the Assembler phase, the assembler source files are assembled. During the Linker phase, all library files and output files from the Compiler and Assembler phases are linked together to produce the load module. Depending on your requirement, you can choose from the various build options available to you. If you want to build an individual file, first select it from proj- ect tab of the workspace window, and then you can select any one of these options:

Ⅲ Click the Build File toolbar button (Figure 4.14) Ⅲ Select Build <file> from the pop- up menu Ⅲ Select the [Build V Build File] menu option Ⅲ Press CTRL F7

If you want to build a project, you can select any one of these:

Ⅲ Click the Build toolbar button (Figure 4.14) Ⅲ Press F7 Ⅲ Select [Build V Build] Ⅲ Right- click on a project in the Project tab of the Workspace window and select [Build V Build] from the pop- up menu 100 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Typically, the build operation compiles or assembles those files that are changed since the last build command. The Build all operation builds all files irrespective of whether the file has been modified or not. For performing a build all operation, you may select any of these options:

Ⅲ Click the Build All toolbar button (Figure 4.14) Ⅲ Select [Build V Build All] Ⅲ Right-click on a project in the Projects tab of the Workspace window and select [Build V Build All] from the pop- up menu

In each of the cases discussed, you can see the status of the build process in the build tab of the output window. An example that shows the status in the output window after the build process is next.

EXAMPLE

Build Finished ‘x’ Errors, ‘x’ Warnings

Here ‘x’ could be 0 or a larger number depending on your coding skills.

Figure 4.14 Explanation of icons on the toolbar. Source: HEW User Manual V.4.08.

Step 4: After the build process, you should download the code onto your board. For that, first go to the debug tab on the menu bar. Click on it and select ‘download modules’ in the drop- down menu list. Click on ‘all modules’ and wait for the HEW to download all mod- ules onto the board. When downloaded, a status will appear on the memory tab of the other component window, indicating the memory area where the program has been downloaded. A snapshot of the same is shown in Figure 4.15. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 101

Figure 4.15 Memory tab of other component window showing status of download.

Step 5: After downloading the program onto the board, you need to make it run to see the response. Click on ‘reset go’ from various other go options as shown in Figure 4.16.

Figure 4.16 Explanation of icons on the toolbar. Source: HEW User Manual V.4.08.

You can easily see the response on the output window as well as on the MCU board. The status on the output window will look like: Reset CPU.

Step 6: If you need to halt the program for debugging or editing the code, you can just click on the red stop button, as seen in Figure 4.17.

Figure 4.17 Snapshot of toolbar before halting the program. 102 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

EXAMPLE 2

This is an example demonstrating how to create and save a header file in the workspace. This example also demonstrates how to add that header file to the current project, and how to edit it. A programmer can create a ‘Header file’ when there is a need for some subroutines, structure, variables, unions, enumerations, and other definitions to be commonly repeated. Declaring the same identifiers again and again can be a tedious task, so the solution is cre- ating a header file that contains all the elements that are being repeated in more than one source file. In a header file, a programmer just declares common declarations, and when there is need for any identifier the programmer can just include that header file in the main source file, and the purpose will be fulfilled in an easier way. Follow these steps to add a header file to your current project.

Step 1: Creating a header file To create a new header file, you need to create a new editing window first. For this, you can apply one of the following:

Ⅲ Click the file tab on the menu bar, and then click the new file option in the drop- down menu Ⅲ Press CTRL N Ⅲ Click the new file toolbar icon

By default, a new file will be given an arbitrary name which you can change when you save the file. To make a header file you just need to save that file as “.h” extension file. It is al- ways good to name the file according to its functionality because other programmers who might want to edit the project later must also know the types of declarations the header file contains. This is the reason the header file that defines input and output registers is named . After you have created a file, the next step is to edit the file.

Step 2: Editing a header file In the editor window, you can declare the basic definitions that are being repeated in more than one source file. Before writing the definitions and declarations, do yourself a favor by writing the description of the current header file, to give other programmers an idea as to what this header file contains in general. Then, you can proceed with writing your content as your application demands. After you have written those basic definitions, you can edit it by using the basic tools available to you such as the menu, toolbar, and keyboard shortcuts. In addition, HEW provides you the functionality of editing through a pop- up menu that is lo- cal to the editor window. That menu will appear when you right click in an editor window. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 103

Table 4.5 outlines the basic operations.

TABLE 4.5 Basic Operations for Editing a Header File.

OPERATION EFFECT ACTION Undo Reverses the last editing operation. Select [Edit V Undo] Press CTRL Z Redo Repeats the last undone editing Select [Edit V Undo] operation. Press CTRL Z Cut Removes highlighted text and places it on Click the Cut toolbar button ( ) the Windows clipboard. Press CTRL X Select [Edit V Cut] Select Cut from the pop- up menu Copy Places a copy of the highlighted text into Click the Copy toolbar button ( ) the Windows clipboard. Press CTRL C Select [Edit V Copy] Select Copy from the pop- up menu Paste Copies the contents of the Windows® Click the Paste toolbar button ( ) clipboard into the active window at the Press CTRL V position of the insertion cursor. Select [Edit V Paste] Select Paste from the pop- up menu Clear Removes highlighted text (it is not copied Select [Edit V Clear] to the Windows clipboard). Press Delete Select All Selects (i.e. highlights) the entire contents Select [Edit V Select All] of the active window. Press CTRL A

Source: HEW User Manual V.4.08, page 120.

While you are editing your file, the title bar will show an asterisk (*). For instance global.h* 104 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Step 3: Saving a header file This step discusses how to save a file as a header file and how to save the contents of the editor window in general. To save the contents of a newly created file as a header file, make sure that it is an active window; i.e., open in an editor window, and then select one of the following:

Ⅲ Click the file button on menu bar, then click the new save button in the drop- down menu Ⅲ Press CTRL S Ⅲ Click the Save File toolbar icon ( )

Since the file has not been saved before, the save operation will provide a file save dialog box. Enter a filename, and ensure that you put “.h” as the extension of the file. After making it a (.h) header file, specify a directory and then click the OK button to create the file with the name given in the directory specified. If you edit and make changes to an already saved file, then you just need to click on the save icon. No dialog box will appear in this case. If you want to save the contents of the file under a new name, you must click the file button on the menu bar, then click the save as instead of the new save button in the drop- down menu. Again a file save dia- log box will be displayed. Enter a filename, specify a directory, and then click the OK button to create the file with the name given in the directory specified. In order to save the contents of every open window, either click on the save all toolbar button ( ) or Click the file button on the menu bar and then click the save all button in the drop- down menu.

NOTE: Saving the file as a “.h” extension file is the key in making a newly created file a header file.

Step 4: Opening a header file To open a file you can do one of the following operations:

Ⅲ Click the file open toolbar button ( ) Ⅲ Press CTRL O Ⅲ Click the file button on menu bar, and then click the open button in the drop- down menu

This operation will lead to the directory browser. You can then navigate to the desired di- rectory to open the file. Once located, you can open that file.

NOTE: You can use the Files of Type combo box to select the type of file you want to open. For in- stance, if you select ‘.h’ extension in the combo box then you will be able to see only files that are of the ‘.h’ extension. Surely this will narrow down your search. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 105

Step 5: Adding a header file to the current project For adding a header file to the current project click on the projects tab in the menu bar, and in the drop- down menu click on the “add files” button. This operation will lead to the di- rectory browser. You can then navigate to the desired directory to find the header file. Once located, you can add that file by clicking the “add” button on the directory browser win- dow. If you want to add that file to one of the folders in the workspace window, such as the C header file or C source file, then just go to that folder and right click. Select add files from the pop- up menu. Again the directory browser will pop- up and you can navigate to your desired file. Once added, you do not need to open that file in a conventional way as discussed in Step 4. Follow these steps to open that header file:

Ⅲ Spot your file in workspace window and double- click the file to open it Ⅲ Select the file and click the right- hand mouse button; select Open <file name> from the pop- up menu Ⅲ If it is already selected, press enter

NOTE: To remove a header file: For removing a header file from the current project, click on the projects tab in the menu bar and in a drop- down menu, click on the “remove files” button. A window, as seen in Figure 4.18, will appear.

Figure 4.18 Removing a header file. 106 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Select the header file you want to remove from your project. If you want to remove a header file from one of the folders in the workspace window, such as the C header file or C source file, then just go to that folder and right click. Select remove files from the pop- up menu. Again, the window shown in Figure 4.18 will appear and you can select the file you want to remove.

4.4 ADVANCED CONCEPTS

4.4.1 Advanced Debugging Concepts

(Source: HEW User Manual V.4.08.) This section describes in detail the various debugging tools and operations present in high per for mance embedded workshop. As discussed in Section 4.2.4 there are two pri- mary tools for debugging embedded real- time systems: the debugger and the monitor. This section discusses the first tool, the debugger, in detail. Details regarding the functionality and operations of the debugger and its related windows and dialog boxes are discussed. The debugger used in the RX family is the J- Link Debugger.

Ⅲ Debugger options in HEW The debugger can debug at level, as well as at the C/C source level. It depends on which setting the user chooses. If users make the de- bug option enabled, the debugger debugs the code at C/C source language level; and if that setting is not enabled then the debugger by default debugs the code at assembly language level. More precisely, your C/C program must be compiled and linked with the debug option enabled for debugging at C/C source level. When the debug option is enabled, the compiler puts all the information necessary for debugging the C/C code into the management information file, which is usually called the ‘debug object files.’ Thus, the de- bug object files are those absolute files that contain only the specific informa- tion essential for debugging, instead of the whole C/C code. While creating a new project, an initial debug session will be automatically configured. A user has to ensure that the debug option is enabled on the compiler and linker while generating an object file for debugging. When the debug option is not enabled, then debugging information will not be present in your debug object file. You can still load that file into the debugger, but it will only debug at the assembly language level. Ⅲ Debugger sessions in HEW The High- per for mance Embedded Workshop offers you the functionality of stor- ing all of your builder options into a configuration. This means you can put all of your building information into one place and refer to it with a name. Similarly, you CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 107

can store all the debugger options in a session. Later on, you can get back to the same session when required, and all of the debugger options will be restored. These sessions allow the user to specify target, download modules, and debug— which basically means you can have different sessions each targeted at different debugger options. For instance, you can easily have different sessions using the same target but with minor variations in session options. As an advantage, you can easily switch sessions as and when required. You can even modify certain things such as register values, or target settings such as clock speed. Look at Figure 4.19. The five sessions shown share the same target, but the sessions are slightly differ- ent with regard to the options defined.

Figure 4.19 Sessions in HEW. Source: HEW User Manual V.4.08, page 356.

In this particular case, there is no need to rebuild because the sessions share the same download module and they are never directly related to the build configura- tion data. In addition, each session’s information is stored in a separate file in the High- per for mance Embedded Workshop project so that you can later manipulate the data according to your application. Ⅲ Selecting a session: Click on the debug tab on the menu bar. In the drop- down menu, click on the de- bug sessions and the debug sessions dialog box will open. After that, select the session that you want to use from the current session drop- down list box, and then click the ok button.

Figure 4.20 Selecting a session. Source: HEW User Manual V.4.08, page 356.

Ⅲ Adding a session: HEW provides you the functionality of creating and naming a new session with an attached target and setup. You can create a new session by clicking on the file tab on the menu bar. In the drop- down menu, click on new session and the new ses- sion dialog box will open. 108 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Figure 4.21 Creating and naming a new session.

You need to fill out the required fields one by one. You can start with the name of the new session, and then select the target you wish to use, followed by selecting the core from the internal core list. This item is only available when you use the synchronized debugging facility. Select the generator in the session generator to use the list. It is possible that there may be multiple generators that support the same target. The last step is to click the OK button to launch the generation process. At this point, an additional dialog box may be displayed for target setup options. When finished, a new session is added to the current project. It should be available in the session’s drop- down list box on the main toolbar. Ⅲ Removing a session: Click on the debug tab on the menu bar. In the drop- down menu, click on the de- bug sessions option, and the debug sessions dialog box will open. After that, select the session that you want to remove and then click the remove button. Click the OK button to close the debug sessions dialog box.

NOTE: It is not possible to remove the current session.

Ⅲ Saving session information: You can save the new session by clicking on the file tab on the menu bar, and then in the drop down menu click on the save session button. If you have checked the “prompt before saving session” checkbox, a dialog box is displayed which asks you whether you wish to save the information. To see whether it is checked or not, click on the settings tab on the menu bar, then click on the options in the drop- down menu (a dialog box will appear), and then click on the workspace tab to look for the checked boxes. Ⅲ Operating memory This section describes one of the ways to debug your code. A user must know how to look at the memory in the CPU’s address space. It would be very useful if a user CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 109

knows how to look at the memory area in different formats. This section also dis- cusses ways to fill and move a memory block. Ⅲ Opening the memory window: A memory window is a window that shows the contents of contiguous memory ar- eas. To open the window, click on the view tab on the menu bar. In the drop- down menu, click on the CPU, then on the memory; or click the Memory toolbar icon ( ). A box, as shown in Figure 4.22, will pop up. It is known as the Display ad- dress box. In that box, you can specify the display address, scroll start address, and scroll end address.

Figure 4.22 Display address box.

Click the OK button to launch the memory window. The display can be scrolled up and down. The range can be selected by entering the values of the scroll start and scroll end address fields in the display address box. Ⅲ Window configuration:

Figure 4.23 Memory window. Source: HEW User Manual V.4.08, page 381. 110 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The label and register columns are hidden by default. You can make it visible by customizing the toolbar. The label column shows the name of the label allocated to the data on the first memory address displayed on the row. Similarly, the regis- ter column shows the name of the register allocated to data on the first memory address, displayed on the row. The ‘؉n’ in the column header of the data column defines the offset value from the first address of the row. The header of the code column shows the code name. In order to change the first address being displayed, double- click the address or label column. In order to change the memory data at the selected address, double- click the data or code column. Changing the values can be recorded in a macro (Macro Recording) to help you remember previous set- tings. In case the new setting does not go your way, you can then always get back to your initial settings since you have the previous data saved somewhere. More- over, values in the address, data, and code columns can be changed by in- place ed- iting. You can always customize your toolbar by right- clicking, and when it dis- plays a pop up window you can select from the various options available. For instance, one of the options would be ‘move’ which moves a specified memory block. In this feature, macro recording is also available to retain your previous memory block. Ⅲ Setting data at a desired memory address: To set data at a memory address, you can do an in- place editing of the code as well as the data column.

Figure 4.24 Data and Code column. Source: HEW User Manual V.4.08, page 383.

The first figure in Figure 4.24 shows the data column and second figure shows the code column. To change the contents of the memory, open a set dialog box. This is done as follows: a. Double- click the Data column b. Double- click the Code column c. Select the data you want to change and choose set from the pop- up menu CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 111

Figure 4.25 Set dialog box. Source: HEW User Manual V.4.08, page 384.

Fill in the required fields, such as address and data type. Value can be either a nu- meric value or a character. If you are setting a numeric value, then set value as the data type. If you are setting a character value, then select string as the data type. Make sure to select the verify check box. Ⅲ Filling an area of memory with constant data: HEW provides you with the feature of setting the range of memory addresses with the constant value. For this, you need to select an address range to fill in the mem- ory window. Select fill from the pop- up menu of the memory window, and then edit the fill dialog box.

Figure 4.26 Fill dialog box. Source: HEW User Manual V.4.08, page 385. 112 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

You must enter the start address and end address. The end address can also be prefixed by a plus (): the end address will become (start address) (the en- tered value). Ⅲ Copying an area of memory: To copy an area of memory into another area, you can use the memory copy feature provided by HEW. First, select a copy- source address range in the memory window using the mouse. Right click on the memory window and choose ‘move’ from the pop- up menu. The move dialog box opens as shown in Figure 4.27. Click on the move address field pop- up menu and choose the copy destination address. Check the verify check box. If you choose not to drag the copy- source address range, you have to enter the start and end address. The end address can also be prefixed by a plus (): the end address will become the (start address) (the entered value).

Figure 4.27 Move dialog box. Source: HEW User Manual V.4.08, page 386.

Ⅲ Comparing the memory contents: To compare the contents of two memory blocks, you can use the memory compare feature provided by HEW. First, select a source address range in the memory win- dow using the mouse. Right click on the memory window and choose ‘compare’ from the pop- up menu. The compare memory dialog box opens as shown in Figure 4.28. Enter the start address of the destination memory area in the com- pare address field and the data length in the data length field. Check the verify check box. If you miss dragging the copy- source address range by any chance, you can enter the start and end address now. The end address can also be prefixed by a plus (): the end address will become the (start address) (the entered value).

Figure 4.28 Compare memory dialog box. Source: HEW User Manual V.4.08, page 386. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 113

There exists only two cases, either mismatch or match. In the former case, the ad- dress where the mismatch was found is displayed in a message box. In the latter case, the message “comparison successful” appears. Ⅲ Saving memory contents in a text file: What if you want to edit the contents of some of the memory addresses, and before doing that you want to save those readings? HEW provides you the functionality of saving the memory contents in a text file using the save memory contents fea- ture. First, select a source address range in the memory window by dragging the mouse. Right click on the memory window and choose ‘save memory contents’ from the pop- up menu. The save memory contents dialog box opens as shown in Figure 4.29. Select the output range in the memory save area field, length of the data in the data length field, number of digits in the column field and the radix in the radix field. You can also select displaying/hiding the Label column and Reg- ister column by checking the output the label column and the output the regis- ter column fields, respectively. If you did not drag the address range to be saved, you must enter the output range.

Figure 4.29 Save memory contents dialog box.

Ⅲ Looking at I/O memory: A microcontroller contains various on- chip peripheral modules. The modules vary according to devices, but some of the common modules are DMA controllers, 114 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

serial communications interfaces, A/D converters, integrated timer units, a bus state controller, and a watchdog timer. Accessing registers play a very important role in programming on- chip peripherals. Since the setting up of such on- chip pe- ripheral registers is usually very important in an embedded microcontroller appli- cation, it would be very useful if we can look into the values of the registers. As discussed in the previous section, the memory view allows you to look at the data in the memory only as a byte, word, longword, single- precision floating- point, double- precision floating- point, or ASCII values. So the High- per for mance Em- bedded Workshop also provides an I/O window to analyze the values inside the registers. Ⅲ Opening the I/O window: To open the I/O window, click on the view tab on the menu bar. Select CPU from the drop down menu. Choose I/O to open the window or click the view I/O toolbar button ( ). Modules that match the on- chip peripheral modules organize the I/O register information. The I/O window has two tabs: All Register and Selected Register. When the I/O window is first opened, only a list of module names are shown on the All Register tabbed pane. Ⅲ Window configuration:

Figure 4.30 Input- output window. Source: HEW User Manual V.4.08, page 411.

The All register tab displays all I/O registers and the selected register tab displays selected I/O registers. By default, this page is blank. I/O registers can be used as and when required. While running the code, if the value of an I/O register is changed, the value is displayed in red. If you need to change the value of a regis- ter, then double click on the line of an I/O register. You can even record the value in a macro. In addition, the value can be changed in the value column by in- place CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 115

editing. HEW provides various options which can be expanded by right- clicking on the I/O window. It will display a pop- up menu containing options such as re- fresh, load I/O file, print, toolbar display, customize toolbar, etc. For displaying the names, addresses and values of the I/O registers you can either double- click on the module name or select the module name. To select the module name, click on it or use the cursor keys, and press the right cursor key. The module display will expand to show the individual registers names, addresses, and their values. To close the I/O register display, once again double- click on the module name (or press the left cursor key). Ⅲ Modifying the values of I/O registers: To modify the value of an I/O register, select either of the following: In- place edit in the value column.

Figure 4.31 Selected register tab of Input- output window. Source: HEW User Manual V.4.08, page 413.

Double- click on the line of the I/O register or bit to open a dialog box.

Figure 4.32 Edit dialog box. Source: HEW User Manual V.4.08, page 413. 116 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Ⅲ Selecting the I/O register(s) for viewing: First, click on the select register tabbed pane of the I/O window. To view the value of the registers, open a pop- up menu by right- clicking within the window. Then se- lect I/O register, and a dialog box will open as shown in Figure 4.33.

Figure 4.33 Selecting I/O register. Source: HEW User Manual V.4.08, page 414.

As you can see, there is a checkbox in front of every item; clicking on it selects the specific item. Clicking the ‘’ sign expands the collapsed item while clicking on ‘’ collapses the expanded item. If you select the checkbox for an item with ‘’ or ‘’ the checkboxes for all of its elements are also selected. Similarly, if you de- select the checkbox for an item, all of its elements are also deselected. You should select the checkboxes for the I/O register(s) you wish to view. After checking the item, click OK to close the dialog box. The selected I/O registers are shown on the select I/O register tabbed pane of the I/O window.

Figure 4.34 Selected register tab of Input- output window. Source: HEW User Manual V.4.08, page 415. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 117

Ⅲ Finding an I/O register: Many times you might want to know the value stored in a particular register. In such a case, instead of selecting an I/O register to view, you can try a faster way of directly accessing your desired register. In order to achieve this, right click within the window to open up a pop- up menu. After that select find and a dialog box will open as shown in Figure 4.35.

Figure 4.35 Find dialog box. Source: HEW User Manual V.4.08, page 416.

Fill in the fields one by one in any order you want. Select the column of an I/O register: you can select either the address or name of an I/O register. Then in the find field, select the string to be found in the selected column. The char- acters are case- insensitive. You can use the ‘match whole word’ feature to completely match the string entered. If you type a more general word and want to see all registers that partially match with the entered string, then do not check the ‘match whole word’ box. Finally, click OK to start the search from the first line.

4.4.2 The J- Link Debugger

(Source: http://www.segger.com/cms/jlink.html.J-Link Debugger) The debugger used for the RX family is the J- Link Debugger. J- Link RX supports all RX- CPUs with RX600 core and JTAG interface. The RX610 Group, RX62N Group, and RX621 Group are compatible with this debugger. The J- Link RX is compatible to the Renesas E1 emulator and works with the Renesas HEW and the IAR Embedded Workbench for RX (EWRX). 118 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Features Ⅲ Flash breakpoints are much faster on J- Link than on E1 or E20. J- Link uses differ- ent techniques like: Instruction set simulation, use of hardware breakpoints where possible, dynamic conversion of breakpoint types, flash caching, CRC, and others to minimize the amount of times a flash breakpoint is set or removed. Ⅲ It supports direct download into flash memory. Ⅲ It also supports software breakpoints in flash memory (Flash breakpoints). Ⅲ Seamless integration into the Renesas HEW & IAR Embedded Workbench IDE. Ⅲ Virtual UART support (C2E support) provided. Ⅲ All kinds of events are supported (execution break, data access, trace break, combination/sequence of events). Ⅲ USB 2.0 interface provided. Ⅲ JTAG speed up to 12 MHz or 25 MHz (depending on the J- Link model). Ⅲ No power supply required since it is powered through the USB. Ⅲ All JTAG signals can be monitored and the target voltage can be mea sured. Ⅲ Supports multiple devices. Ⅲ Wide target voltage range: 1.2V—3.3V, 5V tolerant. Ⅲ Target power supply: J- Link can supply up to 300 mA to target with overload protection.

4.4.3 Description of the Header Files Used in the RX Family

1. This is a configuration file for the generic API for graphics LCD glyph; i.e., “glyph.c”. It defines macro names used in common in the “glyph.h” include file. The macros defined here can be used to select the font size. It includes a header file “preamble.h” which defines simple types and constants. 2. This is the main header file for glyph API library. The Generic API for Graphics LCD (nicknamed “Glyph”) is a reusable software design to support multiple projects where the LCD size and resolution may change, but the basic feature set will stay consistent. Glyph is a standard library interface for use with any graphic LCD. It uses macros already defined in the header file “config.h”. It defines ex- ternal constants, typedef enumerations, typedef structures, prototype for mini- mum access, and prototype for full access. a. Type: External constant This declares constant values for various font sizes that will be available to all users of glyph API.

Example: extern const uint8_t * FontHelvr10_table [256]; CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 119

FontHelvr10_table is a macro defined in “config.h” that signifies the default font size. b. Type: Typedef definition The typedef keyword defines new types or provides an alternative name to the already existing types. 1) The typedef allows you to use t_glyphhandle as a type rather than using void*. Now, t_glyphhandle can be used to declare a pointer to the type void.

Example: typedef void *T_glyphHandle.

2) The enum keyword is used to create an enumerated type that consists of constants that represent error identifiers of the glyph API. Since each subsequent value is incremented by one over the previous constant, the value of GLYPH_ERROR_ILLEGAL_OPERATION is 1.

Example: typedef enum { GLYPH_ERROR_NONE = 0, GLYPH_ERROR_ILLEGAL_OPERATION } T_glyphError;

3) The enum keyword is used to create enumerated type that consists of constants that represent status values of the glyph API. By default, the first constant in an enumeration is assigned value zero, and each subse- quent value is incremented by one over the previous constant. In this par- ticular case, since each constant is given a specific value, each subse- quent value is not incremented. Instead, it retains the value that is set in the declaration.

Example: typedef enum { GLYPH_STATUS_READY = 0, GLYPH_STATUS_BUSY = 2, GLYPH_STATUS_FULL = 4 } T_glyphStatusBits;

4) The enum keyword is used to create enumerated type that consists of constants that represent font values of the glyph API. By default, the first 120 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

constant in an enumeration is assigned value zero, and each subsequent value is incremented by one over the previous constant.

Example: typedef enum { GLYPH_FONT_8_BY_8, GLYPH_FONT_8_BY_16, GLYPH_FONT_5_BY_7, ...... } T_glyphFont;

5) The enum keyword is used to create an enumerated type that consists of constants which define drawing modes of the glyph API. Since each sub- sequent value is incremented by one over the previous constant, the value of GLYPH_CMD_ERASE_BLOCK is 8.

Example: typedef enum { GLYPH_CMD_NOP = 0, GLYPH_CMD_SCREEN_CLEAR, GLYPH_CMD_SCREEN_INVERT, GLYPH_CMD_SCREEN_REGULAR, ...... } T_glyphDrawMode;

6) Description: The enum keyword is used to create enumerated type that consists of constants that represent the glyph API registers. These are used by Glyph Read and Glyph Write to specify a function of the glyph API to run.

Example: typedef enum { GLYPH_STATUS = 0, GLYPH_CHAR_X, GLYPH_CHAR_Y, ...... GLYPH_CONTRAST, GLYPH_CONTRAST_BOOST } T_glyphRegisters; CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 121

7) A struct in C programming language is a collection of elements, in which each element belongs to a different type. The total storage required for a struct object is the sum of the storage requirements of all the elements. This typedef allows you to use T_glyphVersionInfo as a type rather than using a struct. Now, T_glyphVersionInfo can be used instead of struct T_glyphVersionInfo whenever you want to declare a new instance of the structure_glyph_version_info named T_glyphVersionInfo. The structure below contains elements that depict various versions of glyph API structure.

Example: typedef struct_glyph_version_info { uint8_t strVersionAPI [50]; uint8_t strVersionIMPL [50]; int32_t nVersionAPIMajor; int32_t nVersionAPIMinor; int32_t nVersionIMPLMajor; int32_t nVersionIMPLMinor; int32_t nImplementationID; } T_glyphVersionInfo;

8) In future statements, you can use the specifier T_LCD_API (instead of the expanded struct T_LCD_API) to refer to the structure and create an instance. The structure below contains elements that are used in applica- tions where LCD is required. This is a glyph API LCD structure which is frequently used by the LCD drivers.

Example: typedef struct { /* Adding Font- Decal Section */ const uint8_t ** iFont; /* Define Global Variables */ uint32_t iCharX_Position; uint32_t iCharY_Position; uint32_t iCharX2_Position; uint32_t iCharY2_Position; uint32_t iCharFont; ...... 122 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

T_glyphError (*iWrite)(T_glyphHandle aHandle, uint32_t aRegister, uint32_t Value); } T_LCD_API;

9) In future statements, you can use the specifier T_Comm_API (instead of the expanded struct T_Comm_API) to refer to the structure and create an instance. The following structure contains elements that are used in ap- plications where communication needs to be set up. This is a glyph API communication structure which is frequently used by the Communi- cation drivers.

Example: typedef struct { T_glyphError (*iOpen)(T_glyphHandle aHandle); void (*iCommandSend)(int8_t cCommand); void (*iDataSend)(int8_t cData); } T_Comm_API;

10) In future statements, you can use the specifier T_glyphworkspace (in- stead of the expanded struct T_glyphworkspace) to refer to the structure and create an instance. The following structure contains elements that are used in applications where LCD is required and communication needs to be set up. This is a glyph API workspace structure which is fre- quently used by Communication and LCD drivers.

Example: typedef struct { T_LCD_API *iLCDAPI; T_Comm_API *iCommAPI; } T_glyphWorkspace;

c. Type: Function Glyph API provides you the capability to interact with the graphical LCD. The prototypes defined in the following example are used to access the glyph API library definitions. Its implementation totally depends on the type of ap- plication. These prototypes define the functions for minimum and full access of the members of the glyph libraray.

Examples: Prototypes for minimum access: T_glyphError GlyphOpen(T_glyphHandle *aHandle, int32_t aAddress); CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 123

T_glyphError GlyphClose(T_glyphHandle *aHandle); T_glyphError GlyphWrite(T_glyphHandle aHandle, uint32_t aRegister, uint32_t * aValue); T_glyphError GlyphRead(T_glyphHandle aHandle, uint32_t aRegister, uint32_t *aValue); Prototypes for full access: T_glyphError GlyphGetStatus(T_glyphHandle aHandle, T_glyphStatusBits *aStatus); T_glyphError GlyphSetX(T_glyphHandle aHandle, uint32_t aX); T_glyphError GlyphSetY(T_glyphHandle aHandle, uint32_t aY); ...... T_glyphError GlyphSetContrastBoost(T_glyphHandle aHandle, uint8_t cContrastBoost);

3. Description: This header file contains basic definitions of all simple constants and types. The purpose of this file is to maintain compatibility between the com- pilers and hardware. It defines macros which can be used in other header files or in source code of any application. a. Type: Constant.

Example: #define ON 1 #define OFF 0 #define ENABLE 1 #define DISABLE 0

b. Type: Typedef definitions. In future statements, any variable can be used as a type instead of its pre- existing type. For instance, Int8_t can be used as a type instead of a signed char.

Example: typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; 124 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

c. Type: Bit definitions. A bit from b0 to b7 signifies some hexadecimal value as defined in the fol- lowing example.

Example: #define b0 0x01 #define b4 0x10 #define b7 0x80

4. Description: It defines prototypes that are required by the LCD driver in the glyph API. It includes all the definitions of “glyph.h”. Note: The name of the header file comes from st7579 which is a driver and controller LSI for the graphic dot- matrix liquid crystal display systems. This chip is connected directly to a microprocessor, accepts 3-line serial periph- eral interface (SPI) with a four wire inde pen dent transmit only, displays data, and can store an on- chip display data RAM of 68 102 bits. a. Type: Macros These macros signify function sets, which are used to define the function set call for every command that is sent to the ST7579 Display controller. When setting the display controller to the four different function sets of commands to be sent to the controller, setting the function set also sets the following:

MX direction: normal or reverse i[0Ϻ1] MY direction: normal or reverse [0Ϻ1] PD controller active or power down [0Ϻ1]

If the preprocessor directive #if, is set to 1, then every Function Set call will produce MY set to the reverse direction. This is required for Glyph to work. Otherwise, MY will be set to the normal direction and Glyph will not work. These function sets do not take any arguments and do not return any value.

Example: #if 1 //MY reverse direction #define LCD_FUNCTION_ZERO 0X28 #define LCD_FUNCTION_ONE 0X29 #define LCD_FUNCTION_TWO 0X2A #define LCD_FUNCTION_THREE 0X2B //command sets #define LCD_DISPLAY_REVERSE 0x280D CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 125

#define LCD_DISPLAY_NORMAL 0x280C #else //MY normal direction #define LCD_FUNCTION_ZERO 0X20 #define LCD_FUNCTION_ONE 0X21 #define LCD_FUNCTION_TWO 0X22 #define LCD_FUNCTION_THREE 0X23 //command sets #define LCD_DISPLAY_REVERSE 0x200D #define LCD_DISPLAY_NORMAL 0x200C #endif

b. Type: Functions 1) The prototypes defined in the following example are used to access “glyph LCD API” library definitions.

Example: T_glyphError ST7579_Open(T_glyphHandle aHandle, uint32_t aAddress); T_glyphError ST7579_Close(T_glyphHandle aHandle); T_glyphError ST7579_Write(T_glyphHandle aHandle, uint32_t aRegister, uint32_t aValue); T_glyphError ST7579_Read(T_glyphHandle aHandle, uint32_t aRegister, uint32_t *aValue);

2) The prototypes defined in following example are used to access “LCD API” library definitions.

Example: void ST7579_Config(T_glyphHandle aHandle); void ST7579_SetSystemBiasBooster(T_glyphHandle aHandle, int8_t c Value 0 To 17); void ST7579_SetVO_Range(T_glyphHandle aHandle, int32_t n Value 0 to 254);

5. Description: This header file defines prototypes for the glyph communication API.

NOTE: The name of the header file indicates the hardware it is associated with. It is Y Renesas Development Kit (RDK) for Renesas RX62N Group CPU. The trans- mitter number is 0 and the operational channel is 3. 126 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The Chip Select for the flash device (LCD) is set to PC_2. This is the RSPI chan- nel used to communicate with the ST7579 Graphics Display. The RSPI configu- ration has the baud rate generator set for maximum speed, which is PLCK/2 or 25 MHz. The communications protocol followed is SPI 3-Wire Transmit only MASTER SPI. Its Slave Device is OKAYA LCD with a ST2579 microprocessor.

Example: void YRDKRX62N_CommandSend(int8_t cCommand); void YRDKRX62N_DataSend(int8_t cData); T_glyphError YRDKRX62N_RSPIOpen(T_glyphHandle aHandle);

6. Description: In further statements, any variable can be used as a type instead of its pre- existing type. For instance, _SBYTE can be used as a type instead of signed char. Here, an underscore before the variable name SBYTE signifies that it is a global variable.

Example:

typedef signed char _SBYTE; typedef unsigned char _UBYTE; typedef signed short _SWORD;

7. Description: This is a header file for sbrk.c. It defines a macro that signifies the size of the area managed by sbrk.

Example: #define HEAPSIZE 0x400

8. Description: This header file defines various vectors. The vector list is basically a list which indicates where the ISRs (interrupt subroutines) are located in mem- ory. Each entry in the list is called a vector. Vector signifies the four bytes address of each ISR. Some of the vectors are reserved—like vector 16 is reserved by an interrupt Excep_BUSERR; i.e., the ISR to be called when exception happens during a bus error; and the rest of them are free to be occupied. Vector table starts with the vectors that refer to the fixed interrupts. These vectors cannot be changed since they point to ISRs at hardware- defined addresses such as unde- fined instruction, supervisor instruction, floating point, NMI, Dummy, or BRK. Then comes the variable vectors that point to ISRs at user- definable vectors. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 127

Example: Fixed interrupts: //Exception(Supervisor Instruction) #pragma interrupt (Excep_SuperVisorInst) void Excep_SuperVisorInst(void); //Exception(Undefined Instruction) #pragma interrupt (Excep_UndefinedInst) Variable Interrupts: #pragma interrupt (Excep_BUSERR(vect = 16)) void Excep_BUSERR(void); //vector 17 reserved //vector 18 reserved //vector 19 reserved //vector 20 reserved //FCU_FCUERR #pragma interrupt (Excep_FCU_FCUERR(vect = 21)) void Excep_FCU_FCUERR(void); //vector 22 reserved

9. Description: This header file defines macros that refer to the setting of the stack area.

Example: #pragma stacksize su = 0x300 #pragma stacksize si = 0x100

10. Description: This header file uses numerous macros, about sixty- eight structures, one union, and four enumerations to define the various input and output registers.

Example: a. Macros:

#pragma bit_order left #pragma unpack #define SYSTEM (*(volatile struct st_system __evenaccess *)0x80000) #define BSC (*(volatile struct st_bsc __evenaccess *)0x81300) #define IEN__IRQ1 IEN1 #define IEN__IRQ2 IEN2 128 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

b. Structure: The structure below defines various input and output registers that are used in analog to digital conversion. Within the structure, a union is being used to de- clare variables of different types. It is the same as structure, except that in- stead of struct you write union. Also, in union you can only store information in one field at any one time. Technically, it can be seen as a chunk of memory that is used to store variables of different types. Once a new value is assigned to a field, the existing data is wiped over and rewritten with the new data.

Example: struct st_da { unsigned short DADR0; unsigned short DADR1; union { unsigned char BYTE; struct { unsigned char DAOE1Ϻ1; unsigned char DAOE0Ϻ1; unsigned char DAEϺ1; unsigned char:5; } BIT; } DACR; union { unsigned char BYTE; struct { unsigned char DPSEL:1; unsigned char:7; } BIT; } DADPR; };

In this example, the structure st_da contains four members; namely DADR0, DADR1, union DACR, and a union DADPR. This is an example of nested unions. Union DACR has two members. BYTE and structure BIT. The BIT member is a structure with four bit- field members, DAOE1, DAOE0, DAE and one nameless field member, all of them are of type unsigned char. Mem- ber BYTE is of type unsigned char. Union DADPR has two members, BYTE and structure BIT. The BIT member is a structure with two bit- field mem- bers, DPSEL and one nameless field member, both of which are of type un- signed char. Member BYTE is of type unsigned char. At any given time, each union element holds either the unsigned char represented by BYTE or the CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 129

structure represented by BIT. The other two variables of st_da are of type un- signed char. Table 4.6 provides an explanation of the terms that were used in the previous example.

TABLE 4.6 Register Description.

NUMBER MODULE- REGISTER REGISTER ADDRESS OF BITS ABBREVIATION NAME ABBREVIATION 0008 80C0h 16 D/A D/A data register 0 DADR0 0008 80C2h 16 D/A D/A data register 1 DADR1 0008 80C4h 8 D/A D/A control register DACR 0008 80C5h 8 D/A D/A data placement DADPR register

c. Enumerations: These are used to define various ICU registers. 1) Usage of some specific registers such as IR (interrupt register), DTCER (DTC activation enable register), IER (interrupt request enable register), and IPR (Interrupt source priority register) follows. The bit access oper- ation is “bit name (interrupt source, name)”. A part of the interrupt source can be omitted.

Example: IR(TPU0,TGI0A) = 0; DTCER( ,IRQ0) = 1; IEN(CMT0,CMI0) = 1; IPR(MTU0,TGIA0) = 3; IPR(MTU0,TGI ) = 3; //TGIA0,TGIB0,TGIC0,TGID0 is same level. IPR(CMT0, CMI0) = 1; IPR(CMT0, ) = 1; //CMT0 interrupt is only one factor.

2) Usage of the interrupts listed in vector table: #pragma interrupt Function_Identifier (vect **).The number of vector is “(interrupt source, name)”. 130 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Example: #pragma interrupt INT_MTU0_TGIA0(vect = VECT(MTU0,TGIA0)) #pragma interrupt INT_IRQ0 (vect = VECT( ,IRQ0)) #pragma interrupt INT_CMT0_CMI0 (vect = VECT(CMT0,CMI0))

3) Usage of some specific system registers such as MSTPCRA (Module stop control register A), MSTPCRB (Module stop control register B), MSTPCRC (Module stop control register C), and MSTPCRD (Module stop control register D) is given as follows: The bit access operation is “MSTP (name)”. The name that can be used is a macro name defined with “iodefine.h”.

Example: MSTP (TMR2) = 0; //TMR Unit 1 (TMR3/TMR2) MSTP (PPG1) = 0; //PPG1 MSTP (MTU6) = 0; //MTU Unit 1 (TPU6 to TPU11) MSTP (CMT3) = 0; //CMT Unit 1 (CMT2/CMT3)

4.5 ADVANCED EXAMPLES

(Source: HEW User Manual V.4.08.)

EXAMPLE 1

This example demonstrates how to look at the contents of the CPU’s general registers. To view the contents, first open the register window. For this, click on the view tab on the menu bar, and in the popup menu select CPU from the drop down menu. Choose reg- ister to open the window or click on the registers toolbar button ( ).The Register window gives the status of current register and flag data. You can even modify the register/flag value from the window.

Window Configuration Double-clicking the register display line opens a dialog box, which allows you to change a register value. Everything can be recorded by macro recording. This is helpful in a case where you want to get back to older values. The easy way to change the register’s contents is by using in- place editing. Also, you can change a flag value by clicking the button corre- sponding to the flag. If you right click on the window, you can change the display radix point and the register bank. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 131

Figure 4.36 Register window.

Popup menu:

Changing the Register Display Radix To change the display radix, right click the mouse on the register to be changed and select display radix from the pop- up menu. You can select one of the four radix options shown in Table 4.7.

Setting the Layout To change the layout of the register window, choose layout from the pop- up menu. The following settings are displayed:

Radix: It Switches display or non- display of the radix. 132 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 4.7 Display Radix Point and the Register Bank Options.

MENU OPTION FUNCTION Radix: Hex Displays in hexadecimal Dec Displays in Decimal Oct Displays in Octal Bin Displays in Binary Layout: Radix Switches display or non- display of radix FLAGs Switches display or non- display of flags display area Settings Chooses a register to be displayed Edit Changes a register’s contents Refresh Refreshes the Register window Lock Refresh Disables refresh of the Register window Split Splits up the window display Save To File Saves register contents in a text file

Source: HEW User Manual V.4.08, page 418.

Flags: It Switches display or non- display of the flags display area.

Figure 4.37 Displays the radix and flags. Source: HEW User Manual V.4.08, page 420. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 133

Choosing a Register to be Displayed Figure 4.38 shows the dialog box which is displayed when you choose the settings tab from the register pop- up menu. In this way you can choose a register to be displayed in the Register window.

Figure 4.38 Settings dialog box to select register to be displayed. Source: HEW User Manual V.4.08, page 420.

Modifying the Register Contents To change the register contents, enter a value in the value field of the register as shown in Figure 4.39.

Figure 4.39 In place modification of register value. Source: HEW User Manual V.4.08, page 421.

To change a register’s contents, open the Set Value dialog box as described in the follow- ing and select one of the operations:

1. Double- click the register to be changed. 2. Select the register and choose the Edit option from the pop- up menu. 134 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Figure 4.40 Set value dialog box. Source: HEW User Manual V.4.08, page 421.

Setting the Flag Value When the flag itself is displayed, click the flag which you want to change. Every time a flag is clicked, the flag status switches from either 1 to 0 or 0 to 1. If a flag is composed of mul- tiple bits, then a dialog box will open, where you can enter a value.

Screenshot:

Figure 4.41 Flag status. Source: HEW User Manual V.4.08, page 422.

When the flag is displayed in the register, double- click the FLG line. A dialog box will open and then you can enter the value to be changed.

Figure 4.42 Debugger (FLG line (FPSCR)). Source: HEW User Manual V.4.08, page 422. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 135

Saving Register Contents To save the register contents in a text file, choose Save to file from the register pop- up menu. The Save As dialog box will open, which allows you to specify the file name.

EXAMPLE 2

Displaying memory contents as waveforms.

NOTE: Support for this function depends on the debugger. To analyze the data that has just been saved into the memory, creating a waveform could be a very good option. It gives insight into how your code is responding to the appli- cation that you are making. For creating a waveform, first you need to open the waveform properties dialog box. Click on the view tab on the menu bar, select graphics, and then waveform to get the waveform window. The other way is to just click on the waveform toolbar button ( ).

Figure 4.43 Waveform properties dialog box. Source: HEW User Manual V.4.08, page 407.

You need to fill in the properties before going any further. For data address property, you need to specify the start address of the data in memory. It should be displayed in hexadec- imal. Data size property signifies the size of the data, which can be either 8 bit or 16 bit. Two types of channels are supported: mono and stereo. Select buffer size to specify the buffer size of the data in hexadecimals. Now click the OK button to open the waveform window. You can change the display contents later by right clicking the window and choos- ing ‘properties’ from the pop- up menu. In the pop- up menu, some of the other fields are zoom in, zoom out, zoom magnification, scaling, refresh now, etc. 136 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Figure 4.44 shows the display of the memory contents as a waveform. The X- coordinate refers to the number of sampling data and the Y - coordinate refers to the sam- pling value.

Figure 4.44 Memory contents as waveform. Source: HEW User Manual V.4.08, page 407.

If you double- click the coordinate where you wish to view the sampling information, the sample information dialog box appears. For refreshing the window, there is a function called auto refresh, available in the pop- up menu. Selecting auto refresh and then non re- fresh will not refresh the window. Selecting auto refresh and then stop from the pop- up menu will allow the window contents to be automatically refreshed. Selecting auto refresh and then real time from the pop- up menu will allow the window contents to be refreshed while the user program is running. To specify the refresh interval, select update interval from the pop- up menu. This item can be selected only when it is supported by the debugger.

4.6 REFERENCES

RX Compiler Package, http://america.renesas.com/products/tools/coding_tools/c_compilers_assemblers/ rx_compiler/rx_c_tools_product_landing.jsp Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print. CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 137

Compiler Package User Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electron- ics America, Inc., 2010. Print. High- per for mance Embedded Workshop V.4.08, User’s Manual. Renesas Electronics America, Inc., 2010. Print.

4.7 EXERCISES

1. What is the difference between compilers used for embedded systems and com- pilers used for desktops PCs? 2. How does the linker differ from the compiler? 3. Other than macro definition, for what purpose can the “#define” identifier can be used? 4. What are the various phases of the building process in HEW? 5. Where in HEW debugger options are saved and why? 6. Can all display the contents of the memory as a waveform? 7. For what purpose is synchronized debugging used? 8. We have an integer array called x. All the numbers from 1 to 100 appear exactly once in x but the numbers are not sorted (e.g., the order can be x[100] {2; 10; 3; 8; 9; 4; 97; 94; ...... 37; 99}). Due to alpha particles destroying a par- ticular entry in x, a number is missing and is read as 0 when accessed. Use less than ten lines of C code (one statement per line) to find the missing number (not the index) and put it in an integer variable called missing. Don’t forget to include proper documentation suggested in coding guidelines (comments, header, etc.). 99 99 (Hint: consider the current a x i and what the uncorrupted value of a x i i0 3 4 i0 3 4 would be).

9. What is the one thing that all of our code should have? a. Your name and file name in comments at the top of every file. b. Twelve subroutines. c. A while(1) loop in every subroutine. d. A function call to the ST7579_LCD.c file. e. None of the above. 10. Which header file defines prototypes for the glyph communication API? a. yrdkrx62n_rspio.h b. config.h c. ST7579_lcd.h d. glyph.h e. sbrk.h 138 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

11. Which header file is mandatory to include in source code if your code uses an In- terrupt Subroutine? a. b. c. ST7579_lcd.h d. glyph.h e. sbrk.h 12. Which of the following fully describes the outcome of the code below?

int i,sum; sum = 0; i = 0; for(i = N; i < 100; i++) { if((i % 2)) sum += i; }

a. Add all the numbers from 0 to 100 and put the result in sum. b. Add all the odd numbers from 0 to 100 and put the result in sum. c. Add all the even numbers from 0 to 100 and put the result in sum. d. Add all the odd numbers from N to 100 and put the result in sum. e. Add all the even numbers from N to 100 and put the result in sum. 13. Which of the following is not a part of the compiler? a. Linker b. Pre- processor c. Code generator d. Garbage collector e. Parser 14. Consider the code below. The first printf statement below prints “1C3F”. What is printed by the second printf?

union { int w; char b[2]; }x; x.w = 0x1C3F; printf(“%X \ n”, x.w); x.b [1] = 0xA6; printf(“%X \ n”, x.w); CHAPTER 4 / SOFTWARE DEVELOPMENT TOOLS 139

a. 1C3F b. A63F c. 1CA6 d. 1A6F e. None of the above. 15. In C, the term volatile is applied to a variable in order to: a. Tell the compiler that a variable’s value may change due to forces other than the program in which the variable appears. b. Tell the compiler that a variable’s value is not constant. c. Mark that a variable may be optimized out of the code when unused. d. Tell the compiler to store the variable’s value in “volatile” ram instead of “non- volatile” ram, such as an EEPROM. e. None of the above. 16. For our processor and compiler, does the stack grow toward larger or smaller addresses? a. Larger b. Neither c. Smaller d. Both e. None of the above 17. For our processor and compiler, a. How many bytes are required to represent the data type: char? 1) 1 2) 2 3) 3 4) 4 5) 8 b. How many bytes are required to represent the data type: int? 1) 1 2) 2 3) 3 4) 4 5) 8 c. How many bytes are required to represent the data type: short? 1) 1 2) 2 3) 3 4) 4 5) 8 d. How many bytes are required to represent the data type: long? 1) 1 2) 2 3) 3 4) 4 5) 8 e. How many bytes are required to represent the data type: float? 1) 1 2) 2 3) 3 4) 4 5) 8 18. A C source program is converted into an executable file with the help of: a. An b. A compiler c. An d. None of the above 140 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

19. Which among the following best describes a header file? a. A file that consists of functions b. A file that consists of definitions and macros c. A file that is a main source file d. A file that consists of standard library functions 20. State the difference between the following two #include directives:

#include <“Config.h”> #include Chapter Five

Software Engineering for Embedded Systems

5.1 LEARNING OBJECTIVES

We have tremendous flexibility when creating software; we make many decisions going from an idea to a final working system. There are technical decisions, such as which components we use to build a system, their internal structure, and how we interconnect them. Some of the technical decisions will lead to a product that works, but not all will. There are also process decisions, such as how we plan to build the system and how to select those components. Sim- ilarly, some process decisions can lead to an easier or more predictable development effort, while others will lead to project delays or cancellation, or can even bankrupt the company. A good software process will evolve over time, incorporating lessons learned from each pro- ject’s successes and failures. Hence a good process will make it easier to do the technical work. The goal of this chapter is to show how both process and technical issues need to be considered to successfully create a product on time and on budget. In this chapter we try to present just the most critical concepts to help the reader under- stand that “does the code work?” is one question, but not the only question to answer. There are many excellent books and articles which go into great depth on software engineering for embedded and general purpose software; a few are listed in the references section. For exam- ple, Jack Ganssle has a “top ten list” of why embedded systems projects get into trouble (Ganssle, J.). In this chapter we discuss how a good software engineering process addresses eight of them. Phil Koopman presents a detailed and practical book on embedded software development processes and issues (Koopman, P.). We will refer the reader to specific chapters in the latter text periodically in order to keep this chapter short and readable.

5.2 INTRODUCTION

5.2.1 Risk Reduction

Reducing risks is a driving force behind software engineering and project management. A software development organization can benefit by constantly refining its processes as it learns both what it does well, and how to improve what it does poorly.

141 142 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Developing embedded software is usually unpredictable. For example:

What if there is a bug in our code? What if the compiler sometimes seems to gen- erate buggy code? What if the code we need to write actually turns out to be a lot more complex than we thought? What if we don’t have enough memory for our program or its data? What if the processor can’t run our code fast enough? What if activating a motor resets the processor due to a weak power supply? What if that external A/D converter peripheral doesn’t seem to work the way the datasheet said it would? What if the lead developer wins the lottery and quits a month before the product deadline? What if the new developer we hired turns out to be incompetent, lazy, or both? What if half of our development team gets sick, is laid off, or is reassigned? What if the customer adds new requirements every week, or wants the product done two months early?

If any of these risks actually occur they will increase the amount of development work needed. Whether it affects the product development deadlines depends on how much overtime the development team is willing to put in, whether other developers can help out, whether anything in the development process turns out to be faster than ex- pected, and so forth. Missing deadlines will have negative financial impacts: project costs will increase and income from product sales will be delayed. Some of these risks also have other impacts: higher power consumption, fewer features, board redesign, and so forth. Ganssle identifies “Unrealistic Schedules” as the number one reason for embedded system project problems. Successful software organizations create a development plan for the project to show development tasks and output products, as well as risk management ap- proaches. Koopman discusses development plans in detail in Chapters 2 through 4 of his book Better Embedded System Software (Koopman).

5.3 SOFTWARE DEVELOPMENT STAGES

5.3.1 Development Lifecycle Overview

The embedded product lifecycle has multiple steps, as shown in Figure 5.1. The software process consists of multiple steps within the embedded product lifecycle. One example process model is the V model, shown in Figure 5.2. It consists of: CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 143

NEED/ OPPORTUNITY CONCEPT RETIREMENT/ DEVELOPMENT DISPOSAL

PRODUCT MANUFACTURING UPGRADES DESIGN PROCESS DESIGN

SUPPORT/ PRODUCTION MAINTENANCE DEPLOYMENT

Figure 5.1 The embedded product lifecycle. Courtesy P. Koopman.

Requirements Analysis

Validation provided by testing Requirements Functional Specification Testing Review Architectural Integration Design Testing Review Detailed Integration Design Testing Review

Coding S/W Unit Testing Review

Code

Figure 5.2 The “V” model of software development emphasizes testing at each level of de- sign detail.

Defining system requirements. Creating an architectural or high- level design, deciding on the general approach to build the system, and then creating appropriate hardware and software architectures. 144 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Creating detailed designs. Implementing code and performing unit testing. Integrating the code components and performing integration testing. Changing the code after “completion” to fit custom deployment requirements, fix bugs, add features, etc.

The process breaks a problem into smaller easier problems through the process of top- down design or decomposition. Each small problem is solved and the solutions are com- bined into a software solution. There are many approaches possible:

Do we design everything up front, and then code it? This is called a big up- front design. Do we have a prototype or a previous version which we can build upon? Do we design and build a little at a time? What do we work on first, the easy or the hard parts?

Which model we should use depends on the types and severity of risks. Some industries may be required to follow a specific development process in order for the product to re- ceive certification. Ganssle identifies “Poorly Defined Process” as reason number six for embedded system project troubles. In this chapter we will use an example embedded system to illustrate the issues involved. Our target system is an electronic chartplotter for boats. The chartplotter can display a depth chart on a graphical LCD with an icon superimposed to show the boat’s current position and direction, as shown in Figure 5.3. This helps the user steer the boat to avoid shallow water. Alternatively, we may choose to have a numerical display and omit the chart, as shown

Figure 5.3 Chartplotter screen with boat icon overlaid on depth chart. CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 145

Figure 5.4 Chartplotter screen with numerical depth and speed information.

in Figure 5.4. The chartplotter receives position, direction, and speed information from a GPS receiver, and depth and battery voltage information from a depth sounder. Later in this chapter we discuss various development models. At this point, it is suffi- cient to understand that there are different ways to “slice and dice” the work to be done, keeping in mind that we should develop each sub- system in the order: architect-design- implement. For example, don’t start writing code if you haven’t designed the algorithm yet. This sequencing is quite important, so we discuss it further.

5.3.2 Requirements

A system design begins with functional requirements. Ganssle identifies “Vague Require- ments” as reason number five for projects getting into trouble. Koopman presents an ex- cellent discussion of software requirements (Chapters 5 through 9) so we will just present a high- level view here.

Requirements should be written down. This helps everyone have the same picture of what needs to be accomplished, and makes omissions easier to spot. There are three types of requirements. Functional requirements define what the system needs to do. Nonfunctional requirements describe emergent system be- haviors such as response time, reliability, and energy efficiency. Constraints de- fine the limits on the system design, such as cost and implementation choices. There are multiple ways to express requirements, both in text and graphically. The most appropriate and convenient method should be used. Graphical methods 146 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

such as state charts, flow charts, and message sequence charts should be used whenever possible because (1) they concisely convey the necessary information and (2) they often can be used as design documents. Requirements should be traceable to tests. How will the system be tested to ensure that a requirement is met? Requirements should be quantified and measurable. The requirements should be stable. Frequent changes to requirements (“churn”) often have side effects and disrupt the ideal prioritization of work tasks. It is easy for the latest changed requirement to be interpreted as the most important require- ment, when in fact this is rarely the case.

5.3.3 Design Before Coding

One of the most effective ways to reduce risks in developing software is to design before writing code1. Ganssle identifies “Starting Coding Too Soon” as reason number nine for projects getting into trouble. We refer to high- level design as the architecture, and the low- level design as the detailed design.

Writing code locks you in to specific implementations of an algorithm, data structure, object, interface method, and so forth. If this happens before you under- stand the rest of the system, then you probably haven’t made the best possible choice, and may end up having to make major changes to the code you’ve written, or maybe even throw it away. Designing the system before coding also gives you an early insight into what parts are needed, and which ones are likely to be complex. This helps prevent the sur- prises which slow down development. One of the best ways of reducing schedule risk is to understand the system in depth before creating a schedule, and then add in extra time buffers for dealing with the risky parts. Estimation is the process of predicting how long it will take to create the system. Designs should include graphical documents such as flowcharts and state ma- chines when possible. The goal is to have a small and concise set of documents which define how the system should do its work. Graphical representations are easier to understand than code because they abstract away many implementation details, leaving just the relevant items2. This makes it easy for others to understand your design and identify risks. It also helps bring new hires up to speed on the proj- ect and reduces the chances they’ll break something when they start maintaining or enhancing the code.

1 There is related prior work in carpentry: Think thrice, mea sure twice, cut once. 2 Different businesses may have differing levels of formality (e.g., UML), but do not underestimate the benefit of a simple diagram (whether hand-written or created in Visio). CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 147

5.3.4 Peer Reviews of Design Artifacts

It is very helpful to have other team members review artifacts before proceeding to the next phase of development. First, having another perspective on an issue brings in greater expe- rience and helps detect oversights. Ganssle identifies “Bad Science” as reason number seven for projects getting into trouble. Second, if you know that someone else will be re- viewing what you are creating, you are likely to be more careful and professional. Peer re- views should be applied to all development artifacts: requirements, test plans, architec- ture, detailed designs, and code. We refer the reader elsewhere for more details on peer reviews (Koopman).

SONAR RxQ1 CurDepth UART CurLat Rx ISR CurLon CurTime Process CurDate Pri. GPS RxQ2 NMEA CurTemp user UART interf. data CurVelG Rx ISR CurVelW TxQ MemUsed UART Tx ISR Sec. user interf. Format and save data ISR Task

Flash Data Global Variable Memory

Figure 5.5 System architecture for chartplotter.

5.3.5 System Architecture and Design Approach

The system architecture defines your approach to building the system. What pieces are there, and how are they connected? What type of microcontroller and peripherals will be used? What major pieces of software will there be? How do they communicate? What will make them run at the right time? We present a summary of architectural concepts here, and encourage the reader to dig deeper in the referenced text (see Chapter 10 and Chapter 11 in Koopman). In Figure 5.5 we see the system architecture for the chartplotter. Sonar and GPS infor- mation is delivered through two serial ports to the system. We will use interrupt ser vice 148 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

routines and queues to buffer the data between the serial ports and the main application task code. There are four separate tasks in the system:

The Process NMEA Data task will receive the data from the sonar and GPS, de- code it, and update the relevant variables which indicate current depth, position, and so forth. The Primary User Interface task will update the display. The Format and Save Data task will convert the depth and other variables into a human- readable text format and write them to flash memory. The Secondary User Interface task will provide a serial console interface so we can read the logged data from flash memory, erase it, and perform other system main- tenance functions.

We also see how information is shared between tasks in the system:

Queues buffer the incoming and outgoing serial data. A table of global variables is written by Process NMEA Data and read by two other tasks.

How does this architecture meet the most critical aspects of the requirements? These may be related to time, safety, robustness, or something else which is application- specific. In any case it is important to convey these concepts.

Time- Critical Processing It is quite helpful to have a section in the architecture document which describes which processing is time- critical, and how the system is architected to ensure the timing re- quirements are met. For example, consider a light dimmer controller:

The system must switch power outputs within 50 microseconds of a zero- crossing of the AC power line. Failure to switching within this time will lead to electrical noise and inter- ference with other devices. The system is designed so that a hardware analog window com- parator detects zero crossings and triggers a non- maskable interrupt. All power output switching is performed by the ISR, which controls its outputs based on flags set by the main code which indicates which outputs to enable. Hence interrupts must not be disabled for longer than x microseconds. The system must shut down within 10 ms of an overcurrent or overvoltage condition oc- curring. Failure to shut down within this time can lead to equipment damage and failure. We plan to use a periodic interrupt running at 1 kHz in order to sample dedicated analog hard- ware comparators which detect these conditions. Because of the 1 kHz interrupt rate, inter- rupts must not be disabled for longer than 8 ms, in order to allow a 1 ms safety margin. CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 149

Further information on real- time system design is available in Chapter 14 of the refer- enced text (Koopman).

Safety- Critical Processing It is quite helpful to have a section in the architecture document which describes which processing is safety- critical and how the system is architected, to ensure the safety re- quirements are met. For example: The software tasks X, Y, and Z are safety- critical. They cannot be modified without trig- gering recertification. In order to ensure real- time per for mance, we use a preemptive scheduler and assign X, Y, and Z priorities higher than all other tasks. In order to minimize the chances of data corruption, all critical variables used by X, Y and Z are protected by storing them with complements or with a block CRC. Again, there is further detailed information in the referenced text (Chapters 26–30 in Koopman cover critical system properties).

5.3.6 Detailed Design

After we have decided upon an architecture for the system, we can work on designing the subsystems within it. Again, graphical representations can be quite useful; especially if the corresponding requirements are graphical, as in this and similar cases they can be reused. For example, state- based system behavior is best presented graphically. Figure 5.6 shows a finite state machine design for a UART Receive data ISR (the two circles labeled “UART Rx ISR” in Figure 5.5) which recognizes certain valid NMEA- 0183 messages and enqueues them for later decoding. Corrupted or unneeded messages are discarded, saving buffer space in RAM and processor time. These messages have a specific format which includes the talker type (GPS, depth sounder, etc.), the message type, multiple data fields (often with each fol- lowed by engineering units), and a checksum for error detection. We use an FSM- plus- ISR combination for two reasons. First, we want to minimize the amount of time spent in the ISR. Structuring the problem as an FSM allows us to write code which doesn’t waste any time waiting for things to happen. The ISR is only executed when the UART has received a byte of data. Second, parsing data such as text is a good match for FSMs as it allows us to define rules to step through the different fields in a mes- sage and validate them. Figure 5.7 shows a flowchart design for the task “Process NMEA Data” which decodes these enqueued messages and acts on the data. This code is much less time- critical, so it is implemented in a task which the scheduler runs after being notified that the RxQ holds at least one valid message. The flowchart emphasizes the consecutive and conditional pro- cessing nature of the activity: decode the message, check to see if it is valid or not, update variables, and so on. 150 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Any char. except *, \r or \n Append char to buf. Start ϩ $ Talker Inc. counter Append char to buf. Sentence *, \r or \n, or Type buf == $SDDBT, $VWVHW, or counter == 6 $YXXDR Enqueue all chars. from buf \r or \n Sentence Body Any char. except * Enqueue char * Enqueue char

Checksum 1 Any char. Save as checksum 1 Checksum 2 Any char. Save as checksum2, Increment # of msgs available Figure 5.6 Finite state machine design for recognizing NMEA-0183 depth below transducer, heading and speed through water, and battery voltage messages.

Start RxQ Decode NMEA Sentence Data In Invalid? Yes No Update CurPos Data Out Skip? Yes No Write to Data Flash

Update MemUsed

Data Out End

Figure 5.7 Flowchart for decoding NMEA sentence and saving data to flash memory. CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 151

There are various other representations available beyond these two workhorses, so we direct the reader other texts (see Chapter 12 and Chapter 13 of Koopman).

5.3.7 Implementation

Now that we have a detailed design it should be straightforward to proceed to the actual im- plementation of the code. C is the dominant programming language for embedded systems, followed by Cϩϩ and assembly language. C is good enough for the job, even though there are some languages which are much safer. The risk with C is that it allows the creation of all sorts of potentially unsafe code. Ganssle identifies “The Use of C” (or “The Misuse of C”) as reason eight for projects getting into trouble. There are a few points to keep in mind as you develop the code:

Three fundamental principles should guide your decisions when implementing code: simplicity, generality, and clarity (Kernighan and Pike). ▫ Simplicity is keeping the programs and functions short and manageable. ▫ Generality is designing functions that can work, in a broad sense, for a variety of situations and that require minimum alterations to suit a task. ▫ Clarity is the concept of keeping the program easy to understand, while re- maining technically precise. Code should conform to your company’s coding standards to ensure that it is easy to read and understand. See Koopman’s Chapter 17 for more information on why coding style matters. There are many coding standards examples available (Ganssle, J.). The rules we have seen broken most often, and which have the biggest payoff, are these: ▫ Limit function length to what fits onto one screen or page. ▫ Use meaningful and consistent function and variable naming conventions. ▫ Avoid using global variables. ▫ If you find yourself writing the same code with minor variations, it may be worth parameterizing the code so only one version is needed. Data sharing in systems with preemption (including ISRs) must be done very care- fully to avoid data race vulnerabilities. See Chapter 12 of this text and Koopman’s Chapters 19 and 20 for more details. Static analysis should be used to ensure that your code is not asking for trouble. Most (if not all) compiler warnings should be turned on to identify potential bugs lurking in your source code. Tools such as LINT are also helpful and worth considering. Magic numbers are hard- coded numeric literals used as constants, array sizes, character positions, conversion factors, and other numeric values that appear di- rectly in programs. They complicate code maintenances because if a magic num- ber is used in multiple places, and if a change is needed, then each location must 152 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

be revised and it is easy to forget about one. Similarly, some magic numbers may depend on others (e.g., a time delay may depend on the MCU’s clock rate). It is much better to use a const variable or a preprocessor #define to give the value a meaningful name which can be used where needed. It is important to track available design margin as you build the system up. How much RAM, ROM, and nonvolatile memory are used? How busy is the CPU on average? How close is the system to missing deadlines? The Software Gas Law states that software will expand to fill all available resources. Tracking the resource use helps give an early warning. For more details, see Koopman’s discussion on the cost of nearly full resources. Software configuration management should be used as the code is developed and maintained to support evolving code and different configurations as well.

5.3.8 Software Testing

Testing is an important part of software development. It is essentially impossible to develop error- free non- trivial software in a single try. It is especially difficult to design up- front a sys- tem which will handle all possible input conditions (including failures) correctly. Ganssle iden- tifies “Inadequate Testing” and “Writing Optimistic Code” as reasons number three and two for projects getting in trouble. Koopman covers verification and validation of systems in detail. Testing the developed software ensures that the product meets the requirements de- fined. That is, testing proves that the software does what it is supposed to do. A corol- lary is that testing identifies the software’s weaknesses. These defects are typically prior- itized based on their criticality. Although one can never completely test a program, some tests are more useful and im- portant than others. Hence, it makes sense to think while planning the tests in order to get the biggest return. Testing should be a logical, disciplined, and systematic process, rather than a rote and mechanical process. As with other subjects covered here, there are many excellent texts on software testing for further information (Phillips). There are several inde pen dent dimensions of testing to consider:

Software tests may or may not depend on the internal details of how the module is built. Black box testing assumes no knowledge about the internal structure, and focuses instead on functionality. White box (or clear box) testing takes advantage of such knowledge, so it can be more efficient in finding faults. Software testing should be done at various phases of the development process. Unit tests are performed during coding on a per- module basis. Integration tests are performed as the system is assembled (integrated) from modules. Regression testing ensures that past bugs which were fixed have not been re- introduced. CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 153

Do We Know How the System is Built? Black Box Testing tests the functionality of the software by treating it like a black box with unknown contents. How the software performs a task is unknown and unimportant to the test. The only needed thing to pass the test is for the software to do what it should. There are many types of black box testing. Among them are tests for readiness, finite state machine, cause- effect graphing, boundary value testing, and user profile:

Readiness: This test checks if a function is present and functional, and ready for testing. Black box testing should always begin with this form of testing. Finite state machine: Much software can be considered as finite state machines that transit between different states based on different events. This form of testing tests the transitioning between states and for errors that may occur with them. Cause effect graphing: This form of testing helps to organize the concepts in other black box techniques. For this test, the tester organizes all possible inputs and out- puts of a program. This results in a form of a complete software test and helps to systematically organize test cases. Boundary value testing: In this form of testing the inputs to the test system are di- vided into meaningful sets and then tested in groups. One value from each set is then input to the system rather than the whole set. This helps save time. User profile: This form of testing focuses on how the user intends to use the soft- ware and which errors are important to their proper functioning while using the software. This minimizes the amount of time needed to be put into testing. How- ever, learning what part of the program is used often is the difficult part of the test.

White Box Testing relies on knowledge of the structure of the software. It is also known as clear box testing. How the software performs a task is known to the testers, enabling them to identify probable errors. Important elements of white box testing are coverage and branch and conditioning testing.

Coverage: The aim of white box testing is to cover every statement, state, and path in a program within the constraints of time and money. This can be a daunting task, especially if the program has many conditional statements. Branch and condition testing: The goal of branch testing is to traverse every path through the program. One way to do this is to use a flow chart of the program. The first test goes through one part of the program. The next one differs from the one be- fore. In this manner, all paths are traversed, even those that share a common part.

How Many Modules Do We Test at a Time? Individual unit testing of modules is typically done by the software developer as the code is created. As the developer has intimate knowledge of the implementation of the module, 154 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

this testing is typically white- box testing to maximize the effectiveness. The developer writes test harness code to run the unit under specific conditions and verify the correct re- sponses. Unit testing is quite effective because if there is a bug, it is in that module’s code, design, or requirements. With integration testing each module is merged into the main program and is tested to check if it works individually as well as with the rest of the program without causing any errors. There are often scenarios where a subroutine works perfectly on its own, but fails when integrated into the overall system due to unexpected dependencies, requirements, or interactions. There are various types of integration testing: Bottom up, top down, sandwich, and build. Selecting the type of integration testing depends upon the people and product in- volved in development.

Bottom up: This is one of the classic approaches for design and testing. Each prob- lem is broken down into smaller parts and solutions are written for them, also called modules. Each module is tested individually and combined into subsystems which in turn are also tested and then combined into a larger system. This goes on till the complete solution is acquired and tested. Top down: The top down form of integration testing is similar to the bottom up form, but starts with a fully tested main routine. Modules are added to the main routine one after the other and tested as a combination. The process thus continues until all the modules have been added to the main program and tested. Sandwich: The sandwich testing form combines the bottom up and the top down forms of testing. The top down part tests the main controlling subsystems whereas the bottom up part integrates and tests the individual modules into subsystems. Build: The build form of integration testing starts with a core system to which functionally related module sets are added consecutively.

There is also a “worst- practice” integration testing method known as Big Bang testing. With this form of testing, all modules are combined and tested as a whole. Big bang testing is not advisable with untested modules as diagnosing the error can be very difficult— which of the many modules is really causing the problem? Or is an interaction between two or more modules the cause?

How Do We Keep from Breaking Old Bug Fixes? The goal of regression testing is to ensure that bugs which were found in past testing were fixed and are still fixed. Sometimes an effort to fix a bug introduces other bugs. Regression testing uses a suite of tests which triggered bugs in the past. Automated regression testing allows developers to verify quickly and easily that their bug fix really is a fix. Regression testing may be applied to both unit and integration testing. CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 155

5.4 SOFTWARE DEVELOPMENT LIFECYCLE MODELS

We now discuss software development lifecycle models in more detail. We can divide them into two categories: waterfall (big up front design) and everything else (build a piece at a time). The advantage of the latter approaches is that they deliver portions of the implemen- tation to the customer and other stakeholders earlier. This allows problems and misconcep- tions to be found earlier, and therefore fixed without disrupting the schedule as much. Proj- ects with greater risks will benefit more from more iterative approaches, while less risky projects may be implemented more efficiently with a less iterative approach. This chapter only provides a general description of these software processes. Further details can be found in the references of this chapter.

5.4.1 Waterfall Process

The waterfall model of software development is an idealized process which assumes that we know everything up front. The process gets its name because the processes flows down the steps like falling water. This process is most appropriate when the problem is very well understood so there is little risk. The following are the steps for the waterfall process:

1. Determine user needs 2. Gather requirements 3. Design 4. Build 5. Test 6. Demonstrate user product

Figure 5.8 illustrates the waterfall process. In practice, there are often arrows jumping back up the waterfall3 which makes this model an idealization.

User Needs Requirements Design Waterfall Process Build Test User Product Figure 5.8 The waterfall process expressed as a V- chart.

3 Imagine salmon leaping upstream over the rapids. 156 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

5.4.2 Iterative Process

The iterative process is used to deliver a product in increments. The customers define the goals of the product at the beginning of development and are always anxious to have some- thing quickly working. The iterative process provides the product to the customer in parts and provides developers an opportunity to learn about the product and the customer while building the product. This type of process is typically used when there is enough time for developing a project in parts and the customer is eager to provide on the how the product functions while it is being developed. Figure 5.9 illustrates the iterative process.

First Second Third Delivery Delivery Delivery

Figure 5.9 Example of an iterative process with one development team, expressed as a V- chart.

5.4.3 Spiral Process

The spiral process combines many fundamental contents of different process models into a single process. This process works best for projects that have a high risk of failure, such as research projects dealing with developing a new technology. Figure 5.10 illustrates the spi- ral process. Each cycle starts with the steps shown in the upper left quadrant, which are ob- jectives (goals to achieve), constraints (limitations on resources), and alternatives (different approaches to achieve the objectives). The second quadrant (clockwise direction) shows the next steps in the process, which are risk analysis and prototyping. It begins with alter- natives produced in the first quadrant. The developers then use the prototypes to analyze each alternative’s risks and gain more insight. The third quadrant consists of the evaluation and decision making processes, followed by building the solution. The final quadrant con- sists of understanding what to do for the next cycle, which is repeated in the first quadrant. The developers revise the previous phases and create a plan for the next quadrant, review the same, and then decide whether to go ahead with the plan or stop building the project. CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 157

Acquire Objectives Evalute the risk Acquire Constraints using prototyping Acquire Alternatives

Evalute product Evalute the risk aversion approach. Plan the next cycle Build the product Continue or stop of the cycle

Figure 5.10 The general spiral process.

5.4.4 Agile Development Methods

The most common agile development methods are scrum, extreme programming, and lean development. These methods seek to deliver the product to the customer in satisfactory condition as early as possible in a continuous manner. Let’s examine scrum. With scrum, development activity is divided into a series of sprints lasting two to four weeks. At the end of the sprint the team will have a working, de- liverable software product. There are three main types of participants:

The product owner speaks for the customer. The team delivers the product. The Scrum Master is responsible for eliminating obstacles from the team’s path.

Each sprint begins with the team members and product owner discussing features from a pri- oritized feature list (the product backlog). The product owner identifies the desired features, and the team estimates which can be delivered within the sprint, adding them to a task list called the sprint backlog. The sprint backlog is frozen for the sprint, so that the team members have clear goals during that development period. Each day during the sprint there is a brief (fif- teen minute) status meeting in which each team member answers three specific questions:

What have you done since yesterday’s meeting? What are you going to do today? Are there any issues keeping you from meeting your goals?

The Scrum Master then seeks to address the issues. Finally, each sprint is time- boxed. If a feature is not completed by the end of the sprint, it goes back into the product backlog. One 158 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

of scrum’s main strengths is the short development cycle, which improves the speed of feedback. There are other aspects to scrum which we do not cover here, but further details are available in numerous texts on the subject.

5.4.5 Prototyping

Prototyping is a popular and useful software process, especially when determining the look and feel of the software has a higher priority than its basic functions. One of the drawbacks of the prototyped process is that when the waterfall model of development is used the de- veloper may create something completely different from what the customer expected, since the requirements are gathered only at the beginning of the development process. Thus, pro- totyping is better when it is performed as either an iterative or evolutionary process. Two basic types of prototypes used are the throw away and evolutionary prototype. In the throw away prototype, developers use a demonstration tool or language. Once the cus- tomer is satisfied with the prototype, the developers throw away the prototype and build the actual product with real programming languages. In the evolutionary prototype, the devel- opers use code from the prototype in the actual system.

5.5 RECAP

A major risk of software development is starting coding too early. Designing the system and its components before coding reduces development risks significantly, and also provides other benefits. Industry follows many (and sometimes differing) processes when developing soft- ware. A process gives a directional path to developing software in an orga nized manner, and allows the people developing the software and using the software to maintain expectations from the development process at regular intervals. Pseudo code and graphical methods to design solutions to a software programming problem allows understanding, resolving, and maintaining logical flow of a pro- gram. They can also be directly included in the documentation for the program. Testing is an integral part of software testing and software not subjected to testing is bound to fail. There are different techniques available for testing which should be applied as appropriate.

5.6 REFERENCES

Ganssle, Jack. “Breakpoints: Jack’s Top Ten.” Embedded Systems Design, December (2006): 61–63. Print. Ganssle, Jack. The Art of Designing Embedded Systems. 2nd ed. Lawrence, KS: Newnes, 2008. Print. CHAPTER 5 / SOFTWARE ENGINEERING FOR EMBEDDED SYSTEMS 159

Kernighan, Brian W., and Rob Pike. The Practice of Programming. Indianapolis: Addison- Wesley, 1999. Print. Koopman, Philip J. Better Embedded System Software. New Castle, PA., Drumnadrochit Education, 2010. Print. Phillips, Dwayne. The Software Project Manager’s Handbook: Principles That Work at Work. Los Alamitos, CA: John Wiley & Sons, 2004. Print.

5.7 EXERCISES

1. Create a set of requirements for a vending machine which accepts coins and one- dollar bills, and provides change. Assume that each type of item has its own button. 2. Create a set of requirements for a controller for an elevator in a ten-story building. 3. Create a state machine for use in a cellphone to identify local phone numbers, long-distance phone numbers, and invalid phone numbers. 4. Estimate how long it will take you to create a working program to flash the LEDs on your favorite microcontroller board at a frequency proportional to the ambient Celsius temperature. Then go ahead and create the program. Log the time spent for each development activity. Analyze the time required for each activity, the accu- racy of your estimations, and finally suggest improvements.

Chapter Six

Converting Between the Analog and Digital Domains

6.1 LEARNING OBJECTIVES

Embedded systems often measure physical parameters such as light intensity and tempera- ture. These parameters are analog but the embedded system’s microcontroller requires dig- ital values to work on. An Analog to Digital Converter (ADC) is used to convert those pa- rameters into a digital form. In some cases, the microcontroller may need to provide analog signals to another sys- tem. For this, the digital output produced by the microcontroller has to be converted to ana- log an analog before being fed to the interfaced system. A Digital to Analog Converter (DAC) is used for this purpose. In this chapter we will learn about:

Ⅲ Converting an analog value to digital, mathematically Ⅲ ADCs in the RX62N Ⅲ Setting up registers and using the 12-bit and 10-bit ADC Ⅲ Using a DAC

6.2 BASIC CONCEPTS

A microcontroller represents information digitally: a voltage less than Vcc/2 represents a logical 0, while a voltage above Vcc/2 represents a logical 1. An analog signal can represent an infinite number of possible values. For example, consider an electronic thermometer with an output voltage which is proportional to the temperature in Celsius: Vout ϭ Temper- ature*0.05 V/°C. At 5° C, Vout ϭ 0.25 V. At 40° C, Vout ϭ 2.0 V. At 40.1° C, Vout ϭ 2.005 V. If we connect this thermometer directly to a microcontroller’s digital input we will not be able to measure temperatures very accurately. In fact, we can only determine if the volt- age is above or below Vcc/2. Assuming a supply voltage of 3.3 V, we can only determine if the temperature is above or below (3.3 V/2)/(0.05 V/°C) ϭ 33° C, throwing away all other

161 162 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

temperature information. In order to preserve this information we need a more sophisti- cated conversion approach.

Analog Input

Digital Output (bits)

Reference Voltage

Figure 6.1 Simple ADC.

An ADC measures an analog input voltage and determines a digital (binary) value which represents it best. This measurement process is called quantization. The conversion is based on reference voltages which define the high (VϩRef) and low (VϪRef) ends of the input voltage range. Often microcontrollers have VϪRef connected to ground (0 V).An input voltage of VϩRef will result in an output code which is all ones, while an input voltage of VϪRef will result in an output code of all zeroes. An intermediate input voltage will result in the proportional binary code value. This is discussed in more detail in Section 6.2.3. A block diagram for a simple ADC is shown in Figure 6.1. The number of bits in the digital output is called the resolution of the ADC. A 10-bit ADC produces an output with 10 bits, with 1024 (210) different binary outputs. Thus, in a 10-bit ADC, a range of input voltages (analog) will map/translate to a unique binary output (0000000000 to 1111111111). A 12-bit ADC will have 4096 (212) unique binary outputs to represent 0 to 100% of an analog input. Quantization usually introduces some error. A specific code (e.g. 0000101010) corre- sponds to a range of analog input voltages. The term quantization error describes how large the error can be. An ADC with higher resolution has more binary codes possible, which reduces the range of voltages corresponding to each code. This reduces the quanti- zation error.

1 Quantization error ϭ , where N ϭ number of quantization levels. (2*2N)

The rate at which new outputs are calculated in an ADC is called the conversion rate or sampling frequency. Sampling theory states that an input signal with no frequency compo- CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 163

nents greater than or equal to one half of the sampling frequency (called the Nyquist fre- quency) will be completely and accurately represented by the samples. If the input signal has any frequency components above the Nyquist frequency, these will be aliased by the sampling and appear as noise in the signals (as lower frequency components). Hence input signals may be bandwidth-limited with a low-pass filter before sampling and quantization. In addition, the system is typically designed so that the Nyquist fre- quency is well above the filter’s corner frequency, allowing the use of less expensive, lower-order filters.

Sampling Switch Output Signal

Hold Capacitor Input Signal AC

Figure 6.2 Sample and hold circuit.

Some types of ADC will generate incorrect results if the analog input signal changes too much during the conversion time. To avoid this problem, a sample and hold circuit (shown in Figure 6.2) can be used to sample the input voltage and save it in a capacitor. The capacitor is then disconnected from the input voltage by opening the sampling switch. The output signal can then be sampled by the ADC without interference from the changing input.

6.2.1 Analog to Digital Conversion by Successive Approximation

Analog to Digital conversion can be performed using many methods, such as Flash Con- version, Dual Slope Integrating, and Successive Approximation. The ADC method used in the RX62N board is Successive Approximation. Conversion using this method gives good resolution and has a wide range. In the Successive Approximation method, the input voltage is repeatedly compared with the output of a DAC, until the best approximation is achieved. The DAC is fed by the current value of the approximation. The binary value of the approximate is found in every step of this method and is stored in the SAR. The SAR then compares the binary value and the reference 164 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

voltage. Successive Approximation requires the same number of clock cycles as the output bits of the ADC; i.e., 12-bit ADC requires 12 clock cycles and 10-bit ADC requires 10 clock cycles (ADC clock cycles, not CPU clock cycles) to perform A/D conversion. This process can be better understood with an example. The reference voltage for the RX62N board is 3.3 V. Let us assume that an input voltage of 2.5 has to be converted to digital form and the ADC used is 10-bit. In the first clock cycle, 2.5 V is compared with 1.65 V (voltage is generated by the DAC and is half the reference voltage of 3.3 V). The 2.5 V is greater than 1.65 V and hence a ‘1’ is set at the MSB of the binary value of the approximate, making the value 1xxxxxxxxx. This value is stored in the SAR. In the second clock cycle, the input (2.5 V) is compared with 2.47 V (halfway between 1.65 V and 3.3 V). Since the input (2.5 V) is greater than the output from DAC (2.47 V), the next bit of the binary value is set to ‘1.’ The binary value of the approximate is now 11xxxxxxxx. In the third clock cycle, the input (2.5 V) is compared with 2.89 V, (halfway between 2.47 V and 3.3 V). The input (2.5 V) is less than the output from DAC (2.89 V), so the next bit of the binary value is set to ‘0.’ The binary value of the approximate is now 110xxxxxxx. In the next cycle, the input (2.5 V) is compared with 2.68 V, (halfway between 2.47 V and 2.89 V). The input (2.5 V) is less than the output from DAC (2.68 V), so the next bit of the binary value is set to ‘0.’ The binary value of the approximate is now 1100xxxxxx. The same process takes place until all the bits of the binary value are found. The final result of this conversion is 1100000111.

Analog Input

Voltage XXXXXXXXX 1XXXXXXXXX 11XXXXXXXX 110XXXXXXX 1100XXXXXX 11000XXXXX 110000XXXX 1100000XXX 11000001XX 110000011X 1100000111

T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 Start of Conversion Time Figure 6.3 A/D conversion using successive approximation. CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 165

Gereration of A/D converstion start condition

Input sampling timing ϷϷ

ADI

tD tSPL tSAM tCONV

[Legend] tD: A/D conversion start delay time tSPL: Input sampling time tSAM: Successive conversion time tCONV: A/D conversion time

Figure 6.4 ADC conversion timing. Source: Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/ RX600 Series. Renesas Electronics America, Inc., 2010, page 1748.

6.2.2 Conversion Speed

The analog input is sampled after A/D conversion start delay time (tD). Input sample time (tSPL) is the time that the capacitor in the sample and hold circuit takes to charge. Succes- sive conversion time (tSAM) is the time after which the next conversion can start. It is fixed at 25 ADC clock cycles. Conversion time (tCONV), or sampling time, is the inverse of conversion speed or sampling frequency. Conversion time is the sum of tD, tSPL, and tSAM only during the first conversion. The following conversions always have a conversion time of tSPL and tSAM. A/D Sampling State Register (ADSSTR) gives the flexibility of altering the sampling time. One may want to alter this if the analog input signal has high impedance or if the ana- log input is a fast changing signal and the original sampling time is insufficient, or when the Peripheral module clock (PCLK) is slow.

6.2.3 Transfer Function Calculation

The digital value for a particular analog value can be found mathematically. This can be useful as a guide to see if the ADC output obtained is correct. 166 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

SETTING EXAMPLE OF SETTING RANGE SAMPLE TIME* Standard (initial value) 19h 0.5 ms (When PCLK ϭ ADCLK ϭ 50 MHz) Analog input signal impendance is 1Ah to FFh Example: FFh high and the sampling time may be 5.1 ms (When PCLK ϭ ADCLK ϭ 50 MHz) insufficient Input sampling time is less than the 02h to 18h Example: 14h initial value when ADCLK is below 0.5 ms (When PCLK ϭ ADCLK ϭ 40 MHz) 50 MHz.

Figure 6.5 ADSSR settings. Source: Hardware Manual, page 1748.

FORMULA

ITEM SYMBOL MIN MAX

A/D conversion start delay time (1) ID 3 1 ϩ 4 PCLK (MHz) ADCLK (MHz) PCLK (MHz) Input sampling time (2) ISPL Setting value of ADSSTR ADCLK (MHz) Successive conversion time (3) ISAM 25 ADCLK (MHz) A/D conversion time*1 ICONV (1) ϩ (2) ϩ (3) A/D conversion time*2 ICONV (2) ϩ (3)

Notes: 1. A/D conversion time in single mode and scan mode (first round) 2. A/D conversion time in scan mode (after the second round)

Figure 6.6 ADC conversion time. Source: Hardware Manual, page 1749.

If Vin is the sampled input voltage, Vϩref is the upper end of the input voltage range, VϪref is the lower end of the input voltage range, and n is the number of bits of resolution in ADC, then the digital output (n) can be found using the following formula:

N (V Ϫ VϪ )(2 Ϫ 1) 1 n ϭϩin ref int c Vϩref Ϫ VϪref 2 d CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 167

N (Vin)(2 Ϫ 1) 1 n ϭϩint (if V Ϫref ϭ 0) c Vϩref 2 d

6.3 BASIC EXAMPLES

6.3.1 Conversion Speed

Let us calculate the conversion time for the first conversion. Let PCLK ϭ ADCLK ϭ 50 Mhz, and ADSSR is the standard value of 19h. From Figure 6.6, it can be seen that for the first conversion:

tCONV ϭ (tD ϩ tSPL ϩ tSAM) tCONV ϭ (3 / PCLK ϩ ADSSR / ADCLK ϩ 25 / ADCLK)

ADSSR value is 19h or 2510. Decimal value has to be used for calculation.

tCONV ϭ (3 / 50 MHz ϩ 25 / 50 MHz ϩ 25 / 50 MHz) tCONV ϭ (0.06 ms ϩ 0.5 ms ϩ 0.5 ms) tCONV ϭ 1.06 ms

While calculating conversion time for the second and subsequent conversions,

tCONV ϭ (tSPL ϩ tSAM).

6.3.2 Digital Value for a Given Analog Value

Let us assume that the analog voltage to be calculated is 2.7 V and the 12-bit ADC has to be used. The digital value will be:

N (Vin)(2 Ϫ 1) 1 n ϭ ϩ int (Since VϪref ϭ 0) c Vϩref 2 d 12 Ϫ ϭ (2.7)(2 1) ϩ 1 c 3.3 2 d

ϭ (2.7)(4095) ϩ 1 c 3.3 2 d

n ϭ 335210 168 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

6.3.3 Step Size

While reference voltage is the maximum analog value that can be converted to digital form, step size is the smallest change in voltage that can be converted. Step size is also known as the resolution of the ADC.

(Vref) Step Size ϭ (Since VϪ ϭ 0) 2N ref

(3.3) The step size for 10-bit ADC ϭϭ3.2 mV 210 (3.3) The step size for 12-bit ADC ϭϭ0.8 mV 212

The resolution (step size) of the 12-bit ADC is much better than that of the 10-bit ADC. Hence, for applications, which need to detect very small changes in voltage, 12-bit ADC should be used.

6.4 ADVANCED CONCEPTS

The RX62N has a 12-bit and a 10-bit A/D converter. Depending on the resolution the application needs, either the 12-bit or 10-bit ADC should be selected. By default peripher- als are in the stop state. They can be enabled by using the Module Stop Register A or B (MSTPRA or MSTPRB). To use the 12-bit ADC, SYSTEM.MSTPCRA.BIT.MSTPA17 must be set to 0; and to use the 10-bit ADC, SYSTEM.MSTPCRA.BIT.MSTPA22 and SYSTEM.MSTPCRA.BIT.MSTPA23 must be set to 0. The ADC has eight channels (AN0 to AN7). They are at Port 4 pin 0 to 7. To use a par- ticular channel, the respective port has to be set up as input. For example, to use AN0, port 4 pin 0 use PORT4.DDR.BIT.B0 = 0. For inputs, the Input Buffer Control Register (ICR) also has to set up. This can be done using PORT4.ICR.BIT.B0 = 1. Next, the ADC registers have to be set up. The 12-bit ADC and the 10-bit ADC have different registers. In this section we shall see how to set the registers and use the use the different operating modes of the ADCs.

6.4.1 12-Bit A/D Converter

The ADC usually consists of a sample and hold circuit and a comparator. The sample and hold circuit gets a one- time snap shot of the analog input (voltage) and this is compared against a reference voltage using the comparator. CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 169 r External trigger (ADTRG0#) Interrupt signal end) (A/D conversion A/D conversion trigge A/D conversion (MTU, TMR) (MTU,

Bus interface ACSTRGR ADCER

ADANS Control circuit

ADADC (including decoder) ADADS ADREF ADCSR Comparator ϩ Ϫ

ADDR0 to Sample & ADDR7 hold circuit Block diagram of 12-bit ADC.

Analog Succesive approximation

register 6.7 Figure ...... 12-bit D/A Power generator (for self(for test) AD0 LL DF AV AV ...... VRERL VREFH Impedance Impedance converting circuit converting converting circuit converting ...... AN0 AN7 170 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Registers The 12-bit ADC registers are presented as structures and unions for easy manipulation, just like the ports, in the ‘iodefine_RX62N.h’ file. The registers can be accessed using the syntax S12AD.REGISTER.WORD to set up an entire register or S12AD.REGISTER.BIT.BIT_ NAME to set up a particular bit of a register.

(A to H ؍ A/D Data Registers n (ADDRn) (n The 12-bit ADC has eight Data Registers each corresponding to the input channels of the ADC. A/D data registers ADDRA to ADDRH are 16-bit read- only registers. They store the A/D conversion results of channels AN0 to AN7. The width of the ADDRn (16-bit) is greater than the width of the ADC output (12-bit). To avoid reading wrong data, the output has to be aligned either to the right or left of ADDRn. This can be done using the A/D Con- trol Extended Register (ADCER). This is explained a little later.

A/D Control Register (ADCSR) The ADCSR is used to select different settings of the ADC.

Address: 0008 9000h b7 b6 b5 b4 b3 b2 b1 b0

ADST ADCS — ADIE CKS[1:0] TRGE EXTRG

Value after reset: 0 0 0 0 0 0 0 0

Figure 6.8 A/D control register. Source: Hardware Manual, page 1717.

The b0 bit is used to specify if an external trigger, ADTRG0# (port 0 pin 7), should start A/D conversion. If 1 is set, the microcontroller starts A/D conversion when a trigger is re- ceived. The value 0 is set when A/D conversion is to be started by other means. To receive the external trigger (if b0 ϭ 0), the external trigger has to be enabled. This is done by setting b1 bit to 1. The value 0 disables external trigger. The frequency of the ADC clock can be selected using the following table. PCLK is the peripheral clock. CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 171

TABLE 6.1 Clock Selection.

b3 b2 FUNCTION 0 0 PCLK/8 0 1 PCLK/4 1 0 PCLK/2 1 1 PCLK

The A/D Scan Conversion End Interrupt Enable (ADIE) bit is used to enable or disable A/D interrupt after A/D conversion has been performed. Setting this bit to 0 disables the in- terrupt, and setting it to 1 enables this interrupt. The A/D Scan Conversion Mode Select (ADCS) is used to select mode of operation of the ADC. Setting this bit to 0 selects Single Cycle Scan Mode, and setting it to 1 selects continuous mode. The A/D Conversion Start (ADST) is used to stop/start the A/D conversion. Setting this bit to 1 starts the ADC and setting it to 0 stops the ADC. If ADC is to be started using soft- ware trigger, ADST must be set to 1 only after all the ADC registers have been set up. Hence set ADST ϭ 0 when setting up this register initially.

A/D Channel Select Register (ADANS) This register is 16 bits wide and is used to select the channel(s) on which A/D conversion should be performed. The top 8 bits (b15 to b8) are reserved and the bottom 8 bits (b7 to b0) are used to select channels. To select a channel, set the corresponding bit to 1. For ex- ample, to select channel 0, set S12AD.ADANS.WORD ϭ 0x0001; and to select all eight channels set S12AD.ADANS.WORD ϭ 0x00FF.

A/D-Converted Value Addition Mode Select Register (ADADS) The 12-bit ADC has a special setting which is called the Converted Value Addition Mode. This setting is used to successively convert and sum two to four times the channels that have been selected using the ADANS register. To perform value addition on a particular channel, set S12AD.ADADS.BIT.ADS [n] ϭ 1 (n ϭ 0 to 7). 172 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Address: 0008 9008h

b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1

— — — — — — — ADS[7:0]

Value after reset: 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Figure 6.9 A/D converted value addition mode select register. Source: Hardware Manual, page 1720.

To understand value addition better, let us consider an example in which all eight channels have been selected (S12AD.ADANS.WORD ϭ 0x00FF) and value addition is to be per- formed on channels 2 and 6.

Continuous conversion count

3 times

4 times AN2 AN6 AN2

3 times AN2 AN6 AN2

2 times AN2 AN6 AN2

1 time AN0 AN1 AN2 AN3 AN4 AN5 AN6 AN7 AN0 AN1 AN2 . . . .

Conversion in progress

Figure 6.10 A/D converted value addition mode. Source: Hardware Manual, page 1720.

According to our example, analog inputs at channels 0, 1, 3, 4, 5, and 7 are A/D converted once, but inputs at channels 2 and 6 are successively converted four times (the number of times can be changed) and added. This added value is stored in the A/D data register. Find- ing the average of this value can improve A/D conversion accuracy.

A/D-Converted Value Addition Count Select Register (ADADC) The ADADC is the register that is used to select the number of times the value adding has to be performed. This register is an 8-bit register. The top 6 bits are reserved and the lower CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 173

2 bits (b1, b0) are used to select the value addition count. Value addition can be performed two to four times. The setting for the value addition count can be seen from the following table.

TABLE 6.2 A/D Converted Value Addition Count Setting.

b1 b0 FUNCTION 0 0 1-time conversion (no addition) 0 1 2-time conversion (addition once) 1 0 3-time conversion (addition twice) 1 1 4-time conversion (addition three times)

A/D Control Extended Register (ADCER) The ADCER is a 16-bit register. All bits except bit 5 and bit 15 of this register are reserved. Bit 5 is for Automatic Clearing Enable (ACE). Thus, setting bit 5 to 1 enables automatic clearing of the Data Register once the A/D value has been read by the microcontroller. This setting makes sure that older A/D values are not read by mistake. Bit 15 (ADRFMT) of the ADCER is used to select the format of the Data Register. Set- ting bit 15 to 0 sets the format of the Data Register to right alignment. Setting this bit to 1 selects left alignment of Data Register. However, if the A/D converted value addition mode is selected, this formatting becomes void. Selection of the value addition mode automati- cally sets left alignment format for the Data Register. Note that the number of bits output after value addition is fourteen and not twelve.

A/D Start Trigger Select Register (ADSTRGR) The ADSTRGR is an 8-bit register. The top four bits (b7 to b4) of this register are reserved and the lower four bits (b3 to b0) are used to select the type of trigger that will start the Analog to Digital Conversion process.

Address: 0008 9010h

b7 b6 b5 b4 b3 b2 b1 b0

— — — — ADSTRS[3:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 6.11 A/D start trigger select register. Source: Hardware Manual, page 1723. 174 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

A/D conversion can be started by one of three sources. They are a) Multi- function Timer pulse Unit (MTU) and Timer (TMR), b) external trigger (ADTRG0#), and c) Software Trigger. To choose a type of trigger, use the following table.

TABLE 6.3 Trigger Selection.

MODULE SOURCE REMARKS ADSTRS[3] ADSTRS[2] ADSTRS[1] ADSTRS[0] ADC ADST Software trigger — — — — External ADTRG0# A/D conversion startup 0 0 0 0 input trigger pin MTU TRG1N Input capture/compare 0 0 0 1 match A from MTU0 TRG2N Input capture/compare 0 0 1 0 match B from MTU0 TRG3N Input capture/compare 0 0 1 1 match from MTU0 to MTU4 TRG4N Input capture/compare 0 1 0 0 match from MTU6 to MTU10 TRG5N Compare match E from MTU0 0 1 0 1 TRG6N Compare match F from MTU0 0 1 1 0 TRG7N Compare match from MTU4 0 1 1 1 TRG8N Compare match from MTU10 1 0 0 0 TMR TRG9N Compare match from TMR0 1 0 0 1 TRG10N Compare match from TMR2 1 0 1 0

Source: Hardware Manual, page 1723.

When the MTU and TMR are to be used as the trigger, the TRGE bit in ADCSR has to be set to 1 and the EXTRG bit in ADCSR has to be set to 0. When an external input is to be used as the trigger (ADTRG0#), the TRGE bit in ADCSR has to be set to 1 and the EXTRG bit in ADCSR has to be set to 1. ADTRG0# has to be set up as an input pin and ICR has to be enabled. Software trigger is enabled at all times irrespective of the values set using TRGE, EXTRG, and ADSTRGR bits in ADCSR. CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 175

Let us now look at an example of setting up the registers of the 12-bit ADC. It is al- ways better to write register set up as a function.

1. void ADC_Init(){ 2. SYSTEM.MSTPCRA.BIT.MSTPA17 = 0; 3. S12AD.ADCSR.BYTE = 0x0C; 4. S12AD.ADANS.WORD = 0x01; 5. S12AD.ADCER.BIT.ACE = 1; 6. S12AD.ADCER.BIT.ADRFMT = 0; 7. }

The setting up of registers has been written as a function named ADC_Init() in line 1. In line 2, the 12-bit ADC has been selected using the Module Stop Control Register A. In line 3, the Control Register is set up—the Software trigger has been enabled (b1 ϭ 0, b0 ϭ 0), the clock PCLK (b3 ϭ 1, b2 ϭ 1) has been selected, A/D Interrupt Enable has not been enabled (b4 ϭ 0) and Single- Cycle Scan mode has been selected (b6 ϭ 0). In line 4, chan- nel 0 (AN0) has been selected. Next, automatic clearing of ADDRn (line 5) and right align- ment of ADDRn (line 6) is done.

Operation The 12-bit ADC is capable of operating in two modes: single- cycle scan mode and contin- uous scan mode.

Single- Cycle Scan Mode In this mode, one to eight channels (number of channels selected using ADANS register) are scanned/converted to digital once in ascending order and then the ADC is stopped. This can be better understood with the following figure in which conversion is performed on three channels (AN4, AN5, and AN6). The ADC in Single- Cycle Scan Mode is started (represented by (1) in Figure 6.12) when the ADST bit (ADCSR) is set to 1. The channels are A/D converted in ascending or- der (AN4, AN5, AN6) and the converted value is stored in the respective Data Register (represented by (2) in the figure). An ADI interrupt request is raised is ADIE bit (ADCSR) is enabled (represented by (3) in the figure). Finally, the ADST bit gets cleared to 0 when inputs of all the channels have been converted (represented by (4) in the figure). The ADC operates similarly when ADC is started using MTU, TMR, or an external trigger input. 176 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER Waiting for conversion for Waiting Waiting for conversion for Waiting Waiting for conversion for Waiting page 1724. A/D conversion result 3 A/D conversion enerated (4) g (2) (3) Interrupt Source: Hardware Manual, Source: A/D conversion result 2 A/D conversion A/D conversion 3 A/D conversion (2) cycle scan mode. A/D conversion result 1 A/D conversion Storing A/D converision 2 A/D converision (2) Single- A/D conversion is performed only once. A/D conversion (1) time A/D conversion Setting* A/D conversion 1 A/D conversion Figure 6.12 Figure started Waiting for Waiting conversion Waiting for conversion for Waiting Waiting for conversion for Waiting A/D conversion ADI ADST ADDR4 ADDR5 ADDR6 Channel 4 (AN4) Channel 5 (AN5) Channel 6 (AN6) CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 177 (5) A/D conversion 6 A/D conversion Setting* Waiting for conversion for Waiting Waiting for conversion for Waiting Clear (4) *2 A/D A/D conversion result 4 A/D conversion Waiting for Waiting conversion conversion 5 conversion page 1725. time A/D conversion result 3 A/D conversion A/D conversion A/D conversion 4 A/D conversion Hardware Manual, (2) (3) Interrupt generated Source: Source: A/D conversion result 2 A/D conversion Waiting for conversion for Waiting A/D conversion 3 A/D conversion (2) A/D conversion is performed sequentially. A/D conversion A/D conversion result 1 A/D conversion Waiting for conversion for Waiting Storing A/D converision 2 A/D converision (2) Continuous scan mode. (1) Setting* A/D conversion 1 A/D conversion Figure 6.13 Figure started Waiting for Waiting conversion Waiting for conversion for Waiting Waiting for conversion for Waiting A/D conversion Notes: 1. software. by indicates the point when instruction is executed 2. data Converted are ignored. ADF ADST ADDR0 ADDR1 ADDR2 Channel 0 (AN0) Channel 1 (AN1) Channel 2 (AN2) 178 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Continuous Scan Mode In this mode, one to eight channels (number of channels selected using ADANS register) are scanned/converted to digital continuously in ascending order until the ADC is stopped manually. This can be better understood with the following figure in which conversion is performed on three channels (AN0, AN1, and AN2). The ADC in Continuous Scan Mode is started (represented by (1) in Figure 6.13) when the ADST bit (ADCSR) is set to 1. The channels are A/D converted in ascending order (AN0, AN1, AN2) and the converted value is stored in the respective Data Register (represented by (2) in the figure). An ADI in- terrupt request is raised is ADIE bit (ADCSR) is enabled (represented by (3) in the figure). Unlike Single- Cycle Scan Mode, the above two processes ((1) and (2)) are repeated until the ADST is set to 0 manually. When ADST is set to 1, the ADC stops and enters a . When ADSR is set to 1 later, A/D conversion starts again. The ADC operates similarly when ADC is started using MTU, TMR, or an external trigger input.

6.4.2 10-Bit A/D Converter

The RX62N has two 10-bit A/D converters (Units 0 and 1). Each unit can convert up to four analog input channels. Channels AN0 to AN3 are considered as unit 0 and channels AN4 to AN7 are considered as unit 1. Like the 12-bit ADC, 10-bit ADC registers are also presented as structures and unions for easy manipulation, just like the ports, in the ‘iodefine_RX62N.h’file. The registers can be accessed using the syntax AD.REGISTER.WORD to set up an entire register or AD.REGISTER.BIT.BIT_NAME to set up a particular bit of a register.

Registers (A to D ؍ A/D Data Register (ADDRn) (n The 10-bit ADC has four Data Registers, each corresponding to the input channels of the ADC. A/D data registers ADDRA to ADDRD are 16-bit read- only registers. They store the A/D conversion results of channels AN0 to AN3, or AN4 to AN7. The width of the ADDRn (16-bit) is greater than the width of the ADC output (10-bit). To avoid reading wrong data, the output has to be aligned either to the right or left of ADDRn. This can be done using the DPSEL bit in the A/D Placement Register (ADDPR). This will be explained a little later.

A/D Control/Status Register (ADCSR) The Control/Status Register is used to select the input channels, start or stop A/D conver- sion, and enable or disable ADI interrupt. CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 179

Module data bus Internal data bus Bus interface AVCC

VREFH 10-bit

D/A register VREFL AD0.ADCR AD0.ADDRA AD0.ADDRB AD0.ADCSR AD0.ADDPR AD0.ADDRC AD0.ADDRD AD0.ADSSTR AD0.ADDIAGR

AVSS approximation Sucessive

AN0

ϩ Control circuit AN1 Ϫ Comparator

AN2 Sample-and- Multiplexer hold circuit ADI0 interrupt signal

AN3 Compare-match/input-capture A from MTU0 Compare-match/input-capture A from MTU0 to MTU4, and MTU6 to MTU10 Compare-match from MTU4 and MTU10

Compare-match A from TMR0 ADTRG0# Synchronous circuit Internal clock PCLK Clock PCLK/2 ADCLK selection PCLK/4 PCLK/8

Figure 6.14 Block Diagram of 10-bit ADC (Unit 0).

b7 b6 b5 b4 b3 b2 b1 b0

— ADIE ADST — CH[3:0]

Value after reset: x 0 0 0 0 0 0 0

Figure 6.15 A/D control/status register. Source: Hardware Manual, page 1737. 180 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The CH [3Ϻ0] is used to select the analog channels which have to be A/D converted. The channels can be selected using the following table.

TABLE 6.4 Channel Selection.

b3 b2 b1 b0 CHANNEL 0 0 0 0 AN0 or AN4 0 0 0 1 AN0 and AN1 or AN4 and AN51 0 0 1 0 AN0 to AN2 or AN4 to AN6 0 0 1 1 AN0 to AN3 or AN4 to AN7

The A/D Start bit (ADST) is used to start or stop the ADC. Setting this bit to 1 starts the ADC, and setting it to 0 stops the ADC. The A/D Scan Conversion End Interrupt Enable (ADIE) is used to enable or disable the A/D scan conversion end interrupt (ADI). When A/D conversion is complete, an interrupt is generated. Setting the ADIE bit to 1 enables the interrupt and setting it to 0 disables the interrupt.

A/D Control Register (ADCR) The Control register is used to select the type of A/D conversion mode, clock, and trigger.

b7 b6 b5 b4 b3 b2 b1 b0

TRGS[2:0] — CKS[1:0] MODE[1:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 6.16 A/D control register. Source: Hardware Manual, page 1739.

Like the 12-bit ADC, the 10-bit ADC also has different modes of operation. They are Sin- gle mode, Continuous Scan mode, and One- cycle scan mode. Setting MODE [1Ϻ0] to 00 is used to select Single mode, 10 to select Continuous Scan mode, and 11 to select One- cycle mode. Setting MODE [1Ϻ0] to 01 is prohibited. Details of these modes are explained later. The ADC clock can be set using the CSK [1Ϻ0] bits. Setting CKS [1Ϻ0] to 00 is used to select PCLK/8, 01 to select PCLK/4, 10 to select PCLK/2, and 11 to select PCLK. PCLK is the peripheral clock. CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 181

The TRGS bits are used to select the type of trigger that will start the A/D conversion process.

TABLE 6.5 Trigger Select for 10-bit ADC Unit 0.

b7 b6 b5 TRIGGER 0 0 0 Software Trigger 0 0 1 Compare-match/input- capture A from MTU0 to MTU4 0 1 0 Compare-match from TMR0 0 1 1 Trigger from ADTRG0# 1 0 0 Compare-match/input- capture A from MTU0 1 0 1 Compare-match/input- capture A from MTU06 to MTU10 1 1 0 Compare-match/input- capture A from MTU04 1 1 1 Compare-match/input- capture A from MTU10

The trigger select for Unit 1 is similar to the above table but 011 selects trigger from ADTRG1# and 100 selects compare- match/input- capture B from MTU0.

A/D Data Placement Register (ADDPR) The A/D output registers (ADDRn) are 16-bits wide, but the output of the ADC is 10-bits wide. Hence the data in the Data Register has to be aligned. The A/D Data Placement Reg- ister (ADDPR) is used to align data. This register is 8 bits wide. All bits except the eighth bit are reserved. The DPSEL bit is the eighth bit. Setting this bit to 0 aligns data to the right (LSB), and setting it to 1 aligns data to the left (MSB).

A/D Self-Diagnostic Register (ADDIAGR) This register is used to check if the 10-bit ADC has any defects. This register is an 8-bit register and the lower two bits (b1 and b0) are used to set up the test voltage for fault de- tection. To perform fault detection, do the following:

Ⅲ Set up the ADC in Single mode (AD.ADCR.BIT.MODE ϭ 00) Ⅲ Enable analog input AN0 (AD.ADCSR.BIT.CH ϭ 0000) Ⅲ Set up software trigger for the ADC (AD.ADCR.TRGS ϭ 000) Ⅲ Set the test voltage by setting (AD.ADDIAGR.DIAG) using Table 6.7 Ⅲ Start conversion (AD.ADCSR.BIT.ADST ϭ 1) 182 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 6.6 Test Voltage Setting.

b1 b0 FUNCTION 0 0 Self- diagnostic function is off

0 1 A/D conversion of Vref ϫ 0 voltage value is enabled

1 1 0 A/D conversion of Vref ϫ ⁄2 voltage value is enabled

1 1 A/D conversion of Vref ϫ 1 voltage value is enabled

The test voltage (0V or Vref/2 or 2Vref) is A/D converted and the result is stored in ADDRA. The result should approximately be 010 if 0V was chosen as test voltage, 102310 if Vref was chosen, and 204610 if 2Vref was chosen. If the result does not correspond to these values then the ADC is at fault. Self- diagnosis takes the same time as A/D conversion for one channel. Let us now look at an example of setting up the registers of the 10-bit ADC. It is al- ways better to write register set up as a function.

1. void ADC_Init(){ 2. SYSTEM.MSTPCRA.BIT.MSTPA23 = 0; 3. SYSTEM.MSTPCRA.BIT.MSTPA22 = 0; 4. AD.ADCSR.BYTE = 0x03; 5. AD.ADCR.BYTE = 0x0F; 6. AD.ADDPR.BYTE = 0x00; 7. AD.ADDIAGR.BYTE = 0x0; 8. }

The setting up of registers has been written as a function named ADC_Init() in line 1. The 10-bit ADC has been selected using the Module Stop Control Register A (lines 2 and 3). In line 4, the Control/Status Register is set up—four channels (AN0 to AN3) have been selected and A/D Interrupt Enable has not been enabled (b6 ϭ 0). Next, One- Cycle Scan mode, PCLK, and software trigger have been selected using the A/D Control Register in line 5. The format of the Data Register has been set to right alignment using line 6. In line 7 the A/D Self- diagnostic function has been turned off as we are not trying to detect any faults.

Operation The 10-bit A/D converter has two operating modes: Single Mode and Scan Mode. In the Single Mode, A/D conversion is performed on the specified single channel only once. In the Scan mode, A/D conversion is performed sequentially on the specified channel(s) (up to four). The Scan Mode can be further classified as the One- Cycle Scan mode and the Continuous Scan mode. The operation of the One- Cycle scan mode is the same as the CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 183

Single- Cycle Scan mode of the 12-bit ADC and the operation of the Continuous Scan mode is the same as the continuous Scan mode of the 12-bit ADC.

6.4.3 D/A Converter

The Digital to Analog converter, as the name suggests, is used to convert Digital Signals to Analog values. A DAC can convert bits to signals only if the Nyquist condition is met. The output of the DAC is in the form of pulses and this could cause harmonics above the Nyquist frequency. This could be avoided by using a low- pass filter. DACs face the issue of high output impedance and slow settling time. DACs are used in digital devices such as iPods to play back stored music. The RX62N has a 10-bit Digital to Analog converter. This DAC has two channels.

Module data bus Internal data bus Bus Interface

AVCC VREFH VREFL 10-bit D/A ADCR

AVSS DADR0 DADR1 DADPR DA1 DA0

Control circuit

Figure 6.17 Block diagram of DAC. Source: Hardware Manual, page 1762.

D/A Registers The DAC has three registers that have to be set in order to perform D/A conversion. They are D/A Data Register, D/A Control Register, and D/A Data Placement Register. 184 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

(1 ,0 ؍ D/A Data Register (DADRm) (m DADR0 and DADR1 are 16-bit registers which store the digital value that has to be con- verted to analog. The format of the 10-bit data register can be changed by setting the DPSEL bit (D/A Data Placement Register).

D/A Control Register (DACR) The D/A Control register is an 8-bit register used to enable or disable D/A conversion. It is also used to select the channel for the D/A operation.

Address: 0008 80C4h b7 b6 b5 b4 b3 b2 b1 b0

DAOE1 DAOE0 DAE — — — — —

Value after reset: 0 0 0 0 0 0 0 0

Figure 6.18 D/A control register. Source: Hardware Manual, page 1764.

The lower five bits (b0 to b4) are reserved. The b5, b6, and b7 bits can be set Table 6.7.

D/A Data Placement Register (DADPR) The format of the D/A Data Register can be set using this register. This is an 8-bit register. All bits except the eighth bit are reserved. The eighth bit is the Data Placement Selection bit (DPSEL). Setting DPSEL to 0 aligns the D/A Data Register to the right (LSB), and set- ting it to 1 aligns the D/A Data Register to the left (MSB).

Operation The RX62N has two circuits for D/A conversion and they can operate inde pen dently. To perform D/A conversion:

Ⅲ Port 0 pin 5 or Port 0 pin 3 has to be set up as the output port (PORT0.DDR.BIT. B3 ϭ 1) and disable ICR (PORT0.ICR.BIT.B3 ϭ 0) for channel 0 (DA0) and PORT0.DDR.BIT.B5 ϭ 1 and PORT0.ICR.BIT.B5 ϭ 0 for channel 1 (DA1). Ⅲ The value to be converted has to written into the D/A Data Register. Ⅲ DAOEn bit (n ϭ 0 or 1) in DACR has to be set to 1. CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 185

TABLE 6.7 Setting of DACR.

BIT SYMBOL BIT NAME DESCRIPTION b4 to b0 — (Reserved) These bits are read as 1. The write value should always be 1. b5 DAE*1 D/A Enable 0: D/A conversion is independently controlled on channels 0 and 1. 1: D/A conversion on channels 0 and 1 is controlled as a single whole. b6 DAOE0 D/A Output Enable 0 0: Analog output of channel 0 (DA0) is disabled. 1: D/A conversion of channel 0 is enabled. Analog output of channel 0 (DA0) is enabled.*2 b7 DAOE1 D/A Output Enable 1 0: Analog output of channel 1 (DA1) is disabled. 1: D/A conversion of channel 1 is enabled. Analog output of channel 1 (DA1) is enabled.*2

Source: Hardware Manual, page 1764.

If a new value is written to DADRn (n ϭ 0 or 1), conversion takes place again. Conversion takes place until DAOEn bit (n ϭ 0 or 1) is cleared.

Setting value of DADRn Analog value ϭϫV 1024 refh

Write to Write to Write to Write to DADR0 DACR DADR0 DACR

DADR0 Conversion data (1) Conversion data (2)

DACR.DAOE0 Conversion DA0 Conversion result result (2) (1) High-impedance state tDCONV tDCONV

[Legend] tDCONV: D/A conversion time

Figure 6.19 Operation of DAC. Source: Hardware Manual, page 1766. 186 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

6.5 ADVANCED EXAMPLES

6.5.1 12-Bit ADC

Let us consider the example of a simple 12-bit ADC. A DC voltage supply of 3 V is con- verted to its corresponding digital code and displayed on the LCD. To perform this Single- Cycle Scan mode an AN0 will be used. Software trigger will be used to start the ADC.

1. #include “iodefine_RX62N.h” 2. #include 3. #include 4. #include “src\Glyph\Glyph.h” 5. #define LCD_LINE1 0 6. #define LCD_LINE2 1 7. #define LCD_LINE3 2 8. #define LCD_LINE4 3 9. void ADC_Init(void); 10. void BSP_Display_String(int8_t, char *); 11. T_glyphHandle G_lcd; 12. void main(void){ 13. unsigned short ADC_out; 14. int i = 0; 15. char ADC_OUT [13 ]; 16. PORT4.DDR.BIT.B0 = 0; 17. PORT4.ICR.BIT.B0 = 1; 18. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 19. GlyphNormalScreen(G_lcd); 20. GlyphSetFont(G_lcd, GLYPH_FONT_6_BY_13); 21. GlyphClearScreen(G_lcd); 22. BSP_Display_String(LCD_LINE1,“12-bit ADC”); 23. ADC_Init(); 24. while(1){ 25. if(S12AD.ADCSR.BIT.ADST == 0 && i == 0){ 26. ADC_out = S12AD.ADDRA & 0X0FFF; 27. sprintf (ADC_OUT,“%d”,ADC_out); 28. BSP_Display_String(LCD_LINE2,ADC_OUT); 29. i++; 30. } 31. } 32. } 33. GlyphClose(&G_lcd); 34. } CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 187

35. void ADC_Init(){ 36. SYSTEM.MSTPCRA.BIT.MSTPA17 = 0; 37. S12AD.ADCSR.BYTE = 0x0C; 38. S12AD.ADANS.WORD = 0x01; 39. S12AD.ADCER.BIT.ACE = 1; 40. S12AD.ADCER.BIT.ADRFMT = 0; 41. S12AD.ADSTRGR.BIT.ADSTRS = 0x0; 42. S12AD.ADCSR.BIT.ADST = 1; 43. } 44. void BSP_Display_String(int8_t aLine, char * aText){ 45. int8_t y = aLine * 16; 46. GlyphEraseBlock(G_lcd, 0, y, 95, y + 15); 47. GlyphSetXY(G_lcd, 0, y); 48. GlyphString(G_lcd, (uint8_t *)aText, strlen(aText)); 49. }

The iodefine_RX62N.h in line 1 defines the ports and the ADC registers which need to be set for the ADC operation. Hence it should be included in the program. Line 2 and line 3 are used to include standard C libraries. The src\Glyph\Glyph.h header file in line 4 is included to enable the LCD display. The start of the LCD lines has been set up as macros in lines 5 to 8. G_lcd is a variable of type T_glyphHandle (line 11) used to open the graphic LCD. In lines 9 and 10, the functions ADC_Init and BSP_Display_String have been proto- typed. The ADC_Init() function (lines 35 to 43) is used to set up the registers for the Single- Cycle Scan mode on AN0 and use a software trigger to start the ADC. The Module Stop Control Register A (MSTPCRA) is set such that the 12-bit ADC is selected (line 36). The A/D Control register (ADCSR) is set for software trigger, PCLK, and Single- cycle scan mode (line 37). Channel AN0 is selected and the A/D Channel Select register (ADANS) is set accordingly (line 38). Automatic clearing of the data registers and right- alignment of the data register has been selected (lines 39 and 40). The A/D Start Trigger Select register (ADSTRGR) is set for the software trigger (line 41). The 12-bit ADC is then started (line 42). The BSP_Display_String() function is used to display strings on the spec- ified line of the LCD. In the main program, three variables have been used: ADC_out, ADC_OUT, and i. ADC_out declared in line 13 is used to get the ADC value from the data register. ADC_OUT declared in line 15, is a string which contains the ADC_out in string form so that it can be displayed on the LCD. The variable i, declared in line 14, is used to print the A/D value once on the LCD. Next, the Port 4 pin 0 (AN0) is set up as an input pin (lines 16 and 17). The LCD is then set up and the string ‘12-bit ADC’ is made to display on the LCD (lines 18 to 22). ADC_Init() function is called to initialize the ADC registers and start the conversion (line 23). 188 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

After conversion is complete, the ADST bit of the ADCSR gets cleared to 0. This con- dition is checked (line 25) and the next few lines are executed only once using the variable ‘i.’ If conversion is complete, the A/D converted value is written to the variable ADC_out (line 26). The Data Register was set to be right aligned. Hence to avoid reading wrong bits, the value 0X0FFF is used to mask the upper four bits (using zeros) and read the lower twelve bits (right bits). ADC_out is then converted into a string ADC_OUT (line 27) and displayed on the LCD (line 28).

Output When a 3 V input was given to channel AN0, the A/D conversion result displayed was 3728. Using the formula, the A/D value is 3723.

6.5.2 10-Bit ADC

1. #include “iodefine_RX62N.h” 2. #include 3. #include 4. #include “src\Glyph\Glyph.h” 5. #define LCD_LINE1 0 6. #define LCD_LINE2 1 7. #define LCD_LINE3 2 8. #define LCD_LINE4 3 9. void ADC_Init(void); 10. void BSP_Display_String(int8_t, char * ); 11. T_glyphHandle G_lcd; 12. void main(void){ 13. unsigned short ADC_value; 14. int i = 0; 15. char ADC_OUT [13]; 16. PORT4.DDR.BIT.B0 = 0; 17. PORT4.ICR.BIT.B0 = 1; 18. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 19. GlyphNormalScreen(G_lcd); 20. GlyphSetFont(G_lcd, GLYPH_FONT_6_BY_13); 21. GlyphClearScreen(G_lcd); 22. BSP_Display_String(LCD_LINE1,“12-bit ADC”); 23. ADC_Init(); CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 189

24. while(1){ 25. if(AD0.ADCSR.BIT.ADST == 0 && i == 0){ 26. ADC_value = AD0.ADDRA & 0x0FFF; 27. sprintf (ADC_OUT,“%d”,ADC_value); 28. BSP_Display_String(LCD_LINE2,ADC_OUT); 29. i++; 30. } 31. } 32. } 33. GlyphClose(&G_lcd); 34. } 35. void ADC_Init(){ 36. SYSTEM.MSTPCRA.BIT.MSTPA23 = 0; 37. AD0.ADCSR.BYTE = 0x00; 38. AD0.ADCR.BYTE = 0x0C; 39. AD0.ADDPR.BYTE = 0x00; 40. AD0.ADDIAGR.BYTE = 0x0; 41. AD0.ADCSR.BIT.ADST = 1; 42. } 43. void BSP_Display_String(int8_t aLine, char * aText){ 44. int8_t y = aLine * 16; 45. GlyphEraseBlock(G_lcd, 0, y, 95, y + 15); 46. GlyphSetXY(G_lcd, 0, y); 47. GlyphString(G_lcd, (uint8_t *)aText, strlen(aText)); 48. }

The iodefine_RX62N.h in line 1 defines the ports and the ADC registers which need to be set for the ADC operation. Hence it should be included in the program. Line 2 and line 3 are used to include standard C libraries. The src\Glyph\Glyph.h header file in (line 4) is included to enable the LCD display. The start of the LCD lines has been set up as macros in lines 5 to 8. G_lcd is variable of type T_glyphHandle (line 11) used to open the graphic LCD). In lines 9 and 10, the functions ADC_Init and BSP_Display_String have been proto- typed. The ADC_Init() function (lines 35 to 42) is used to set up the registers for Single mode on AN0 (unit 0) and use a software trigger to start the ADC. The Module Stop Con- trol Register A (MSTPCRA) is set such that Unit 0 of 10-bit ADC is selected (line 36). The A/D Control register (ADCSR) is used to select Channel 0 (AN0) and disable A/D end in- terrupt (line 37).The A/D Control Register (ADCR) is used to select Single mode, PCLK and software trigger (line 38). The Data Placement register (ADDPR) is used to select right alignment (line 39).The Self- Diagnostic function is set to off by default and it need not be 190 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

set explicitly if the Self- Diagnostic function is not going to be used. The ADC is then started (line 42). The BSP_Display_String() function is used to display strings on the spec- ified line of the LCD. In the main program three variables have been used: ADC_value, ADC_OUT, and i. ADC_value declared in line 13 is used to get the ADC value from the data register. ADC_OUT declared in line 15, is a string which contains the ADC_value in string form so that it can be displayed on the LCD. The variable i, declared in line 14, is used to print the A/D value once on the LCD. Next, the Port 4 pin 0 (AN0) is set up as an input pin (lines 16 and 17). The LCD is then set up and the string ‘10-bit ADC’ is made to display on the LCD (lines 18 to 22). ADC_Init() function is called to initialize the ADC registers and start the conversion (line 23). After conversion is complete, the ADST bit of the ADCSR gets cleared to 0. This con- dition is checked (line 25) and the next few lines are executed only once using the variable ‘i.’ If conversion is complete, the A/D converted value is written to the variable ADC_value (line 26). The Data Register was set to be right aligned. Hence, to avoid reading wrong bits, the value 0X0FFF is used to mask the upper four bits (using zeros) and read the lower twelve bits (right bits). ADC_value is then converted into a string ADC_OUT (line 27) and displayed on the LCD (line 28).

Output When a 3 V input was given to channel AN0, the A/D conversion result displayed was 1007. Using the formula, the A/D value is 930.

6.5.3 DAC

To understand how to program DACs let us look at an example in which DAC unit1 has been used.

1. #include “iodefine_RX62N.h” 2. #include 3. #include 4. #include “src\Glyph\Glyph.h” 5. void DAC_Init(void); 6. T_glyphHandle G_lcd; 7. void main(void){ 8. PORT0.DDR.BIT.B5 = 1; 9. PORT0.ICR.BIT.B5 = 0; CHAPTER 6 / CONVERTING BETWEEN THE ANALOG AND DIGITAL DOMAINS 191

10. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 11. GlyphNormalScreen(G_lcd); 12. GlyphSetFont(G_lcd, GLYPH_FONT_6_BY_13); 13. GlyphClearScreen(G_lcd); 14. BSP_Display_String(LCD_LINE1,“DAC”); 15. DAC_Init(); 16. while(1){} 17. } 18. GlyphClose(&G_lcd); 19. } 20. void DAC_Init(){ 21. SYSTEM.MSTPCRA.BIT.MSTPA19 = 0; 22. DA.DADR1 = 102; 23. DA.DACR.BYTE = 0x9F; 24. } 25. void BSP_Display_String(int8_t aLine, char * aText){ 26. int8_t y = aLine * 16; 27. GlyphEraseBlock(G_lcd, 0, y, 95, y + 15); 28. GlyphSetXY(G_lcd, 0, y); 29. GlyphString(G_lcd, (uint8_t *)aText, strlen(aText)); 30. }

Programming the DAC also requires the same header files as the ADC example. The out- put of DAC1 can be observed on DA1, which is port 0 pin 5. This pin is set up as an output pin to observe the result (lines 8 and 9). The DAC has been set up using the DAC_Init() function (line 15). In the DAC_Init() function, the DAC unit is started up by setting SYSTEM.MSTPCRA.BIT.MSTPA19 to 0 (line 21). The digital value that has to be converted to analog value is set using DA.DADR1 (line 22), and DAC unit 1 has been selected by setting DA.DACR.BYTE = 0x9F. Thus the DAC can be programmed and the analog value can be observed from port 0 pin 5 using a multimeter.

6.6 RECAP

Thus we have seen how the ADC and DAC of the RX62N board can be programmed. The methods discussed above have been using polling. Polling is not very efficient. An efficient method of using these features would be using interrupts. Interrupts are discussed in detail in Chapter 9. 192 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

6.7 REFERENCES

Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print. RX62N Quick Start Guide. Renesas Electronics America, Inc., 2010. Computer Disc. RX Family C/Cϩϩ Compiler, Assembler, Optimizing Linkage Editor; Compiler Package User’s manual. Renesas Electronics America, Inc., 2010. Print.

6.8 EXERCISES

1. What is the output code (in decimal) of a 12-bit ADC with Vin ϭ 2.7 V? Vϩref ϭ 5V? V Ϫref ϭϪ5 V? 2. What is the output code (in decimal) of a 10-bit ADC with Vin ϭ 3 V? Vϩref ϭ 5V? V Ϫref ϭ 0 V? 3. Given the following information of a particular analog to digital converter, deter- mine the value of the digitally represented voltage and the step size of the converter: Ⅲ The device is 10-bit ADC with a Vϩref —reference voltage of 3.3 volts and a VϪref reference voltage of 0 volts. Ⅲ The digital representation is: 0100110010. 4. What is the maximum quantization error for a 10-bit ADC with Vϩref ϭ 3.3 V, V Ϫref ϭ 0 V? 5. Write a simple subroutine to set up the ADC registers for a 12-bit ADC operation of the following specifications: continuous scan mode, software triggered, PCLK/4, and Channel AN3. 6. Identify the modifications to be made if the above problem works on the value ad- dition mode (3—time conversion). 7. Write a subroutine to set up the registers for a 10-bit ADC operation of the follow- ing specifications: continuous scan mode on channels AN1 and AN2, software triggered, PCLK/2, and data aligned to the LSB end. 8. Write a program to display the percentage of light intensity given a light sensor circuit. Record the ‘darkness’ (cover the sensor to make it dark) and ‘brightness’ (shine a bright LED or other light on the sensor) values. Identify the correct cali- bration such that the average room light lies between these values. Chapter Seven

Serial Communications

7.1 LEARNING OBJECTIVES

Microcontrollers often need to communicate with other devices. Sending information seri- ally (rather than in parallel) reduces the number of signal connections needed, saving space and cost. This chapter introduces how microcontrollers can exchange information serially using the UART, SPI, and I2C communication controllers.

7.2 BASIC CONCEPTS OF SERIAL COMMUNICATIONS

Communication is the exchange of information between entities. In computers, informa- tion can be of any form which can be represented in a digital form. The medium of com- munication is electrical signals that vary continuously between high and low. The patterns in which they vary follow a set of rules that dictate the information the two entities want to exchange. Also these signals can be communicated one at a time, or as we are familiar with by now, bit by bit; or all at the same time on a single set of wires. The former is called se- rial communication wherein the information/data is sent one bit at a time, and the latter is called parallel communication where more than a single bit of data is shifted out at the same time from one side of the communication channel. Also there can be information channels where both ends can send as well as receive information at the same time. Such channels are called full duplex channels. Parallel communication is primarily used when there is a need to transfer data at a very high speed over short distances, such as inside a computer from one peripheral to another. In such cases, the data and its delivery is of utmost importance. Parallel forms of commu- nication are usually implemented using a bus. You may already be familiar with commonly used terms when talking about computer peripherals such as the IDE bus or the PCI bus. A fact to note is that these are low capacitance wires bundled together to form the bus and are usually not extremely long. Among other factors which affect the choice of parallel or serial communication are: the PCB board space, number of I/O pins, density, capacitance, signal integrity, and optical/electrical. Serial communication, on the other hand, is a preferred medium when data is to be transferred over long distances. This may include a range of a couple hundred feet, from

193 194 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

one building to another, or one computer to another. Serial communication is usually much slower than parallel. However, with the advent of time and technology, serial busses are be- coming more and more high speed and are now also being used for short distances; i.e., in- ternal communication mechanisms of computers. In this chapter, we will primarily deal with serial communication only to establish data transfer between the Renesas microcontroller and a PC or other microcontroller boards or devices using various protocols such as USART, SPI, and I2C. It should be noted that there are other protocols beyond these that are also available with the RX62N; however, they re- quire implementation using complex techniques. As you go through this chapter you will learn:

The basics of each technique for serial communication, through polling; since polling is the best way to understand the exact details of the working of the pe- ripheral device. The practical working of each technique through guided and intricately explained examples. How to distinguish between the implementation of each technique and the over- heads of communication along with necessary precautions.

Before we jump into understanding the working of each serial communication interfacing technique, it is necessary to understanding the terminologies that are used while talking about serial communication, and also understand the need for communication. So why would we need communication between different peripherals? A few examples are men- tioned below:

Parallel Computation: In these cases, a complex problem is broken down into smaller, less complex parts and is distributed to other computers on a network, solved and then returned back to the source. The result is a reduction in the time taken to solve the problem, full use of available resources, etc. from remote locations: This is prominent in industrial applica- tions where there are sensors deployed in the field or inside a factory. The sensors continuously gather data and send it to a central controller which monitors them and controls the overall system. Control of remote devices such as smart transducers. Developing fault tolerant systems.

Terminologies : A communication junction that provides for connecting a cable responsible for conducting electrical signals between the communicating entities, usually a 9 pin DBI male/female header. CHAPTER 7 / SERIAL COMMUNICATIONS 195

Bus: One or more wires shared between devices in order to communicate electrical signals.

Baud Rate: Number of symbols transferred per second. A symbol may represent one or more bits of data through its encoding.

Bit Rate: Number of bits of information transferred per second.

Start Bit: Initial bit sent on the communication channel before communication begins.

Stop Bit: Final bit sent on the communication channel before communication terminates.

Parity Bit: A bit included in the communicated data whose status determines the parity (even/odd) of the information/data byte transferred.

Simplex Communication: A communication channel that can perform communication in only one direction, for example, family radios and walkie- talkies.

Full Duplex Communication: A communication channel is considered to be full duplex if both entities at the end of the channel can communicate in both directions simultane- ously; i.e., transmit and receive data.

Half Duplex Communication: A communication channel/port is said to be half duplex if it can either transmit or receive data at an instant of time, but not simultaneously.

Synchronous: A clock signal accompanies the data being transmitted on a separate line thereby synchronizing the two end processors. Examples of such buses are HDMI and DVI for video signals.

Asynchronous: A clock signal does not accompany the data being transmitted. Instead an internal clock is maintained on both ends of the communicating modules to assist in syn- chronizing the data transfer. Typical PC serial port communications devices are an exam- ple of such transfers. Now that we are familiar with some of the terms and needs of serial communication, we are ready to learn a few of the different interfaces available with the RX62N in detail. Section 7.2 will introduce basic concepts applicable to each serial communication interface. Section 7.3 will demonstrate the concepts of Section 7.2 by providing an example for each interface. Section 7.4 will describe advanced concepts of serial communication and Section 7.5 will demonstrate them with more complex examples. 196 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

7.2.1 Introduction to the RX62N Serial Communication Interfacing

In order to fulfill the previously mentioned needs for communication between the proces- sor and its desired peripherals or other devices, the RX62N has been provided with various mechanisms. These include the serial communication interface (SCI), Renesas serial pe- ripheral interface (RSPI), and the Renesas Inter Integrated Chip (RIIC) bus interface. All three interfaces perform the same task of communicating data between various entities se- rially; i.e., one bit every cycle, however, the manner in which they do so is different for each interface. Depending upon the different requirements of communication, such as speed, number of devices needed to connect to, or topography of the communication, you may choose between the three different interfaces as desired. The three interfaces along with their features are described in the following:

Serial Communication Interface (SCI): This interface provides for one of the oldest and most fundamental methods in serial communication, the Universal Synchronous/ Asynchronous Receiver/Transmitter (USART). The RX62N microcontroller has a total of six of these interfaces available which support USART communication as well as provide an interface to smart cards. The SCI has a variable transfer speed due to the availability of an on chip bit- rate generator and can transfer data with either the MSB or LSB leading the communication. It also provides for multi- processor communication functions. Other available functions include data length selection (i.e., 7 or 8 bits), number of stop bits, par- ity selection, clock source selection, receive error detection, and break detection. Details of the SCI are further discussed in Section 7.2.2.

Serial Peripheral Interface (RSPI): The Renesas SPI is a means for high- speed syn- chronous data transfer between the microcontroller and other connected serial peripher- als, such as an SD card or other Renesas microcontrollers. The RSPI provides two chan- nels for serial transfer. Each channel has either 3 or 4 pins; i.e., MISO, MOSI, SPCK, and SSL depending upon the mode of operation. The RSPI also has interchangeable data formats with which one can transmit either the LSB or MSB at the start of com- munication. The RSPI is also capable of handling data as either a master or slave. These shall be further discussed in Section 7.2.3. The number of bits transferred by the RSPI can be varied between eight to thirty- two bits. The RSPI operates through the means of a double buffer for both transmission and reception; each of which is 128-bits long, thereby permitting storage of four 32-bit long frames.

I2C Bus Interface (RIIC): The RIIC is a simple, powerful, and flexible serial transmis- sion method that generally operates using only two wires with a well- defined protocol. The RIIC provides for two channels with variable communication formats and transfer rates up CHAPTER 7 / SERIAL COMMUNICATIONS 197

to 1 Mbps. Also a total of 128 devices may be connected on a single RIIC bus may be con- nected at a time with only the requirement of a pull up resistor. Details of the RIIC bus are discussed in Section 7.2.4. Table 7.1 provides for a comparison between the mentioned interfaces:

TABLE 7.1 Comparison Between Different Interfaces.

SERIAL RENESAS SERIAL RENESAS INTER COMMUNICATION PERIPHERAL INTEGRATED INTERFACE INTERFACE CHIP BUS Modes USART/Smart Four wire/Three I2C mode or SM Card interface wire mode bus mode Max transfer speed 1.92 Mbps with Up to 25 Mbps Up to 1Mbps PCLK @ 50 Mhz Max. number of 1 8 SPI integrated 127 devices/slaves channels for slave connected per bus selection Number of wires 2 to 3 3 to 4 2 required for communication (not including ground) Max. length of wires1 500 ft @ 9600 bps 10 feet with clock 10 meters @ 100 kbps speed of few kHz Number of bits per 7 or 8 Up to 32 bits 8 unit transfer (excluding start and stop) Slave selection Addressed during Using slave select line Through addressing method communication when in multiprocessor communication mode, or else not available.

1Becke et al., Comparing Bus Solutions; High- Performance Linear/Interface: An Application Report, , revised 2004. http://www.lammertbies.nl/download/ti- appl- slla067a.pdf 198 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Now that we have an idea of some of the different available techniques of serial communi- cation available on the Renesas board and the differences between each of them, we can proceed to the details of operation for each interface available.

7.2.2 Universal Asynchronous Receiver and Transmitter

The UART/USART is one of the oldest mechanisms available for the serial transmission of data. The idea of a UART was developed in order to convert parallel data into serial data to be transmitted over large distances. This is usually done by means of a shift register which shifts out a one bit per clock cycle. Given the premise that the shift register clocks out a one bit per clock cycle, it requires one clock cycle to fill the shift register in parallel; and where the clock provided to both the CPU and the shift register is the same, one can easily deter- mine that serial transmission is at least N times slower than parallel transmission, where N is the number of bits available in the serial register; i.e., if the size of the shift register is eight bits, serial communication is at least eight times slower than parallel communication. Before we jump into detailed concepts of the Renesas UART, let us look at the mechanism of a shift register.

CLR CLK

R R R R DQ DQ DQ DQ SERIAL SERIAL IN D-FLIP D-FLIP D-FLIP D-FLIP OUT FLOP FLOP FLOP FLOP

Q1 Q2 Q3 Q4 Figure 7.1 Serial Input Parallel Output (SIPO) shift register.

If one is familiar with digital circuits, one may easily note from Figure 7.1 that a shift reg- ister is nothing but a series of cascaded flip- flops that share the same clock. The most com- monly used flip- flop for shift registers is the D flip- flop where the D stands for Delayed. More detailed information on the D flip- flop can be found in Digital Logic and Micro- with VHDL (Hwang), but in essence it is enough to know that the flip- flop outputs the state of the input (D), or data, for every rising edge of the clock, and main- CHAPTER 7 / SERIAL COMMUNICATIONS 199

tains it until the next rising edge. Depending on the configuration, there can be two types of shift registers, Parallel In Serial Out (PISO) and Serial In Parallel Out (SIPO). A PISO type shift register usually shifts out data serially, that is, the data is input to the shift regis- ter through a parallel bus and gets shifted out onto the serial bus in parallel, and is therefore used on the transmitter side of the interface; whereas the SIPO type shift register takes data in serially and converts it to parallel form, and is thus used at the receiver side of the inter- face. The two types of shift registers are shown in Figure 7.1 and Figure 7.2 respectively. This is the basis of operation for the UART. More reading on the electronics part of the flip- flops can be found at http://faculty.lasierra.edu/ϳehwang/digitaldesign (Hwang, Digital Logic and Microprocessor Design with VHDL).

D0 D1 D2 D3 WRITE/ SHIFT

D Q D Q D Q D Q CLK Q or Q or Q or Q or Q

CLEAR Figure 7.2 Parallel Input Serial Output (PISO) shift register.

Now that we are aware of the basic mechanism of UART serial communication, it is worthwhile to notice that there are various other overheads to communication that are required, such as ensuring that the data has been communicated properly and identified. These are usually done by addition of extra bits in the communication process. Addi- tional bits are padded to the eight bits of data, and then the data is transmitted. The ad- ditional bits padded are the START and STOP bits. When not communicating, both the TX(transmit) and RX(receive) lines are held in the Hi- Z (high impedance) state. When transmission/reception of data is about to occur, the line is first pulled low. This period is called the START bit and is maintained for one clock cycle. After eight bits of data transmission, the line is pulled high again and maintained high. This is the STOP bit and is maintained for at least one clock cycle before the next byte of data can be com- municated. In this manner data is recognized over the channel for reception. But this 200 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

does not yet resolve the problem of incorrect data transmission. Over distances, electri- cal signals have a tendency to weaken, reduce in amplitude, and also pick up noise. This may result in data corruption. This is checked by the addition of an extra bit to the data, also called the parity. The parity bit is set to 1 or 0 in order to make the total number of 1 bits even (for even parity) or odd (for odd parity). One more note is that all the above mentioned transactions are performed at logic levels; i.e., voltages range from 0 to 3 V at most 5 V. These voltages are very much susceptible to noise and signal corruption over long distances. To prevent this, an amplifier circuit boosts and inverts the voltages so that they vary from 15 V (logic high) to 15 V (logic low). These are the voltage levels for the telecommunications Recommended Standard 232(RS- 232). A level-shifting inverter circuit converts the RS232 voltages back to logic levels at each receiver. More information regarding the RS- 232 standard can be found in “EIA Standard RS- 232-C Interface between Data Terminal Equipment and Data Communication Equipment Em- ploying Serial Data Interchange” (Electronic Industries Association). This concludes the basic working mechanism of the UART. Now we come to the control part of the UART, which is essentially done by means of a few special function registers (SFRs) that are linked to the serial communications interface available with the Renesas Mi- crocontroller.

Registers Related to the SCI in UART Mode The Serial Communications Interface provides for a Universal Synchronous Transmitter/ Receiver, a Universal Asynchronous Transmitter/Receiver, and a interface. The Renesas Microcontroller has six serial communication interfaces, which can provide for the previously mentioned three communication methods. However, before one can use the SCI it needs to be properly configured to work in one of the three modes. We shall be con- figuring the SCI to work as a UART, and therefore we would be talking about the special function registers and the values to be injected into them to make the UART work success- fully. Finally, we will discuss how to test the configured UART and the physical variations possible to the communication signals. The special function registers related to the UART are:

Serial Mode Register (SMR) Bit Rate Register (BRR) Serial Control Register (SCR) Transmit Data Register (TDR) Serial Status Register (SSR) Receive Data Register (RDR) Smart Card Mode Register (SCMR) Serial Extended Mode Register (SEMR) CHAPTER 7 / SERIAL COMMUNICATIONS 201

Smart Card Mode Register (SCIx.SCMR): This is the register that selects whether the SCI is going to be in either the Smart Card Interface mode or act as a UART or USART. It has four bits that need to be assigned values. However, since we are only concerned with setting up the SCI as a UART, the only bit we need to be concerned with is the SMIF bit. Setting this bit to 1 causes the particular SCI to enter smart card interface mode else the SCI can behave as either a Synchronous or Asynchronous transmitter/receiver. Hence we always set it to 0.

b7 b6 b5 b4 b3 b2 b1 b0

BCP2 — — — SDIR SINV — SMIF

Value after reset: 1 1 1 1 0 0 1 0

Figure 7.3 The SCI Smart card mode register. Source: Hardware Manual, Renesas 32-Bit Microcom- puter, RX Family/RX600 Series, Renesas Electronics America, Inc., 2010, page 1418.

Serial Mode Register (SCIX.SMR) This special function register is concerned with operational variations of the UART. The register details are as follows:

b7 b6 b5 b4 b3 b2 b1 b0

CM CHR PE PM STOP MP CKS[1:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.4 The SCI Serial mode register. Source: Hardware Manual, page 1405.

Clock speed applied to the shift register: The clock applied to the Shift Register which is related to the TDR is the PCLK. The frequency of this clock can be re- duced by means of a frequency divider. This is selectable by the CKS1 and CKS0 bits which give combinations to divide the PCLK frequency by 1, 4, 16, or 64. Refer to Table 7.2 for details. These bits usually depend upon the acceptable baud rate error and the value of the BRR register. Whether the communication line is concerned with multiprocessor communica- tion: Setting the Multiprocessor mode bit MP in the SMR causes the UART to be- come aware of multiprocessor communication taking place on the channel. If one is not using multiprocessor communication, this bit is set to 0. Multiprocessor mode (or 9 bit wake- up mode, or multidrop mode) was a very common way of placing more than one slave on an UART bus or giving it multi- drop capability. In these systems when the ninth bit was set as a high this indicated that the remaining eight bits were the address of the device that the Master wanted 202 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

to communicate with. All devices processed the address field. Only the device with the corresponding address continued to communicate, all other devices went back to “sleep” waiting for the next address command. In most devices that support MP the UART peripheral will create an interrupt when the ninth bit is high. This allows the devices that are not actively communicating with the Master to ignore all other traffic on the bus, reducing the overhead on those MCUs. Stop bit length: STOP determines the length of the Stop bit, whether it is either one or two bits wide. Setting this bit to 0 selects length of stop bit as 1 whereas setting it to 1 causes the length of stop bit to be 2 bits wide. Parity mode: Setting this bit to 1 causes the parity bit to be high when the parity of the data is odd; whereas, setting this bit to 0 causes the parity bit to be high if the parity of the data is even. Parity enable: Setting the PE bit to 1 enables the transmission of the parity bit and disables otherwise. Length of data being transmitted: Setting the CHR bit to 1 truncates the size of the data being transmitted to seven bits, or else 8-bit long data is transmitted. Communications mode: The CM bit determines the operation of the SCI, whether it is operating in synchronous or asynchronous mode. If this bit is set to 1, the in- terfaces act in the Clock synchronous mode, or else it enters the Clock asynchro- nous mode. If operating in the Clock synchronous mode, a clock signal can be generated on the SCLK line by the transmitter which also acts as the clock input to the shift register on the receiver end of the module. Selection whether the clock is input or output is de pen dent on the state of the CKEbit in register SCIx.SCR.

Serial Control Register (SCIx.SCR) This register is responsible for controlling the Serial Communications Interface; whether it is turned on or off, the choice of input clock to the shift register, and function of the SCK pin. The register details are as follows:

b7 b6 b5 b4 b3 b2 b1 b0

TIE RIE TE RE MPIE TEIE CKE[1:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.5 The SCI serial control register. Source: Hardware Manual, page 1409.

Clock Enable bits (CKE 0, CKE 1): These bits determine which clock is to be used when transferring data, internal or external, and the function of the SCKn pin corre- sponding to the SCIn module. The Table 7.2 determines the functions depending on each of the four combinations of the 2 bits when the SCI is in Asynchronous mode. Transmit end interrupt enable: Setting this bit to 1 and 0 enables and disables the trans- mit end interrupt that is generated every time a byte is transmitted from the SCI. CHAPTER 7 / SERIAL COMMUNICATIONS 203

Multiprocessor Interrupt Enable: This bit is related to Multiprocessor communica- tion and is usually set to 0 when there is no multiprocessor communication occur- ring on the bus. Receive Enable: Setting this bit to 0 and 1 disables and enables reception of data on the Rxn pin, respectively. Transmit Enable: Setting this bit to 0 and 1 disables and enables transmission of data on the Txn pin, respectively. Receive Interrupt Enable: Setting this bit to 1 and 0 enables and disables the gen- eration of a receive interrupt, respectively. Transmit Interrupt Enable: Setting this bit to 1 and 0 enables and disables the gen- eration of a transmit interrupt, respectively.

Serial Status Register (SCIx.SSR) This is a read only type of register (except for bit 0) which determines the condition of the currently received byte over the corresponding SCI by means of various flag bits.

b7 b6 b5 b4 b3 b2 b1 b0

TDRE RDRF ORER FER PER TEND MPB MPBT

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.6 The SCI serial status register. Source: Hardware Manual, page 1411.

Multiprocessor bit transfer: This bit sets the value of the multiprocessor bit for adding to the transmission frame Multiprocessor bit (received): This bit holds the value of the multiprocessor bit in the received frame. Note that the value of this bit does not change when RE bit in SCR is kept as 0. This is a read only type bit. Transmit End Flag: This flag is set at the end of transmission of a byte from the TDR or in case the serial transmission is disabled. Resetting this flag requires one to write data to the TDR. Parity Error Flag: This bit indicates a parity error has occurred during reception in asynchronous mode and reception ends abnormally. When a parity error occurs, data is maintained in the RDR and the parity error flag is set but subsequent recep- tion in terminated until PER is reset Error signal status flag: This flag is set when a low error signal and reset after clearing to 0 manually Overrun Error Flag: This flag is set if data is received in RDR before the previous data has been read. The flag is cleared when 0 is written to it. 204 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Bit Rate Register (SCIx.BRR)

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.7 The SCI bit rate register. Source: Hardware Manual, page 1419.

This is the register that controls the generation of the clock signal to be provided to the shift registers. Table 7.2 shows the relation between the value N input into the BRR and the bit rate B for normal asynchronous mode. In asynchronous mode, one should note that there is always a minor difference in timings between the two processors involved in com- munication, due to the minor differences in parts (oscillator circuits). The actual bit rate may not exactly meet the desired rate because only rates which can be generated by divid- ing PCLK by multiples of 16 are possible. Therefore, an error in communication, such as loss of reception of a bit, may occur if the bit rate mismatch (error) between the transmit- ter and receiver is too large. Table 7.2 defines a few standard values of BRR along with the generated bit rate’s percentage error for each case.

TABLE 7.2 Bit Rates and Percent Errors (N BRR value, n Clock source setting with CKS bits in SMR).

OPERATING FREQUENCY PCLK (MHZ)

BIT 25 30 33 50 RATE ERROR ERROR ERROR ERROR (bit/s) n N (%) n N (%) n N (%) n N (%) 110 3 110 0.02 3 132 0.13 3 145 0.33 3 221 0.02 150 3 80 0.47 3 97 0.35 3 106 0.39 3 162 0.15 300 2 162 0.15 2 194 0.16 2 214 0.07 3 80 0.47 600 2 80 0.47 2 97 0.35 2 106 0.39 2 162 0.15 1200 1 162 0.15 1 194 0.16 1 214 0.07 2 80 0.47 2400 1 80 0.47 1 97 0.35 1 106 0.39 1 162 0.15 4800 0 162 0.15 0 194 0.16 0 214 0.07 1 80 0.47 9600 0 80 0.47 0 97 0.35 0 106 0.39 1 40 0.77 19200 0 40 0.76 0 48 0.35 0 53 0.54 0 80 0.47 31250 0 24 0.00 0 29 0.00 0 32 0 0 49 0.00 38400 0 19 1.73 0 23 1.73 0 26 0.54 0 40 0.77 CHAPTER 7 / SERIAL COMMUNICATIONS 205

Transmit Data Register (SCIx.TDR)

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.8 The SCI transmit data register. Source: Hardware Manual, page 1404.

This register contains the data to be transmitted over the communication channel. The data is usually eight bits long and is padded with the start, stop, and parity bits. The TDR acts as a buffer to the transmit shift register which is the actual register responsible for shifting out the data serially on to the transmit pin.

Receive Data Register (SCIx.RDR)

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.9 The SCI receive data register. Source: Hardware Manual, page 1404.

This register contains the data received over the communication channel. The data is usu- ally eight bits long and is stripped off the start, stop, and parity bits.

Variations to the UART Before we move on to other techniques of serial communication, it is worthwhile to men- tion that there are other UART-based communication standards which use different types of voltage signaling, such as the RS- 422, RS- 423, RS- 449, and RS- 485. More readings on these can be found at http://focus.ti.com/lit/an/slla070d/slla070d.pdf (Soltero et al.).

7.2.3 Renesas Serial Peripheral Interface

Serial Peripheral Interface (SPI) uses synchronous communication, so a dedicated clock sig- nal must be transmitted in addition to the serial data. Providing this clock signal lets us sim- plify the hardware down to just the shift registers and some minor supporting logic. This is much simpler than the USART, as there is no need for a bit rate generator, start and stop bits, 206 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

and other modules. The dedicated clock signal determines the bit rate. This interface is simi- lar to the USART. SPI is a full duplex mode of communication in which data can be trans- mitted and received simultaneously. The SPI was designed by Motorola to achieve high speed data transfer between peripherals of a microcontroller, and generally requires three wires for communication. In case multiple slave devices (devices to communicate with) are attached on the SPI bus, additional lines for selecting the device are required. However if not more than one slave device is connected on the bus, communication may be performed with only three wires. A typical SPI set up between a microcontroller and a peripheral is shown in Figure 7.10. As seen in the figure, the devices connected on the SPI bus usually have one master and one or more slave peripherals. However a multi- master mode may also be used. Master devices are usually microcontrollers or processors that control the flow of data to and from the slave peripheral device. The four required lines for communication are Serial Clock (SCLK), Master In Slave Out (MISO), Master Out Slave In (MOSI), and Slave Select (SSL).

This LSI (master) RSPI slave 0 RSPCK RSPCK MOSI MOSI MISO MISO SSL0 SSL SSL1 SSL2 SSL3 RSPI slave 1 RSPCK MOSI MISO SSL

RSPI slave 2 RSPCK MOSI MISO SSL

RSPI slave 3 RSPCK MOSI MISO SSL

Figure 7.10 Serial Peripheral Interface bus; Single master with multiple slaves connected. Source: Hardware Manual, page 1664. CHAPTER 7 / SERIAL COMMUNICATIONS 207

Serial Clock: Accompanying each data transfer is a clock signal that synchronizes the Master and Slave device. The length of the clock signal also determines the amount of data transferred on the MISO and MOSI pins. The serial clock is always generated by the mas- ter device and the slave synchronizes itself and the data transfer using the same clock.

Master Out Slave In: This line is similar to the transmit line of the USART, provided the Master device remains the same.

Master In Slave Out: This line is similar to the receive line of the USART, provided the Master device remains the same.

Slave Select: This pin, when acting as an output pin, provides for an active low signal that activates or de- activates the slave. The slave is usually in sleep mode until this line is tog- gled to the desired state (low or high) for activating the device. When in multi master mode, this pin acts as an input, and when pulled low indicates that another master is trying to communicate on the SPI bus. Now that we have an introduction to the physical part of the SPI interface, it is time to understand the working. But before we move on, it is worthwhile to note some of the fea- tures of the Renesas SPI that are different from most other microcontrollers. The Renesas Microcontroller has two inde pen dent SPI modules with multiple (four) slave select lines for each channel. The important features of the Renesas Serial Peripheral Interface are:

Transmit only operation available. Switching of phase and polarity of the serial clock. LSB/MSB first option. 128-bit transmit/receive buffers. Transfer bit length is selectable as 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, or 32 bits. Up to four frames can be transferred in one round of transmission/reception (each frame consisting of up to 32 bits). Mode fault error, overrun error, and parity error detection. A transfer of up to eight commands can be executed sequentially in looped execu- tion with SSL signal value, bit rate, RSPCK polarity/phase, transfer data length, LSB/MSB- first, burst, RSPCK delay, SSL negation delay, and next- access delay which can be changed for each command. A transfer can be initiated by simply writing to the transmit buffer.

General Working of SPI Modules During every SPI transfer, there always exists a Master device and a slave device. The mas- ter device is the one responsible for performing the transfer of data and generating the clock signal for performing the synchronous transfer of data. The slave device, while re- ceiving data also sends out data of its own to the master over the MISO line. Thus full 208 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

duplex communication occurs. The slave is active only when the master pulls the corre- sponding Slave Select Line low. This results in a “chip select” and activates the slave device.

Events take place in this sequence:

Master selects slave by pulling SSL low, thereby activating the slave device for communicating data. Master starts synchronous transfer of data by sending out a clock signal over the SCLK pin and the data over the MOSI line. The master waits until the data trans- fer completes. On reception of the serial clock signal from the master, the slave device starts out- putting data that it might want to transfer to the master. Data transfer halts as soon as the clock signal stops. Master deselects the slave by pulling the SSL line high.

Configurations of the Renesas SPI The Renesas microcontroller SPI bus can be configured to have:

Single Master Single Slave Single Master Multiple Slaves Multiple Masters Multiple Slaves

For the sake of simplicity, and understanding the basics of SPI, we shall consider only the Sin- gle Master Single Slave configuration. These configurations are shown in Figures 7.11 to 7.13.

Registers Related to the Renesas Serial Peripheral Interface The following describes the registers that are responsible for control of the RSPI with a short explanation, and the values to be assigned to each bit for setting up the SPI in the sin- gle master single slave configuration with the RX62N functioning as the master device.

Serial Peripheral Control Register (SPCR): This register controls the operating mode of the RSPI. The functions of the bits are as follows:

SPMS: This is the RSPI mode select bit which determines whether the SPI will act as a three wire (SCLK, MOSI, MISO) or a four wire interface (SCLK, MOSI, MISO, and SSLn). Setting this bit to 0 makes the RSPI operate in four wire mode whereas setting it to 1 makes the RSPI function in three wire clock synchronous mode. When operating in four wire mode, the pins SSL0 to SSL3 become available for chip selection; the default chip (slave) select pin being SSL0. When CHAPTER 7 / SERIAL COMMUNICATIONS 209

This LSI (master X) This LSI (master Y)

RSPCK RSPCK MOSI MOSI MISO MISO SSL0 SSL0 SSL1 SSL1 SSL2 SSL2 SSL3 SSL3 Port Y Port X

RSPI slave 1 RSPCK MOSI MISO SSL

RSPI slave 2 RSPCK MOSI MISO SSL

Figure 7.11 Multiple Masters Multiple Slaves. Source: Hardware Manual, page 1666.

This LSI (master) RSPI slave 0 RSPCK RSPCK MOSI MOSI MISO MISO SSL0 SSL SSL1 SSL2 SSL3 RSPI slave 1 RSPCK MOSI MISO SSL

RSPI slave 2 RSPCK MOSI MISO SSL

RSPI slave 3 RSPCK MOSI MISO SSL

Figure 7.12 Single Master Multiple Slaves. Source: Hardware Manual, page 1664. 210 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

This LSI (master) RSPI slave 0 RSPCK RSPCK MOSI MOSI MISO MISO SSL0 SSL SSL1 SSL2 SSL3

Figure 7.13 Single Master Single Slave (also shows clock synchronous configuration). Source: Hardware Manual, page 1663.

b7 b6 b5 b4 b3 b2 b1 b0

SPRIE SPE SPTIE SPEIE MSTR MODFEN TXMD SPMS

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.14 The SPI serial peripheral control register. Source: Hardware Manual, page 1635.

operating in three wire mode, it is assumed that either the desired chip is selected manually or there is only one active SPI slave on the device. TXMD: This is the Communications Operating Mode Select bit that determines whether the SPI will be acting in full duplex mode or perform transmit operations only. MODFEN: This bit enables or disables mode fault error detection. Mode fault er- ror occurs when the SPI is in master mode and an external device drives a slave se- lect pin low. MSTR: This bit determines whether the microcontroller acts as a master or a slave. SPEIE: Setting this bit to 1 enables the generation SPI error interrupt. This inter- rupt occurs when the RSPI module detects a mode fault or an overrun error, and sets the corresponding bits in the status register SPSR to 1. SPTIE: Setting this bit to 1 enables SPI transmit interrupt to indicate that the trans- mit buffer is empty. SPE: Setting this bit to 1 enables the SPI module. SPRIE: Setting this bit to 1 enables SPI receive interrupt. The interrupt occurs whenever the receive buffer is successfully written without errors.

Serial Peripheral Control Register (SPCR2): This register adds to the controllability of the operating mode of the Renesas SPI. The functions of the bits are as follows: CHAPTER 7 / SERIAL COMMUNICATIONS 211

b7 b6 b5 b4 b3 b2 b1 b0

— — — —PTESPIIE SPOE SPPE

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.15 The SPI serial peripheral control register 2. Source: Hardware Manual, page 1653.

SPPE: The SPPE bit enables or disables the parity function. The parity bit is added to transmit data, and parity checking is performed for receive data when the com- munications operating mode select bit (TXMD) in the RSPI control register (SPCR) is 0 and the SPPE bit in SPCR2 is 1. The parity bit is added to transmit data but parity checking is not performed for receive data when the SPCR.TXMD bit is 1 and the SPPE bit in SPCR2 is 1. SPOE: When even parity is set, parity bit addition is performed so that the total number of 1-bits in the transmit/receive character plus the parity bit is even. Simi- larly, when odd parity is set, parity bit addition is performed so that the total num- ber of 1-bits in the transmit/receive character plus the parity bit is odd. The SPOE bit is valid only when the SPPE bit is 1. SPIIE: The SPIIE bit enables or disables the generation of RSPI idle interrupt re- quests when the RSPI being in the idle state is detected and the IDLNF flag in the RSPI status register (SPSR) is cleared to 0. PTE: The PTE bit enables the self- diagnosis function of the parity circuit in order to check whether the parity function is operating correctly.

Slave Select Polarity (SSLP): This register sets the polarity of the slave select lines SSL0 to SSL3 of the Renesas SPI module. SSLP has four usable bits that select the polarity (ac- tive low/active high) for the corresponding slave select lines.

b7 b6 b5 b4 b3 b2 b1 b0

— — — — SSL3P SSL2P SSL1P SSL0P

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.16 The SPI slave select polarity register. Source: Hardware Manual, page 1637.

Setting the SSLxP bits to 0 sets the SSLx pin to active low, while setting SSLxP bit to 1 sets the SSLx pin to active high (x 0 or 1 or 2 or 3). 212 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Serial Peripheral Pin Control Register (SPPCR): This register sets the modes of the RSPI pins.

b7 b6 b5 b4 b3 b2 b1 b0

— — MOIFE MOIFV — SPOM SPLP2 SPLP

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.17 The SPI pin control register. Source: Hardware Manual, page 1638.

SPLP: When the SPLP (SPI Loopback) bit is set to 1, the RSPI shuts off the path between the MISOn pin and the shift register, and between the MOSIn pin and the shift register, and connects (reverses) the input path and output path for the shift register (loopback mode). SPLP2: The function of this bit is the same as the SPLP. When the SPLP2 bit is set to 1, the RSPI shuts off the path between the MISOn pin and the shift register, and between the MOSIn pin and the shift register, and connects (reverses) the input path and output path for the shift register (loopback mode). SPOM: The SPI Output Mode bit when set to 0 sets the RSPI output pins to func- tion as CMOS output pins, or open drain output pins when set to 0. MOVIFV: If the MOSI Idle Fixed Value bit is 1 in master mode, the MOIFV bit determines the MOSIn pin output value during the SSL negation period (including the SSL retention period during a burst transfer). MOVIFE: The MOSI Idle Value Fixing Enable bit fixes the MOSI output value when the RSPI in master mode is in an SSL negation period (including the SSL re- tention period during a burst transfer). When the MOIFE bit is 0, the RSPI outputs the last data from the previous serial transfer during the SSL negation period. When the MOIFE bit is 1, the RSPI outputs the fixed value set in the MOIFV bit to the MOSI bit.

Serial Peripheral Status (SPSR): This register is an indicator of the current operating status of the RSPI.

b7 b6 b5 b4 b3 b2 b1 b0

— — — — PERF MODF IDLNF OVRF

Value after reset: x 0 x 0 0 0 0 0

Figure 7.18 The SPI serial peripheral status register. Source: Hardware Manual, page 1640. CHAPTER 7 / SERIAL COMMUNICATIONS 213

OVRF: This Overrun error flag is set when a serial transfer ends while the SPCR.TXMD bit is 0 and the receive buffer holds data that has not yet been read out, thereby indicating an overrun error. It is cleared when the CPU writes the value 0 to the OVRF bit. IDLNF: The RSPI Idle Flag indicates the transfer status of the RSPI. The IDLNF, when in master mode, is cleared when all of the following conditions are satisfied: ▫ The SPCR.SPE bit is 0 (RSPI is initialized). ▫ The transmit buffer (SPTX) is empty (data for the next transfer is not set). ▫ The SPSSR.SPCP[2Ϻ0] bits are 000 (beginning of sequence control). ▫ The RSPI internal sequencer has entered the idle state (status in which opera- tions up to the next- access delay have finished). The IDLNF bit, when in master mode, is set when any of the above conditions are not satisfied, thereby indicating a non- idle state. When acting as a slave, this bit is set when the SPCR.SPE bit is 1 (RSPI func- tion is enabled) and cleared when SPCR.SPE bit is 0 (RSPI is initialized). MODF: A SPI Mode Fault is detected in a multi master mode when the input level of the SSLn pin changes to the active level while the SPCR.MSTR bit is 1 (master mode) and the SPCR.MODFEN bit is 1 (mode fault error detection is enabled). When in slave mode, a mode fault is detected when the SSLn pin is negated before the RSPCK cycle necessary for data transfer ends while the SPCR.MSTR bit is 0 (slave mode) and the SPCR.MODFEN bit is 1 (mode fault error detection is enabled), the RSPI detects a mode fault error. The MODF flag is cleared by writing 0 to the MODF bit. PERF: The Parity Error Flag is set when a serial transfer ends while the SPCR.TXMD bit is 0 and the SPCR2.SPPE bit is 1. This bit is cleared when CPU reads SPSR when the PERF bit is 1, and then writes the value 0 to the PERF bit.

Serial Peripheral Data Register (SPDR): This register contains data to be transmitted and data received over the SPI channel. Data written to this register is transmitted over the SPI channel. When this register is read from it returns the data received over the transmis- sion channel.

b31 b30 b29 b28 b27 b26 b25 b24 b23 b22 b21 b20 b19 b18 b17 b16

SPD31 SPD30 SPD29 SPD28 SPD27 SPD26 SPD25 SPD24 SPD23 SPD22 SPD21 SPD20 SPD19 SPD18 SPD17 SPD16

Value after reset: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0

SPD15 SPD14 SPD13 SPD12 SPD11 SPD10 SPD9 SPD8 SPD7 SPD6 SPD5 SPD4 SPD3 SPD2 SPD1 SPD0

Value after reset: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Figure 7.19 The SPI serial peripheral data register. Source: Hardware Manual, page 1643. 214 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The frame length and the number of bits transferred from this register depends upon the setting of the SPFC[1Ϻ0] and SPB[3Ϻ0] bits.

Serial Peripheral Sequence Control (SPSCR): This register sets the sequence method when the RSPI operates in master mode.

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — SPSLN[2:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.20 The SPI serial peripheral sequence control register. Source: Hardware Manual, page 1644.

SPSLN[2Ϻ0]: The SPI Sequence Length Specification bits specify a sequence length when the RSPI performs sequential operations in master mode. When in slave mode, the RSPI always refers to SPCMD0.

Serial Peripheral Sequence Status (SPSSR): This register indicates the sequence con- trol status when the RSPI operates in master mode.

b7 b6 b5 b4 b3 b2 b1 b0

— SPECM[2:0] — SPCP[2:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.21 The SPI serial peripheral sequence status register. Source: Hardware Manual, page 1645.

SPCP[2Ϻ0]: The RSPI command pointer bits point to the SPCMDn currently being executed. SPEM[2Ϻ0]: The RSPI Error command in conjunction with the SPSR register points to the command SPCMDn which caused an error.

Serial Peripheral Bit Rate Register (SPBR): The value of this register determines the rate of data transfer. CHAPTER 7 / SERIAL COMMUNICATIONS 215

b7 b6 b5 b4 b3 b2 b1 b0

SPR7 SPR6 SPR5 SPR4 SPR3 SPR2 SPR1 SPR0

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.22 The SPI bit rate register. Source: Hardware Manual, page 1646.

The SPBR register can have any value from 0 to 255. The following table shows a few ex- ample bit rate settings.

TABLE 7.3 Example Bit Rate Settings (n SPDR value, N BRDV[1Ϻ0]); value in SPCMDx.

BIT RATE

SPBR BRDV[1Ϻ0] DIVISION MHz 50 ؍ MHz PCLK 40 ؍ MHz PCLK 36 ؍ MHz PCLK 32 ؍ n) Bits (N) RATIO PCLK) 0 0 2 16.0 Mbps* 18.0 Mbps* 20.0 Mbps* 25.0 Mbps* 1 0 4 8.00 Mbps 9.00 Mbps 10.0 Mbps 12.5 Mbps 2 0 6 5.33 Mbps 6.00 Mbps 6.67 Mbps 8.33 Mbps 3 0 8 4.00 Mbps 4.50 Mbps 5.00 Mbps 6.25 Mbps 4 0 10 3.20 Mbps 3.60 Mbps 4.00 Mbps 5.00 Mbps 5 0 12 2.67 Mbps 3.00 Mbps 3.33 Mbps 4.16 Mbps 5 1 24 1.33 Mbps 1.50 Mbps 1.67 Mbps 2.08 Mbps 5 2 48 667 kbps 750 kbps 833 kbps 1.04 Mbps 5 3 96 333 kbps 375 kbps 417 kbps 521 kbps 255 3 4096 7.81 kbps 8.80 kbps 9.78 kbps 12.2 kbps

Serial Peripheral Data Control Register (SPDCR): This register determines the num- ber of frames that can be stored in SPDR, controls the SSLn pin output reading from SPDR, and selects width access to SPDR.

b7 b6 b5 b4 b3 b2 b1 b0

— — SPLW SPRDTD SLSEL[1:0] SPLF[1:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.23 The SPI serial peripheral data control register. Source: Hardware Manual, page 1647. 216 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

SPFC[1Ϻ0]: These bits specify the number of frames that can be stored in SPDR. Up to four frames can be transmitted or received in one round of transmission or re- ception, and the amount of data is determined by the combination of the RSPI data length specification bits (SPB[3Ϻ0]) in the RSPI command register (SPCMD), the RSPI sequence length specification bits (SPSLN[2Ϻ0]) in the RSPI sequence con- trol register (SPSCR), and the number of frames specification bits (SPFC[1Ϻ0]) in the RSPI data control register (SPDCR). Also, the SPFC[1Ϻ0] bits specify the num- ber of received data at which the RSPI receive buffer full interrupt is requested. The following table shows the frame configurations that can be stored in SPDR and ex- amples of combinations of settings for transmission and reception.

TABLE 7.4 Setting the Number of Frames Transmitted from SPDR.

NUMBER OF FRAMES AT WHICH RECEIVE BUFFER FULL INTERRUPT NUMBER OF OCCURS OR TRANSMIT FRAMES FOR BUFFER HOLDING DATA SETTING SPB[3Ϻ0] SPSLN[2Ϻ0] SPFC[1Ϻ0] TRANSFER IS RECOGNIZED 1–1 N 000 00 1 1 1–2 N 000 01 2 2 1–3 N 000 10 3 3 1–4 N 000 11 4 4 2–1 N, M 001 01 2 2 2–2 N, M 001 11 4 4 3 N, M, O 010 10 3 3 4 N, M, O, P 011 11 4 4 5 N, M, O, P, Q 100 00 5 1 6 N, M, O, P, Q, R 101 00 6 1 7 N, M, O, P, Q, R, S 110 00 7 1 8 N, M, O, P, Q, R, S, T 111 00 8 1

SLSEL[1Ϻ0]: SSL Pin Output Selection bits control the SSLn pin output in master mode for the corresponding RSPI. CHAPTER 7 / SERIAL COMMUNICATIONS 217

TABLE 7.5 SSL Pin Output Selection Configuration/Function.

SLSEL SLSEL SLSEL SLSEL 11 ؍ [1Ϻ0] 10 ؍ [1Ϻ0] 01 ؍ [1Ϻ0] 00 ؍ [1Ϻ0] SSL3 Output I/O I/O

SSL2 Output I/O I/O Setting SSL1 Output I/O Output prohibited SSL0 Output Output Output

Serial Peripheral Clock Delay Register (SPCKD): The value of this register sets a pe- riod from the beginning of SSL signal assertion to the clock oscillations on the RSPK line.

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — SCKDL[2:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.24 The SPI serial peripheral clock delay register. Source: Hardware Manual, page 1650.

SCKDL [2Ϻ0]: The RSPCK Delay Setting bits set an RSPCK delay value when the SPCMD.SCKDEN bit is 1. When using the RSPI in slave mode, set the SCKDL[2Ϻ0] bits to 000.

Slave Select Line Negation Delay (SSLND): This register sets a period/delay from the transmission of final RSPCK edge to the negation of the SSL signal during a serial transfer by the RSPI in master mode.

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — SLNDL[2:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.25 The SPI serial peripheral slave select negation delay register. Source: Hardware Man- ual, page 1651. 218 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

SLNDL [2Ϻ0]: The SSL Negation Delay Setting bits set an SSL negation delay value when the RSPI is in master mode. When using the RSPI in slave mode, set the SLNDL [2Ϻ0] bits to 000.

Serial Peripheral Next Access Delay Register (SPND): This register sets a non- active period after termination of a serial transfer.

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — SPNDL[2:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.26 The SPI serial peripheral next access delay register. Source: Hardware Manual, page 1652.

SPNDL [2Ϻ0]: The RSPI Next- Access Delay Setting bits set a next- access delay when the SPCMD.SPNDEN bit is 1. When using the RSPI in slave mode, set the SPNDL[2Ϻ0] bits to 000.

Serial Peripheral Command Register (SPCMDx): SPCMD0 to SPCMD7 are used to set a transfer format/method for the RSPI in master mode. The SPCMDx register has vari- ous fields that can be set to control the corresponding feature of the RSPI.

b15 b14 b13 b12 b11 b10 b9 b8

SCKDEN SLNDEN SPNDEN LSBF SPB[3:0]

Value after reset: 0 0 0 0 0 1 1 1

b7 b6 b5 b4 b3 b2 b1 b0

SSLKP SSLA[2:0] BRDV[1:0] CPOL CPHA

Value after reset: 0 0 0 0 1 1 0 1

Figure 7.27 The SPI serial peripheral command register. Source: Hardware Manual, page 1655.

CPHA: The RSPCK Phase Setting bit sets an RSPCK phase of the RSPI in master mode or slave mode. Data communications between RSPI modules require the same RSPCK phase setting between the modules. CHAPTER 7 / SERIAL COMMUNICATIONS 219

BRDV[1Ϻ0]: Bit Rate Division Setting bits are used to determine the bit rate. A bit rate is determined by combinations of the settings in the BRDV[1Ϻ0] bits and SPBR (See Section 32.2.8, RSPI Bit Rate Register (SPBR) in the hardware man- ual). The settings in SPBR determine the base bit rate. The settings in the BRDV[1Ϻ0] bits are used to select a bit rate, which is obtained by dividing the base bit rate by 1, 2, 4, or 8. In SPCMD0 to SPCMD7, different BRDV[1Ϻ0] bit settings can be specified. This permits the execution of serial transfers at a different bit rate for each command. SSLA[2Ϻ0]: The SSL Signal Assertion Setting bits control the SSL signal assertion when the RSPI performs serial transfers in master mode. Setting the SSLA[2Ϻ0] bits controls the assertion for the SSL0 to SSL3 signals. When an SSL signal is as- serted, its polarity is determined by the set value in the corresponding SSLP. When the SSLA[2Ϻ0] bits are set to 000 in multi- master mode, serial transfers are per- formed with all the SSL signals in the negated state (as the SSLn0 pin acts as input). When using the RSPI in slave mode, set the SSLA[2Ϻ0] bits to 000. SSLKP: SSL Signal Level Keeping bit RSPI in master mode performs a serial transfer, the SSLKP bit specifies whether the SSL signal level for the current com- mand is to be kept or negated between the SSL negation timing associated with the current command and the SSL assertion timing associated with the next command. When using the RSPI in slave mode, the SSLKP bit should be set to 0. SPB[3Ϻ0]: RSPI Data Length Setting bits set a transfer data length for the RSPI in master mode or slave mode. LSBF: RSPI LSB First bit sets the data format of the RSPI in master mode or slave mode to MSB first or LSB first. SPNDEN: RSPI Next- Access Delay Enable The SPNDEN bit sets the period from the time the RSPI in master mode termi- nates a serial transfer and sets the SSL signal inactive until the RSPI enables the SSL signal assertion for the next access (next- access delay). If the SPNDEN bit is 0, the RSPI sets the next- access delay to 1 RSPCK 2 PCLK. If the SPNDEN bit is 1, the RSPI inserts a next- access delay in compliance with the SPND setting. When using the RSPI in slave mode, the SPNDEN bit should be set to 0.

Port Function Control Register G (PFGSPI): The PFGSPI special function register is used to select I/O pins for RSPI channel 0.

b7 b6 b5 b4 b3 b2 b1 b0

SSL3E SSL2E SSL1E SSL0E MISOE MOSIE RSPCKE RSPIS

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.28 The port function control register. Source: Hardware Manual, page 1665. 220 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

RSPIS Bit (RSPI Pin Select): This bit selects a pin for an RSPI input/output. As an enable bit is provided for each RISPI input/output pin, the input/output pin is selectable while the corresponding enable bit is 1. Otherwise, the pin cannot be selected. RSPCKE Bit (RSPCK Enable): This bit enables or disables the output of the RSPCK pin. Set this bit to 1 to use the RSPCK pin. MOSIE Bit (MOSI Enable): This bit enables or disables the output of the MOSI pin. Set this bit to 1 to use the MOSI pin. MISOE Bit (MISO Enable): This bit enables or disables the output of the MISO pin. Set this bit to 1 to use the MISO pin. SSL0E Bit (SSL0 Enable): This bit enables or disables the output of the SSL0 pin. Set this bit to 1 to use the SSL0 pin. SSL1E Bit (SSL1 Enable): This bit enables or disables the output of the SSL1 pin. Set this bit to 1 to use the SSL1 pin. SSL2E Bit (SSL2 Enable): This bit enables or disables the output of the SSL2 pin. Set this bit to 1 to use the SSL2 pin. SSL3E Bit (SSL3 Enable): This bit enables or disables the output of the SSL3 pin. Set this bit to 1 to use the SSL3 pin.

Configuring the RSPI to Function in Single Master Single Slave Mode This is the simplest configuration possible in which we have 1 slave device connected to the Renesas Serial Peripheral Interface. Section 7.3.2 describes the setup of the afore- mentioned RSPI registers for the Single Master Single Slave configuration as shown in Figure 7.29.

This LSI (master) RSPI slave RSPCK RSPCK MOSI MOSI MISO MISO SSL0 SSL SSL1 SSL2 SSL3

Figure 7.29 Single Master Single Slave Configuration. Source: Hardware Manual, page 1662. CHAPTER 7 / SERIAL COMMUNICATIONS 221

7.2.4 Renesas Inter Integrated Circuit Bus

The Inter Integrated Circuit (I2C) bus was invented by Philips Electronics for serial com- munications between low speed peripherals in an embedded system. The bus allows multi- ple peripheral devices to be connected on the same set of wires to communicate with each other with only two devices, one master device and one slave device, communicating with each other at a given time. The bus mainly consists of two wires Serial Clock (SCL) and Serial Data (SDA) that are responsible for transferring the data from one end to the other. These lines are constantly held high by pull up resistors when the bus is inactive. All de- vices connected on these lines need to communicate with the I2C protocol. Figure 7.30 il- lustrates devices connected on an I2C bus.

Vcc Device 1 Device 2 Device 3 Device 4

Address Address Address Address (0x80) (0xC0) (0xE1) (0x70)

SCL

SDA

Figure 7.30 Four Devices Connected on the I2C Bus with pull up resistors. 128 such devices can be connected on a single bus.

I2C Bus Protocol Each device connected on the bus is assigned a 7-bit address. Data is usually transferred as a byte plus an additional bit and is accompanied by a clock signal that synchronizes the data transfer between the communicating devices. The device that takes control of the bus at the beginning of communication is usually the master device, and is responsible for ad- dressing the slave device and generating a clock signal during data transmission. Before any form of data transfer takes place, a device wanting to transfer data must take control of the bus. This is done by monitoring the bus. If the bus is currently held high (both SDA and SCL are at a high voltage), it implies that the bus is currently free. Other- wise the bus is assumed to be busy and the device must wait for the bus to be free in order to transmit data. When the bus becomes free, the master acquires the control of the bus by sending a START condition in which the device pulls the SDA line low while keeping the SCL line high and thus becomes the current master of the bus. Figure 7.31 (A) illustrates a START condition. The generation of the START condition also informs the other devices 222 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

that the bus is currently busy, and the other devices start listening to the next byte to be transferred on the bus. When the current master of the bus is ready to release the bus from its control, it trans- mits a STOP condition in which the SDA line gets pulled high while the SCL line is high. During the entire period in which the master is in control of the bus, the SDA line is con- stantly held low, except that when there is data being transmitted there is toggling of both lines. Figure 7.31 (B) shows a STOP condition.

SCL SCL

SDA SDA

(A) (B) Figure 7.31 (A) START condition; (B) STOP condition.

Once control of the bus is obtained, the next priority for the master is to address the slave de- vice by transmitting one byte which consists of a seven bit address and one bit that specifies if the master device wants to read from or write to the slave device. This bit is called the Read/Write bit (R/W). If this bit is low, it indicates that the master wants to write to the slave device; if high, the master device wishes to read from the slave. The status of the R/W bit de- termines whether the next transactions are going to be read from or written to the slave devices. After transfer of these eight bits, the master clocks out an additional pulse while keeping the SDA high. If a device with the transmitted seven bit address is presently listening on the bus, it responds immediately on the ninth clock pulse by pulling the SDA line low. This is an ACK bit signaling an acknowledgement, and the slave device becomes an active listener on the bus while other devices stop listening to the bus. Thus the master is now ready to transfer more data to the slave. If the SDA line remains low during the ninth clock pulse, the master gets a “no ac- knowledgement” (NACK) indication and stops transfer of data by sending a STOP bit.

I2C Communication Modes Depending upon the initial transactions mentioned above, a device can be set up in any of the four following modes:

Master Transmitter: In this mode, the device functions as a master and transmits data to a slave after acquiring the control of the bus. This device usually transmits the seven bit address with the R/W bit set to write. It may also transmit additional bytes if an ACK is received for every byte it transfers. CHAPTER 7 / SERIAL COMMUNICATIONS 223

Master Receiver: In this mode, the device functions as a master and clocks out data from the slave. In this case, the master generates the clock pulses to which the slave toggles data on the SDA pin. Before any reception can take place, the master must output the slave device address with the R/W bit set to R and then output the desired number of clock cycles with pseudo data (usually 0xFF). On every ninth clock pulse, the master receiver is required to send an ACK pulse to the slave de- vice acknowledging the reception of data. Slave device stops transmitting the data to the master receiver as soon as the master clocks a NACK as the ninth bit on the most recent 8 byte data. Slave Transmitter: A device enters this mode when another device gains control of the bus and addresses the device with the address assigned to it with the R/W bit set to R. Such a device works in conjunction with a master receiver and responds to commands sent to it by the master receiver. The slave device stops transmitting the data to the master receiver as soon as the master clocks a NACK as the ninth bit on the most recent 8 byte data. Slave Receiver: A device enters this mode as soon as it is successfully addressed by a master transmitter with the R/W bit transmitted as W. The slave device is re- quired to clock out an ACK bit for every relevant byte it successfully received.

Now that we understand some of the basics of the I2C protocol, we can move on to under- stand the detailed working of the I2C interface provided by Renesas; i.e., the Renesas Inter Integrated Circuit bus interface and the registers related to it. Figure 7.32 shows the typical transfers supported by the RIIC interface.

[7-bit address format]

S SLA (7 bit) RW# A DATA (8 bits) A A/A# P

1 7 1 1 8 1 1 1

n (n 1 or more)

[10-bit address format]

S 11110b+SLA(2 bits) W# A SLA (8 bits) A DATA (8 bits) A A/A# P

1 7 1 1 8 1 8 1 1 1

n (n 1 or more)

S 11110b+SLA(2 bits) W# A SLA (8 bits) A Sr 11110b+SLA(2 bits) R A DATA (8 bits) A A/A# P

1 7 1 1 8 1 1 7 1 1 8 1 1 1

n (n 1 or more)

2 Figure 7.32 Typical data transfers supported by the Renesas I C Interface. Source: Hardware Manual, page 1662. 224 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Registers related to the RIIC interface: I2C Bus Control Register 1 (ICCR1): ICCR1 enables or disables the RIIC, resets the in- ternal state of the RIIC, outputs an extra SCL clock cycle, and manipulates and monitors the SCLn pin and SDAn pin. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

ICE IICRSTCLOSOWP SCLO SDAO SCLI SDAI

Value after reset: 0 0 0 1 1 1 1 1

Figure 7.33 The ICCR1 register. Source: Hardware Manual, page 1483.

I2C Bus Interface Enable (ICE): Setting this pin to 1 enables the RIIC transfer function (the SCLn pin and SDAn pin drive the bus) and vice versa. I2C Interface Internal Reset (IICRST): Setting this bit to 1 initiates the RIIC reset resulting in all control, mode, and status registers resetting to default values. This bit needs to be manually cleared to finish the reset. The bit should usually be set when the ICE bit is set to 0. If this bit is set when ICE is 1, it resets the BC[2Ϻ0] bits in ICMR1; the ICSR1, ICSR2, ICDRS registers; and the internal states of the RIIC. (CLO): Setting this bit to 1 causes the RIIC interface to output an extra SCL clock cycle (the CLO bit is cleared automatically after one clock cycle is output). (SOWP): This bit controls the modification of the SCLO and SDAO bits. Setting this bit to 0 allows the SCLO and SDAO bits to be rewritten. This bit is always written as 1. (SCLO): This bit controls the output level of the SCLn pin. This bit also monitors the output state of the SCLn pin. Setting this bit to 0 sets the SCLn pin to low level, and vice versa. (SDAO): This bit controls the output level of the SDAn pin. This bit also monitors the output state of the SDAn pin. Setting this bit to 0 sets the SDAn pin to low level, and vice versa. (SCLI): This bit monitors the input level of the SCLn pin. If this bit is high, it im- plies that the SCL pin is acting as input and is high. If this bit is low, it implies that the SCL pin is acting as input and is low. (SDAI): This bit monitors the input level of the SDAn pin. If this bit is high, it im- plies that the SDA pin is acting as input and is high. If this bit is low, it implies that the SDA pin is acting as input and is low. CHAPTER 7 / SERIAL COMMUNICATIONS 225

I2C Bus Control Register 2 (ICCR2): ICCR2 has a flag function that indicates whether or not the I2C bus is occupied and whether the RIIC is in transmit/receive or master/slave mode, as well as a function to issue a start or stop condition. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

BBSYMSTTRS — SPRSST —

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.34 The ICCR2 register. Source: Hardware Manual, page 1486.

(BBSY): The BBSY flag indicates whether the I2C bus is occupied (bus busy) or released (bus free). This bit is set to 1 when the SDAn line changes from high to low under the condition of SCLn high, assuming that a start condition has been issued. When the SDAn line changes from low to high under the condition of SCLn high, this bit is cleared to 0 after the bus free time (specified in ICBRL) start condition is not detected, assuming that a stop condition has been issued or if an Internal Interface Reset occurs. (MST): This bit indicates whether the RIIC interface is acting as a master or slave mode. This bit is set when: ▫ A start condition is issued normally according to the start condition issuance request (when a start condition is detected with the ST bit set to 1). ▫ A 1 is written to the MST bit with the MTWP bit in ICMR1 set to 1. It is reset when: ▫ A stop condition is detected. ▫ The AL (arbitration lost) flag in ICSR2 is set to 1. ▫ A 0 is written to the MST bit with the MTWP bit in ICMR1 set to 1. ▫ A 1 is written to the IICRST bit in ICCR1 to apply an RIIC reset or an internal reset. Manual setting of this is permitted only when MTWP in ICMR1 is 1. (TRS): This bit indicates transmit or receive mode. This bit is set when: ▫ A start condition is issued normally according to the start condition issuance request (when a start condition is detected with the ST bit set to 1). ▫ The R/W# bit added to the slave address is set to 0 in master mode. ▫ The address received in slave mode matches the address enabled in ICSER, with the R/W# bit set to 1. ▫ A 1 is written to the TRS bit with the MTWP bit in ICMR1 set to 1. 226 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

This bit is cleared when: ▫ A stop condition is detected. ▫ The AL (arbitration lost) flag in ICSR2 being set to 1. ▫ In master mode, reception of a slave address to which an R/W# bit with the value 1 is appended. ▫ In slave mode, a match between the received address and the address enabled in ICSER, when the value of the received R/W# bit is 0 (including cases where the received address is the general call address). ▫ In slave mode, a restart condition is detected (a start condition is detected with ICCR2.BBSY 1 and ICCR2.MST 0). ▫ When 0 is written to the TRS bit with the MTWP bit in ICMR1 set to 1. ▫ When 1 is written to the IICRST bit in ICCR1 to apply an RIIC reset or an in- ternal reset. A combination of this bit and the MST bit indicates the operating mode of the RIIC. Also, writing to this bit is not necessary during normal usage. (SP): This bit is used to request that a stop condition be issued in master mode. This bit is manually set to 1 to request to issue a stop condition, a stop condition is issued only when the BBSY flag is set to 1 (bus busy) and the MST bit is set to 1 (master mode). This bit is set when a 1 is written to it and cleared when any of the following conditions occur: ▫ A 0 is written to the SP bit after reading SP 1. ▫ A stop condition has been issued or a stop condition is detected. ▫ The AL (arbitration lost) flag in ICSR2 is set to 1. ▫ A start condition and a restart condition are detected. ▫ A 1 is written to the IICRST bit in ICCR1 to apply an RIIC reset or an internal reset. (RS): This bit is used to request that a restart condition be issued in master mode. When this bit is set to 1 to request to issue a restart condition, a restart condition is issued when the BBSY flag is set to 1 (bus busy) and the MST bit is set to 1 (mas- ter mode). This bit is set when a 1 is written to it and cleared when any of the fol- lowing conditions occur: ▫ A 0 is written to the RS bit. ▫ A restart condition has been issued or a start condition is detected. ▫ The AL (arbitration lost) flag in ICSR2 is set to 1. ▫ A 1 is written to the IICRST bit in ICCR1 to apply an RIIC reset or an internal reset. (ST): This bit is used to request transition to master mode and issuance of a start con- dition. When this bit is set to 1 to request to issue a start condition, a start condition is issued when the BBSY flag is set to 0 indicating that the bus is free. This bit is set when a 1 is written to it and cleared when any of the following conditions occur: ▫ A 0 is written to the ST bit. CHAPTER 7 / SERIAL COMMUNICATIONS 227

▫ A start condition has been issued. ▫ The AL (arbitration lost) flag in ICSR2 is set to 1. ▫ A 1 is written to the IICRST bit in ICCR1 to apply an RIIC reset or an internal reset.

I2C Mode Register 1 (ICMR1): ICMR1 specifies the internal reference clock source within the RIIC, indicates the number of bits to be transferred, and protects the MST and TRS bits in ICCR2 from being written. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

MTWP CKS[2:0] BCWP BC[2:0]

Value after reset: 0 0 0 0 1 0 0 0

Figure 7.35 The ICMR1 register. Source: Hardware Manual, page 1490.

(MTWP): This bit controls the modification of the MST and TRS bits in ICCR2. Setting this bit enables writing to the MST and TRS bits in ICCR2. (CKS[2Ϻ0]): These bits select a reference clock source (IIC) inside the RIIC. Table 7.6 shows the selections possible:

TABLE 7.6 Clock Source Selection for the RIIC Interface.

CKS2 CKS1 CKS0 CLOCK SOURCE TO RIIC 0 0 0 PCLK/1 clock 0 0 1 PCLK/2 clock 0 1 0 PCLK/4 clock 0 1 1 PCLK/8 clock 1 0 0 PCLK/16 clock 1 0 1 PCLK/32 clock 1 1 0 PCLK/64 clock 1 1 1 PCLK/128 clock 228 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

(BCWP): Clearing this bit to 0 enables a value to be written in the BC[2Ϻ0] bits. (BC[2Ϻ0]): These bits function as a counter that indicates the number of bits re- maining to be transferred at the detection of a rising edge on the SCLn line. Al- though these bits are writable and readable, it is not necessary to access these bits under normal conditions. To write to these bits, specify the number of bits to be transferred plus one (data is transferred with an additional acknowledge bit) be- tween transferred frames when the SCLn line is at a low level. Table 7.7 shows how the Bit counter indicates the number of bits remaining:

TABLE 7.7 Bit Counter Indications.

BC2 BC1 BC0 NUMBER OF BITS REMAINING 0 0 0 9 0 0 1 2 0 1 0 3 0 1 1 4 1 0 0 5 1 0 1 6 1 1 0 7 1 1 1 8

I2C Mode Register 2 (ICMR2): ICMR2 has a timeout function and an SDA output de- lay function. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

DLCS SDDL[2:0] — TMOH TMOL TMOS

Value after reset: 0 0 0 0 0 1 1 0

Figure 7.36 The ICMR2 register. Source: Hardware Manual, page 1492.

(DCLS): This bit is used to select the internal reference clock (IIC) if set to 0, or the internal reference clock divided by 2 (IIC/2) if set to 1, as the clock source of the SDA output delay time. (SDDL[2Ϻ0]): The SDA output can be delayed by the SDDL[2Ϻ0] setting. This counter works with the clock source selected by the DLCS bit. The setting of this function can be used for all types of SDA output, including the transmission of the acknowledge bit. CHAPTER 7 / SERIAL COMMUNICATIONS 229

TABLE 7.8

DELAY TIME WHEN DELAY TIME WHEN 1 ؍ DCLS 0 ؍ SDDL2 SDDL1 SDDL0 DCLS 0 0 0 No Delay in output No Delay in output 0 0 1 1 IIC cycle 1 or 2 IIC cycles 0 1 0 2 IIC cycle 3 or 2 IIC cycles 0 1 1 3IIC cycle 5 or 2 IIC cycles 1 0 0 4 IIC cycle 7 or 2 IIC cycles 1 0 1 5 IIC cycle 9 or 2 IIC cycles 1 1 0 6 IIC cycle 11 or 2 IIC cycles 1 1 1 7 IIC cycle 13 or 2 IIC cycles

(TMOH): This bit is used to enable (when set to 1) or disable (when set to 0) the internal counter of the timeout function to count up while the SCLn line is held high when the timeout function is enabled (TMOE bit 1 in ICFER). (TMOL): This bit is used to enable (when set to 1) or disable (when set to 0) the in- ternal counter of the timeout function to count up while the SCLn line is held low when the timeout function is enabled (TMOE bit 1 in ICFER). (TMOS): This bit is used to select long mode or short mode for the timeout detec- tion time when the timeout function is enabled (TMOE bit 1 in ICFER). When this bit is set to 0, long mode is selected. When this bit is set to 1, short mode is se- lected. In long mode, the timeout detection internal counter functions as a 16 bit- counter. In short mode, the counter functions as a 14 bit- counter. While the SCLn line is in the state that enables this counter as specified by bits TMOH and TMOL, the counter counts up in synchronization with the internal reference clock (IIC) as a count source.

I2C Mode Register 3 (ICMR3): ICMR3 has functions to send/receive acknowledge and to select the RDRF set timing in RIIC receive operation, WAIT operation, and the SCLn pin and SDAn pin input level of the RIIC. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

SMBS WAIT RDRFS ACKWP ACKBT ACKBR NF[1:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.37 The ICMR3 register. Source: Hardware Manual, page 1494. 230 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

(SMBS): Setting this bit to 1 selects the SMBus and enables the HOAE bit in ICSER. Otherwise the interface acts as the standard I2C interface. (WAIT): This bit is valid only in receive mode and is used to control whether to hold the period between the ninth SCL clock cycle and the first SCL clock cycle low until the receive (ICDRR) is completely read each time single- byte data is received in receive mode. (RDRFS): This bit is used to select the RDRF flag set timing in receive mode and also to select whether to hold the SCLn line low at the falling edge of the eighth SCL clock cycle. When the RDRFS bit is 0, the SCLn line is not held low at the falling edge of the eighth SCL clock cycle, and the RDRF flag is set to 1 at the ris- ing edge of the ninth SCL clock cycle. When the RDRFS bit is 1, the RDRF flag is set to 1 at the rising edge of the eighth SCL clock cycle and the SCLn line is held low at the falling edge of the eighth SCL clock cycle. The low- hold of the SCLn line is released by writing a value to the ACKBT bit. After data is received with this setting, the SCLn line is automatically held low before the acknowledge bit is sent. This enables processing to send ACK (ACKBT 0) or NACK (ACKBT 1) ac- cording to receive data. (ACKWP): This bit is used to control the modification of the ACKBT bit. (ACKBT): This bit holds the acknowledgement to be sent in receive mode. When set to 0, ACK is transmitted as 0, and vice versa. (ACKBR): This bit is used to store the acknowledge bit information received from the receive device in transmit mode. This bit is set to 1 when a 1 is received as the acknowledge bit with the TRS bit in ICCR2 set to 1. This bit is set to 0 when a 0 is received as the acknowledge bit with the TRS bit in ICCR2 set to 1, or an interface internal reset occurs. (NF [1Ϻ0]): These bits are used to select the number of stages (1, 2, 3, or 4) of the digital noise filter.

I2C Bus Function Enable Register (ICFER): ICFER enables or disables the timeout function, the arbitration lost detection function, and the receive operation suspension func- tion during NACK reception, and selects the use of a digital noise filter circuit and SCL synchronous circuit. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

FMPE SCLE NFE NACKE SALE NALE MALE TMOE

Value after reset: 0 1 1 1 0 0 1 0

Figure 7.38 The ICFER register. Source: Hardware Manual, page 1497.

(FMPE): This bit is used to specify whether to use a slope control circuit for Fast- mode Plus[fm]. CHAPTER 7 / SERIAL COMMUNICATIONS 231

(SCLE): This bit is used to specify whether to synchronize the SCL clock with the SCL input clock. Normally, set this bit to 1. (NFE): This bit is used to specify whether to use a digital noise filter circuit. (NACKE): This bit is used to specify whether to continue or discontinue the trans- fer operation when NACK is received from the slave device in transmit mode. Nor- mally, set this bit to 1. (SALE): This bit is used to specify whether to cause arbitration to be lost when a value different from the value being transmitted is detected on the bus in slave transmit mode (such as when slaves with the same address exist on the bus, or when a mismatch with the transmit data occurs due to noise). (NALE): This bit is used to specify whether to cause arbitration to be lost when ACK is detected during transmission of NACK in receive mode (such as when slaves with the same address exist on the bus, or when two or more masters select the same slave device simultaneously with a different number of receive bytes). (MALE): This bit is used to specify whether to use the arbitration lost detection function in master mode. Normally, set this bit to 1. (TMOE): This bit is used to enable or disable the timeout function.

I2C Bus Status Enable Register (ICSER): ICSER enables or disables comparison of slave addresses, general call address detection, device- ID command detection, and host ad- dress detection. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

HOAE —DIDE— GCAE SAR2E SAR1E SAR0E

Value after reset: 0 0 0 0 1 0 0 1

Figure 7.39 The ICSER register. Source: Hardware Manual, page 1499.

(HOAE): This bit is used to specify whether to ignore a received host address (0001 000b) when the SMBS bit in ICMR3 is 1. (DIDE): This bit is used to specify whether to recognize and execute the Device- ID address when a device ID (1111 100b) is received in the first frame after a start con- dition or restart condition is detected. Setting this bit to 1 enables Device ID detection. (GCAE): This bit is used to specify whether to ignore the general call address (0000 000b 0 [W]: All 0) when it is received. When this bit is set to 1, if the re- ceived slave address matches the general call address as the first frame received af- ter the START condition, the GCA bit is set in the I2C status register 1. (SAR2E): This bit is used to enable or disable the received slave address and the slave address set in SARL2 and SARU2. 232 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

(SAR1E): This bit is used to enable or disable the received slave address and the slave address set in SARL1 and SARU1. (SAR0E): This bit is used to enable or disable the received slave address and the slave address set in SARL0 and SARU0.

I2C Bus Interrupt Enable Register (ICIER): ICIER enables or disables various inter- rupt sources. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

TIE TEIE RIE NAKIE SPIE STIE ALIE TMOIE

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.40 The ICIER register. Source: Hardware Manual, page 1501.

(TIE): This bit is used to enable or disable transmit data empty interrupts (ICTXI) when the TDRE flag in ICSR2 is set to 1. (TEIE): This bit is used to enable or disable transmit end interrupts (ICTEI) when the TDRE flag in ICSR2 is set to 1. An ICTEI interrupt request is canceled by clearing the TEND flag or the TEIE bit to 0. (RIE): This bit is used to enable or disable receive data full interrupt requests (ICRXI) when the RDRF flag in ICSR2 is set to 1. (NAKIE): This bit is used to enable or disable NACK reception interrupt requests (NAKI) when the NACKF flag in ICSR2 is set to 1. A NAKI interrupt request is canceled by clearing the NACKF flag or the NAKIE bit to 0. (SPIE): This bit is used to enable or disable stop condition detection interrupt re- quests (SPI) when the STOP flag in ICSR2 is set to 1. An SPI interrupt request is canceled by clearing the STOP flag or the SPIE bit to 0. (STIE): This bit is used to enable or disable start condition detection interrupt re- quests (STI) when the START flag in ICSR2 is set to 1. An STI interrupt request is canceled by clearing the START flag or the STIE bit to 0. (ALIE): This bit is used to enable or disable arbitration lost interrupt requests (ALI) when the AL flag in ICSR2 is set to 1. An ALI interrupt request is canceled by clearing the AL flag or the ALIE bit to 0. (TMOIE): This bit is used to enable or disable timeout interrupt requests (TMOI) when the TMOF flag in ICSR2 is set to 1. TMOI interrupt request is canceled by clearing the TMOF flag or the TMOIE bit to 0.

I2C Bus Status Register 1 (ICSR1): ICSR1 indicates various address detection status. Bits in this register are: CHAPTER 7 / SERIAL COMMUNICATIONS 233

b7 b6 b5 b4 b3 b2 b1 b0

HOA —DID— GCA AAS2AAS1AAS0

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.41 The ICSR1 register. Source: Hardware Manual, page 1503.

(HOA): When the received slave address matches the host address (0001 000b) with the HOAE bit in ICSER set to 1 (host address detection enabled). (DID): This bit is set when the first frame received immediately after a start condi- tion or restart condition is detected matches a value of (device ID (1111 100b) 0 [W]) with the DIDE bit in ICSER set to 1 (Device- ID address detection enabled), and is cleared when 0 is written to the DID bit after reading DID 1, when a stop condition is detected, or when the first frame received immediately after a start condition or restart condition is detected does not match a value of the device IDs assigned to the device. (GCA): When the received slave address matches the general call address with the GCAE bit in ICSER set to 1 (general call address detection enabled). This flag is set to 1 at the rising edge of the ninth SCL clock cycle in the frame. This bit is cleared when a stop condition is detected, an internal interface reset occurs, the address does not match the general call address (0b0000000 [0]), or if 0 is written to the GCA bit after reading GCA 1. (AAS2): This bit is set if either the 7-bit or 10-bit slave address is received/ad- dressed by the master transmitter. This bit is cleared when a stop condition is de- tected, an internal interface reset occurs, an address mismatch has occurred, or if 0 is written to the AAS0 bit after reading it. (AAS1): This bit is set if either the 7-bit or 10-bit slave address is received/ad- dressed by the master transmitter. This bit is cleared when a stop condition is de- tected, an internal interface reset occurs, an address mismatch has occurred, or if 0 is written to the AAS0 bit after reading it. (AAS0): This bit is set if either the 7-bit or 10-bit slave address is received/ad- dressed by the master transmitter. This bit is cleared when a stop condition is de- tected, an internal interface reset occurs, an address mismatch has occurred, or if 0 is written to the AAS0 bit after reading it.

I2C Bus Status Register 2 (ICSR2): ICSR2 indicates various interrupt request flags and statuses. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

TDRE TEND RDRF NACKF STOP START AL TMOF

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.42 The ICSR2 register. Source: Hardware Manual, page 1501. 234 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

(TDRE): This flag when set to 1 indicates that ICDRT contains no transmit data. (TEND): This flag when set to 1 indicates that data has been transmitted. (RDRF): This flag when set to 1 indicates that ICDRR contains receive data. (NACKF): This flag when set to 1 indicates that NACK is detected. (STOP): This flag when set to 1 indicates that stop condition is detected. (START): This flag when set to 1 indicates that start condition is detected. (AL): This flag when set to 1 indicates that arbitration is lost. (TMOF): This flag when set to 1 indicates that timeout is detected.

Slave Address Register Upper (SARUm): SARUm selects 7-bit address format or 10-bit address format and sets the upper bits of a 10-bit slave address. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

— — — — —FSVA[9:8] S

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.43 The SARUm register. Source: Hardware Manual, page 1512.

(SVA[9Ϻ8]): These two bits are the upper bits 10-bit address. (FS): This bit, when set to 0 selects the seven bit address format and when set to 1 selects the ten bit addressing format for the device.

Slave Address Register Lower (SARLm): SARLm sets slave address m (7-bit address or lower eight bits of 10-bit address). Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

SVA[7:1] SVA0

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.44 The SARLm register. Source: Hardware Manual, page 1511.

SVA[7Ϻ1]: When the 7-bit address format is selected (SARUm.FS 0) these bits function as a 7-bit address. When the 10-bit address format is selected (SARUm.FS 1) these bits function as the lower eight bits of a 10-bit address in combination with the SVA0 bit. While the SARmE bit in ICSER is 0, the setting of these bits is ignored. SVA0: This bit forms the LSB of the 10-bit or 7-bit address assigned to the device. CHAPTER 7 / SERIAL COMMUNICATIONS 235

I2C Bus Bit Rate Low Level Register (ICBRL): ICBRL is a 5-bit (BRL[4Ϻ0]) register used to set the low- level period of the SCL clock. It also works to generate the data setup time for automatic SCL low- hold operation. ICBRL counts the low- level period with the internal reference clock source (IIC) specified by the CKS[2Ϻ0] bits in ICMR1. When the RIIC is used only in slave mode, this register needs to be set to a value longer than the data setup time. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

— — — BRL[4:0]

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.45 The ICBRL register. Source: Hardware Manual, page 1513.

I2C Bus Bit Rate High Level Register (ICBRH): ICBRH is a 5-bit (BRH[4Ϻ0]) register used to set the high- level period of SCL clock. ICBRH is valid in master mode. If the RIIC is used only in slave mode, this register need not be set. ICBRH counts the high- level pe- riod with the internal reference clock source (IIC) specified by the CKS[2Ϻ0] bits in ICMR1. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

— — — BRH[4:0]

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.46 The ICBRH register. Source: Hardware Manual, page 1514.

I2C Bus Transmit Data Register (ICDRT): ICDRT is an 8-bit readable/writable register that stores transmit data. When ICDRT detects a space in the I2C bus shift register (ICDRS), it transfers the transmit data that has been written to ICDRT to ICDRS and starts transmitting data in transmit mode. ICDRT can always be read and written. Write transmit data to ICDRT once when a transmit data empty interrupt (ICTXI) request is generated. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 1 1 1 1 1 1 1 1

Figure 7.47 The ICDRT. Source: Hardware Manual, page 1516. 236 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

I2C Bus Receive Data Register (ICDRR): ICDRR is an 8-bit read- only register that stores received data. When one byte of data has been received, the received data is trans- ferred from the I2C bus shift register (ICDRS) to ICDRR to enable the next data to be re- ceived. ICDRR cannot be written. Read data from ICDRR once when a receive data full in- terrupt (ICRXI) request is generated. Bits in this register are:

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 0 0 0 0 0 0 0 0

Figure 7.48 The ICDRR register. Source: Hardware Manual, page 1516.

I2C Bus Shift Register (ICDRS): ICDRS is an 8-bit shift register used to transmit and receive data as shown below. ICDRS cannot be accessed directly.

b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: — — — — — — — —

Figure 7.49 The ICDRS register. Source: Hardware Manual, page 1516.

7.3 BASIC EXAMPLES

In this section we shall put into implementation the theoretical concepts learned in Section 7.1 and Section 7.2, the process of setting up the interfaces, and understand the practical working of each of the communication interfaces. Interfaces studied so far in- clude the USART using the SCI, SPI using the RSPI, and the two wire serial interface us- ing the RIIC interface. Sections 7.3.1 to 7.3.3 demonstrate the procedures to setup com- munication using each of the aforementioned interfaces by means of simple examples.

7.3.1 Basic Transmission/Receiving of Serial Data via UART

Aim: Demonstration of only transmission and only reception using the UART interface of SCI. CHAPTER 7 / SERIAL COMMUNICATIONS 237

Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, RX62N Development kit, PC with RS- 232 communication port. Details: In this example, we will setup the RX62N processor to transmit a single byte of information and receive a single byte of information at 9600 baud, no parity, and 1 stop bit via polling. Procedure: The process of transmitting and receiving a data byte from the SCI ports can be divided into three parts: Initialization, Transmitting/Receiving the actual data, Get- ting ready to transmit the next byte/saving the received data into the desired location. As seen in Figure 7.50 the registers required to control the USART SCI are: Baud Rate Register (BRR), Serial Control Mode Register (SCMR), Serial Status Register (SSR), Se- rial Control Register (SCR), Serial Mode Register (SMR), and Serial Extended Mode Reg- ister (SEMR). Upon proper configuration of the values of each of these registers, the SCI can be set up in the desired USART mode with a given baud rate. The step of Initialization consists of setting up the initial values of these registers. In the next step, for transmission, Transmit Data Register (TDR) is filled with the de- sired value of the data and on the few next clock cycles the data is output on the corre- sponding SCI port. This concludes the process of transmitting data. In the case of receiving data, a flag is raised whenever a data byte is received in the Receive Data Register (RDR). This may cause an interrupt to occur. When the receive flag is raised, we need to copy the contents of the RDR into the desired location and conclude the process of reception. The following code snippets show the process for setting up the SCI 2 of RX62N for initialization, transmission, and reception:

1. void init_SCI2(void){ 2. MSTP(SCI2) = 0; 3. IOPORT.PFFSCI.BIT.SCI2S = 1; 4. PORT1.DDR.BIT.B2 = 0; 5. PORT1.ICR.BIT.B2 = 1; 6. PORT1.DDR.BIT.B3 = 1; 7. SCI2.SCR.BYTE = 0; 8. SCI2.SMR.BYTE = 0x00; 9. SCI2.SCR.BIT.RIE = 1; 10. SCI2.SCR.BIT.TIE = 1; 11. IR(SCI2, RXI2) = 0; 12. IR(SCI2, TXI2) = 0; 13. IEN(SCI2, RXI2) = 0; 14. IEN(SCI2, TXI2) = 0; 15. SCI2.BRR = 12; 16. SCI2.SCR.BYTE |= 0x30; 17. }

238 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

s bu data Internal

Bus interface PCLK PCLK/4 PCLK/16 PCLK/64 TEI TXI RXI ERI page 1339. BRR generator Ba u d rate Clock External clock Source: Hardware Manual, Source: SSR SCR SMR SEMR SCMR control s Transmission and reception Mod u le data bu BRR: Bit rate register statu s register SCR: rate SSR: Serial SCMR: Serial control register BRR: Bit Smart card mode register SEMR: mode register extended Serail TSR TDR Parity check Parity Parity error occ u rrenceParity Serial Communications Architecture. Serial Communications Architecture. RSR RDR Figure 7.50 Figure [Legend] RSR: RDR: TSR: shift register Receive TDR: data register Receive SMR: shift register Transmit data register Transmit Serial mode register RxDn TxDn SCKn CHAPTER 7 / SERIAL COMMUNICATIONS 239

Explanation of Initialization Code

Line 2: MSTP(SCI2) = 0; This line of code enables the SCI2 module on the Renesas Microcontroller. Line 3: IOPORT.PFFSCI.BIT.SCI2S = 1; This line enables the use of TxD2-B and RxD2-B. This line of code is applicable to ports that support differential mode of communication. Line 4: PORT1.DDR.BIT.B2 = 0; Here, the SCI 0 interface is setup such that the on- chip baud rate generation circuit is used and the SCK pin operates as a normal Digital I/O pin. The transmission end interrupt is disabled with normal reception, Serial transmission is enabled, reception is disabled, transmit interrupt and reception interrupt are disabled. Line 5: PORT1.ICR.BIT.B2 = 1; Here the input buffer to RxD2-B is enabled. Line 6: PORT1.DDR.BIT.B3 = 1; This line of code enables TxD2-B on port 1 pin 3 as output. Line 7: SCI2.SCR.BYTE = 0; This line of code disables the transmission and reception. Line 8: SCI2.SMR.BYTE = 0x00; This line of code sets the SCI in Asynchronous mode with 8 bits of data being transmitted with no parity, 1 stop bit, and no frequency division for PCLK. Line 9: SCI2.SCR.BIT.RIE = 1; This line of code enables the receive interrupts of the SCI2. These need to be enabled in order to generate flags which we will poll to acquire data. Line 10: SCI2.SCR.BIT.TIE = 1; This line of code enables the transmit interrupts of the SCI2. These need to be enabled in order to generate flags which we will poll to acquire data. Line 11: IR(SCI2, RXI2) = 0; Clear the interrupt request bits for the receive. Line 12: IR(SCI2, TXI2) = 0; Clear the interrupt request bits for the transmit. Line 13: IEN(SCI2, RXI2) = 0; Disable interrupt request for receive from RXI 2. Line 14: IEN(SCI2, TXI2) = 0; Disable interrupt request for receive from TXI 2. 240 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Line 15: SCI2.BRR = 12; Set the Baud rate register for communication to occur at 115200 baud. Line 16: SCI2.SCR.BYTE |= 0x30; Enable Transmission and reception. We are now ready to transmit and receive data.

The following code snippet shows the process for transmitting data from the SCI2 of RX62N:

1. int transmit_data(unsigned char data){ 2. while(IR(SCI2, TXI2) == 0) 3. ; 4. IR(SCI2, TXI2) = 0; 5. SCI2.TDR = data; 6. }

Explanation of Transmission Code

Line 2: while(IR(SCI2, TXI2) == 0); This line of code makes the microcontroller enter a wait state until the transmit buffer becomes empty and generates an interrupt request. Line 3: ; Line 4: IR(SCI2, TXI2) = 0; This line of code clears the interrupt request generated when the transmit buffer becomes empty. Line 5: SCI2.TDR = data; This line of code copies the one byte data passed as an argument to the function in to the transmit data register.

The following code snippet shows the process for receiving data from the SCI2 of RX62N:

1. unsigned char receive_data(void){ 2. unsigned char rcvd_data = 0; 3. while(IR(SCI2, RXI2) != 1) 4. ; 5. rcvd_data = SCI2.RDR; 6. IR(SCI2, RXI2) = 0; 7. return(rcvd_data); 8. } CHAPTER 7 / SERIAL COMMUNICATIONS 241

Explanation of Reception Code

Line 2: unsigned char rcvd_data = 0; Here we initialize an unsigned character variable “rcvd_data” to hold the data received from the SCI2 RxD2-B pin. Line 3: while(IR(SCI2, RXI2) != 1) This line of code makes the microcontroller enter a wait state until an interrupt request is generated after data is successfully received in the RDR. Line 4: ; Line 5: rcvd_data = SCI2.RDR; Here we copy the contents of the data received in the receive data register RDR into the variable rcvd_data. Line 6: IR(SCI2, RXI2) = 0; We now clear the interrupt request flag generated due to reception of data, and make the SCI2 interface ready to receive data again. Line 7: return(rcvd_data); Here we return the received data back to the main program/function.

Putting it together:

1. void main(void){ 2. init_sci2(); 3. transmit_data(‘A’); 4. unsigned char data = 0; 5. data = receive_data(); 6. printf(“\ndata = %c”,data); 7. return 0; 8. }

Explanation of Main Program

Line 2: init_sci2; We call and execute the initialization function so that the SCI 2 gets set up as a UART functioning at 115200 baud, no parity, 1 stop bit, and clocking with no frequency division of PCLK. Line 3: transmit_data(‘A’); We call and execute the transmit_data function to transmit a character “A” over the transmission line. Line 4: unsigned char data = 0; Here a unsigned character variable “data” is declared and initialized to 0. 242 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Line 5: data = receive_data(); Here we call the function receive_data to receive data from the SCI2. The function returns a character when data is received from SCI2 and is stored in the variable “data.” Line 6: printf(“\ndata = %c”,data); Here we print the value of the variable data as a character over the standard output of the microcontroller. Line 7: return 0; This line of code terminates the program and the microcontroller comes to a halt.

7.3.2 Basic Transmission of Data Using Serial Peripheral Interface Bus

Aim: Demonstration of transmitting data with the serial peripheral interface bus. Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, RX62N Development kit, Digital Oscilloscope, Oscilloscope probes. Details: In this example, we will set up the RX62N processor to transmit a single byte of information using the clock synchronous serial peripheral interface bus. Procedure: The process of transmitting and receiving a data byte from the RSPI ports can be divided in to three parts; namely: initialization, selection of a slave device, and transmitting/receiving the actual data. As seen in Figure 7.51 the registers required to control the RSPI are: SPCR, SPCR2, SSLP, SPPCR, SPSR, SPDR, SPSSR, SPDCR, SSLND, SPCKD, SPND, SPCMD, and SPBR. Upon proper configuration of the values of each of these registers, the RSPI can be set up in the desired clock synchronous mode with a given bit rate. The step of Initializa- tion consists of setting up the initial values of these registers. In the next step for slave selection, a chip select/active low signal is output from one of the SSL pins, or any other digital I/O pins, bringing the device out of the sleep state. Next, the SPDR and SPCMDn registers are loaded with the proper values and the data is transmitted as soon as the RSPI becomes idle. In order to view the transmission of data, it is recommended to connect an oscilloscope probe to the SCK, MOSI, MISO, and SSL- 0 pins. If configuration of the RSPI is done as shown in initialization code, an output similar to that of Figure 7.52 would be observed on the oscilloscope. For our configuration D1 was connected to serial clock, D2 connected to Master Out Slave In, D3 connected to Master In Slave Out and D4 was connected Slave Select/Chip Select pins. CHAPTER 7 / SERIAL COMMUNICATIONS 243

Module data bus Peripheral bus B u s interface

SPRX SPTX SPCR SPBR SSLP Baud rate SPPCR generator PCLK SPSR SPDR Parity circuit SPSCR SPSSR SPDCR SPCKD SSLND Shift register SPND SPCR2 SPCMD

Selector Transmission/ Normal reception controller

Clock Loopback

MOSI Normal Master Loopback 2

Loopback Slave Loopback 2 Normal Master SPTI Loopback Slave SPRI Loopback 2 SPII

SSLn0 SPEI SSLn1 to SSLn3 RSPCKn (n A, B)

[Legend] SPCR: RSPI control register SSLND: RSPI slave select negate delay register SPCR2: RSPI control register 2 SPND: RSPI next-access delay register SSLP: RSPI slave select polarity register SPCMD: RSPI command registers 0 to 7 (eight registers) SPPCR: RSPI pin control register SPBR: RSPI bit rate register SPSR: RSPI status register SPTX: RSPI transmit buffer SPDR: RSPI data register SPRX: RSPI receive buffer SPSCR: RSPI sequence control register SPTI: RSPI transmit interrupt SPSSR: RSPI sequence status register SPRI: RSPI receive interrupt SPDCR: RSPI data control register SPII: SPI idle interrupt SPCKD: RSPI clock delay register SPEI: RSPI error interrupt

Figure 7.51 Block Diagram of the Renesas Serial Peripheral Interface. Source: Hardware Manual, page 1631. 244 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The following are the codes for initialization, transmission, and the main program.

1. void Init_RSPI(void){ 2. MSTP(RSPI0) = 0; 3. IOPORT.PFGSPI.BIT.RSPIS = 0; 4. PORT.PFGSPI.BIT.RSPCKE = 1; 5. IOPORT.PFGSPI.BIT.SSL3E = 0; 6. IOPORT.PFGSPI.BIT.MOSIE = 1; 7. PORTC.DDR.BIT.B4 = 1; 8. PORTC.DR.BIT.B4 = 1; 9. PORTC.DDR.BIT.B7 = 1; 10. PORTC.DR.BIT.B7 = 1; 11. PORTC.DDR.BIT.B6 = 1; 12. PORTC.DR.BIT.B6 = 1; 13. PORTC.DDR.BIT.B5 = 1; 14. PORTC.DR.BIT.B5 = 1; 15. RSPI0.SPPCR.BYTE = 0x00; 16. RSPI0.SPBR.BYTE = 0x00; 17. RSPI0.SPDCR.BYTE = 0x00; 18. RSPI0.SPCKD.BYTE = 0x00; 19. RSPI0.SSLND.BYTE = 0x00; 20. RSPI0.SPND.BYTE = 0x00; 21. RSPI0.SPCR2.BYTE = 0x00; 22. RSPI0.SPCMD0.WORD = 0x0700; 23. RSPI0.SPCR.BYTE = 0x6B; 24. RSPI0.SSLP.BYTE = 0x08; 25. RSPI0.SPSCR.BYTE = 0x00; 26. }

Explanation of Initialization Code

Line 2: MSTP(RSPI0) = 0; This line of code enables the RSPI0(RSPI- A) module on the Renesas Microcontroller, since the SPI2 is the interface connected to the RS- 232 convertor on board the development kit. Line 3: IOPORT.PFGSPI.BIT.RSPIS = 0; This line of code Selects the proper bank of pins for SPI0. CHAPTER 7 / SERIAL COMMUNICATIONS 245

Line 4: IOPORT.PFGSPI.BIT.RSPCKE = 1; SCK (PC.5) is active and acts as a serial clock output. Line 5: IOPORT.PFGSPI.BIT.SSL3E = 0; SSL3 (PC.2) is inactive (toggled as GPIO instead). Line 6: IOPORT.PFGSPI.BIT.MOSIE = 1; MOSI (PC.6) is active. Line 7: PORTC.DDR.BIT.B4 = 1; Select Port C bit 4 as Chip select pin, set up chip select pin, make it an output. Line 8: PORTC.DR.BIT.B4 = 1; Set level to high so as to not perform a chip select. Line 9: PORTC.DDR.BIT.B7 = 0; Set MISO as an input. Line 10: PORTC.DR.BIT.B7 = 1; Enable input buffer for peripheral. Line 11: PORTC.DDR.BIT.B6 = 1; Set MOSI as an output. Line 12: PORTC.DR.BIT.B6 = 1; Enable input buffer for peripheral. Line 13: PORTC.DDR.BIT.B5 = 1; Set SCK as an output. Line 14: PORTC.DR.BIT.B5 = 1; Set level to inactive. Line 15: RSPI0.SPPCR.BYTE = 0x00; Initialize SPI (per flowchart in hardware manual), no loopback, CMOS Output. Line 16: RSPI0.SPBR.BYTE = 0x00; Run the RSPI at Full Speed with PCLK frequency of 48 MHz. Line 17: RSPI0.SPDCR.BYTE = 0x00; 16-bit data 1 frame 1 chip select. Line 18: RSPI0.SPCKD.BYTE = 0x00; This line of code sets up the RSPI to have two clock delays before next access to SPI device. Line 19: RSPI0.SSLND.BYTE = 0x00; This line of code sets up the RSPI to have two clock delays after de- asserting SSL. 246 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Line 20: RSPI0.SPND.BYTE = 0x00; This line of code sets up the RSPI to have two clock delays before next access to SPI device. Line 21: RSPI0.SPCR2.BYTE = 0x00; Initialize the RSPI with no parity, no idle interrupts. Line 22: RSPI0.SPCMD0.WORD = 0x0700; MSB first 8-bit data, keep SSL low. Line 23: RSPI0.SPCR.BYTE = 0x6B; Enable RSPI 3-wire in master mode with RSPI Enable Transmit only and Interrupts. Line 24: RSPI0.SSLP.BYTE = 0x08; SSL3A Polarity is active high. Line 25: RSPI0.SPSCR.BYTE = 0x00; Transmit One frame of data.

Transmission Code 1. void RSPI_Transmit_LWord(int16_t sLowWord, int16_t sHighWord){ 2. PORTC.DR.BIT.B4 = 0; 3. while(RSPI0.SPSR.BIT.IDLNF) 4. ; 5. RSPI0.SPDR.WORD.L = sLowWord; 6. RSPI0.SPDR.WORD.H = sHighWord; 7. while(RSPI0.SPSR.BIT.IDLNF) 8. ; 9. (void)RSPI0.SPDR.WORD.L; 10. (void)RSPI0.SPDR.WORD.H; 11. PORTC.DR.BIT.B4 = 1; //CS OFF 12. }

Explanation of Transmission Code Line 2: PORTC.DR.BIT.B4 = 0; Here we set the bit to be pulled low so as to perform a chip select manually to begin transmission. Line 3: while(RSPI0.SPSR.BIT.IDLNF) Wait for the RSPI to become idle. Program proceeds as soon as the IDLNF flag becomes 0. CHAPTER 7 / SERIAL COMMUNICATIONS 247

Line 4: ; Line 5: RSPI0.SPDR.WORD.L = sLowWord; Set the lower word of the SPDR to the value passed through the argument. Line 6: RSPI0.SPDR.WORD.H = sHighWord; Set the higher word of the SPDR to the value passed through the argument. Line 7: while(RSPI0.SPSR.BIT.IDLNF); Wait for the RSPI to finish transmission. Line 8: ; Line 9: (void)RSPI0.SPDR.WORD.L; Read the lower word of the SPDR; Line 10: (void)RSPI0.SPDR.WORD.H; and read the higher word of the SPDR to clear interrupt flag. Line 11: PORTC.DR.BIT.B4 = 1 ; Set the Chip select pin to high to terminate transmission.

Main Code 1. void main(void) { 2. Init_RSPI(); 3. while(1) 4. RSPI_Send_LWord(0x0000, 0x0055); 5. }

Explanation of Main Code

Line 2: Init_RSPI(); We initialize the Renesas SPI by calling the Init_RSPI function. Line 3: while(1) Perform the next step forever. Line 4: RSPI_Send_LWord(0x0000, 0x0055); Transmit 0x00000055. 248 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Agilent Technologies THU AUG 05 03:41:02 2010

n n 1 2 184.0 s 200.0 s / StopD10 TTL

D4

D3

D2

D1

Cursors Menu Mode X1 X2 X1 X2 -12.00ns 30.00ns

Figure 7.52 Oscilloscope capture of a functional RSPI.

7.3.3 Basic Transmission and Reception of Data Using the Renesas I2C Bus

Aim: To demonstrate the setting up of the RIIC module to transmit and receive data from a peripheral. Details: In this example we will set up the RIIC peripheral module to transmit and re- ceive 1 byte of data from an on board peripheral device. Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, RX62N Development kit, Digital Oscilloscope, Oscilloscope probes. Procedure: The YRDKRX62N development kit has an on board accelerometer ADXL345. This is a three axis accelerometer capable of measuring accelerations in the X, Y, and Z axis directions. The ADXL345 can communicate the measured values through the SPI and I2C buses. Depending on the mode of communication selected using the CS pin, one can use either of the two communication methods to obtain details and data from the ADXL345. The ADXL345 is composed of several registers that it constantly updates when not in the SLEEP or STAND BY mode. One particular register of interest is the 0x00 regis- ter that contains the value 0xE5 that symbolically represents “345.” Therefore when the 0x00 address location is read using the I2C mechanism, the value 0xe5 is acquired/read. The address that we are going to write to is the pointer address for the ADXL 345 which is the default register location select for the first byte of data transferred to the device after trans- mitting the device address 0x3A. The procedure for writing data to a peripheral device is: CHAPTER 7 / SERIAL COMMUNICATIONS 249

1. Generate START condition. 2. Transmit address of device to communicate with and wait for the acknowledge bit to arrive. 3. Transmit the data to be communicated with the device and wait for the acknowl- edge bit to arrive for each byte transmitted. 4. If all bytes to be communicated have been transmitted, generate a STOP condition.

The procedure to read data from a peripheral device is in two parts that consist of writing to the register pointer and then reading the desired bytes from the peripherals. In the first half of the read cycle, the RX62N:

1. Generate a START condition. 2. Transmit address of device to communicate with and wait for acknowledge bit to arrive. 3. Transmit the value of the register pointer and wait for an acknowledge. 4. Generate a STOP condition.

Next comes the read cycle which begins with:

1. Generating a START condition. Transmitting the address of the device to communicate with ؉1 (note that this .2 address is always odd) and wait for an acknowledge. 3. Generate clock cycles or generate pseudo transactions of 0xFF to which the slave device or peripheral clocks out the desired data. To each byte successfully received the RIIC has to output an ACK bit which is a 0 on the ninth bit. If the Master re- ceiver RX62N wishes to terminate a transaction, it needs to generate a NACK, which is a 1 on the ninth bit of the last desired byte. 4. Generate a STOP condition.

To be able to do all of these activities, the microcontroller needs to be configured/initial- ized properly. The following code shows the procedure for initialization of the RIIC chan- nel 0 aboard the RX62N. If RIIC channel 1 is available, then similar steps should be followed:

1. void RiicIni(unsigned char in_SelfAddr){ 2. SYSTEM.MSTPCRB.BIT.MSTPB21 = 0; 3. RIIC0.ICCR1.BIT.ICE = 0; 4. RIIC0.ICCR1.BIT.IICRST = 1; 5. RIIC0.ICCR1.BIT.IICRST = 0; 6. RIIC0.SARU0.BIT.FS = 0; 7. RIIC0.SARL0.BYTE = in_SelfAddr; 250 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

8. RIIC0.ICMR1.BIT.CKS = 7; 9. RIIC0.ICBRH.BIT.BRH = 28; 10. RIIC0.ICBRL.BIT.BRL = 29; 11. RIIC0.ICMR3.BIT.ACKWP = 1; 12. RIIC0.ICIER.BIT.RIE = 1; 13. RIIC0.ICIER.BIT.TIE = 1; 14. RIIC0.ICIER.BIT.TEIE = 0; 15. RIIC0.ICIER.BIT.NAKIE = 1; 16. RIIC0.ICIER.BIT.SPIE = 1; 17. RIIC0.ICIER.BIT.STIE = 0; 18. RIIC0.ICIER.BIT.ALIE = 0; 19. RIIC0.ICIER.BIT.TMOIE = 0; 20. PORT1.ICR.BIT.B3 = 1; 21. PORT1.ICR.BIT.B2 = 1; 22. RIIC0.ICCR1.BIT.ICE = 1; 23. }

The following is the explanation of the above code line by line:

Line 1: void RiicIni(unsigned char in_SelfAddr) Declaring the function and the arguments. Line 2: SYSTEM.MSTPCRB.BIT.MSTPB21 = 0; Enable the RIIC channel zero. Line 3: RIIC0.ICCR1.BIT.ICE = 0; Disable the RIIC channel 0 manually just to make sure. Line 4: RIIC0.ICCR1.BIT.IICRST = 1; Reset the RIIC0 module. Line 5: RIIC0.ICCR1.BIT.IICRST = 0; Release the reset. Line 6: RIIC0.SARU0.BIT.FS = 0; Set the device address as a 7 bit address. Line 7: RIIC0.SARL0.BYTE = in_SelfAddr; Set the device address from the argument of the function. Line 8: RIIC0.ICMR1.BIT.CKS = 7; Select clock input to the RIIC0 module as PCLK/128. Line 9: RIIC0.ICBRH.BIT.BRH = 28; Set the bit counter for the high level of the serial clock cycle. Line 10: RIIC0.ICBRL.BIT.BRL = 29; Set the bit counter for the low level of the serial clock cycle. CHAPTER 7 / SERIAL COMMUNICATIONS 251

Line 11: RIIC0.ICMR3.BIT.ACKWP = 1; Disable write protect for the ACK bit. Line 12: RIIC0.ICIER.BIT.RIE = 1; Enable the Receive data full interrupt. Line 13: RIIC0.ICIER.BIT.TIE = 1; Enable the Transmit data full interrupt. Line 14: RIIC0.ICIER.BIT.TEIE = 0; Enable the Transmit End interrupt. Line 15: RIIC0.ICIER.BIT.NAKIE = 1; Enable the NACK received interrupt. Line 16: RIIC0.ICIER.BIT.SPIE = 1; Enable the Stop condition received interrupt. Line 17: RIIC0.ICIER.BIT.STIE = 0; Disable the Start condition received interrupt. Line 18: RIIC0.ICIER.BIT.ALIE = 0; Disable the Arbitration lost interrupt. Line 19: RIIC0.ICIER.BIT.TMOIE = 0; Timeout interrupt request is disabled. Line 20: PORT1.ICR.BIT.B3 = 1; Enable input buffer on PORT1 pin 3. Line 21: PORT1.ICR.BIT.B2 = 1; Enable input buffer on PORT1 pin 2. Line 22: RIIC0.ICCR1.BIT.ICE = 1; Enable the RIIC0 module. Line 23: } End of function definition.

The process to uninitialized the RIIC0 is

1. void RiicUnIni(void){ 2. SYSTEM.MSTPCRB.BIT.MSTPB21 = 1; 3. }

The following is the explanation of the above code line by line:

Line 1: void RiicUnIni(void){ Declare the function name to uninitialization 252 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Line 2: SYSTEM.MSTPCRB.BIT.MSTPB21 = 1; Disable the RIIC0 module Line 3: } End function definition

The following snippet of code demonstrates how data transfer takes place, using polling: There are three essential parts to data transfer when using the I2C protocol:

1. Generating the START condition. 2. Performing the transfer. 3. Sending the STOP condition.

The following is the code for generating the START condition:

1. unsigned char RiicSendStart(void){ 2. if(RIIC0.ICCR1.BIT.ICE){ 3. while(RIIC0.ICCR2.BIT.BBSY) 4. ; 5. RIIC0.ICCR2.BIT.ST = 1; 6. while(!(RIIC0.ICCR2.BIT.BBSY && RIIC0.ICSR2.BIT.START)) 7. ; 8. RIIC0.ICSR2.BIT.START = 0; 9. return 1; 10. } 11. else return 0; 12. }

The following is the explanation for the above code:

Line 1: unsigned char RiicSendStart(void){ Declare the function name and arguments. Line 2: if(RIIC0.ICCR1.BIT.ICE){ Check if the RIIC0 module is enabled. Line 3: while(RIIC0.ICCR2.BIT.BBSY) Wait here until the bus becomes free. Line 4: ; Line 5: RIIC0.ICCR2.BIT.ST = 1; When bus becomes free, request for transmitting a START condition. Line 6: while(!(RIIC0.ICCR2.BIT.BBSY && RIIC0.ICSR2.BIT.START)) Wait here until START condition is detected by the RIIC0 module. CHAPTER 7 / SERIAL COMMUNICATIONS 253

Line 7: ; Line 8: RIIC0.ICSR2.BIT.START = 0; After detecting the module, disable the interrupt bit in the status register. Line 9: return 1; Report success. Line 10: } Line 11: else return 0; Report failure if RIIC0 module is not enabled. Line 12: }

The following is the code for generating the STOP condition:

1. unsigned char RiicSendStop(void){ 2. if(RIIC0.ICCR1.BIT.ICE){ 3. while(RIIC0.ICCR2.BIT.BBSY){ 4. RIIC0.ICCR2.BIT.SP = 1; 5. } 6. return 1; 7. } 8. else return 0; 9. }

The following is the explanation for the code given above:

Line 1: unsigned char RiicSendStop(void){ Declare the function name and arguments. Line 2: if(RIIC0.ICCR1.BIT.ICE){ If the RIIC0 module is enabled perform the following steps. Line 3: while(RIIC0.ICCR2.BIT.BBSY){ Line 4: RIIC0.ICCR2.BIT.SP = 1; While the bus is busy, request to generate a stop condition. Line 5: } Line 6: return 1; Report Success. Line 7: } Line 8: else return 0; If the RIIC0 module is disabled report failure. Line 9: } 254 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The following is the code for writing a data byte to a peripheral device on the I2C bus:

1. unsigned char RiicWriteByte(unsigned char slave_addr, unsigned char slave_register_num, unsigned char data_byte){ 2. RIIC0.ICDRT = slave_addr & (0xFE); 3. while(!RIIC0.ICSR2.BIT.TDRE) 4. ; 5. RIIC0.ICDRT = slave_register_num; 6. while(!RIIC0.ICSR2.BIT.TEND){ 7. if(RIIC0.ICSR2.BIT.NACKF){ 8. RIIC0.ICSR2.BIT.NACKF = 0; 9. return 0; 10. } 11. } 12. while(!RIIC0.ICSR2.BIT.TDRE) 13. ; 14. RIIC0.ICDRT = data_byte; 15. while(!RIIC0.ICSR2.BIT.TEND){ 16. if(RIIC0.ICSR2.BIT.NACKF){ 17. RIIC0.ICSR2.BIT.NACKF = 0; 18. return 0; 19. } 20. } 21. while(!RIIC0.ICSR2.BIT.TDRE) 22. ; 23. while(!RIIC0.ICSR2.BIT.TEND){ 24. if(RIIC0.ICSR2.BIT.NACKF){ 25. RIIC0.ICSR2.BIT.NACKF = 0; 26. return 0; 27. } 28. } 29. return 1; 30. }

The following is the explanation for the above codes:

Line 1: unsigned char RiicWriteByte2(unsigned char slave_addr, unsigned char slave_register_num, unsigned char data_byte){ Declare and define the function and its arguments. CHAPTER 7 / SERIAL COMMUNICATIONS 255

Line 2: RIIC0.ICDRT = slave_addr & (0xFE); Fill the transmit buffer with the slave address input as an argument to the function. Line 3: while(!RIIC0.ICSR2.BIT.TDRE) Wait until the Transmit data empty flag becomes high. Line 4: ; Line 5: RIIC0.ICDRT = slave_register_num; Fill the transmit data buffer with the slave register number to be written to. Line 6: while(!RIIC0.ICSR2.BIT.TEND){ Since the RIIC has a double buffer for transmission and reception, we need to wait until the previous transmission is finished. Line 7: if(RIIC0.ICSR2.BIT.NACKF){ Check if a NACK is received in response to the transmit operation. Line 8: RIIC0.ICSR2.BIT.NACKF = 0; If a NACK is received, then Reset the NACKF flag. Line 9: return 0; And report failure. Line 10: } Line 11: } Line 12: while(!RIIC0.ICSR2.BIT.TDRE) Wait here until the transmit data register becomes empty again. Line 13: ; Line 14: RIIC0.ICDRT = data_byte; Fill the transmit data register with the actual data byte that needs to be transmitted. Line 15: while(!RIIC0.ICSR2.BIT.TEND){ Since the RIIC has a double buffer for transmission and reception, we need to wait until the previous transmission is finished. Line 16: if(RIIC0.ICSR2.BIT.NACKF){ Check if a NACK is received in response to the transmit operation. Line 17: RIIC0.ICSR2.BIT.NACKF = 0; If a NACK is received, then Reset the NACKF flag. Line 18: return 0; And report failure. Line 19: } Line 20: } 256 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Line 21: while(!RIIC0.ICSR2.BIT.TDRE) Wait here until the transmit data register becomes empty again. Line 22: ; Line 23: while(!RIIC0.ICSR2.BIT.TEND){ Since the RIIC has a double buffer for transmission and reception, we need to wait until the previous transmission is finished. Line 24: if(RIIC0.ICSR2.BIT.NACKF){ Check if a NACK is received in response to the transmit operation. Line 25: RIIC0.ICSR2.BIT.NACKF = 0; If a NACK is received, then Reset the NACKF flag. Line 26: return 0; And report failure. Line 27: } Line 28: } Line 29: return 1; If all goes well, report success. Line 30: }

The following is a piece of code similar to the above code, however it writes only the slave address and the register number to the I2C peripheral device. This is useful when reading data from the peripheral device in which one needs to write to the slave device the register from which the data is to be transferred and then data is read consecutively from the registers.

1. unsigned char RiicWriteByte(unsigned char slave_addr, unsigned char data_byte){ 2. RIIC0.ICDRT = slave_addr & (0xFE); 3. while(!RIIC0.ICSR2.BIT.TDRE) 4. ; 5. RIIC0.ICDRT = data_byte; 6. while(!RIIC0.ICSR2.BIT.TEND){ 7. if(RIIC0.ICSR2.BIT.NACKF){ 8. RIIC0.ICSR2.BIT.NACKF = 0; 9. return 0; 10. } 11. } 12. while(!RIIC0.ICSR2.BIT.TDRE) 13. ; CHAPTER 7 / SERIAL COMMUNICATIONS 257

14. while(!RIIC0.ICSR2.BIT.TEND){ 15. if(RIIC0.ICSR2.BIT.NACKF){ 16. RIIC0.ICSR2.BIT.NACKF = 0; 17. return 0; 18. } 19. } 20. return 1; 21. }

The following is the code for reading a data byte from a peripheral device on the I2C bus:

1. unsigned char RiicReadByte(unsigned char slave_addr, unsigned char slave_register_num){ 2. RiicWriteByte(slave_addr,slave_register_num); 3. RiicSendStop(); 4. RIIC0.ICSR2.BIT.STOP = 0; 5. RiicSendStart(); 6. while(!RIIC0.ICSR2.BIT.TDRE) 7. ; 8. RIIC0.ICDRT = slave_addr | (0x01); 9. while(!RIIC0.ICSR2.BIT.RDRF) 10. ; 11. if(RIIC0.ICSR2.BIT.NACKF == 0){ 12. RIIC0.ICMR3.BIT.WAIT = 1; 13. RIIC0.ICMR3.BIT.ACKBT = 1; 14. read_byte = RIIC0.ICDRR; 15. while(!RIIC0.ICSR2.BIT.RDRF) 16. ; 17. RIIC0.ICSR2.BIT.STOP = 0; 18. RIIC0.ICCR2.BIT.SP = 1; 19. read_byte = RIIC0.ICDRR; 20. while(!RIIC0.ICSR2.BIT.STOP) 21. ; 22. return read_byte; 23. } 24. else return 0xFF; 25. } 258 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The following explains the above given code :

Line 1: unsigned char RiicReadByte(unsigned char slave_addr, unsigned char slave_register_num){ Line 2: RiicWriteByte(slave_addr,slave_register_num); Write the data register from which the data is to be read. Line 3: RiicSendStop(); Send a STOP condition. Line 4: RIIC0.ICSR2.BIT.STOP = 0; Reset the STOP condition flag. Line 5: RiicSendStart(); Send a START condition over the I2C Bus. Line 6: while(!RIIC0.ICSR2.BIT.TDRE) Wait here until transmit buffer gets empty. Line 7: ; Line 8: RIIC0.ICDRT = slave_addr | (0x01); Request a read from the peripheral device by transmitting the read address as Slave device (write) address 1. Line 9: while(!RIIC0.ICSR2.BIT.RDRF) Wait until the read buffer becomes full. Line 10: ; Line 11: if(RIIC0.ICSR2.BIT.NACKF == 0){ If a ACK is received; i.e., the device is ready, do the following actions. Line 12: RIIC0.ICMR3.BIT.WAIT = 1; Set the WAIT bit to 1, due to which the period between ninth clock cycle and first clock cycle is held low. Line 13: RIIC0.ICMR3.BIT.ACKBT = 1; Set the ACK bit transmitted as 1, which corresponds to a NACK for the peripheral device. Line 14: read_byte = RIIC0.ICDRR; Read dummy data from the I2C receive data register. Line 15: while(!RIIC0.ICSR2.BIT.RDRF); Wait here until the ICDRR becomes full again when the shift register transfers data from itself to the ICDRR. This is due to double buffering of data. Line 16: ; CHAPTER 7 / SERIAL COMMUNICATIONS 259

Line 17: RIIC0.ICSR2.BIT.STOP = 0; Reset the status of the STOP bit in the ICSR2. Line 18: RIIC0.ICCR2.BIT.SP = 1; Request for generation of STOP signal. Line 19: read_byte = RIIC0.ICDRR; Read data from the ICDRR. Line 20: while(!RIIC0.ICSR2.BIT.STOP) Wait here until the STOP condition is generated. Line 21: ; Line 22: return read_byte; Return the Data received as the return value of the function. Line 23: } Line 24: else return 0xFF; If a NACK was received return 0xFF (or any desired value) as a Failure value. Line 25: }

The following code shows the entire process of reading one byte from a peripheral con- nected on the I2C bus:

1. void main(void){ 2. RiicIni(0x10); 3. RiicSendStart(); 4. RiicWriteByte2(0x3A, 0x2D, 0x00); 5. RiicSendStop(); 6. RiicSendStart(); 7. i = RiicReadByte(0x3A, 0x00); 8. RiicSendStop(); 9. RiicUnIni(); 10. while(1) 11. ; 12. }

The following is the explanation of the above code:

Line 1: void main(void){ Define the main function. 260 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Line 2: RiicIni(0x10); Initialize the I2C module RIIC0 with self address as 0x10. Line 3: RiicSendStart(); Send a START condition. Line 4: RiicWriteByte2(0x3A, 0x2D, 0x00); Write a byte 0x00 to the register 0x2D of the peripheral device with address 0x3A. Line 5: RiicSendStop(); Send a STOP condition. Line 6: RiicSendStart(); Send a START condition again. Line 7: i = RiicReadByte(0x3A, 0x00); Read a byte from the register 0x00 of the peripheral with address 0x3A. Line 8: RiicSendStop(); Send a STOP condition. Line 9: RiicUnIni(); Disable the RIIC0 interface. Line 10: while(1) Wait here forever. Line 11: ; Line 12: }

Agilent Technologies FRI OCT 08 05:48:01 2010

m m 1 1.00V/ 2 11.40 s 5.000 s / Stop D8 TTL

D8 D8

D9 D9

1 1

_ _ Digital Channel Menu D15 ______D0 1.56MSa/s D9 Turn on Turn on Thresholds Bus D15 - D8 D7 - D0 Figure 7.53 Oscilloscope Capture of the complete I2C communication for Basic Example 7.3.3. CHAPTER 7 / SERIAL COMMUNICATIONS 261

Agilent Technologies FRI OCT 08 05:46:54 2010

m m 1 1.00V/ 2 5.260 s 2 .000 s / Stop D8 TTL

D8 D8

D9 D9

1 1

_ _ Digital Channel Menu D15 ______D0 1.56MSa/s D9 Turn on Turn on Thresholds Bus D15 - D8 D7 - D0

Figure 7.54 Oscilloscope Capture of the beginning of I2C communication for Basic Example 01 (scaled along x-axis). There are three data bytes transferred for the write cycle (first twenty- seven clock pulses).

Agilent Technologies FRI OCT 08 05:47:23 2010

m m 1 1.00V/ 2 16.22 s 2 .000 s / Stop D8 TTL

D8 D8

D9 D9

1 1

_ _ Digital Channel Menu D15 ______D0 1.56MSa/s D9 Turn on Turn on Thresholds Bus D15 - D8 D7 - D0

Figure 7.55 Oscilloscope Capture of the end of I2C communication for Basic Example 7.3.3 (scaled along the x- axis). There are two cycles here, each consisting of two data bytes. First is the 2 byte write cycle and the other is the 2 byte read cycle. 262 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

7.4 ADVANCED CONCEPTS

Now that we have learned the details of the working behind various communication tech- niques with polling; i.e., the UART, SPI, and I2C interfaces, in this section we will study some of the advanced features and implementations of the same. Concepts learned in these chapters will be implemented in Section 7.5 by means of examples. Concepts learned in this section will require basic knowledge of interrupts and interrupt ser vice routines, and additional hard- ware to be present. It is advisable for the reader to be aware of the additional peripherals being used while illustrating the advanced features of the communication techniques in this section.

7.4.1 Applying FIFO Data Structures for Transmission and Reception Using the UART Serial Communications Interface

As mentioned in Section 7.2.1 the UART in essence contains a single byte buffer each for transmitting and receiving data from other peripherals connected via the UART interface. These buffers are occasionally filled with data and then the data is transmitted or received. But what if an application is required to transmit data continuously? Usually the peripher- als of a Microcontroller operate slower than the actual processing unit. In short, the data output by the processing unit to be transmitted is more quickly generated than transmitted. In such a case, there are two options available: wait for the peripheral to finish transmitting the current data and then load the peripheral with new data, or maintain a First In First Out type of mechanism in which bulk data is stored in a given data structure and then transmit- ted as and when the peripheral becomes available. The advantage of the latter technique is that the processing unit is free to perform other tasks as data transmission is going on. Be- fore we move on to understanding the design of a UART FIFO, let us take a quick look at a FIFO data structure. A FIFO type data structure can be visualized as a queue of units standing in line for ser vice. The unit that gets in line first gets ser vice earlier than the unit that enters the queue at a later point of time. This is quite contrary to a LIFO type of data structure in which the last unit to enter the queue gets service prior to the one which entered the queue earlier. FIFOs are generally used wherever operations are to be done on all data in a sequential/ consecutive manner. An example of a FIFO is shown in Figure 7.56.

older newer Figure 7.56 Example of a data data FIFO (queue).

head tail CHAPTER 7 / SERIAL COMMUNICATIONS 263

As seen in Figure 7.56 the FIFO consists of a head and a tail where the head contains data that was added to the queue earlier, whereas the tail end contains relatively new data. The size of the queue is also maintained by monitoring variables. Essentials for regulating queues for the UART SCI are as follows:

Need to maintain one queue for transmission and one queue for reception. The transmit ISR unloads data from the transmission queue. The receive ISR loads data to the reception queue. Pointers are used to maintain the head and tail of the queue. A variable “size” keeps track of the current size of the queue. Pointers are wrapped around the queue when queue is not empty but the queue reaches the end of the allotted area. The main program is responsible for loading the transmit queue and unloading the receive queue.

Queues are implemented with interrupt ser vice routines and not polling, since polling re- quires the microcontroller to wait and do nothing until current operation is performed. In- terrupt Service Routines, on the other hand, are performed intermittently when required and do not disturb the working of the main program. As we shall see in the Advanced Example 7.5.1, the queues will be loaded at a single occasion and then the main program proceeds without waiting for the transmission to complete. The ISRs continue to occur in- termittently and finish the transfer of data. The following is the algorithm followed for the complex example in Section 7.5.1.

Initialize the UART. Set up switches and define the size of the queue. Define a FIFO queue structure consisting of a data array, a pointer to the head of the array, a pointer to the tail of the array, and a variable for holding the current size of the queue. Allot memory for two queues, one for transmission and other for reception. Define function for checking if a queue is empty and another function to check if a queue is full. Initialize the queues by setting the data in the queue, head and tail to zero. Define a function for queuing data in a given queue. In order for the data to be queued, perform a check if the queue is full. If queue is not full, then queue data by adding to the tail of the array, update the tail and size values, and report success. Otherwise abort queuing and report failure. Define a function for dequeuing data. In order to dequeue data, check if the queue is empty. If the queue is not empty, copy a byte of data from the head of the queue, update the head and size of the queue, and return the copied variable. If the queue is empty, exit the function. 264 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Define the interrupt ser vice routines that do the following: ▫ Transmit routines: Check if the queue is empty. If the queue is not empty, de- queue a byte of data from the transmission queue and give it to the transmit buffer of the microcontroller. ▫ Receive routine: Try to enqueue the data to the receive queue. If the queue is full, provide with an indication.

Setting up the interrupts: The following is the procedure for setting up the serial communi- cation interface interrupts:

In the vect.h file define the vector table locations of the interrupts and declare them as follows: ▫ #pragma interrupt (Excep_SCI2_RXI2(vect 223)) void Excep_SCI2_RXI2 (void); ▫ #pragma interrupt (Excep_SCI2_TXI2(vect 224)) void Excep_SCI2_TXI2 (void); In the file intprg.c write the detailed interrupt ser vice routines for transmit and re- ceive under the function names void Excep_SCI2_RXI2 (void) and void Excep_ SCI2_TXI2 (void).

7.4.2 Multiprocessor Communication Using the Renesas Serial Peripheral Interface

One of the advantages of the serial peripheral interface is the high rate of data transfer. Data is usually transferred at a rate more than 1 MHz’s. These speeds are much higher than most other communication protocols and makes SPI well suited for setting up communica- tion amongst processors. As an example, we shall set up two microcontrollers, one as a master and the other as a slave, and demonstrate high speed data transfer between the two. This setup can be used for various applications such as rapid data accumulation or distrib- uted problem solving; in which a problem is split up into various smaller sections and sent to different processors, solved simultaneously in parts, and then transferred back to the main processor. The following section will demonstrate how to set up two microcon- trollers, one in master mode and the other in slave mode, such that data can be rapidly transferred between two or more processors. In essence the setup here is the Single Master Multiple Slave configuration, as shown in Figure 7.57. Data transfer in the above mentioned configuration is done by means of interrupts and interrupt service routines. The two important interrupts for SPI transfer are the SPTIx and SPRIx interrupts, where x 0, 1 and “x” is the module number of the RSPI, RSPI0/RSPIA, and RSPI1/RSPIB. Timing details of the interrupts and data transfer are de- scribed as follows. CHAPTER 7 / SERIAL COMMUNICATIONS 265

This LSI (master) RSPI slave 0 RSPCK RSPCK MOSI MOSI MISO MISO SSL0 SSL SSL1 SSL2 SSL3 RSPI slave 1 RSPCK MOSI MISO SSL

RSPI slave 2 RSPCK MOSI MISO SSL

RSPI slave 3 RSPCK MOSI MISO SSL

Figure 7.57 Single Master Multiple Slaves. Source: Hardware Manual, page 1664. Ϸ SPDR access I W I W Ϸ I W I Ϸ Ϸ Ϸ SPTI Ϸ

(1) (2) (3) (4) (5)

SPRI Ϸ Ϸ RSPCKn (CPHA 1, Ϸ CPOL 0) 1 2345678Ϸ 12345678

(n A, D)

Figure 7.58 Operation and timing diagram of SPI interrupts. Source: Hardware Manual, page 1681. 266 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Interrupts occur at times (1) to (5) and are as follows:

1. If the interrupts are enabled and currently no data is present in the transmit buffer, an interrupt, SPTI, is generated, which writes to SPDR. Since the transmit buffer is empty, data is copied into the transmit buffer. 2. When the shift register is/becomes empty, the RSPI copies the data from the trans- mit buffer to the shift register, starts shifting out the data, and generates a transmit buffer empty request (SPTI). 3. When transmit data is written to SPDR by the transmit buffer empty interrupt rou- tine, the data is transferred to the transmit buffer. Because the data being trans- ferred serially is stored in the shift register, the RSPI does not copy the data in the transmit buffer to the shift register. 4. The serial transfer ends. Since the receive buffer is empty, the RSPI copies the re- ceived data from the shift register into the receive buffer and generates a receive buffer full interrupt SPRI. As the transmit buffer is filled from step 3, the RSPI copies the data from the transmit buffer into the shift register and resumes trans- mission of data. 5. When SPDR is read by the receive buffer full interrupt routine, the RSPI sends the data in the receive buffer to the bus inside the chip.

In this manner, the data transfer keeps occurring continuously when the RSPI is enabled. Next we will proceed to the setting up of the microcontrollers in required modes and then proceed to use FIFO queues as explained and demonstrated in Section 7.4.1. Using FIFO queues for communication simplifies the transfer of data and enables fast and con- tinuous communication. Rules for operating the queues remain the same as in Section 7.4.1 however one must notice that now data transfer is taking place in both directions at the same time, with much higher speeds as compared to the SCI interface. For setting up multiprocessor communication, at least two microcontrollers are needed. One microcon- troller will be set up in Master mode while the other will be set up in the Slave mode. The complex example in Section 7.5.2 follows the algorithms for the two microcontrollers as mentioned in the following:

Master Algorithm Initialize one Renesas Microcontroller as the master device by assigning the cor- rect values for the registers. Define a FIFO queue structure consisting of a data array, a pointer to the head of the array, a pointer to the tail of the array, and a variable for holding the current size of the queue. Allot memory for two queues, one for transmission and the other for reception. CHAPTER 7 / SERIAL COMMUNICATIONS 267

Define function for checking if the queue is empty, and another function to check if the queue is full. Initialize the queues by setting the data in the queue, head and tail to zero. Define a function for queuing data in a given queue. In order for the data to be queued, perform a check if the queue is full. If the queue is not full, then queue data by adding to the tail of the array, update the tail and size values, and report success. Otherwise, abort queuing and report failure. Define a function for dequeuing data. In order to dequeue data, check if the queue is empty. If the queue is not empty, copy a byte of data from the head of the queue, update the head and size of the queue, and return the copied variable. If the queue is empty, exit the function. Define the interrupt ser vice routines that do the following: ▫ Transmit routines: Check if the queue is empty. If the queue is not empty, de- queue a byte of data from the transmission queue and give it to the transmit buffer of the microcontroller. ▫ Receive routine: Try to enqueue the data to the receive queue. If the queue is full, provide with an indication.

Setting up the interrupts: The following is the procedure for setting up the serial communi- cation interface interrupts:

In the vect.h file define the vector table locations of the interrupts and declare them as follows: ▫ #pragma interrupt (Excep_RSPI0_SPRIO(vect 45)) void Excep_RSPI0_SPRIO (void); ▫ #pragma interrupt (Excep_RSPI0_SPTIO(vect 46)) void Excep_RSPI0_SPTIO (void); In the file intprg.c write the detailed interrupt ser vice routines for transmit and re- ceive under the function names void Excep_RSPI0_SPRIO (void) and void Excep Excep_RSPI0_SPTIO (void).

Slave Algorithm Initialize another Renesas Microcontroller as the slave device by assigning the cor- rect values for the registers. Define a FIFO queue structure consisting of a data array, a pointer to the head of the array, a pointer to the tail of the array, and a variable for holding the current size of the queue. Allot memory for two queues, one for transmission and the other for reception. Define function for checking if the queue is empty, and another function to check if the queue is full. 268 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Initialize the queues by setting the data in the queue, head and tail to zero. Define a function for queuing data in a given queue. In order for the data to be queued, perform a check if the queue is full. If the queue is not full, then queue data by adding to the tail of the array, update the tail and size values, and report success. Otherwise, abort queuing and report failure. Define a function for dequeuing data. In order to dequeue data, check if the queue is empty. If the queue is not empty, copy a byte of data from the head of the queue, update the head and size of the queue, and return the copied variable. If the queue is empty, exit the function. Define the interrupt ser vice routines that do the following: ▫ Transmit routines: Check if the queue is empty. If the queue is not empty, de- queue a byte of data from the transmission queue and give it to the transmit buffer of the microcontroller. ▫ Receive routine: Try to enqueue the data to the receive queue. If the queue is full, provide with an indication.

Setting up the interrupts: The following is the procedure for setting up the serial communi- cation interface interrupts:

In the vect.h file define the vector table locations of the interrupts and declare them as follows: ▫ #pragma interrupt (Excep_RSPI0_SPRIO(vect 45)) void Excep_RSPI0_SPRIO (void); ▫ #pragma interrupt (Excep_RSPI0_SPTIO(vect 46)) void Excep_RSPI0_SPTIO (void); In the file intprg.c write the detailed interrupt ser vice routines for transmit and re- ceive under the function names void Excep_RSPI0_SPRIO (void) and void Excep_RSPI0_SPTIO (void).

7.4.3 Transfer of Data Between Peripherals Connected on the I2C Bus Using FIFOs

In section 7.2.3 we explained the details of the Renesas I2C interface module and the pro- cedure for setting it up. In section 7.3.3 we demonstrated how to transfer a single byte of data to and from a peripheral. As observed, there is a lot of overhead to transfer a single byte to a peripheral. It thus makes sense to transfer more than one byte at a single time to the device. Most devices that operate using the I2C interface store and read out data bytes from registers; i.e., we read and write data from registers of the device. The devices usually have a register address pointer which points to the register to write to or read from. This register is usually auto incremented when the data is transferred. This allows us to transfer multiple CHAPTER 7 / SERIAL COMMUNICATIONS 269 bytes to and from the device. Thus we can use FIFOs to implement the transfer of data. The easiest method to operate the FIFOs is by using interrupts. The following are the algorithms to read and write data to the device. Data provided to the transmit buffer is from the transmit FIFO and data received from the receive buffer is input into the receive FIFO: Writing data to a peripheral device/Master transmitter operation using interrupts:

1. Set the IICRST bit in ICCR1 to 1 (internal reset) and then clear the IICRST bit to 0 (canceling reset) with the ICE bit in ICCR1 cleared to 0 (disabling the inter- face). This initializes the internal state and the various flags of ICSR1. After that, set registers SARLn, SARUn, ICSER, ICMR1, ICBRH, and ICBRL (n 0 to 2), and set the other registers as necessary (for initial settings of the RIIC, see Figure 30.5 in the hardware manual). When the necessary register settings have been completed, set the ICE bit to 1 (to enable transfer). This step is not necessary if ini- tialization of the RIIC has already been completed. 2. Read the BBSY flag in ICCR2 to check that the bus is open, and then set the ST bit in ICCR2 to 1 (start condition issuance request). Upon receiving the request, the RIIC issues a start condition. At the same time, the BBSY flag and the START flag in ICSR2 are automatically set to 1 and the ST bit is automatically cleared to 0. At this time, if the start condition is detected, and the internal levels for the SDA output state and the levels on the SDAn line have matched while the ST bit is 1, the RIIC recognizes that issuing of the start condition as requested by the ST bit has been successfully completed, and the MST and TRS bits in ICCR2 are automatically set to 1, placing the RIIC in master transmitter mode. The TDRE flag in ICSR2 is also automatically set to 1 in response to the setting of the TRS bit to 1. 3. Check that the TDRE flag in ICSR2 is 1, and then write the value for transmis- sion (the slave address and the R/W# bit) to ICDRT. Once the data for transmis- sion are written to ICDRT, the TDRE flag is automatically cleared to 0, the data are transferred from ICDRT to ICDRS, and the TDRE flag is again set to 1. Af- ter the byte containing the slave address and R/W# bit has been transmitted, the value of the TRS bit is automatically updated to select master transmitter or mas- ter receiver mode in accord with the value of the transmitted R/W# bit. If the value of the R/W# bit was 0, the RIIC continues in master transmitter mode. Since the ICSR2.NACKF flag being 1 at this time indicates that no slave device recognized the address or that there was an error in communications, write 1 to the ICCR2.SP bit to issue a stop condition. For data transmission with an address in the 10-bit format, start by writing 1111 0b, the two higher- order bits of the slave address, and W to ICDRT as the first address transmission. Then, as the second address transmission, write the eight lower- order bits of the slave address to ICDRT. 270 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

4. After confirming that the TDRE flag in ICSR2 is 1, write the data for transmission to the ICDRT register. The RIIC automatically holds the SCLn line low until the data for transmission are ready, or a stop condition is issued. 5. After all bytes of data for transmission have been written to the ICDRT register, wait until the value of the TEND flag in ICSR2 returns to 1, and then set the SP bit in ICCR2 to 1 (stop condition issuance request). Upon receiving a stop condition issuance request, the RIIC issues the stop condition. 6. Upon detecting the stop condition, the RIIC automatically clears the MST and TRS bits in ICCR2 to 00b and enters slave receiver mode. Furthermore, it auto- matically clears the TDRE and TEND flags to 0, and sets the STOP flag in ICSR2 to 1. 7. After checking that the ICSR2.STOP flag is 1, clear the ICSR2.NACKF and STOP flags to 0 for the next transfer operation.

The following two figures show the timings of the operations:

Reading data from a peripheral device/Master receiver operation:

1. Set the IICRST bit in ICCR1 to 1 (internal reset) and then clear the IICRST bit to 0 (canceling reset) with the ICE bit in ICCR1 cleared to 0 (disabling the interface). This initializes the internal state and the various flags of ICSR1. After that, set registers SARLn, SARUn, ICSER, ICMR1, ICBRH, and ICBRL (n 0 to 2), and set the other registers as necessary (for initial settings of the RIIC, see Figure 30.5 in the hardware manual). When the necessary register settings have been completed, set the ICE bit to 1 (to enable transfer). This step is not necessary if initialization of the RIIC has al- ready been completed. 2. Read the BBSY flag in ICCR2 to check that the bus is open, and then set the ST bit in ICCR2 to 1 (start condition issuance request). Upon receiving the request, the RIIC issues a start condition. When the RIIC detects the start condition, the BBSY flag and the START flag in ICSR2 are automatically set to 1 and the ST bit is auto- matically cleared to 0. At this time, if the start condition is detected and the levels for the SDA output and the levels on the SDAn line have matched while the ST bit is 1, the RIIC recognizes that issuing of the start condition as requested by the ST bit has been successfully completed. As a result the MST and TRS bits in ICCR2 are automatically set to 1, placing the RIIC in master transmitter mode. The TDRE flag in ICSR2 is also automatically set to 1 in response to setting of the TRS bit to 1. 3. Check that the TDRE flag in ICSR2 is 1, and then write the value for transmission (the first byte indicates the slave address and value of the R/W# bit) to ICDRT. Once the data for transmission are written to ICDRT, the TDRE flag is automati- cally cleared to 0, the data are transferred from ICDRT to ICDRS, and the TDRE flag is again set to 1. Once the byte containing the slave address and R/W# bit has been transmitted, the value of the ICCR2.TRS bit is automatically updated to CHAPTER 7 / SERIAL COMMUNICATIONS 271 4 b 4 DATA 2 DATA 3 b 5 DATA 3 DATA “0” (ACK) 2 b 6 DATA 2 DATA [4] 1 b 7 Write ICDRT page 1522. (DATA 3) (DATA 9 ACK Transmit data (DATA 2) data (DATA Transmit 8 b 0 7 b 1 6 b 2 Source: Hardware Manual, Source: DATA 2 DATA 5 b 3 4 DATA 1 DATA b 4 DATA 1 DATA “0” (ACK) 3 b 5 “0” (ACK) 2 XXXX (Initial val u e/last data reception) for b 6 [4] 1 b 7 Write ICDRT (DATA 2) (DATA 9 ACK Transmit data (DATA 1) data (DATA Transmit 8 b 0 W 7 b 1 DATA 1 DATA 6 b 2 5 b 3 7- b it address W 4 b 4 “X” (ACK/NACK) 3 b 5 it slave address 7- b it slave [4] Write ICDRT (DATA 1) (DATA Operation of the RIIC module in master transmitter mode. 2 b 6 tomatic low-hold (to prevent wrong transmission) u tomatic low-hold (to prevent A 1 b 7 7- b it address W [3] W) Transmit data (7- b it address W) Transmit Write ICDRT Write Figure 7.59 Figure (7- b it address S [2] to ST Write 1 Write ST TRS MST SCLn SDAn BBSY TDRE TEND RDRF CKBR ICDRT ICDRS START ICDRR ACKBT A 272 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER [7] Clear STOP 0 STOP P [5] Write SP 1 “X” (ACK/NACK) 9 A/NA 8 b 0 page 1522. 7 b 1 6 b 2 DATA n DATA 5 b 3 DATA n DATA 4 b 4 “0” (ACK) 3 b 5 DATA n DATA Source: Hardware Manual, Source: 2 b 6 e/final receive data) XXXX (Initial val u e/final receive 1 b 7 “0” (ACK) 9 ACK 8 b 0 Transmit data (DATA n) data (DATA Transmit 7 b 1 6 b 2 5 b 3 4 b 4 DATA n-1 DATA DATA n-1 DATA “0” (ACK) RIIC module in master transmitter mode. 3 b 5 [4] 2 b 6 Write ICDRT Write 1 b 7 (Final transmit data [DATA n]) data(Final transmit [DATA Figure 7.60 Figure 9 ACK Transmit data (DATA n-1) data (DATA Transmit 8 b 0 DATA n-2 DATA 7 DATA n-1 DATA b 1 DATA n-2 DATA SP TRS MST SCLn SDAn STOP BBSY TDRE TEND RDRF ICDRT ICDRS ICDRR ACKBT ACKBR CHAPTER 7 / SERIAL COMMUNICATIONS 273

select master transmitter or master receiver mode in accord with the value of the transmitted R/W# bit. If the value of the R/W# bit was 1, the TRS bit is cleared to 0 on the rising edge of the ninth cycle of SCLn (the clock signal), placing the RIIC in master receiver mode. At this time, the TDRE flag is automatically cleared to 0 and the ICSR2.RDRF flag is automatically set to 1. Since the ICSR2.NACKF flag being 1 at this time indicates that no slave device recognized the address or there was an error in communications, write 1 to the ICCR2.SP bit to issue a stop condition. For master reception from a device with a 10-bit address, start by using the master transmission to issue the 10-bit address, and then issue a restart condition. After that, transmitting 1111 0b, the two higher- order bits of the slave address, and the R bit places the RIIC in master receiver mode. 4. Dummy read ICDRR after confirming that the RDRF flag in ICSR2 is 1. This makes the RIIC start output of the SCL (clock) signal and start data reception. 5. After one byte of data has been received, the RDRF flag in ICSR2 is set to 1 on the rising edge of the eighth or ninth cycle of SCL clock (the clock signal) as selected by the RDRFS bit in ICMR3. Reading out ICDRR at this time will produce the re- ceived data, and the RDRF flag is automatically cleared to 0 at the same time. Fur- thermore, the value of the acknowledgement field received during the ninth cycle of SCL clock is returned as the value set in the ACKBT bit of ICMR3. Save the re- ceived data into the FIFO and increment the pointer to the FIFO. 6. When the next value to be received will be the final byte, set the WAIT bit in ICMR3 to 1 (so that waiting is applied) before reading ICDRR. This causes the SCLn line to be held low from the falling edge of the ninth clock cycle after re- ception of the next data (i.e., the final byte), enabling issuance of a stop condition. However, when the ICMR3.RDRFS bit is 0 and the slave device must be notified that it is to end transfer for data reception after transfer of the next (final) byte, set the ACKBT bit in ICMR3 to 1 (NACK). 7. After reading out the byte before last from the ICDRR register, if the value of the ICSR2.RDRF flag is confirmed to be 1, write 1 to the SP bit in ICCR2 (stop con- dition issuance request) and then read the last byte from ICDRR. Save the received data bytes into the FIFO and increment the pointer to the FIFO. When ICDRR is read, the RIIC is released from the wait state and issues the stop condition after low- level output in the ninth clock cycle is completed or the SCL line is released from the low- hold state. 8. Upon detecting the stop condition, the RIIC automatically clears the MST and TRS bits in ICCR2 to “00b” and enters slave receiver mode. Furthermore, detec- tion of the stop condition leads to setting of the STOP flag in ICSR2 to 1. 9. After checking that the ICSR2.STOP flag is 1, clear the ICSR2.NACKF and STOP flags to 0 for the next transfer operation.

The following two figures show the timings of the operations. 274 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER 4 b 4 DATA 2 DATA 3 b 5 DATA 2 DATA “0” (ACK) 2 b 6 DATA 1 DATA [5] Read 1 ICDRR b 7 (DATA 1) (DATA page 1526. 9 ACK 8 b 0 7 b 1 6 Receive data (DATA 1) data (DATA Receive b 2 5 b 3 DATA 1 DATA Source: Hardware Manual, Source: 4 DATA 1 DATA b 4 “0” (ACK) 7- b it address R 3 b 5 2 b 6 “0” (ACK) [4] 7- b it address R 1 b 7 Master receive mode Master receive Read ICDRR Read mmy read (D u mmy 9 [7- b it address R]) ACK 8 R b 0 7 b 1 Receive data (7- b it address R) Receive 6 b 2 Master transmit mode Master transmit 5 b 3 4 b 4 7- b it address R u e/last data reception) for 3 b 5 it slave address 7- b it slave Operation of the RIIC module in master receiver mode. Operation of the RIIC module in master receiver 2 b 6 “X” (ACK/NACK) 1 b 7 XXXX (Initial val u tomatic low-hold A (error protected) transmission [3] R) Figure 7.61 Figure Transmit data (7- b it address R) Transmit Read ICDRT Read (7- b it address S [2] to ST Write 1 Write ST TRS MST SCLn SDAn BBSY TDRE TEND RDRF ICDRT ICDRS ICDRR START ACKBT ACKBR CHAPTER 7 / SERIAL COMMUNICATIONS 275 to 0 [9] Clear STOP “0” to 0 P DATA n DATA Clear WAIT “1” (NACK) NACK 9 [7] 8 b 0 Read ICDRR Read page 1527. 7 b 1 (last data for reception)[DATA n] (last data reception)[DATA for 6 b 2 DATA n DATA Receive data (DATA n) data (DATA Receive to SP Write 1 Write 5 b 3 “1” (NACK) DATA n DATA 4 b 4 DATA n-1 DATA “0” (ACK) 3 u tomatic low hold (error protected) transmission b 5 Source: Hardware Manual, Source: A (Data n-1) 2 Read ICDRR Read b 6 1 b 7 [6] Write 1 Write 9 to ACKBT ACK 8 b 0 Write 1 Write to WAIT 7 b 1 Receive data (DATA n-1) data (DATA Receive 6 b 2 5 b 3 DATA n-2 DATA 4 b 4 DATA n-1 DATA “0” (ACK) DATA n-1 DATA RIIC module in master receiver mode. RIIC module in master receiver 3 b 5 “0” (ACK) 2 b 6 [5] 1 b 7 (Data n-2) Read ICDRR Read Figure 7.62 Figure 9 ACK XXXX (last data for transmission [7- b t address R/Upper 10 its R]) XXXX (last data transmission for 8 b 0 7 b 1 DATA n-2 DATA DATA n-2 DATA DATA n-3 DATA “0” (ACK) Receive data (DATA n-2) data (DATA Receive SP TRS MST WAIT SCLn SDAn STOP BBSY TDRE TEND RDRF ICDRT ICDRS ICDRR ACKBT ACKBR 276 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Advanced Section 7.5.3 helps demonstrate these concepts.

7.5 ADVANCED EXAMPLES

7.5.1 FIFO Data Structures for Transmission and Reception Using the UART Serial Communications Interface

Aim: Demonstration of the use of FIFOs towards transmission and reception. Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, Renesas Development Kit; PC with RS- 232 serial port. Details: In this example we demonstrate the use of FIFO data structures for transmis- sion and reception to show how the communication interface operates using interrupts, and how the microcontroller manages to work on other tasks while communication proceeds normally. This example is based on the initialization codes of the Basic Example 7.3.1 and is similar to the one detailed in Section 7.4.1. Procedure: For this example, create a new workspace in HEW and fill the given lines of code in the corresponding files mentioned before the following code. Compile; build all files and Download to board as mentioned in Chapter 4. When downloaded, connect the RX62N development board to a standard PC with an RS-232 port configured at 115200 baud, no parity, and 1 stop bit to view the results on a HyperTerminal program or on a Serial Port Terminal. Code: The following is the code related to the demonstration:

Setting up Interrupt Service Routines Filename: vect.h

1. pragma interrupt (Excep_SCI2_RXI2(vect = 223)) 2. void Excep_SCI2_RXI2(void); 3. #pragma interrupt (Excep_SCI2_TXI2(vect = 224)) 4. void Excep_SCI2_TXI2(void);

Filename: intprg.c

1. #include “RX62N_SCI_UART.h” 2. #include 3. #include “vect.h” 4. #pragma Section IntPRG 5. void Excep_SCI2_RXI2(void){ CHAPTER 7 / SERIAL COMMUNICATIONS 277

6. if(!Q_Enqueue(&rx_q, SCI2.RDR)){ 7. } 8. } 9. void Excep_SCI2_TXI2(void){ 10. if(!Q_Empty(&tx_q)) 11. SCI2.TDR = Q_Dequeue(&tx_q); 12. }

Setting up function definitions for operating on the queues:

Filename: RX62N_SCI_UART.h

1. #include “iodefine_RX62N.h” 2. #define Q_SIZE (32) 3. typedef struct { 4. unsigned char Data [Q_SIZE]; 5. unsigned int Head; //points to oldest data element 6. unsigned int Tail; //points to next free space 7. unsigned int Size; //quantity of elements in queue 8. } Q_T; 9. int Q_Empty(Q_T * q); 10. int Q_Full(Q_T * q); 11. int Q_Enqueue(Q_T * q, unsigned char d); 12. unsigned char Q_Dequeue(Q_T * q); 13. void Q_Init(Q_T * q); 14. void delay(long unsigned int n); 15. void init_switches(); 16. void init_LEDs(); 17. void init_UART0(); 18. void d3_send_string(far char * s); 19. void demo3(void); 20. extern Q_T tx_q, rx_q;

Setting up all the function details related to the functioning of the UART and FIFO queues:

Filename: RX62N_SCI_UART.c

1. #include “RX62N_SCI_UART.h” 2. Q_T tx_q, rx_q; 3. int Q_Empty(Q_T * q){ 278 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

4. return (q->Size == 0); 5. } 6. int Q_Full(Q_T * q){ 7. return (q->Size == Q_SIZE); 8. } 9. int Q_Enqueue(Q_T * q, unsigned char d){ 10. if(!Q_Full(q)){ 11. q->Data [q->Tail++] = d; 12. q->Tail %= Q_SIZE; 13. q->Size++; 14. return 1; 15. } 16. else return 0; 17. } 18. unsigned char Q_Dequeue(Q_T * q){ 19. unsigned char t = 0; 20. if(!Q_Empty(q){ 21. t = q->Data [q->Head]; 22. q->Data [q->Head++] = 0; 23. q->Head %= Q_SIZE; 24. q->Size––; 25. } 26. return t; 27. } 28. void Q_Init(Q_T * q){ 29. unsigned int i; 30. for(i = 0; i < Q_SIZE; i++) 31. q->Data [i] = 0; 32. q->Head = 0; 33. q->Tail = 0; 34. q->Size = 0; 35. } 36. void init_UART0(){ 37. MSTP(SCI2) = 0; 38. IOPORT.PFFSCI.BIT.SCI2S = 1; 39. PORT1.DDR.BIT.B2 = 0; 40. PORT1.ICR.BIT.B2 = 1; 41. PORT1.DDR.BIT.B3 = 1; 42. SCI2.SCR.BYTE = 0; 43. SCI2.SMR.BYTE = 0x00; 44. SCI2.SCR.BIT.RIE = 1; 45. SCI2.SCR.BIT.TIE = 1; CHAPTER 7 / SERIAL COMMUNICATIONS 279

46. IPR(SCI2,RXI2) = 1; 47. IPR(SCI2,TXI2) = 1; 48. IEN(SCI2, RXI2) = 1; 49. IEN(SCI2, TXI2) = 1; 50. SCI2.BRR = 12; 51. SCI2.SCR.BYTE |= 0x30; 52. } 53. void d3_send_string(far char * s){ 54. while(*s){ 55. if(Q_Enqueue(&tx_q, *s)) 56. s++; 57. else { } 58. } 59. if(IR(SCI2, TXI2) == 0){ 60. SCI2.TDR = Q_Dequeue(&tx_q); 61. } 62. } 63. void demo3(void){ 64. char c; 65. d3_send_string(“Hello, interruptible world!\n\r”); 66. while(1){ 67. if(!Q_Empty(&rx_q)){ 68. c = Q_Dequeue(&rx_q); 69. d3_send_string(“Ouch!\n\r”); 70. } 71. } 72. }

Main Program Filename: Workspace_name.c

1. void main(){ 2. init_switches(); 3. init_LEDs(); 4. init_UART0(); 5. Q_Init(&tx_q); 6. Q_Init(&rx_q); 7. demo3(); 8. while(1) 9. ; 10. } 280 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

7.5.2 Multiprocessor Communication Using Queues and the Renesas Serial Peripheral Interface

Aim: Demonstration of Multiprocessor Communication using queues and the RSPI for rapid communication between microcontrollers. Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, Two Renesas Development Kits. Details: In the previous example, we demonstrated how communication takes place at a continuous pace using queues. In this example we demonstrate how to perform Multi- processor communication at much higher speeds than those available with the SCI interface. Baud rates can reach maximum speeds of PCLK, which is the peripheral clock generated by the RX62N processor. Since the RSPI operates much faster than the SCI, it is an ideal serial bus for Multiprocessor communication as compared to the SCI and I2C interface. Procedure: For this example, create a new workspace in HEW and fill the given lines of code in the corresponding files mentioned before the following code. You now need to download two separate pieces of codes on to each board; one for the master device and one for the slave device. At the beginning of the main file for the master device, make sure that the “#define RSPI_Master_Device” is not commented out while the “#define RSPI_Slave_Device” is commented out. This will build the main example code for the master device. Once this example code has been built, download the module on to one board. For the slave device, make sure that the “#define RSPI_Slave_Device” is not com- mented where as the “#define RSPI_Master_Device” is commented out. This will build the main example code for the slave device. Once this example code has been built, download the module on to the other board. Make sure that you are not building both modules at the same time; i.e., “#define RSPI_Master_Device” and “#define RSPI_Slave_Device” are not defined at the same time, or else the code/device will not function. Code: The following is the code related to the demonstration:

Setting Up Interrupt Service Routines Filename: vect.h

1. #pragma interrupt (Excep_RSPI0_SPRI0(vect = 45)) 2. void Excep_RSPI0_SPRI0(void); 3. #pragma interrupt (Excep_RSPI0_SPTI0(vect = 46)) 4. void Excep_RSPI0_SPTI0(void);

Filename: intprg.c

1. void Excep_RSPI0_SPRI0(void){ 2. LED_Y = LED_ON; CHAPTER 7 / SERIAL COMMUNICATIONS 281

3. if(!SPI_Q_Enqueue(&rx_q, (0x00FF & RSPI0.SPDR.WORD.L))){ 4. LED_R = LED_ON; 5. } 6. LED_Y = LED_OFF; 7. } 8. void Excep_RSPI0_SPTI0(void){ 9. LED_G = LED_ON; 10. if(!SPI_Q_Empty(&tx_q)) 11. RSPI0.SPDR.WORD.H = (0x00FF & SPI_Q_Dequeue(&tx_q)); 12. LED_G = LED_OFF; 13. }

Setting Up Function Definitions for Operating on the Queues Filename: RX62N_RSPI.h

1. #include “iodefine_RX62N.h” 2. #define NULL (0) 3. #define SW1 (PORT4.PORT.BIT.B0) 4. #define SW2 (PORT4.PORT.BIT.B1) 5. #define SW3 (PORT4.PORT.BIT.B2) 6. #define SW1_EN (PORT4.DDR.BIT.B0) 7. #define SW2_EN (PORT4.DDR.BIT.B1) 8. #define SW3_EN (PORT4.DDR.BIT.B2) 9. #define Q_SIZE (32) 10. typedef struct { 11. unsigned char Data [Q_SIZE]; 12. unsigned int Head; 13. unsigned int Tail; 14. unsigned int Size; 15. } Q_T; 16. int SPI_Q_Empty(Q_T * q); 17. int SPI_Q_Full(Q_T * q); 18. int SPI_Q_Enqueue(Q_T * q, unsigned char d); 19. unsigned char Q_Dequeue(Q_T * q); 20. void SPI_Q_Init(Q_T * q); 21. void SPI_delay(long unsigned int n); 22. void SPI_init_switches(); 23. void SPI_init_LEDs(); 24. void SPI_init_RSPI_Master(); 25. void SPI_init_RSPI_Slave(); 282 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

26. void SPI_d3_send_string(far char * s); 27. void SPI_demo3(void); 28. extern Q_T tx_q, rx_q;

Setting Up All the Function Details Related to the Functioning of the UART and FIFO Queues Filename: RX62N_SCI_UART.c

1. #include “iodefine_RX62N.h” 2. #include “RX62N_RSPI.h” 3. #include “RX62N_LED_Defs.h” 4. Q_T tx_q, rx_q; 5. void SPI_init_RSPI_Master(void){ 6. MSTP(RSPI0) = 0; 7. IOPORT.PFGSPI.BIT.RSPIS = 0; 8. IOPORT.PFGSPI.BIT.RSPCKE = 1; 9. IOPORT.PFGSPI.BIT.SSL0E = 1; 10. IOPORT.PFGSPI.BIT.MOSIE = 1; 11. IOPORT.PFGSPI.BIT.MISOE = 1; 12. PORTC.DDR.BIT.B7 = 0; 13. PORTC.DDR.BIT.B6 = 1; 14. PORTC.DDR.BIT.B5 = 1; 15. PORTC.DDR.BIT.B4 = 1; 16. PORTC.DR.BIT.B4 = 1; 17. PORTC.DR.BIT.B7 = 1; 18. PORTC.DR.BIT.B6 = 1; 19. PORTC.DR.BIT.B5 = 1; 20. RSPI0.SPPCR.BYTE = 0x00; 21. RSPI0.SPBR.BYTE = 0x00; 22. RSPI0.SPDCR.BYTE = 0x00; 23. RSPI0.SPCKD.BYTE = 0x00; 24. RSPI0.SSLND.BYTE = 0x00; 25. RSPI0.SPND.BYTE = 0x00; 26. RSPI0.SPCR2.BYTE = 0x00; 27. IPR(RSPI0, SPTI0) = 1; //Clear Transmit interrupt bit 28. IEN(RSPI0, SPTI0) = 1; //Enable Transmit interrupt bit 29. IPR(RSPI0, SPRI0) = 1; //Clear Transmit interrupt bit 30. IEN(RSPI0, SPRI0) = 1; //Enable Transmit interrupt bit 31. RSPI0.SPCMD0.WORD = 0x0701; 32. RSPI0.SPCR.BYTE = 0xE8; CHAPTER 7 / SERIAL COMMUNICATIONS 283

33. RSPI0.SSLP.BYTE = 0x00; 34. RSPI0.SPSCR.BYTE = 0x00; 35. } 36. void SPI_init_RSPI_Slave(void){ 37. MSTP(RSPI0) = 0; 38. IOPORT.PFGSPI.BIT.RSPIS = 0; 39. IOPORT.PFGSPI.BIT.RSPCKE = 1; 40. IOPORT.PFGSPI.BIT.SSL0E = 1; 41. IOPORT.PFGSPI.BIT.MOSIE = 1; 42. IOPORT.PFGSPI.BIT.MISOE = 1; 43. PORTC.DDR.BIT.B7 = 1; 44. PORTC.DDR.BIT.B6 = 0; 45. PORTC.DDR.BIT.B5 = 0; 46. PORTC.DDR.BIT.B4 = 0; 47. PORTC.DR.BIT.B4 = 0; 48. PORTC.DR.BIT.B7 = 1; 49. PORTC.DR.BIT.B6 = 0; 50. PORTC.DR.BIT.B5 = 0; 51. RSPI0.SPPCR.BYTE = 0x04; 52. RSPI0.SPBR.BYTE = 0x00; 53. RSPI0.SPDCR.BYTE = 0x00; 54. RSPI0.SPCKD.BYTE = 0x00; 55. RSPI0.SSLND.BYTE = 0x00; 56. RSPI0.SPND.BYTE = 0x00; 57. RSPI0.SPCR2.BYTE = 0x00; 58. RSPI0.SPCMD0.WORD = 0x0701; 59. RSPI0.SPDR.WORD.L = 0xAA55; 60. RSPI0.SPDR.WORD.H = 0x55AA; 61. IEN(RSPI0, SPRI0) = 1; //Enable Receive interrupt 62. IEN(RSPI0, SPTI0) = 1; //Enable Transmit interrupt 63. IPR(RSPI0, SPRI0) = 1; 64. IPR(RSPI0, SPTI0) = 1; 65. RSPI0.SSLP.BYTE = 0x00; 66. RSPI0.SPCR.BYTE = 0xA0; 67. RSPI0.SPSCR.BYTE = 0x00; 68. RSPI0.SPCR.BIT.SPE = 1; 69. } 70. int SPI_Q_Empty(Q_T * q){ 71. return (q->Size == 0); 72. } 284 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

73. int SPI_Q_Full(Q_T * q){ 74. return (q->Size == Q_SIZE); 75. } 76. int SPI_Q_Enqueue(Q_T * q, unsigned char d){ 77. if(!SPI_Q_Full(q)){ 78. q->Data [q->Tail++] = d; 79. q->Tail %= Q_SIZE; 80. q->Size++; 81. return 1; 82. } 83. else return 0; 84. } 85. unsigned char SPI_Q_Dequeue(Q_T * q){ 86. unsigned char t = 0; 87. if(!SPI_Q_Empty(q)){ 88. t = q->Data [q->Head]; 89. q->Data [q->Head++] = 0; 90. q->Head %= Q_SIZE; 91. q->Size—; 92. } 93. return t; 94. } 95. void SPI_Q_Init(Q_T * q){ 96. unsigned int i; 97. for(i = 0; i < Q_SIZE; i++) 98. q->Data [i] = 0; 99. q->Head = 0; 100. q->Tail = 0; 101. q->Size = 0; 102. } 103. void SPI_delay(long unsigned int n){ 104. while (n—) 105. ; 106. } 107. void SPI_init_switches(){ 108. SW1_EN = SW2_EN = SW3_EN = 0; //inputs 109. } 110. void SPI_init_LEDs(){ 111. ENABLE_LEDS; 112. ALL_LEDS_ON; 113. } CHAPTER 7 / SERIAL COMMUNICATIONS 285

114. void SPI_d3_send_string(far char * s){ 115. while(*s){ 116. if(SPI_Q_Enqueue(&tx_q, *s)) 117. s++; 118. if(IR(RSPI0, SPTI0) == 0){ 119. SCI2.TDR = SPI_Q_Dequeue(&tx_q); 120. } 121. } 122. void SPI_demo3(void){ 123. char c; 124. SPI_d3_send_string(“Hello, interruptible world!\n\r”); 125. while(1){ 126. if(!SPI_Q_Empty(&rx_q)){ 127. c = SPI_Q_Dequeue(&rx_q); 128. (void)c; 129. SPI_d3_send_string(“Ouch!\n\r”); 130. } 131. } 132. }

Main Program Filename: Workspace_name.c

1. #include “iodefine_RX62N.h” 2. #include “RX62N_LED_Defs.h” 3. #include “RX62N_RSPI.h” 4. #define RSPI_SLAVE 5. #define RSPI_MASTER 6. void main(){ 7. SPI_init_switches(); 8. SPI_init_LEDs(); 9. #ifdef RSPI_MASTER 10. SPI_init_RSPI_Master(); 11. #endif 12. #ifdef RSPI_MASTER 13. SPI_init_RSPI_Slave(); 14. #endif 15. SPI_Q_Init(&tx_q); 16. SPI_Q_Init(&rx_q); 286 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

17. SPI_demo3(); 18. while(1) 19. ; 20. }

7.5.3 Transfer of data between peripherals connected on the I2C bus using FIFOs

Aim: To demonstrate mass transfer of data between peripherals connected on the I2C bus. Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, Renesas Development Kits (YRDKRX62N) with on board I2C peripherals. Details: In this example we will demonstrate how to use the I2C bus to transfer large amounts of data to the desired peripheral with minimum overhead. The device we will use is the ADXL345 and will be writing the default values to the ADXL345, specified in the device datasheet and reading the acceleration values for the X, Y, and Z values. The code also provides for a standard framework that can be used to access other devices using the RX62N microcontroller. Procedure: For this example, create a new workspace in HEW and fill the given lines of code in the corresponding files mentioned before the code below. To use the following code for other peripherals make sure to specify the correct address and number of data bytes to read and write. The given following code is for the Analog Devices Accelerometer ADXL345 whose device sheet is found at http://www.analog.com/static/imported-files/ data_sheets/ADXL345.pdf (Analog Devices, Inc.; ADXL345 datasheet: 3-Axis, 2 g/4 g/8 g/16 g Digital Accelerometer, ADXL345). A point to note is for the user to use the iodefine_RX62N.h header file instead of the standard iodefine.h file. Additional changes may be required if the two header files are switched.

Filename: riic.h

This file contains the most declarations and #define variables used by the RIIC module.

1. #ifndef _RIIC_SETTING_DEF 2. #define _RIIC_SETTING_DEF 3. #define RIIC_CH0 //When use channel0, define “RIIC_CH0” 4. #define RIIC_CH1 //When use channel1, define “RIIC_CH1” 5. #ifdef RIIC_CH0 6. #define RIIC RIIC0 //Replace I/O define 7. #else 8. #define RIIC RIIC1 //Replace I/O define 9. #endif 10. #define RIIC_OK 0 //Return value for function “RiicMst” CHAPTER 7 / SERIAL COMMUNICATIONS 287

11. #define RIIC_NG 1 //Return value for function “RiicMst” 12. #define RIIC_BUS_BUSY 2 //Return value for function “RiicMst” 13. void RiicIni(unsigned char, unsigned char); 14. unsigned char RiicStart(unsigned char, unsigned char*, unsigned long); 15. #endif //_RIIC_SETTING_DEF

Filename: riic.c

This file contains definitions of functions that perform actions in response to calls from ei- ther the user or the interrupts.

1. void RiicIni(unsigned char in_SelfAddr, unsigned char in_Enable) 2. { 3. #ifdef RIIC_CH0 4. SYSTEM.MSTPCRB.BIT.MSTPB21 = 0; //RIIC0(MSTPB21) 5. #else 6. SYSTEM.MSTPCRB.BIT.MSTPB20 = 0; //RIIC1(MSTPB20) 7. #endif 8. RIIC.ICCR1.BIT.ICE = 0; //RIIC disable 9. RIIC.ICCR1.BIT.IICRST = 1; //RIIC all reset 10. RIIC.ICCR1.BIT.IICRST = 0; 11. RiicMstCnt = 0; 12. RiicMstNum = 0; 13. if(in_Enable != 0){ //Initialise RIIC 14. /* Self address setting */ 15. RIIC.SARU0.BIT.FS = 0; //7bit address format 16. RIIC.SARL0.BYTE = in_SelfAddr; //Set self address 17. RIIC.ICMR1.BIT.CKS = 7; //IIC phi = PCLK/128 clock 18. RIIC.ICBRH.BIT.BRH = 28; //100kbps (PCLK = 50 MHz) 19. RIIC.ICBRL.BIT.BRL = 29; 20. RIIC.ICMR3.BIT.ACKWP = 1; //Disable ACKBT protect 21. RIIC.ICIER.BIT.RIE = 1; //Edge interrupt 22. RIIC.ICIER.BIT.TIE = 1; //Edge interrupt 23. RIIC.ICIER.BIT.TEIE = 0; //Level interrupt 24. RIIC.ICIER.BIT.NAKIE = 1; //Level interrupt 25. RIIC.ICIER.BIT.SPIE = 1; //Level interrupt 26. RIIC.ICIER.BIT.STIE = 0; //Level interrupt 27. RIIC.ICIER.BIT.ALIE = 0; //Level interrupt 28. RIIC.ICIER.BIT.TMOIE = 0; //Level interrupt 288 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

29. #ifdef RIIC_CH0 //RIIC channel0 30. ICU.IPR [0x88].BYTE = 0x04; //EEI0 interrupt level 31. ICU.IPR [0x89].BYTE = 0x04; //RXI0 interrupt level 32. ICU.IPR [0x8A].BYTE = 0x04; //TXI0 interrupt level 33. ICU.IPR [0x8B].BYTE = 0x04; //TEI0 interrupt level 34. ICU.IER [0x1E].BIT.IEN6 = 1; //EEI0 interrupt enable 35. ICU.IER [0x1E].BIT.IEN7 = 1; //RXI0 interrupt enable 36. ICU.IER [0x1F].BIT.IEN0 = 1; //TXI0 interrupt enable 37. ICU.IER [0x1F].BIT.IEN1 = 1; //TEI0 interrupt enable 38. ICU.IR [246 ].BIT.IR = 0; //EEI0 clear interrupt flag 39. ICU.IR [247].BIT.IR = 0; //RXI0 clear interrupt flag 40. ICU.IR [248].BIT.IR = 0; //TXI0 clear interrupt flag 41. ICU.IR [249].BIT.IR = 0; //TEI0 clear interrupt flag 42. PORT1.ICR.BIT.B3 = 1; //SDA0 setting 43. PORT1.ICR.BIT.B2 = 1; //SCL0 setting 44. #else //RIIC channel1 45. ICU.IPR [0x8C].BYTE = 0x04; //EEI1 interrupt level 46. ICU.IPR [0x8D].BYTE = 0x04; //RXI1 interrupt level 47. ICU.IPR [0x8E].BYTE = 0x04; //TXI1 interrupt level 48. ICU.IPR [0x8F].BYTE = 0x04; //TEI1 interrupt level 49. ICU.IER [0x1F].BIT.IEN2 = 1; //EEI1 interrupt enable 50. ICU.IER [0x1F].BIT.IEN3 = 1; //RXI1 interrupt enable 51. ICU.IER [0x1F].BIT.IEN4 = 1; //TXI1 interrupt enable 52. ICU.IER [0x1F ].BIT.IEN5 = 1; //TEI1 interrupt enable 53. ICU.IR [250].BIT.IR = 0; //EEI1 clear interrupt flag 54. ICU.IR [251].BIT.IR = 0; //RXI1 clear interrupt flag 55. ICU.IR [252].BIT.IR = 0; //TXI1 clear interrupt flag 56. ICU.IR [253].BIT.IR = 0; //TEI1 clear interrupt flag 57. PORT1.ICR.BIT.B3 = 1; //SDA1 setting 58. PORT1.ICR.BIT.B2 = 1; //SCL1 setting 59. #endif //RIIC_CH0 60. RIIC.ICCR1.BIT.ICE = 1; //RIIC enable 61. } 62. else { //Stop RIIC 63. #ifdef RIIC_CH0 64. SYSTEM.MSTPCRB.BIT.MSTPB21 = 1; //RIIC0(MSTPB21) 65. #else 66. SYSTEM.MSTPCRB.BIT.MSTPB20 = 1; //RIIC1(MSTPB20) 67. #endif 68. } 69. } CHAPTER 7 / SERIAL COMMUNICATIONS 289

70. unsigned char RiicStart(unsigned char in_addr, unsigned char *in_buff, unsigned long in_num) 71. { 72. if(in_num < 2){ //Check data number (include first byte (address)) 73. return RIIC_NG; 74. } 75. if((RIIC.ICCR2.BYTE & 0xE0) != 0x00){ 76. return RIIC_BUS_BUSY; //Bus busy 77. } 78. RIIC.ICCR2.BIT.ST = 1; //Generate start condition 79. RiicTrmAddr = in_addr; //Set transmission address 80. RiicMstBuff = in_buff; //Set transmission buffer 81. RiicMstCnt = 0; 82. RiicMstNum = in_num; 83. return RIIC_OK; 84. } 85. void RiicRDRF(void){ 87. volatile unsigned long cnt; 89. if(RIIC.ICSR2.BIT.NACKF != 0){ //When receive NACK 90. if(RIIC.ICCR1.BIT.SCLI == 0){ 91. for(cnt = RIIC_WAIT_VALUE; cnt! = 0; cnt——); 92. } 93. RIIC.ICCR2.BIT.SP = 1; //Generate stop condition 94. *RiicMstBuff = RIIC.ICDRR; //Dummy read 95. return; 96. } 98. if(RiicMstCnt >= RiicMstNum){ //After receive all data 99. if(RIIC.ICCR1.BIT.SCLI == 0){ 100. for(cnt = RIIC_WAIT_VALUE; cnt != 0; cnt——); 101. } 102. RIIC.ICCR2.BIT.SP = 1; //Generate stop condition 103. RIIC.ICMR3.BIT.ACKBT = 0; //Set ACK 104. *RiicMstBuff = RIIC.ICDRR; //Read data 105. RiicMstBuff++; //Add pointer 106. } 107. else if(RiicMstCnt == RiicMstNum -1){ //Next is last data 108. RIIC.ICMR3.BIT.WAIT = 1; 109. RIIC.ICMR3.BIT.ACKBT = 1; //Set NACK 110. *RiicMstBuff = RIIC.ICDRR; //Read data 111. RiicMstBuff++; //Add pointer 290 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

112. } 113. else { //Transfer next data 114. *RiicMstBuff = RIIC.ICDRR; //Read data 115. RiicMstBuff++; //Add pointer 116. } 118. RiicMstCnt++; //Add internal counter 119. } 120. void RiicTDRE(void) 121. { 122. volatile unsigned long cnt; 123. if(RiicMstCnt >= RiicMstNum){ //After transfer all data 124. #ifdef RIIC_CH0 125. ICU.IER [0x1F].BIT.IEN0 = 0; //TXI0 126. #else 127. ICU.IER [0x1F].BIT.IEN4 = 0; //TXI1 128. #endif 129. RIIC.ICIER.BIT.TEIE = 1; //TEND 130. } 131. else if(RiicMstCnt == 0){ //First byte 132. #ifdef RIIC_CH0 133. ICU.IER [0x1F].BIT.IEN0 = 0; //TXI0 134. #else 135. ICU.IER [0x1F].BIT.IEN4 = 0; //TXI1 136. #endif 137. RIIC.ICIER.BIT.TEIE = 1; //TEND 139. RIIC.ICDRT = RiicTrmAddr; //Write slave address 140. } 141. else { //Transfer next data 142. if((RIIC.ICSR2.BIT.TEND == 1) && (RIIC.ICCR1.BIT.SCLI == 0)){ 143. for(cnt = RIIC_WAIT_VALUE; cnt != 0; cnt——); 144. } 145. RIIC.ICDRT = *RiicMstBuff; //Write next data 146. RiicMstBuff++; //Add pointer 147. } 149. RiicMstCnt++; //Add internal counter 150. } 151. void RiicTEND(void) 152. { 153. volatile unsigned long cnt; 154. if(RiicMstCnt >= RiicMstNum){ //After transfer all data CHAPTER 7 / SERIAL COMMUNICATIONS 291

155. if(RIIC.ICCR1.BIT.SCLI == 0){ // 156. for(cnt = RIIC_WAIT_VALUE; cnt != 0; cnt——); 157. } 158. RIIC.ICCR2.BIT.SP = 1; //Generate stop condition 159. return; 160. } 161. #ifdef RIIC_CH0 162. ICU.IER [0x1F].BIT.IEN0 = 1; //TXI0 163. #else 164. ICU.IER [0x1F].BIT.IEN4 = 1; //TXI1 165. #endif 166. RIIC.ICIER.BIT.TEIE = 0; //TEND 168. if(RIIC.ICCR1.BIT.SCLI == 0){ 169. for(cnt = RIIC_WAIT_VALUE; cnt != 0; cnt——); 170. } 171. RIIC.ICDRT = *RiicMstBuff; //Write first data 172. RiicMstBuff++; //Add pointer 173. RiicMstCnt++; //Add internal counter 174. } 175. void RiicSTOP(void){ 176. RIIC.ICSR2.BIT.STOP = 0; 177. RIIC.ICSR2.BIT.NACKF = 0; 179. #ifdef RIIC_CH0 180. ICU.IER [0x1F].BIT.IEN0 = 1; //TXI0 181. #else 182. ICU.IER [0x1F].BIT.IEN4 = 1; //TXI1 183. #endif 184. RIIC.ICIER.BIT.TEIE = 0; //TEND 185. } 186. void RiicNACK(void) 187. { 188. volatile unsigned long cnt; 189. #ifdef RIIC_CH0 190. ICU.IER [0x1F].BIT.IEN0 = 0; //TXI0 191. #else 192. ICU.IER [0x1F].BIT.IEN4 = 0; //TXI1 193. #endif 194. RIIC.ICIER.BIT.TEIE = 0; //TEND 196. if(RIIC.ICCR1.BIT.SCLI == 0){ 197. for(cnt = RIIC_WAIT_VALUE; cnt != 0; cnt——); 198. } 292 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

199. RIIC.ICCR2.BIT.SP = 1; //Generate stop condition 200. } 201. void RiicSTART(void){} 202. void RiicAL(void){} 203. void RiicTMO(void){}

Filename: vect.h

Add the following definition to vect.h to enable the working of the EEI0, RXI0, and TXI0 interrupts.

1. #pragma interrupt (Excep_RIIC0_EEI0(vect = 246)) 2. void Excep_RIIC0_EEI0(void); 3. #pragma interrupt (Excep_RIIC0_RXI0(vect = 247)) 4. void Excep_RIIC0_RXI0(void); 5. #pragma interrupt (Excep_RIIC0_TXI0(vect = 248)) 6. void Excep_RIIC0_TXI0(void);

Filename: riic_int.c:

This file contains the definitions of the interrupts and what they should do whenever they occur.

1. #include “..\iodefine_RX62N.h” 2. #include “..\vect.h” 3. #include “riic.h” 4. void RiicSTART(void); 5. void RiicAL(void); 6. void RiicNACK(void); 7. void RiicTMO(void); 8. void RiicSTOP(void); 9. void RiicRDRF(void); 10. void RiicTDRE(void); 11. void RiicTEND(void); 12. void Excep_RIIC0_EEI0(void){ 13. if((RIIC.ICIER.BIT.STIE != 0) && (RIIC.ICSR2.BIT.START != 0)){ 14. RiicSTART(); 15. } 16. if((RIIC.ICIER.BIT.NAKIE != 0) && 17. (RIIC.ICSR2.BIT.NACKF != 0)){ 18. RiicNACK(); CHAPTER 7 / SERIAL COMMUNICATIONS 293

19. } 20. if((RIIC.ICIER.BIT.ALIE != 0) && (RIIC.ICSR2.BIT.AL != 0)){ 21. RiicAL(); 22. } 23. if((RIIC.ICIER.BIT.TMOIE != 0) && (RIIC.ICSR2.BIT.TMOF != 0)){ 24. RiicTMO(); 25. } 26. if((RIIC.ICIER.BIT.SPIE != 0) && (RIIC.ICSR2.BIT.STOP != 0)){ 27. RiicSTOP(); 28. } 29. } 30. void Excep_RIIC0_RXI0(void){ 31. RiicRDRF(); 32. } 33. void Excep_RIIC0_TXI0(void){ 34. RiicTDRE(); 35. } 36. void Excep_RIIC0_TEI0(void){ 37. RiicTEND(); 38. } 39. void Excep_RIIC1_EEI1(void){ 40. if((RIIC.ICIER.BIT.STIE != 0) && (RIIC.ICSR2.BIT.START != 0)){ 41. RiicSTART(); 42. } 43. if((RIIC.ICIER.BIT.NAKIE != 0) && (RIIC.ICSR2.BIT.NACKF != 0)){ 44. RiicNACK(); 45. } 46. if((RIIC.ICIER.BIT.ALIE != 0) && (RIIC.ICSR2.BIT.AL != 0)){ 47. RiicAL(); 48. } 49. if((RIIC.ICIER.BIT.TMOIE != 0) && (RIIC.ICSR2.BIT.TMOF != 0)){ 50. RiicTMO(); 51. } 52. if((RIIC.ICIER.BIT.SPIE != 0) && (RIIC.ICSR2.BIT.STOP != 0)){ 53. RiicSTOP(); 54. } 55. } 56. void Excep_RIIC1_RXI1(void){ 57. RiicRDRF(); 58. } 294 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

59. void Excep_RIIC1_TXI1(void){ 60. RiicTDRE(); 61. } 62. void Excep_RIIC1_TEI1(void){ 63. RiicTEND(); 64. }

Filename: main.c

This is the main file responsible for setting up the RIIC module correctly.

1. #include “iodefine_RX62N.h” 2. #include “iic\riic.h” 3. #define SELF_ADDRESS 0x10 //Self address (bit0 = 0. (R/W bit)) 4. #define SLV_ADDRESS 0x3A //Slave address (bit0 = 0. (R/W bit)) 5. #define DATA_NUM (1 + 1) //Date number (“+1” means first byte(slave address)) 6. #define T_BUFF_SIZE (2) 7. #define R_BUFF_SIZE (7) 8. #define POWER_CTL_ADDR (0x2D) 9. #define POWER_CTL_VAL0 (0) 10. #define POWER_CTL_VAL1 (16) 11. #define POWER_CTL_VAL2 (8) 12. #define DATA_ADDRESS (0x32) 13. #define MST_WRITE 0x00 //Write bit (Don’t change) 14. #define MST_READ 0x01 //Read bit (Don’t change) 15. unsigned char MstTrmBuff [T_BUFF_SIZE]; //Buffer for transmission data 16. unsigned char MstRcvBuff [R_BUFF_SIZE] = {255}; //Buffer for reception data 17. void main(void) 18. { 19. unsigned long cnt,i; 20. unsigned char rtn; 21. SYSTEM.SCKCR.LONG = 0x00020100; //ICLK = 100 MHz, BCLK = 25 MHz, PCLK = 50 MHz (EXTAL = 12.5 MHz) 22. for(cnt = 0; cnt < T_BUFF_SIZE; cnt++){ 23. MstTrmBuff [cnt] = 0xFF; 24. MstRcvBuff [cnt] = 0xFF; 25. } CHAPTER 7 / SERIAL COMMUNICATIONS 295

26. MstTrmBuff [0] = POWER_CTL_ADDR; 27. MstTrmBuff [1] = POWER_CTL_VAL0; 28. RiicIni(SELF_ADDRESS, 1); //Initialise RIIC (Enable) 29. rtn = RiicStart(SLV_ADDRESS | MST_WRITE, MstTrmBuff, DATA_NUM + 1); 30. switch (rtn){ //Return value check 31. case RIIC_OK: //OK 32. break; 33. case RIIC_BUS_BUSY: //Bus busy 34. break; 35. case RIIC_NG: //Data number error 36. break; 37. default: //Internal error 38. while(1) 39. ; 40. } 41. while(RIIC.ICCR2.BIT.BBSY != 1) //Check Bus busy 42. ; 43. while(RIIC.ICCR2.BIT.BBSY != 0) //Check Bus free 44. ; 45. MstTrmBuff [1] = POWER_CTL_VAL1; 46. rtn = RiicStart(SLV_ADDRESS | MST_WRITE, MstTrmBuff, DATA_NUM+1); 47. switch (rtn){ //Return value check 48. case RIIC_OK: //OK 49. break; 50. case RIIC_BUS_BUSY: //Bus busy 51. break; 52. case RIIC_NG: //Data number error 53. break; 54. default: //Internal error 55. while(1) 56. ; 57. } 58. MstTrmBuff [1] = POWER_CTL_VAL2; 59. while(RIIC.ICCR2.BIT.BBSY != 1) //Check Bus busy 60. ; 61. while(RIIC.ICCR2.BIT.BBSY != 0) //Check Bus free 62. ; 63. MstTrmBuff [0] = DATA_ADDRESS; 296 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

64. rtn = RiicStart(SLV_ADDRESS | MST_WRITE, MstTrmBuff, DATA_NUM); 65. switch (rtn){ //Return value check 66. case RIIC_OK: //OK 67. break; 68. case RIIC_BUS_BUSY: //Bus busy 69. break; 70. case RIIC_NG: //Data number error 71. break; 72. default: //Internal error 73. while(1) 74. ; 75. } 76. while(RIIC.ICCR2.BIT.BBSY != 1) //Check Bus busy 77. ; 78. while(RIIC.ICCR2.BIT.BBSY != 0) //Check Bus free 79. ; 80. rtn = RiicStart(SLV_ADDRESS | MST_WRITE, MstTrmBuff, DATA_NUM); 81. switch (rtn){ //Return value check 82. case RIIC_OK: //OK 83. break; 84. case RIIC_BUS_BUSY: //Bus busy 85. break; 86. case RIIC_NG: //Data number error 87. break; 88. default: //Internal error 89. while(1) 90. ; 91. } 92. while(RIIC.ICCR2.BIT.BBSY != 1) //Check Bus busy 93. ; 94. while(RIIC.ICCR2.BIT.BBSY != 0) //Check Bus free 95. ; 96. rtn = RiicStart(SLV_ADDRESS | MST_READ, MstRcvBuff, DATA_NUM+6); 97. switch (rtn){ //Return value check 98. case RIIC_OK: //OK 99. break; 100. case RIIC_BUS_BUSY: //Bus busy CHAPTER 7 / SERIAL COMMUNICATIONS 297

101. break; 102. case RIIC_NG: //Data number error 103. break; 104. default: //Internal error 105. while(1) 106. ; 107. } 108. while(RIIC.ICCR2.BIT.BBSY != 1) //Check Bus busy 109. ; 110. while(RIIC.ICCR2.BIT.BBSY != 0) //Check Bus free 111. ; 112. RiicIni(0, 0); //Stop RIIC 113. while(1) 114. ; 115. }

7.6 RECAP

The Serial Communications Interface can act as a Smart Card Interface and as a Universal Synchronous/Asynchronous Receiver and Transmitter. The UART is one of the oldest, simplest, and most frequently used techniques for half duplex serial communication that uses three wires at the most for data transfer. The SCI2 interface is available on the YRDKRX62N development board via an RS- 232 level shifter. The Serial Peripheral Interface bus is a full duplex bus similar to the Universal Synchronous Receiver/Transmitter and is capable of data transfer at very high speeds. Each SPI device can act as either a master or a slave device. The master device is responsible for generating the clock cycles for synchronizing the data transfer. Slave Selection is always required prior to transfer of data on the SPI bus, other- wise data on the bus is void. Slave devices available aboard the YRDKRX62N on the SPI bus are the Graphical LCD module, Micro SD card interface, and the Micron/Numonyx Omneo P5Q Serial Flash Chip. I2C is a two wire interface capable of talking to up to 128 devices connected on the same bus. The I2C cycle consists of generation of a start condition, selecting a slave device, performing a data transfer, and sending a stop condition. 298 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Devices available with the YRDKRX62N board that are connected on the I2C bus are accelerometer: ADXL345 (slave address: 0x3A) and the temperature sensor ADT7240 (slave address: 0x90). The following table is a recap of Table 7.1 which summarizes the differences be- tween the three protocols.

SERIAL RENESAS SERIAL RENESAS INTER COMMUNICATION PERIPHERAL INTEGRATED INTERFACE INTERFACE CHIP BUS Modes USART/Smart Card Four wire/Three wire I2C mode or SM bus interface mode mode Max Transfer Speed 1.92 Mbps with Up to 25 Mbps Up to 1 Mbps PCLK @ 50 Mhz Max. number of 1 8 SPI integrated 127 devices/slaves channels for slave connected per bus selection Number of wires 2 to 3 3 to 4 2 required for communication (not including ground) Max. Length of wires 500 ft @ 9600 bps 10 feet with clock 10 meters @ speed of few kHz 100 kbps Number of bits per 7 or 8 Up to 32 bits 8 unit transfer (excluding start and stop) Slave Selection Adressed during Using slave select line Through addressing method communication when in multiprocessor communication mode, else not available. CHAPTER 7 / SERIAL COMMUNICATIONS 299

7.7 REFERENCES

Analog Devices, Inc. 0.25°C Accurate, 16-Bit Digital I2C Temperature Sensor, ADT7420 information and datasheet. Norwood, MA: Analog Devices, Inc. 2011. Electronic publication. Accessed at http://www.analog.com/en/mems- sensors/digital- temperature- sensors/adt7420/products/product.html Analog Devices, Inc. ADXL345 datasheet: 3-Axis, 2 g/4 g/8 g/16 g Digital Accelerometer, ADXL345. Norwood, MA: Analog Devices, Inc. 2009–2011. Electronic publication. Accessed at http://www.analog.com/static/imported- files/data_sheets/ADXL345.pdf Becke, G., Borgert, C., Corrigan, S., Dehmelt, F., Feulner, M., Gonzalez, C., Groenebaum, M., Kabir, F., Kacprzak, A., Kinnaird, C., and Zipperer, J. Comparing Bus Solutions; High- Performance Linear/Inter- face: An Application Report. Texas Instruments. Revised February 2004. Electronic publication. Accessed at http://www.lammertbies.nl/download/ti- appl- slla067a.pdf Electronic Industries Association, “EIA Standard RS- 232-C Interface Between Data Terminal Equipment and Data Communication Equipment Employing Serial Data Interchange,” August 1969. Reprinted in Telebyte Technology Data Communication Library, Greenlawn, NY, 1985. Print. Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print. Hwang, Enoch. Digital Logic and Microprocessor Design with VHDL. Thomson. ISBN 0–534–46593–5. 2006. Electronic Publication. Accessed at http://faculty.lasierra.edu/ϳehwang/digitaldesign Soltero, M., Zhang, J. and Cockril, C. Revised by Kevin Zhang, Clark Kinnaird, and Thomas Kugelstadt, 2010. RS- 422 and RS- 485 Standards Overview and System Configurations, Application Report, SLLA070D. Texas Instruments, Revised May 2010. Electronic publication. Accessed at http://focus.ti.com/lit/an/slla070d/slla070d.pdf

7.8 EXERCISES

1. Write a program to setup the Renesas serial communication interface to operate in the UART mode functioning at 9600 baud, odd parity, 2 Stop bits to transmit 8 bits of data with the LSB first. 2. Write a program to set up the Renesas Serial Peripheral Interface to transfer and receive 32 bit and 16 bit long data alternately as a single unit at 5 Mbps, with par- ity enabled in clock synchronous mode. The RSPI should function only as a master. 3. Write a program to maintain queues for multiprocessor communication using the Renesas Serial Peripheral Interface so as to perform data transfer between one master device and two slave devices. Mention algorithms for both. (Hint: Main- tain six queues; two for each microcontroller). 4. Write a program to communicate with and to continuously obtain the values of the X, Y, and Z axis of the onboard ADXL345 accelerometer at 100 kbps. 300 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

5. Write a program to interface two microcontrollers that are monitoring tempera- tures and exchanging the observed temperature as strings with each other. Each board should display the observed temperature of itself and the other board on the graphical/character LCD. (Hint: Use FIFO type data structures). Chapter Eight

Event Counters, Timers, and the Real Time Clock

8.1 LEARNING OBJECTIVES

In this chapter we show how timers work as event counters, as well as go into more ad- vanced features. It is possible to cascade timers together when one timer does not provide the range needed. Using timers it is also possible to output a square wave with a control- lable frequency and duty cycle. Additionally, the RX62N includes a Real Time Clock pe- ripheral that can keep track of the current date and time. In this chapter we will cover the concepts behind these features and how to use them.

8.2 BASIC CONCEPTS

8.2.1 Timer and Event Counter

Timer A timer in a microcontroller is a counter whose value can be read and written as a special- function register. When the timer is started, the value in the register increases or decreases each time it is clocked, and the rate at which the value changes is based upon the clock source provided to it. If the clock source for the timer is 10 MHz, then one count (incre- ment or decrement) of the register would be equal to 0.1 ms. The timers may have a bit length of 8-bit (0–255), 16-bit (0–65535) and 32-bit (0–4294967295). For an 8-bit timer with a clock source of 10 MHz, the maximum time a timer can count depends on the max- imum value a timer count register can hold; i.e., the maximum value in an 8-bit register is 255 (FFh). Therefore the maximum time for an 8-bit timer count is:

255 ϭ 255 * 0.1 msec ϭ 25.5 msec 10 MHz

Therefore, with an 8-bit timer you can mea sure a maximum of 25.5 ms, but what if you want to measure 100 ms with an 8-bit register? Should we count four times through an 8-bit timer? The answer is no. For this purpose the microcontroller has a prescaler, which

301 302 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

is used to divide the external or internal clock source by a fixed integer. This increases the amount of time a timer can count without adding much hardware. The general division factor for the prescaler would be multiples of two. For example, if we have a division fac- tor of thirty- two, then the maximum amount of time a timer can count with a 10 MHz clock source is:

255 32 ϭ 255 * msec ϭ 816 msec 10 MHz a 10b 32

As a result, the maximum amount of time a timer can count increases as the prescaler divi- sion factor increases. A timer can also be used as an event counter. The function of the event counter is the same as the counter, but the event counter counts external events (indicated by signal transitions on an input pin or on overflows of another timer). For example, an event counter can be set up in a place where you need to automatically keep track of the number of people entering a building using a particular entrance. A person passing the entrance is tracked using an infrared sensor. The sensor is set up such that a person en- tering the building breaks an infrared light beam directed at the sensor, which changes its output from high to low as long as the beam is broken. The event counter can be set up to increment on the high to low transition of the sensor output, and in the end the count would give us the amount of people who entered the building using a selected en- trance. We can also use the event counter to calculate the time intervals between two events.

Event Counter The RX62N/RX621 group has two units (Unit 0, Unit 1) of 8-bit timers/counters. The 8-bit timer can be used in different operating modes: timer mode, event counter mode, and pulse output mode. The timer mode can also be used to generate interrupts at particular intervals, and two timers can be cascaded to use a 16-bit timer. In this chapter we cover the basic concepts of an event counter mode. The timer units can also generate a baud rate clock, which can be used for serial communication. Table 8.1 shows the functionality available from the timers. The event counter of RX62N microcontroller is used detect the overflow of the timer. After detecting the overflow, another timer can be made to start counting. For example, the TMR0 (TMR2) can be made to start counting once the TMR1 overflows (TMR3). This fea- ture is mainly used to cascade two timers. The overflow function can be used by setting the CSS [1Ϻ0] bits in TCCR to a value of three. (The description of timer registers can be found in Chapter 10.) CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 303

TABLE 8.1 Specification of Timers.

ITEM DESCRIPTION Count clock Ⅲ Internal clock: PCLK, PCLK/2, PCLK/8, PCLK/32, PCLK/64, PCLK/1024, PCLK/8192 Ⅲ External clock Number of channels 8 bits ϫ 4 channels (16 bits ϫ 2 channels) Compare match Ⅲ 8-bit mode (compare match A, compare match B) Ⅲ 16-bit mode (compare match A, compare match B) Counter clear Selected by compare match A or B, or an external reset signal. Timer output Output pulses with a desired duty cycle or PWM output Cascading of two channels Ⅲ 16-bit count mode 16-bit timer using TMR0 for the upper 8 bits and TMR1 for the lower 8 bits (TMR2 for the upper 8 bits and TMR3 for the lower 8 bits) Ⅲ Compare match count mode TMR1 can be used to count TMR0 compare matches (TMR3 can be used to count TMR2 compare matches). Interrupt sources Compare match A, compare match B, and overflow DTC activation DTC can be activated by compare match A interrupts or compare match B interrupts. Generation of trigger to start Compare match A of TMR0 and TMR2*1 A/D converted conversion Capable of generating baud rate Generates baud rate clock for SCI5 and SCI6.*2 clock for SCI Low power consumption facilities Each unit can be placed in a module stop state.

Source: Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010, page 20–1.

The RX62N has a TMR timer peripheral which provides two 8-bit timer units (Units 1 and 0), each comprising two counter channels. Each timer can be used as an inde - pendent timer, to count an external event, or as a pulse output device. The timer works by incrementing a register each time there is a ‘count’ within the device. The count is either triggered by a pulse from the internal peripheral clock, a scaled version of the clock, or an external count source. When this count overflows from its maximum value to zero and/or 304 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Internal clock PCLK PCLK/2 PCLK/8 PCLK/32 PCLK/64 PCLK/1024 PCLK/8192

Counter clock 1 TMCI0 Counter clock 0 Clock select TMCI1 TCORA TCORA

Compare match A1 Compare match A0 Comparator A0 Comparator A1

TO SCI5 Overflow 1 TMO0 Overflow 0 TCNT TCNT TMO1 Counter clear 0 Counter clear 1 Compare match B1 Compare match B0 Comparator B0 Comparator B1 Control logic TMRI0 Internal bus TMRI1 TCORB TCORB

A/D conversion TCSR TCSR strat request signal*

TCR TCR

TCCR TCCR

Channel 0 Channel 1 CMIA0 (TMR0) (TMR1) CMIA1 CMIB0 CMIB1 OVI0 OVI1 Interrupt signal

[Legend] TCORA: Time constant register A TCSR: Timer control/status register TCNT: Timer counter TCR: Timer control register TCORB: Time constant register B TCCR: Timer counter control register

Note: * Fore the corresponding A/D converter channels, see section 33, 12-Bit A/D Converter (S12AD), and section 34, 10-Bit A/SD Converter (ADa).

Figure 8.1 Block diagram of timer unit 0. Source: Hardware Manual, page 1110. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 305

there is a compare match with one of the timer constant registers; an action is performed, such as toggling an output signal, or an interrupt is triggered. Before covering how the timer works more specifically we will briefly describe the 8-bit timer device’s registers and how they work. Figure 8.1 is a block diagram of timer unit 0; Unit 1 is identical except for naming dif- ferences (e.g., Timer2 in place of Timer0, and Timer3 in place of Timer1). Do not feel like you need to understand this entire diagram right away, we will cover the individual parts as we go along and by the end of this chapter it should all seem very simple. We will start by first covering the registers that are used when setting up a timer channel. The legend in the bottom left of Figure 8.1 lists the registers you need to consider when setting up the 8-bit timer unit. For some registers we have an illustration included of the registers contents taken from the RX62N Hardware Manual. Make note of the register parts, as we will use these later when setting them up for specific features. Further details are available in the hardware manual if needed. The TCNT (Timer Count) register holds the current timer value at any time after the timer has been configured. Whenever you want to know the value of the timer or counter you will read the value in this register. Also, when not currently operating the timer, you can load a value into this register and the timer will begin counting from that value when restarted. Note in Figure 8.2 that in the 16-bit mode TMR0.TCNT and TMR1.TCNT (TMR2.TCNT and TMR3.TCNT as well) cascade into one 16-bit register. This holds true for the timer constant registers as well.

Address: TMR0.TCNT 0008 8208h, TMR1.TCNT 0008 8209h TMR2.TCNT 0008 8218h, TMR3.TCNT 0008 8219h

TMR0.TCNT (TMR2.TCNT) TMR1.TCNT (TMR3.TCNT)

b7 b6 b5 b4 b3 b2 b1 b0 b7 b6 b5 b4 b3 b2 b1 b0

Value after reset: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Figure 8.2 TCNT (Timer Count) register. Source: Hardware Manual.

The TCNT register is where the count is held. After the timer is started this register will in- crement every time a count is detected. If you want to know the current count, you can read this register. If the timer is stopped you can write a value to this register and it will begin counting from the written value when re- started. 306 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Timer Control Register (TCR)

Address: TMR0.TCR 0008 8200h, TMR1.TRC 0008 8201h TMR2.TCR 0008 8210h, TMR3.TCR 0008 8211h

b7 b6 b5 b4 b3 b2 b1 b0

CMIEB CMIEA OVIE CCLR[1:0] — — —

Value after reset: 0 0 0 0 0 0 0 0

BIT SYMBOL BIT NAME DESCRIPTION R/W b2 to b0 — (Reserved) This bit is read as 0. The write value R/W should always be 0. b4, b3 CCLR[1:0] Counter Clear* b4 b3 R/W 0 0: Clearing is disabled 0 1: Cleared by compare match A 1 0: Cleared by compare match B 1 1: Cleared by the external reset input (Select edge or level by the TMRIS bit in TCCR.) b5 OVIE Timer Overflow Interupt 0: Overflow interrupt requests R/W (OVIn) are disabled Enable 1: Overflow interrupt requests (OVIn) are ensabled b6 CMIEA Compare Match Interrupt 0: Compare match A interrupt R/W requests (CMIAn) are disabled Enable A 1: Compare match A interrupt requests (CMIAn) are enabled b7 CMIEB Compare Match Interrupt 0: Compare match B interrupt R/W requests (CMIBn) are disabled Enable B 1: Compare match B interrupt requests (CMIBn) are enabled

Note: * To use an external reset, set the Pn.DDR.Bi bit for the corresponding pin “0” and the Pn.ICR.Bi bit to “1”.

Figure 8.3 TCR (Timer Control Register) description. Source: Hardware Manual, Section 20.2.4. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 307

The TCCR controls where the timers count source comes from. Depending what value is set here will determine if the count comes from the internal peripheral clock, a pre- scaled pe- ripheral clock, an external count source, or from another timer overflowing. This register also enables the timer’s interrupts on the peripheral level. Keep in mind you must also enable to interrupts in the ICU (Interrupt Controls Unit) in order for an interrupt routine to be called.

Timer Counter Control Register (TCCR)

Address: TMR0.TCCR 0008 820Ah, TMR1.TCCR 0008 820Bh TMR2.TCCR 0008 821Ah, TMR3.TCCR 0008 821Bh

b7 b6 b5 b4 b3 b2 b1 b0

TMRIS — — CSS[1:0] CKS[2:0]

Value after reset: 0 0 0 0 0 0 0 0

BIT SYMBOL BIT NAME DESCRIPTION R/W b2 to b0 CKS[2Ϻ0] Clock Select* See table 20.5. R/W b4, b3 CSS[1Ϻ0] Clock Source Select See table 20.5. R/W b6, b5 — (Reserved) These bits are always read as 0. The write R/W value should always be 0. b7 TMRIS Timer Reset Input 0: Cleared at rising edge of the external reset R/W Select 1: Cleared when the external reset is high

Note: * To use an external clock, set the Pn.DDR.Bi bit for the corresponding pin to “0” and the PnICR.Bi bit to “1”. For details, see section 16, I/O Ports.

Figure 8.4 TCCR (Timer Counter Control Register) description. Source: Hardware Manual, Section 20.2.5.

The TCORA (Timer Constant Register A) and TCORB (Timer Constant Register B) are used to store constants to compare against the TCNT register. Every time the TCNT incre- ments it is constantly being compared against either of these registers. When TCNT matches either of these registers, a compare match event occurs. Compare match events have many uses depending on what mode we are using the timer in. The TCSR (Timer Control Status) register controls compare match output. Each timer has an output port assigned to it which is controlled via compare match events. This is one of many uses of the compare match events. When a compare match event occurs this register can set the output of the timer’s port to 1 or 0, or toggle it. This register is used when we want the timer to control a pulse output. 308 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TCCR REGISTER CSS[1Ϻ0] CKS[2Ϻ0] CHANNEL b4 b3 b2 b1 b0 DESCRIPTION TMR0 0 0 — 0 0 Clock input prohibited (TMR2) 1 Uses external clock. Counts at rising edge*1. 1 0 Uses external clock. Counts at falling edge*1. 1 Uses external clock. Counts at both rising and falling edges*1. 0 1 0 0 0 Uses internal clock. Counts at PCLK. 1 Uses internal clock. Counts at PCLK/2. 1 0 Uses internal clock. Counts at PCLK/8. 1 Uses internal clock. Counts at PCLK/32. 1 0 0 Uses internal clock. Counts at PCLK/64. 1 Uses internal clock. Counts at PCLK/1024. 1 0 Uses internal clock. Counts at PCLK/8192. 1 Clock input prohibited 1 0 — — — Setting prohibited 1 1 — — — Counts at TMR1.TCNT (TMR3.TCNT) overflow signal*2 TMR1 0 0 — 0 0 Clock input prohibited (TMR3) 1 Uses external clock. Counts at rising edge*1. 1 0 Uses external clock. Counts at falling edge*1. 1 Uses external clock. Counts at both rising and falling edges*1. 0 1 0 0 0 Uses internal clock. Counts at PCLK. 1 Uses internal clock. Counts at PCLK/2. 1 0 Uses internal clock. Counts at PCLK/8. 1 Uses internal clock. Counts at PCLK/32. 1 0 0 Uses internal clock. Counts at PCLK/64. 1 Uses internal clock. Counts at PCLK/1024. 1 0 Uses internal clock. Counts at PCLK/8192. 1 Clock input prohibited 1 0 — — — Setting prohibited 1 1 — — — Counts at TMR0.TCNT (TMR2.TCNT) overflow signal*2 Notes: 1. To use an external clock, set the Pn.DDR.BI bit for the corresponding pin to “0” and the Pn.ICR.BI bit to “1”. For details, see section 16, I/O Ports. 2. If the clock input of TMR0 (TMR2) is the overflow signal of the TMR1.TCNT (TMR3.TCNT) counter and that of TMR1 (TMR3) is the compare match signal of the TMR0.TCNT (TMR2.TCNT) counter, no incrementing clock is generated. Do not use this setting.

Figure 8.5 Clock input to TCNT and count condition. Source: Hardware Manual, Table 20.5. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 309

Timer Counter/Status Register (TCSR)

Address: TMR0.TCSR 0008 8202h, TMR2.TCSR 0008 8212h

b7 b6 b5 b4 b3 b2 b1 b0

— — — ADTE OSB[1:0] OSA[1:0]

Value after reset: x x x 0 0 0 0 0

Address: TMR1.TCSR 0008 8203h, TMR3.TCSR 0008 8213h

b7 b6 b5 b4 b3 b2 b1 b0

— — — — OSB[1:0] OSA[1:0]

Value after reset: x x x 1 0 0 0 0 TMR0, TCSR, TMR2 [Legend] x: Undefined

BIT SYMBOL BIT NAME DESCRIPTION R/W b1, b0 OSA[1Ϻ0] Output b1 b0 R/W 1 Select A* 0 0: No change when compare match A occurs 0 1: 0 is output when compare match A occurs 1 0: 1 is output when compare match A occurs 1 1: Output is inverted when compare match A occurs (toggle output) b3, b2 OSB[1Ϻ0] Output b3 b2 R/W 1 Select B* 0 0: No change when compare match B occurs 0 1: 0 is output when compare match B occurs 1 0: 1 is output when compare match B occurs 1 1: Output is inverted when compare match B occurs (toggle output) b4 ADTE A/D Trigger 0: A/D converter start requests by compare R/W Enable*2 match A are disabled 1: A/D converter start requests by compare match A are enabled b7 to b5 — (Reserved) These bits are always read as an indefinite R/W value. The write value should always be 1. Notes: 1. Timer output is disabled when the OSB[1Ϻ0] and OSA[1Ϻ0] bits are all 0. Timer output is 0 until the first compare match occurs after a reset. 2. For the corresponding A/D converter channels, see section 34, A/D Converter.

Figure 8.6 TCSR (Timer Control/Status Register) description. Source: Hardware Manual, Section 20.2.6. 310 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

That is a basic overview of the registers and what they do. Now that we know a bit about how the timer works we can start going into how we modify these registers to get the timer to go into its different modes of operation.

8.2.2 Cascading Timers

Sometimes when using a timer for an application you need a delay longer than is allowed when only using 8-bits. The RX62N allows both timer channels in either time unit to be cascaded into one 16-bit channel. Essentially every time the first timer overflows, the next timer will count. This multiplies the total time able to be counted by a factor of 28 (256). Originally we could only count from 0 to 255, now we can count to 65535. So how do we calculate how long it will take for the timer to count to 0xFFFF (our max value)? First we consider the RX62N’s main clock which is 24 MHz. This means every clock tick takes approximately 41.57 nanoseconds. We multiply by what division of the pe- ripheral clock we are using, say 64, because the period for that clock is 64 times as long. Then we multiply by the number of ticks which is 0xFFFF or 65535. So when using PCLK/64 and a 16-bit counter, there will be approximately 174.76 ms between each over- flow interrupt.

1 64 (clock division) 65535 (counts per interrupt) * * ϭ 174.76 ms. 24 MHz (peripheral clock) 1 1

Table 8.2 lists the approximate time between interrupts for each clock division.

TABLE 8.2 Clock Division and Interrupt Times.

TIME BETWEEN OVERFLOW INTERRUPTS CLOCK DIVISION TIMER PER COUNT IN 16-BIT MODE PLCK 41.67 ns 2.73 ms PLCK/2 83.33 ns 5.41 ms PCLK/8 333.33 ns 21.84 ms PCLK/32 1.33 ms 87.38 ms PCLK/64 2.67 ms 174.76 ms PCLK/1024 42.67 ms 2.79 s PCLK/8192 341.333 ms 22.37 s CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 311

NOTE: It is possible in hardware setup to alter the speed of the PCLK, make sure to take note of this and alter your calculations accordingly. A basic HEW setup with no alterations will still have a PCLK of 24 MHz.

To set up a timer unit in 16-bit cascaded timer mode, set the bits in TMR0.TCCR.CSS[1Ϻ0] to 11b. This effectively sets the count source for Timer0 as Timer1. Whenever TCNT in Timer1 overflows, Timer0 will count once. In effect, this makes TMR0.TCNT and TMR1.TCNT combine into a single 16-bit register. The speed at which Timer1 can count is still determined in TMR1.TCCR.CSS and TMR1.TCCR.CKS. The settings for clearing the counter and interrupts are now controlled by the TMR0.TCR register; any settings in TMR1.TCR are ignored. We have just covered how to cascade two 8-bit timer units to make one 16-bit timer. In the examples section we will give an example of how to set up a cascaded timer and an ex- ample of its usage.

8.2.3 Pulse Output Operation

Before covering how the RX62N 8-bit timer peripheral handles pulse outputs, we’ll do a brief overview of pulse- width modulation concepts. There are three aspects of a wave we will concern ourselves with when dealing with pulse output operation: the period, fre- quency, and duty cycle. Any wave is basically a repeating pattern in output over time, such as a sine wave, square wave, or sawtooth wave. The period of the wave is defined as the time between repeats in the simplest form of the wave’s pattern. In the case of a square wave, the period is the time between the rising edges of the positive output portion. The frequency is determined by how many periods there are of a wave in a second. We Number of Periods can determine frequency by the formula f ϭ , yielding a value in Herz Length of Time (Hz, periods/second). If we want to determine the period using the frequency we use the 1 formula T (period) ϭ . Duty cycle is defined as the percentage of the period during f(Hz) Time High which the waveform is high. Duty cycle can be determined by the formula ϫ 100%. T (period) Using the 8-bit timer peripheral we can output a square wave where the frequency and duty cycle are controlled by changing values in the registers we have already covered. 312 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

1.5 Voltage

Period 2 ms 1 Duty Cycle 1.75 ms 87.5%

0.5

0

Ϫ0.5 0 246 81Time 0 Figure 8.7 Pulse-width modulation signal attributes.

Pulse output mode is handy in applications such as interfacing the microcontroller to sev- eral types of motors. A servo motor usually uses a square wave input to determine the po- sition or speed of the motor. Varying the duty cycle will vary the speed or position. When interfacing to a DC motor, the microcontroller almost always lacks the power output to drive the motor. A power amplifier must be used, most often an H- bridge. The H- bridge will take a square wave signal from the microcontroller and amplify it to whatever voltage and current levels are needed for the application. By varying the duty cycle of the wave we vary the average power that is delivered to the motor, making an efficient means of digi- tally controlling an analog device. Now we will go over how to set up the RX62N in pulse output mode. First in pulse out- put mode, TCR.CCLR[1Ϻ0] is set to 01b. This will make TCNT clear to 0x00 every time a compare match A occurs. Now we set TCSR.OSA[1Ϻ0] to 10b and TCSR.OSB[0Ϻ1] to 01b. This will make the output from the timer channel change to 1 at the occurrence of compare match A and change back to 0 at the occurrence of compare match B. Here is a brief overview of what happens on a single timer channel when set up in pulse output mode. TCNT begins to count up. Once it reaches the value of timer constant register A the first time, the pulse output becomes 1 and TCNT resets to 00h. TCNT restarts counting and upon reaching the value of timer constant register B, the output goes CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 313

to 0. TCNT continues to count until it reaches the value of timer constant register A again. TCNT now resets to 00h again and the output goes back to 0. This process repeats, pro- ducing a square wave on the TCOn port (n being the number of the timer used). This is il- lustrated in Figure 8.8, TMOn being the waveform of the output pulse.

TCNT FFh Counter clear TCORA

TCORB

00h

TMOn

(n ϭ 0 to 3)

Figure 8.8 An example of pulse output. Source: Hardware Manual, Figure 20.3.

By altering the value of TCORA we change the frequency of the pulse output, and by al- tering TCORB without altering TCORA we alter the duty cycle of the wave. Take note that by altering TCORA without altering TCORB the duty cycle does not remain the same be- cause the output is going low at the same amount of time after TCNT resets, but the time between when the pulse goes low and a compare match A occurrence has become longer. We have just covered a basic overview of concepts to do with pulse output and how to control it on the RX62N. In the examples section we will show and explain a basic exam- ple of how to set up pulse output from one of the timer units.

8.3 REAL TIME CLOCK

The Real Time Clock is a separate unit unto itself. Without an indepen dent Real Time Clock unit it would be necessary to cascade timers, set up variables, and use interrupt routines to track the time. Another advantage to a separate unit is that it takes less energy to keep run- ning in low power modes. This unit makes keeping track of time much easier by keeping a separate binary coded decimal register for the years, months, date, day of the week, hours, minutes, and seconds. The unit also automatically tracks leap years. Using the Real Time Clock is as simple as setting the values for the date then setting it to start counting. The clock keeps count via a dedicated 32.768 KHz count source and outputs a 1 Hz clock. 314 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

8.3.1 RTC Registers

We will now cover all of the registers in the RTC and their functions.

64-Hz Counter (R64CNT)

Address: 0008 C400h

b7 b6 b5 b4 b3 b2 b1 b0

— F1HZ F2HZ F4HZ F8HZ F16HZ F32HZ F64HZ

Value after reset: 0 x x x x x x x [Legend] x: Undefined

BIT SYMBOL BIT NAME DESCRIPTION R/W b0 F64HZ 64 Hz Indicate the state between 64 Hz and 1 Hz. R b1 F32HZ 32 Hz R b2 F16HZ 16 Hz R b3 F8HZ 8 Hz R b4 F4HZ 4 Hz R b5 F2HZ 2 Hz R b6 F1HZ 1 Hz R b7 — (Reserved) This bit is always read as 0 and cannot be modified. R

Figure 8.9 R64CNT (64 Hz Counter). Source: Hardware Manual, Section 22.2.1.

The second counter uses the 64 Hz counter (R64CNT) as its count source. This register can be read to determine time in the sub- seconds range. RSECCNT is where the current count in seconds is read/written. Once the value is above fifty- nine it will reset to zero and the minute counter will increment. The RMINCNT register is where the current value of the minutes is read/written. This counter behaves just like the second counter in that the hour counter will increment once it counts past fifty- nine and the minute counter will reset. The RHRCNT register is where the current value in hours is read/written. The register counts from zero to twenty- three, then resets. When it resets, the day counter and day of the week counter are incremented. RWKCNT holds the value of the current day of the week. It counts from zero to six, then resets. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 315

Second Counter (RSECCNT)

Address: 0008 C402h

b7 b6 b5 b4 b3 b2 b1 b0

— SEC10[2:0] SEC1[3:0]

Value after reset: 0 x x x x x x x

BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 SEC1[3Ϻ0] Ones Place of Seconds Counts from 0 to 9 once per second. R/W When a carry is generated, 1 is added to the tens place. b6 to b4 SEC10[2Ϻ0] Tens Place of Seconds Counts from 0 to 5 for 60-second R/W counting. b7 — (Reserved) This bit is always read as 0. The write R/W value should always be 0.

Figure 8.10 RSECCNT (Second Counter). Source: Hardware Manual, Section 22.2.2.

Minute Counter (RMINCNT)

Address: 0008 C404h b7 b6 b5 b4 b3 b2 b1 b0

— MIN10[2:0] MIN1[3:0]

Value after reset: 0 x x x x x x x

[Legend] x: Undefined

BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 MIN1[3Ϻ0] Tens Place of Minutes Counts from 0 to 9 once per minute. R/W When a carry is generated, 1 is added to the tens place. b6 to b4 MIN10[2Ϻ0] Ones Place of Minutes Counts from 0 to 5 for 60-minute R/W counting. b7 — (Reserved) This bit is always read as 0. The write R/W value should always be 0.

Figure 8.11 RMINCNT (Minute Counter). Source: Hardware Manual, Section 22.2.3. 316 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Hour Counter (RHRCNT) Address: 0008 C406h

b7 b6 b5 b4 b3 b2 b1 b0

— — HOUR10[1:0] HOUR1[3:0]

Value after reset: 0 0 x x x x x x [Legend] x: Undefined BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 HOUR1[3Ϻ0] Ones Place of Hours Counts from 0 to 9 once per hour. R/W When a carry is generated, 1 is added to the tens place. b5, b4 HOUR10[1Ϻ0] Tens Place of Hours Counts from 0 to 2 once per carry from R/W the ones place. b7, b6 — (Reserved) These bits are always read as 0. The R/W write value should always be 0.

Figure 8.12 RHRCNT (Hour Counter). Source: Hardware Manual, Section 22.2.4.

Day-of-Week Counter (RWKCNT) Address: 0008 C408h b7 b6 b5 b4 b3 b2 b1 b0

— — — — — DAY[2:0]

Value after reset: 0 0 0 0 0 x x x [Legend] x: Undefined

BIT SYMBOL BIT NAME DESCRIPTION R/W b2 to b0 DAY[2Ϻ0] Day- of- Week 000: Sunday R/W Counting 001: Monday 010: Tuesday 011: Wednesday 100: Thursday 101: Friday 110: Saturday 111: (Setting Prohibited) b7 to b3 — (Reserved) These bits are always read as 0. The write value R/W should always be 0.

Figure 8.13 RWKCNT (Day-of- Week Counter). Source: Hardware Manual, Section 22.2.5. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 317

Date Counter (RDAYCNT) Address: 0008 C40Ah

b7 b6 b5 b4 b3 b2 b1 b0

— — DAY10[1:0] DAY1[3:0]

Value after reset: 0 0 x x x x x x [Legend] x: Undefined

BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 DAY1[3Ϻ0] Ones Place of Days Counts from 0 to 9 once per day. When a R/W carry is generated, 1 is added to the tens place. b5, b4 DAY10[1Ϻ0] Tens Place of Days Counts from 0 to 3 once per carry from R/W the ones place. b7, b6 — (Reserved) These bits are always read as 0. The write R/W value should always be 0.

Figure 8.14 RDAYCNT (Date Counter). Source: Hardware Manual, Section 22.2.6.

RDAYCNT holds the current value of the day of the month. The counter automatically accounts for the number of specifiable days in a month and leap years. When the count goes above the days of the current month it resets to zero and the month counter is incremented. RMONCNT holds the value for the current month. It counts from one to twelve, and then resets. When it resets to zero, the year counter is incremented. The RYRCNT register holds the current count of the years from zero to 9999. For each counter register besides the 64 Hz Counter (R64CNT), there is a correspon- ding alarm register. Each of these is written to the same as the corresponding count regis- ter, other than the unused bit 7 which is now an enable bit; except in the case of the year alarm register which uses an entire word (it has a separate enable register named RYAREN). Whenever the values in each of the counters match the alarm registers with the enable bits set, the Real Time Clock alarm interrupt is triggered. Take note that writing the decimal value of the number you want to input to these reg- isters will not be input as the value you want. This is because the registers are not read as an 8-bit decimal value, but are instead split so that each 4-bit span is a binary encoded dec- imal digit. As a review of basic concepts of base 2 (binary) and base 16 (hexadecimal) numbers you will remember that a hexadecimal number can be used as shorthand for 4 bits of a binary number. As an example the hexadecimal 0x45 is equivalent to the binary 318 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Month Counter (RMONCNT) Address: 0008 C40Ch

b7 b6 b5 b4 b3 b2 b1 b0

— — — MON10 MON1[3:0]

Value after reset: 0 0 0 x x x x x [Legend] x: Undefined

BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 MON1[3Ϻ0] Ones Place Counts from 0 to 9 once per month. When a carry R/W of Months is generated, 1 is added to the tens place. b4 MON10 Tens Place Counts from 0 to 1 once per carry from the ones R/W of Months place. b7 to b5 — (Reserved) These bits are always read as 0. The write value R/W should always be 0.

Figure 8.15 RMONCNT (Month Counter). Source: Hardware Manual, Section 22.2.7.

Year Counter (RYRCNT) Address: 0008 C40Eh

b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0

YEAR1000[3:0] YEAR100[3:0] YEAR10[3:0] YEAR1[3:0]

Value after reset: x x x x x x x x x x x x x x x x [Legend] x: Undefined

BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 YEAR1[3Ϻ0] Ones Place Counts from 0 to 9 once per year. R/W of Years When a carry is generated, 1 is added to the tens place. b7 to b4 YEAR10[3Ϻ0] Tens Place Counts from 0 to 9 once per carry R/W of Years from ones place. When a carry is generated in the tens place, 1 is added to the hundreds place. b11 to b8 YEAR100[3Ϻ0] Hundreds Place Counts from 0 to 9 once per carry R/W of Years from tens place. When a carry is generated in the hundreds place, 1 is added to the thousands place. b15 to b12 YEAR1000[3Ϻ0] Thousands Place Counts from 0 to 9 once per carry R/W of Years from hundreds place.

Figure 8.16 RYRCNT (Year Counter). Source: Hardware Manual, Section 22.2.8. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 319

RTC Counter Register 1 (RCR1) Address: 0008 C422h

b7 b6 b5 b4 b3 b2 b1 b0

— PES[2:0] — PIE CIE AIE

Value after reset: 0 0 0 0 0 0 0 0

BIT SYMBOL BIT NAME DESCRIPTION R/W b0 AIE Alarm 0: An alarm interrupt is not requested R/W Interrupt 1: An alarm interrupt is requested Enable b1 CIE Carry 0: A carry interrupt is not requested when a carry to the R/W Interrupt second counter occurred or a carry to the 64-Hz Enable counter occurred during react access to the 64-Hz counter. 1: A carry interrupt is requested when a carry to the second counter occurred or a carry to the 64-Hz counter occurred during read access to the 64-Hz counter. b2 PIE Periodic 0: A periodic interrupt is not requested. R/W Interrupt 1: A periodic interrupt is requested. Enable b3 — (Reserved) This bit is always read as 0. The write value should R/W always be 0. b6 to b4 PES[2Ϻ0] Periodic 000: No periodic interrupts generated R/W

Interrupt 1 001: A periodic interrupt generated every ⁄256 second Select 1 010: A periodic interrupt generated every ⁄64 second

1 011: A periodic interrupt generated every ⁄16 second

1 100: A periodic interrupt generated every ⁄4 second

1 101: A periodic interrupt generated every ⁄2 second 110: A periodic interrupt generated every 1 second 111: A periodic interrupt generated every 2 seconds b7 — (Reserved) This bit is always read as 0. The write value should R/W always be 0.

Figure 8.17 RCR1 (RTC Control Register). Source: Hardware Manual, Section 22.2.17. 320 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

RTC Counter Register 2 (RCR2) Address: 0008 C424h

b7 b6 b5 b4 b3 b2 b1 b0

— — — — RTOOE ADJ RESET START

Value after reset: 0 0 0 0 0 0 0 1

BIT SYMBOL BIT NAME DESCRIPTION R/W b0 START Start 0: Year, month, day-of- week, date, hour, R/W minute, second, and 64-Hz counters, and prescaler are stopped. 1: Year, month, day-of- week, date, hour, R/W minute, second, and 64-Hz counters, and prescaler operate normally. b1 RESET Reset 0: Normal count operation or the initialization is R/W completed 1: Prescaler, 64-Hz counter, and alarm registers are initialized. b2 ADJ 30-Second 0: Normal count operation or completion of R/W Adjustment 30-second adjustment 1: During 30-second adjustment b3 RTOOE RTOOUT Output 0: Clock signals are not output from the R/W Control RTOOUT pin. 1: Clock signals are output from the RTOOUT pin. b7 to b4 — (Reserved) These bits are always read as 0. The write value R/W should always be 0.

Figure 8.18 RCR2 (RTC Control Register 2). Source: Hardware Manual, Section 22.2.18.

number 0b01000101. So if we were to write 0x45 to the seconds counter register, then 4 would be written to the tens span and 5 would be written to the ones span. The new count for the seconds register would be read as 45. Keep in mind it is not a good idea to write to each span of the register individually as the counters update on each 128 Hz count. If your code writes a new value to the register during the same 128 Hz count it may not be acknowledged, even if is to different bits. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 321

RCR1 enables and disables the three available RTC interrupts and the period of the pe- riodic interrupt request. We will go over these interrupts in further detail in the advanced concepts section, for now we are most concerned with just understanding and initially set- ting up the Real Time Clock. RCR2 controls the start and reset of the Real Time Clock. By writing a 1 or 0 to the START bit you start or stop the clock. By writing a 1 to the RESTART bit you will reset the 64 Hz counter, presecalers, and alarm registers to 0. Take note that these bits are updated in sync with the count source, so if you write to either of these bits it won’t take effect until the next count of the RTC’s 128 Hz clock. More details are available in the hardware man- ual. We will cover how to account for this in code examples.

8.3.2 Setting the RTC

Setting the Real Time Clock is relatively simple, as illustrated in Figure 8.19. After setting and waiting for the START bit in RCR2 to clear to 0, you set a 1 to the RESET bit. After this you can set the counter registers in any order. Then you set a 1 to the START bit in RCR2 to get the counter started again. Be sure to wait for the bit to set to 1 before you con- tinue with any other operations on the RTC.

Clear the START bit to 0 Write 0 to the START bit in RCR2

No START ϭ 0 Wait for the START bit in RCR2 to be cleared to 0

Yes

Reset the prescaler and 64CNT Write 1 to the RESET bit in RCR2

Set the year, month, day of the week, date, hour, Settings in arbitrary order is possible minute, and second

Set the START bit to 1. Write 1 to the START bit in RCR2 Yes

No START ϭ 1 Wait for the START bit in RCR2 to be set to 1

Figure 8.19 Setting the Real Time Clock. Source: Hardware Manual, Figure 22.2. 322 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

8.3.3 Reading the RTC

Reading the values in the RTC is a little tricky. If a carry request is performed from the 64 KHz clock to the second counter while a reading occurs, then the correct time won’t be read. There are two ways to read the time that avoids this.

Disable the ICU carry interrupt request Write 0 to the IER07.EN7 bit of the ICU

Enable the RTC carry Interrupt request Write 1 to the CIE bit in RCR1

Clear the carry flag Write 0 to the IR63.IR flag of the ICU

Read counter register Read all the necessary counter registers

Yes Carry flag ϭ 1? Read the IR63.IR flag of the ICU for checking

No

(a) To read the time without using Interrupt

Clear the carry flag Write 0 to the IR63.IR flag of the ICU

Disable the ICU carry interrupt Write 1 to the IER07.IEN7 bit of the ICU request

Enable the RTC carry Interrupt request Write 1 to the CIE bit in RCR1

Clear the carry flag Write 0 to the IR63.IR flag of the ICU

Read counter register Read all the necessary counter registers

Yes Interrupt?

No

Disable the RTC carry Interrupt Write 0 to the CIE bit in RCR1

(b) To read the time using interrupts

Figure 8.20 Reading 64 Hz Counter and Time. Source: Hardware Manual, Figure 22.4. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 323

This flowchart from the RX62N manual illustrates the operation to take when reading the counter values using interrupts or not using interrupts. In the non- interrupt method you disable the carry interrupt in the ICU, but enable it in the RTC. Then you check the interrupt flag for the carry operation after reading the registers. If a carry has occurred, you clear the carry flag and start reading over again because the time has changed since reading started. When using the interrupt method you start the same, but instead of check- ing the carry flag you use the carry interrupt to indicate that a carry has occurred between the 64 Hz counter and the second count. The non- interrupt method is preferred as it takes less code.

8.4 BASIC EXAMPLES

Now that we have covered the basic concepts needed to understand how the timer works in these different modes, we will cover a few examples. For now we will demonstrate the ini- tial setup of the clock and how to read from it.

8.4.1 Setting Up Cascaded Timers

For this demo we will be setting up Timer Unit 0 in cascaded timer mode by cascading Timer 0 and Timer 1 together. We will call an interrupt ser vice routine every time this cas- caded counter overflows from 0xFFFF to 0x0000. In the ser vice routine we will put a call to a function that rotates the LEDs on the board. The resulting program will make the LEDs on the board blink in a rotating sequence at a speed determined by how we set up our timer. We will start with a base HEW project that includes the iodefine.h file and other sup- port headers for the RX62N. In this example we will use macros to control the LEDs, we will continue assuming you have defined a similar substitute for performing the action de- scribed by the macro. The first thing to do in our main program is to declare our only global variable.

1. int Current_LED = 1;

We will use this variable to keep track of which LED is currently lit. We will cover how when we discuss the function that uses it. Then we need to include our function prototypes. As you can see we will only use two function calls, one to set up the timer and another to blink the LEDs.

1. void InitTimer(void); 2. void Rotate_LED(void); 324 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

After our main() loop begins we will only need to include the macro for initializing the LEDs and our timer initialization function call. Our while(1) loop will be empty, as all op- erations will be handled in the timer interrupt. Note that this is generally bad programming practice and very uncommon; however, in some cases this is the correct solution.

1. void main(void){ 2. ENABLE_LEDS; 3. InitTimer(); 4. while(1){} 5. }

Now comes the part we are most concerned with, the timer initialization. In this function we will set the timer registers for 16-bit cascaded mode.

1. void InitTimer(void){ 2. IEN(TMR0,OVI0) = 1; //Enable TMR0 Overflow interrupt in ICR 3. IPR(TMR0,OVI0) = 2; //Set priority level of interrupt 4. MSTP(TMR0) = 0; //Activate TMR0 unit 5. MSTP(TMR1) = 0; //Activate TMR1 unit 6. TMR1.TCCR.BIT.CSS = 1; 7. TMR1.TCCR.BIT.CKS = 4; //Count source is PCLK/64 for TMR1 8. TMR0.TCCR.BIT.CSS = 3; 9. TMR0.TCR.BIT.CCLR = 1; //Count source is TMR1 for TMR0 10. TMR0.TCR.BIT.OVIE = 1; //Overflow interrupt enabled 11. }

We start on lines 2–3 by enabling the Timer 0 overflow interrupt in the ICU and setting its priority level. Then on lines 4–5 we activate the Timer 0 and 1 units in the Module Stop Control Register (they are off by default). On lines 6–7 we set the count source for Timer 1 as the PCLK/64 input which is just the main clock divided by 64. On lines 9–10 we set the count source for Timer 0 as Timer 1. With the count source set, this will make Timer 0 count every time Timer 1 overflows. Now, with this set the two timers are cascaded. On line 14 we finish by setting the interrupt in the timer unit itself. As we calculated earlier in our concepts, this setup will take the main clock of 24 MHz and divide it by 64. Then every 65535 counts of that the Timer 0 interrupt will occur and the interrupt routine will be called, thus rotating the current LED that is lit. This is calcu- 1 64 (clock division) lated to be approximately every 174.76 ms. * * 24 MHz (main clock) 1 65535 (counts per interrupt) ϭ 174.76 ms 1 CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 325

The next function is used to light the LEDs on the board one at a time in a circular se- quence. It uses the Current_LED variable to hold which Led is currently lit. Each time it is called, it increments the value, and as soon as it passes 12 it restarts at 1.

1. void LED_Rotate(void){ 2. switch(Current_LED){ 3. case 1: 4. ALL_LEDS_ON; 5. LED6 = LED_OFF; 6. break; 7. case 2: 8. ALL_LEDS_ON; 9. LED12 = LED_OFF; 10. break; 11. case 3: 12. ALL_LEDS_ON; 13. LED3 = LED_OFF; 14. break; 15. case 4: 16. ALL_LEDS_ON; 17. LED9 = LED_OFF; 18. break; 19. case 5: 20. ALL_LEDS_ON; 21. LED5 = LED_OFF; 22. break; 23. case 6: 24. ALL_LEDS_ON; 25. LED11 = LED_OFF; 26. break; 27. case 7: 28. ALL_LEDS_ON; 29. LED2 = LED_OFF; 30. break; 31. case 8: 32. ALL_LEDS_ON; 33. LED8 = LED_OFF; 34. break; 35. case 9: 36. ALL_LEDS_ON; 37. LED4 = LED_OFF; 38. break; 326 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

39. case 10: 40. ALL_LEDS_ON; 41. LED10 = LED_OFF; 42. break; 43. case 11: 44. ALL_LEDS_ON; 45. LED1 = LED_OFF; 46. break; 47. case 12: 48. ALL_LEDS_ON; 49. LED7 = LED_OFF; 50. break; 51. default: 52. ALL_LEDS_OFF; 53. break; 54. } 55. Current_LED++; 56. if(Current_LED == 13){ 57. Current_LED = 1; 58. } 59. }

That is all of the code we need in the main program file. Now we need to define our inter- rupt and put a call to our LED_Rotate() function.

1. #pragma interrupt (Excep_TMR0_OV0I(vect = VECT_TMR0_OVI0)) 2. void Excep_TMR0_OV0I(void); 3. //TMR0_OV0I 4. void Excep_TMR0_OV0I(void){LED_Rotate();}

The first line of this code snippet defines an interrupt at the vector for Timer 0. Next it gives a function definition and the function itself. Inside the function is a call to the LED_Rotate() function. Make note that it is bad practice to include function calls inside of an ISR for many reasons. We will go over reasons why and workarounds for this later. We have now successfully set up a 16-bit cascaded timer on the RX62N and used it to trigger an interrupt that rotates the board’s LEDs. By modifying the count source of Timer 1 we can change the speed of this rotation. Later, in a more advanced example, we will cover how to take greater control of the timer and interrupt timing using the timer con- stant registers and compare match events. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 327

8.4.2 Setting Up a Timer for Pulse Output

Now we will cover an example of setting up a timer for pulse output. This requires very lit- tle code to execute. Once we have set up the timer it will begin to output our desired pulse without any further intervention.

1. void main(void); 2. void InitTimer(void); 3. void main(void){ 4. InitTimer(); 5. while(1){} 6. } 7. void InitTimer(void){ 8. MSTP(TMR0) = 0; //Activate TMR0 unit 9. TMR0.TCCR.BIT.CSS = 1; //Count source is PCLK/8 10. TMR0.TCCR.BIT.CKS = 2; 11. TMR0.TCR.BIT.CCLR = 1; //Timer resets at compare match A 12. TMR0.TCSR.BIT.OSA = 2; //1-output at compare match A 13. TMR0.TCSR.BIT.OSB = 1; //0-output at compare match B 14. TMR0.TCORA = 0x55; //Frequency 15. TMR0.TCORB = 0x20; //Duty cycle 16. //Pulse outputs to TMo0, which is also P22/USB_DRPD 17. //Can be monitored by touching a scope probe to the top 18. //of resistor R46, near bottom right corner of ethernet 19. //port. Port JN2 provides a ground. 20. }

As can be seen here, we have no global variables to initialize and the only function we need is the function to set up the timer. In the timer initialization we first enable the 8-bit timer unit on Line 8. We set the count source for Timer 0 as PCLK/8 on Lines 9 and 10. On line 11 we set the Timer 0 to clear every time a compare match A occurs. This al- lows us to alter how fast the timer resets with more control than just changing the count source. 328 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

On Lines 12 and 13 we set the timer output to go high every time there is a compare match A and to go low when there is a compare match B. This allows us to control the frequency us- ing the timer constant register A, and the duty cycle using timer constant register B. On Lines 14 and 15 we set the frequency and duty cycle by assigning a value to timer constant registers A and B. These are randomly chosen; we will worry about getting an ex- act frequency and duty cycle in the advanced concept section. When running this code the pulse will be output on signal TMO0. By referencing the hardware manual and schematic we find that this is output to Pin 22/USB_DRPD on the board. There is no output pin to monitor this so we will have to observe the output waveform by touching a scope probe to the top of resistor R46 near the bottom right corner of the Ethernet port. You can get a ground reference by connecting to pin 2 on port JN1.

Figure 8.21 Resistor R46 location.

In this example we have set up a pulse output from Timer 0 and observed the output square wave. In a more advanced example later we will cover how to calculate and control the ex- act frequency of the wave and discuss how this relates to controlling external devices.

8.4.3 Setting and Reading from the Real Time Clock

In this example we will demonstrate how to set the time in the Real Time Clock. We will then continuously read the value in the RTC and display it on the LCD. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 329

To start we will use a base project that has all of the included support files for the graphic LCD. The only needed font file is helvr10.c. Also included is the iodefine_RX62N.h file. The first step in this example is to define our global variables.

1. char Year1000, Year100, Year10, Year1, Mon10, Mon1, Day10, Day1, Day, Hour10, Hour1, Min10, Min1, Sec10, Sec1;

These will all hold the value for each of the decimal places of the date values.

Next we insert the function prototypes for the functions we will write:

1. void InitTimer(void); 2. void DisplayTime(void); 3. void GetTime(void);

Now that all of that is defined we go into our main() program.

1. void main(void){ 2. int i; 3. 4. InitTimer(); 5. 6. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 7. /* use Glyph full access direct functions */ 8. GlyphNormalScreen(G_lcd); 9. GlyphSetFont(G_lcd, GLYPH_FONT_HELVR10); 10. GlyphClearScreen(G_lcd); 11. while(1){ 12. DisplayTime(); 13. for (i = 0; i < 100000; i++){} 14. } 15. } else { 16. } 17. GlyphClose(&G_lcd); 18. } 19. } 20. 21. GlyphClose(&G_lcd); 22. } 330 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

First we define the variable ‘i’ in line 2. This is used to create a delay loop between writes to the LCD. Next we call our function initializing the timer in Line 4; this is where all of the code is that initializes and starts the Real Time Clock. The next few lines we won’t cover in depth, but are merely to initialize the LCD. All of the code we are concerned with is in the while(1) loop. The function DisplayTime() is called which retrieves the time from the RTC and then sends it to be displayed on the LCD on Line 12. The for() loop on Line 13 is merely to create a delay so we aren’t constantly writing to the LCD, which makes the display flicker. The else() clause on Line 15 would hold error handling code to executed in the event the LCD did not start up correctly. We also will not go into depth on the closing function on Line 17. The next section of code we will consider is the InitTime() function.

1. void InitTimer(void){ 2. //Set date and time on RTC 3. 4. RTC.RCR2.BIT.START = 0; //Write 0 to start bit in RCR2 5. while(RTC.RCR2.BIT.START == 1){} //Wait for start bit to clear to 0 6. 7. RTC.RCR2.BIT.RESET = 1; //Write 1 to Reset bit in RCR2 8. 9. RTC.RYRCNT.WORD = 0x2015; //Set year, month, day of 10. RTC.RMONCNT.BYTE = 0x10; //week, date, hour, minute, 11. RTC.RDAYCNT.BYTE = 0x21; //second to 2015 Oct 21st 12. RTC.RWKCNT.BYTE = 0x02; //Tue 12:00:00 13. RTC.RHRCNT.BYTE = 0x12; 14. RTC.RMINCNT.BYTE = 0x00; 15. RTC.RSECCNT.BYTE = 0x00; 16. 17. RTC.RCR2.BIT.START = 1; //Set start bit to 1 in RCR2 18. while(RTC.RCR2.BIT.START == 0){} //Wait for start bit to set to 1 19. 20. //Set carry interrupt for use later when reading time from RTC 21. IEN(RTC,CUP) = 0; //Disable carry interrupt in ICU 22. RTC.RCR1.BIT.CIE = 1; //Enable carry interrupt in the RTC 23. }

Here we set up the Real Time Clock and initialize all of the count registers to the date we want. This follows the flowchart in Figure 8.19. Lines 4 and 5 clear and wait for the START bit in the RCR2 register to equal to 0. The wait is necessary because the bits in this register only update on every count of the 128 KHz clock in the RTC, and the program is executing CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 331 at a much faster 24 MHz. Next the RESET bit in RCR2 is set to 1 on Line 7. This resets the RTC’s prescaler clocks, 64 Hz counter, and alarm registers to 0. After this is done, from Line 9 through 15 the clock’s count registers are set to the starting date and time desired. In this example the start time and date is 12:00 PM Tue, Oct 21, 2015. The next step is to start the clock. In Line 17 we write a 1 to the START bit in RCR2 and then wait for it to be set in Line 18. The code on Lines 21 and 22 disable the carry interrupt in the ICU, but enable it in the Real Time Clock peripheral. This allows us to monitor if there has been a carry from the 64 Hz counter to the second counter later on when we are reading the time. We will demonstrate this later in the example. The next function is the DisplayTime() function. This function calls the GetTime func- tion to update the value of the time in our global variables. It then writes them to the LCD using the sprintf() and BSP_Display() functions.

1. void DisplayTime(void){ 2. char buffer [30]; 3. const char DayNames [7][4]= {“Sun”, “Mon”, “Tue”, “Wed”, “Thu”, “Fri”, “Sat”}; 4. 5. GetTime(); 6. 7. BSP_Display_String(LCD_LINE1, “RTC Example”); 8. sprintf((char *)buffer, “%d%d%d%d %d%d / %d%d”, 9. Year1000, 10. Year100, 11. Year10, 12. Year1, 13. Mon10, 14. Mon1, 15. Day10, 16. Day1); 17. BSP_Display_String(LCD_LINE2, buffer); 18. BSP_Display_String(LCD_LINE3, DayNames [Day]); 19. sprintf((char *)buffer, “%d%d:%d%d:%d%d”, 20. Hour10, 21. Hour1, 22. Min10, 23. Min1, 24. Sec10, 25. Sec1); 26. BSP_Display_String(LCD_LINE4, buffer); 27. } 332 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

In this function we first define two character arrays on Lines 2 and 3. The GetTime() func- tion is called on line 5; this copies the values of the time and date into our global variable placeholders. On line 7 we write text to the first line of the display to show the program that is running. On Line 8 we use the sprintf() function to take date values and translate them into ASCII text, and then we place these in an array called buffer. On Line 17 we write these values to the second line of the screen using the BSP_Display_String function, and a pointer to the array holding the text to write. The day of the week is written to the screen on Line 18. On Line 19 we use sprintf() once again to write the time to an array of ASCII characters. On Line 26 we write this to line 4 of the display. The last function we use is the GetTime() function.

1. void GetTime(void) 2. { 3. do { 4. IR(RTC,CUP) = 0; //Clear the Carry Flag 5. Year1000 = RTC.RYRCNT.BIT.YEAR1000; 6. Year100 = RTC.RYRCNT.BIT.YEAR100; 7. Year10 = RTC.RYRCNT.BIT.YEAR10; 8. Year1 = RTC.RYRCNT.BIT.YEAR1; 9. Mon10 = RTC.RMONCNT.BIT.MON10; 10. Mon1 = RTC.RMONCNT.BIT.MON1; 11. Day10 = RTC.RDAYCNT.BIT.DAY10; 12. Day1 = RTC.RDAYCNT.BIT.DAY1; 13. Day = RTC.RWKCNT.BYTE; 14. Hour10 = RTC.RHRCNT.BIT.HOUR10; 15. Hour1 = RTC.RHRCNT.BIT.HOUR1; 16. Min10 = RTC.RMINCNT.BIT.MIN10; 17. Min1 = RTC.RMINCNT.BIT.MIN1; 18. Sec10 = RTC.RSECCNT.BIT.SEC10; 19. Sec1 = RTC.RSECCNT.BIT.SEC1; 20. } while(IR(RTC,CUP) == 1); 21. //If carry bit has been set since reading started, try again 22. }

This function follows procedure a in Figure 8.20: Reading 64 Hz Counter and Time. The interrupt has already been disabled in the ICU and enabled in the RTC peripheral by the TimerInit() function. Now when there is a carry from the 64 Hz counter to the seconds counter, the interrupt flag in the ICU will set but an interrupt will not trigger. Now we start this function by clearing the interrupt request flag for the carry interrupt. We then read all of the digits the RTC counter registers into separate variables from Lines 5 through 19. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 333

After we have read the time we check and make sure the interrupt request flag for the carry interrupt hasn’t been set. If it has, that means the seconds counter has incremented and the time held in our variables is no longer correct and we will need to call the function again. The GetTime() function will repeat itself until it successfully reads a time without the carry interrupt being requested. Once all of this code is in our program we can compile it and load it onto our board. Once run, within a second the following text should appear on the graphical LCD screen.

Timer Example 2015 10/21 Tue 12:00:00

The time will now be displayed as a clock until the program is paused in the debugger and/or power is removed from the board. This example covered the basics of setting up and reading from the Real Time Clock by setting the time and then reading it and displaying it on the boards graphical LCD as it counts. In the advanced concepts section we will cover how to use the RTC interrupts such as the periodic and alarm interrupts.

8.5 ADVANCED CONCEPTS

By now we should have a basic grasp on how to set up and use the more advanced features of the 8-bit timers along with how to set up and read the real time clock. We have covered the basics in setting up a cascaded timer, the bare minimum set up of a pulse output signal, and how to set up and read the real time clock. Now we cover how to take more control of our timer count duration by using the timer counter registers. We will go into more detail on the pulse output operation by covering how to calculate and control our output frequency and duty cycle. Also, we will cover usage of the real time clocks alarm and periodic interrupts.

8.5.1 Using a Cascaded Timer with 16-Bit Timer Constant Registers

We have covered the basics of using a cascaded 16-bit timer and have given examples of a basic set up. However, this set up lacks a bit of control that an embedded designer would want. Currently, with what we know, we can only count in increments of 0xFFFF (65535). The only control we have over how fast the timer overflows is by altering the count source. This only leaves us with the capability to count to the lengths of time in Table 8. With the timer constant registers we can extend that functionality. We have taken note of this while setting up the timer in pulse output mode, and now will cover it in more depth. 334 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Each timer channel offers three interrupts: the overflow interrupt, and two timer con- stant interrupts. If we set a value in either of the timer constant registers and enable these interrupts, the respective interrupt will be triggered when a compare match event occurs for that register. A compare match event will occur when the TCNT register matches the value in that timer constant register; i.e., compare match A when TCNT matches timer constant register A, and compare match B when TCNT matches timer constant register B. So now that gives us the ability to trigger interrupts at even more precise times. But we still have to wait for the timer to finish counting to 0xFFFF and overflow and then count back to the timer constant value before the interrupt is triggered again. This is imprecise and not prac- tical in many situations. So, by setting in the TCR for the timer channel to reset on compare match A or B, we can control to a much higher degree the time the counter will count to. This describes how the compare match counters work in 8-bit mode, but what about 16-bit mode? There is only a minor difference. When we place the timer channel into 16-bit mode, the TCNT, TCORA, and TCORB registers from the two timer channels in the unit span into one register. So now they each are practically one 16-bit register. We can still only write to them as their 8-bit entities; so when we calculate the values we want to enter into them, we just convert to hex and write the upper byte to the register of the channel with a higher number and the lower byte to the other. If we wanted a value of 0x1234 in TCORA of timer unit 1, we would enter 0x12 in TCORA of Timer 0, and 0x34 in TCORA of timer 1. For timer unit two we write the upper bytes to Timer 2’s registers and the lower bytes to Timer 3’s registers. As an example we have a timer set up in 16-bit cascaded timer mode with a count source of 1/1028. If we wait for an overflow, that gives us an interrupt every 2.8 s. But what if we want to generate an interrupt every 1 s? First we calculate what fraction of 2.8 1 is, 1 and then multiple 65535 by that: * 65535 ϭ 23405 (approximately). We enter this 2.8 value into the timer constant register A and enable the compare match A interrupt. Of course, this is a 16 bit value, so we can’t enter it at one time. So we convert it to hex and en- ter the upper byte into TMR0.TCORA and the lower byte into TMR1.TCORA. Now we still have the interrupt occurring every 2.8 s, but that’s because the timer is still counting to 65535 before resetting. So we set the bit CCL bit in the TCR so the timer is clear by com- pare match A. Thus giving us an interrupt every 1 s on compare match A.

8.5.2 Calculating and Programming Pulse Frequency and Duty Cycle in Pulse Output Mode, and Controlling a Servo Motor

We have covered the concept of how pulse output works and demonstrated the basic regis- ter set up needed to get a pulse output. We did not go into much detail about calculating the frequency and duty cycle of our output wave. This is not too complex but has been saved CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 335 for this section just to give time to get used to the concept of pulse output operation first. If you understand the concepts of pulse output operation and calculating timer speeds from the basic concepts section, this should be no problem. For this example we will assume we are using the pulse output to control a servo mo- tor. Common servo motors use a pulse input to determine how or where it moves to. Spec- ifications vary by motor, as per frequency and duty cycle required. We will use specifica- tions from an anonymously chosen motor for this example. In the case of this motor we need a 1 ms pulse to turn full left and a pulse of 2 ms to turn full right. Usually a frequency is not specified, however you want to have adequate space between your pulses for smooth operation; and also not have them too spaced apart, so that when the duty cycle is updated the servo reacts in a timely manner. 50 Hz (20 ms period) is a safe frequency for smooth operation. For this example we will be using the timer in 16-bit cascaded mode as well as in pulse output mode. This gives us more precise control over the duty cycle while still allowing for a wide period between pulses (low frequency). This is not much more complicated than 8-bit pulse output. Our first step is to choose a speed for our prescaler. If we look at Table 8.2: Clock Di- vision and Interrupt Times we see that PCLK/8 (3 MHz) offers almost a 21.84 ms period between TCNT overflows. We will choose this prescaler, as choosing PCLK/32 (87.38 ms) will provide us with a much smaller resolution between a 1 ms pulse and a 2 ms pulse. Now we must calculate the values for the timer counter registers. First, we will calculate the values to place in timer constant register B to obtain a pulse of 1 ms and 2 ms. Then we must calculate the value to place in timer constant register A to obtain a 20 mS low signal after the pulse. Note that when we change the value of TCORB, the frequency of the wave still stays the same, so the time our wave is low is affected. However, since 1–2 ms is small compared to 20 ms, this is negligible and we don’t have to worry about recalculating for TCORA. To calculate the value for TCORB we divide 1 ms and 2 ms by the length of time 1ms 2ms between timer counts; ϭ 3000 and ϭ 6000. For the value in TCORA 333.33 ns 333.33 ns we add 20 ms to our maximum high period (2 ms) to get 22 ms, then divide this by the time 22 ms for a clock tick, ϭ 66000. In this case it gives us a value greater than our range, 333.33 ns which is 65535. Luckily we only max out 155 ns shorter than our desired time, which is ac- ceptable because, once again, having a precise low period is not crucial with servo motors, only having a fair amount of low time for the control circuitry to acknowledge our high pulse. So in the case of this application it is fine to leave the value of TCORA at 0xFFFF. So, in all practicality, when setting up a pulse output signal we are just calculating a timer length for the period of our wave and for each high duty cycle we desire, and then 336 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

programing it into the timer constant registers. Also, keep in mind that with this example 1 ms and 2 ms are the maximum value pulses for our motor. If this were a 180 degree servo, 1 ms would put it at 0 degrees, and 2 ms at 180 degrees. If we wanted any position in between we would have to output a signal proportionally between 1 and 2 ms. 1.5 ms would place the servo at 90 degrees, 1.75 ms at 135 degrees and so on. In the case of a con- tinuous rotation servo, 1 and 2 ms would be full forward and backward, and any pulse length in between would speed up or slow down the rotation; 1.5 ms would be a full stop.

8.5.3 Using the Real Time Clock’s Alarm and Periodic Interrupts

The RX62N’s real time clock peripheral includes three interrupts: the carry interrupt, peri- odic interrupt, and alarm interrupt. The carry interrupt we have used in a previous example, and is triggered every time there is a carry from the 64 KHz counter to the second counter. The periodic interrupt is an interrupt that can be set to occur on a regular interval determined by what we set in the RCR1 register. We can alter this interval by editing three bits in the register, allowing us seven options for interrupt intervals. The alarm interrupt gives us the ability to choose an exact time for an interrupt to occur. For each count register there is an alarm register. When enabled, once the values in all of the enabled registers match the real time clocks counter registers, an interrupt will be triggered. Besides triggering an interrupt routine the alarm interrupt also has the ability to wake the processor from low power modes. Setting the periodic interrupt is simple in comparison to calculating and setting an 8-bit timer to do the same task. First we must make sure that the interrupt is disabled in the ICU. Then we set the periodic interrupt enable bit in RCR1 and set the periodic interrupt select 1 bits to whichever interrupt period we desire. The options are 2 seconds, 1 second, ⁄2 second, 1 1 1 1 ⁄4 second, ⁄16 second, ⁄64 second, and ⁄256 second. After clearing the request flag we enable the interrupt in the ICU and the ISR will begin triggering on the chosen interval. Setting the alarm interrupt is a bit more complicated, but is illustrated in a flowchart in the RX62N hardware manual. We can set all of the alarm registers and have the interrupt only trigger at a specific date and time, or we can only enable certain registers so the inter- rupt triggers each time the counters match those particular alarm registers. Say we want an interrupt to trigger at thirty minutes of every hour; we will set the minute alarm register to thirty minutes, and then set the enable bit in the same register. After enabling and setting a priority level for the alarm interrupt, every time the value in the minute count register matches 30 the interrupt will occur. First we make sure that the real time clock is running. Then we make sure the interrupt is not enabled in the ICU, so that it doesn’t trigger accidentally while we are setting it. Now we are able to set all of the alarm registers to the time we desire the interrupt to be triggered at. Once done, we write a 1 to the alarm interrupt bit in the ICU. Using the periodic inter- 1 rupt we will wait for the ⁄64 second interrupt, this is to allow time for the alarm interrupt enable bit to be set. We then clear the alarm interrupt request flag in the ICU in case it has been set while we were setting the alarm. Our last step before the interrupt is ready to be CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 337

Check that the count is in operation Clock running (the START bit in RCR2 is 1)

Disable the ICU alarm interrupt Write 0 to the IER0B.IEN4 bit of the ICU to request prevent erroneous interrupts

Set alarm time

Enable the RTC alarm interrupt request Write 1 to the AIE bit in RCR1

Use a periodic interrupt Set the PES[2:0] bits in RCR1 to 010b to wait for to wait for 1/64 of a second periodic interrupts twice

Always clear the IR92.IR flag of the ICU Clear alarm flag to 0, since the flag may have been set while the alarm time was being set

Enable the ICU alarm interrupt Write 1 to the IER0B.IEN4 bit of the ICU request

Monitor alarm time Wait for alarm interrupt or the IR92.IR flag (wait for interrupt or of the ICU to be set to 1 check alarm flag)

Figure 8.22 Alarm interrupt setting procedure. Source: Hardware Manual, Figure 22.5.

used is to enable the interrupt in the ICU. Now we can return to our normal program, and once the counters match the enabled alarm registers the interrupt will trigger.

8.6 ADVANCED EXAMPLES

Now that we have covered the more advanced concepts to using these features we will now go over examples implementing these concepts in code. The code will follow along with the examples in the earlier sections.

8.6.1 Using a Cascaded Timer with 16-Bit Timer Constant Registers

In this example our program will once again cause the LEDs on the board to blink in a ro- tating sequence, but this time with a 1s delay between blinks. We will implement this delay using a 16-bit cascaded timer and its interrupt. 338 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

We will be using the LEDs in these examples so the first part of our code will be the definitions for the LED ports. After the LED definitions, we declare our first global vari- able, which will keep track of which LED is currently lit. Also we set a global variable we will use to indicate whether the timer interrupt has triggered or not. This is known as a flag, and such usage will be covered in more depth in a later chapter.

1. int Current_LED = 1; 2. int TimerInterruptFlag = 0;

Next we have to declare our functions.

1. void main(void); 2. void InitTimer(void); 3. void Rotate_LED(void);

Our main() function doesn’t contain much code. First we enable the LEDs with a macro on line 3, and then we call the timer setup function on line 4. Nothing happens in our while(1) loop until the TimerInterruptFlag variable is set by the interrupt. Note that the interrupt will run upon the timer triggering, and there will be some time delay between when the variable is set and the program returns to the main function and the LED is rotated. Because of this, the timing of the LED rotation won’t be exactly one second, but that is acceptable because LEDs aren’t time critical and can be off by a few milliseconds without hurting anything. It is bad programming practice to include the function call in the interrupt itself because it requires more time overhead in the ISR along with the need to save and restore all proces- sor registers.

1. void main(void) 2. { 3. ENABLE_LEDS; 4. InitTimer(); 5. 6. while(1) 7. { 8. if(TimerInterruptFlag) 9. { 10. LED_Rotate(); 11. TimerInterruptFlag = 0; 12. } 13. } 14. } CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 339

The most important part of this example is our InitTimer() function. On lines 2 and 3 we en- able and set a priority for the compare match A interrupt. We then enable timer unit 0 chan- nels one and two (TMR0 and TMR1) on lines 5 and 6. On lines 8 and 9 the TMR1 count source is set to PCLK/1024, which gives us a count every 42.66 ms. This is done by writing the appropriate values to the TCCR register. Then on lines 11 and 12 we set the count source for TMR0 to TMR1, so now TMR0 counts once every time TMR1 overflows. Now we have a total of 2.8 s between timer overflows. In order to make the timer reset every 1 s we need to write the appropriate value to the TCORA(timer constant A) register and set the timer to reset on ever compare match A event. In Section 8.4.1 we calculated the needed value as 23405. We convert this into hex, separate it into a higher and lower byte, and then write the higher byte to TMR0 and the lower byte to TMR1 on lines 14 and 15. On line 17 we set the bit in the TCR that enables resets on compare match A event.

1. void InitTimer(void){ 2. IEN(TMR0,CMIA0) = 1; 3. IPR(TMR0,CMIA0) = 3; 4. 5. MSTP(TMR0) = 0; //Activate TMR0 unit 6. MSTP(TMR1) = 0; //Activate TMR1 unit 7. 8. TMR1.TCCR.BIT.CSS = 1; 9. TMR1.TCCR.BIT.CKS = 5; //Count source is PCLK/1024 for TMR1 10. 11. TMR0.TCCR.BIT.CSS = 3; 12. TMR0.TCR.BIT.CCLR = 1; //Count source is TMR1 for TMR0 13. 14. TMR0.TCORA = 0x5B; //Set TCORA to 23405 15. TMR1.TCORA = 0x6D; //(0x5B6D hex) 16. 17. TMR0.TCR.BIT.CMIEA = 1; 18. }

The only remaining code in our main C file is our LED_Rotate function which we have al- ready covered. The last code we need to consider is our interrupt. For this example, unlike our basic example, we will be using the compare match A interrupt.

1. #pragma interrupt (Excep_TMR0_CMI0A(vect = VECT_TMR0_CMIA0)) 2. void Excep_TMR0_CMI0A(void); 3. 4. //TMR0_CMI0A 5. void Excep_TMR0_CMI0A(void){LED_Rotate();} 340 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

If we look in the RX62N hardware manual we will see that the compare match A interrupt is at vector 174. This code defines an interrupt routine at that vector and places the LED_Rotate() function inside of it. Now we have a program that once compiled and downloaded to the board will cause the LEDs to blink in a rotating sequence. The LEDs will advance at a rate of 1 per second as defined by our timer setup. This program demonstrates a timer function that makes use of a 16-bit cascaded timer with a compare match interrupt and reset on compare match event. This provides greater precision and a broader range of times to count.

8.6.2 Setting Up Pulse Output Mode to Control a Servo Motor

In this example we will use our calculations from Section 8.5.2 to write a program that will control our theoretical servo motor. We will be setting up a timer for the pulse output mode and then make two functions that will alter our timer setup such that the servo will rotate left or right. Our program will only need the default iodefine_RX62N.h file, so we won’t need any LED definitions or code for the graphical LCD. We begin our main program by defining our function prototypes.

1. void main(void); 2. void InitTimer(void); 3. void Turn_Left(void); 4. void Turn_Right(void);

As you can see, once again we will only need a function to set up the timer initially, then we have two functions that when called will alter the timer setup to give us the needed pulse output to turn left or right.

1. void main(void){ 2. float i; 3. 4. InitTimer(); 5. 6. while(1){ 7. 8. for(i = 0; i < 10000000; i++); 9. Turn_Left(); 10. for(i = 0; i < 10000000; i++); 11. Turn_Right(); CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 341

12. } 13. }

Also, once again, our main program is very simple. We merely create the variable i as a method to create a delay. Once we call the function to initialize our timer we go into our while(1) loop. In that loop we repeatedly pause, call the function to turn left, pause again, then call the function to turn right. This represents a very simple method of setting up mo- tor control in C. The for() loops merely create an arbitrary delay between the duty cycle changes which is long enough that we can observe the difference. In a normal program we would not make a delay this way; this is merely for the sake of demonstration.

1. void InitTimer(void){ 2. MSTP(TMR0) = 0; //Activate TMR0 unit 3. MSTP(TMR1) = 0; //Activate TMR1 unit 4. 5. 6. TMR1.TCCR.BIT.CSS = 1; 7. TMR1.TCCR.BIT.CKS = 2; //Count source is PCLK/64 for TMR1 8. 9. TMR0.TCCR.BIT.CSS = 3; 10. TMR0.TCR.BIT.CCLR = 1; //Count source is TMR1 for TMR0 11. 12. TMR0.TCR.BIT.CCLR = 1; //Timer resets at compare match A 13. 14. TMR0.TCSR.BIT.OSA = 2; //1-output at compare match A 15. TMR0.TCSR.BIT.OSB = 1; //0-output at compare match B 16. 17. TMR0.TCORA = 0xFF; //Frequency 18. TMR1.TCORA = 0xFF; 19. 20. TMR0.TCORB = 0x00; //Duty cycle 21. TMR1.TCORB = 0x00; 22. 23. //Pulse outputs to TMo0, which is also P22/USB_DRPD 24. //Can be monitored by touching a scope probe to the top of resistor 25. //R46, near bottom right corner of ethernet port. Port JN2 26. //provides a ground. 27. } 342 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Next in our code is our timer initialization function. This will set up the timer unit 0 chan- nels one and two for the pulse output we desire. We will use the values we calculated ear- lier in Section 8.5.2. First we activate the timer channels on lines 2 and 3, because we can- not alter the registers in the unit until it is activated. Our next step is to set the Timer 1 count source to the PCLK/64 prescaler on lines 6 and 7. On lines 9 and 10 we set the count source for Timer 0 as Timer 1. We now have a 16-bit cascaded timer so any settings made for clearing in the Timer 0 TCR are effective for the entire cascaded unit. On line 12 we set the unit to reset on a compare match A event. We then set the timer output port to go to one output on compare match A events, and to zero on compare match B events. Remember that because the unit is now 16-bits, the timer constant registers are now spanned into sin- gle 16-bit registers, with the upper byte in the Timer 0 timer constant register and the lower byte in the Timer 1 timer constant registers. Any value we want to write to the compare match registers must first be converted to hex, and then the upper and lower bytes written to the appropriate registers. Lines 17 and 18 set our time count for compare match A events, thus setting the period and therefore frequency of our waveform. Lines 20 and 21 set our initial duty cycle to zero, so at this point our timer is set up but we are not yet out- putting a waveform because the wave is constantly held low by the compare match B event at time count 0x0000.

1. void Turn_Left(void){ 2. 3. TMR0.TCORB = 0x0B; //Duty cycle 4. TMR1.TCORB = 0xB8; 5. 6. } 7. 8. void Turn_Right(void){ 9. 10. TMR0.TCORB = 0x17; //Duty cycle 11. TMR1.TCORB = 0x70; 12. 13. }

Now all we need are our functions to turn left and right. These functions are very simple; they merely alter the values in the Timer constant B registers so that the duty cycle is either 1 ms or 2 ms. In the Turn_Left() function we write the value for 1 ms and in the Turn_Right() function we write the value for 2 ms. After being compiled and downloaded to the board this program will initially not give an output, then begin to toggle the output between a 22 ms wave with 1 ms high pulse and 2 ms high pulse after an arbitrary delay created by the for() loops in our while(1) code. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 343

8.6.3 Using the Real Time Clock’s Alarm and Periodic Interrupts

This program example begins with the program we wrote in Section 8.3, so we already have a program that sets the real time clock, then reads it and displays the count. Initially the program will behave like our basic example: set the time, then begin counting, and dis- play the time on the LCD. Then when the time reaches 12:00:15 the LEDs will be enabled by the alarm interrupt and begin to blink in a circular pattern at a rate determined by the pe- riodic interrupt. For review on the code we have already written refer to Section 8.3. In this section we will only focus on the parts we are adding to give the alarm and periodic interrupt func- tionality, which will not require the removal or modification of any old code.

1. void Set_Alarm(void); 2. void LED_Rotate(void);

Our first addition to the basic example is the addition of two new function prototypes. We are adding a function to set the alarm time and also we will be using our LED_Rotate function once again to make the LEDs rotate in a circular sequence.

1. void main(void){ 2. int i; 3. ENABLE_LEDS; 4. ALL_LEDS_OFF; 5. DISABLE_LEDS; 6. 7. InitTimer(); 8. Set_Alarm(); 9. 10. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 11. /* use Glyph full access direct functions */ 12. GlyphNormalScreen(G_lcd); 13. GlyphSetFont(G_lcd, GLYPH_FONT_HELVR10); 14. GlyphClearScreen(G_lcd); 15. while(1){ 16. for(i = 0; i < 10000; i++); 17. DisplayTime(); 18. } 19. } 20. else {} 21. 22. GlyphClose(&G_lcd); 23. } 344 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

As you can see, our main function is the same save for some additions. The first addition is lines 4 through 6; this code enables the LEDs and turns them off, then disables them once again. Initially our program doesn’t use the LEDs, so this makes sure LEDs left lit from previous running programs are turned off and then disables them so they won’t be lit until re- enabled by the alarm interrupt. After this our only other addition is the Set_Alarm() function call on line 8 after we initialize the real time clock.

1. void Set_Alarm(void){ 2. 3. //Check clock running 4. if(RTC.RCR2.BIT.START == 1){ 5. 6. //Disable ICU alarm interrupt 7. IEN(RTC,ALM) = 0; 8. IEN(RTC,PRD) = 1; 9. 10. //Set alarm 11. RTC.RSECAR.BYTE = 0x15; 12. RTC.RMINAR.BYTE = 0x00; 13. RTC.RHRAR.BYTE = 0x12; 14. RTC.RWKAR.BYTE = 0x02; 15. RTC.RDAYAR.BYTE = 0x21; 16. RTC.RMONAR.BYTE = 0x10; 17. RTC.RYRAR.WORD = 0x2015; 18. 19. RTC.RSECAR.BIT.ENB = 0x01; 20. RTC.RMINAR.BIT.ENB = 0x01; 21. RTC.RHRAR.BIT.ENB = 0x01; 22. RTC.RWKAR.BIT.ENB = 0x01; 23. RTC.RDAYAR.BIT.ENB = 0x01; 24. RTC.RMONAR.BIT.ENB = 0x01; 25. RTC.RYRAREN.BIT.ENB = 0x01; 26. 27. //Enable RTC alarm 28. RTC.RCR1.BIT.AIE = 1 29. while(RTC.RCR1.BIT.AIE == 0) //Wait for it to be written before continuing 30. ; 31. //Use periodic interrupt to wait 1/64 second 32. IR(RTC,PRD) = 0; 33. RTC.RCR1.BIT.PES = 0x02; //Set periodic interrupt to 1/64s CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 345

34. while(IR(RTC,PRD) == 0) //Wait for flag to be set 35. ; 36. //Clear alarm flag 37. IR(RTC,ALM) = 0; 38. 39. //Enable ICU alarm interrupt 40. IEN(RTC,ALM) = 1; 41. IPR(RTC,ALM) = 3; 42. } 43. else { 44. //error handling code 45. } 46. 47. //Set up Periodic interrupt to trigger ISR every 0.5s 48. RTC.RCR1.BIT.PES = 0x05;//Set periodic interrupt to 0.5s 49. IR(RTC,PRD) = 0; //Clear periodic interrupt flag 50. IEN(RTC,PRD) = 1; //Enable periodic interrupt in ICU 51. IPR(RTC,PRD) = 4; //Set priority level 52. }

Our most important addition to the basic program is our Set_Alarm() function. The code in this function follows the flowchart in Figure 8.22. First on line 4 we have an if statement that checks if the real time clock is counting, this is in case we call the function and have forgotten to initialize the real time clock or somehow the clock has ceased to count. On line 43 we have an else statement where error handling code would be put, but we will not worry about what to put there yet. The next step is to disable the alarm interrupt in the ICU; this ensures we aren’t interrupted by the alarm while we are setting it. We also disable the periodic interrupt in the ICU since we are using it to set the alarm but do not want the ISR routine interrupting our configuration code. This is done on line 7. With the periodic interrupt disabled, we can set the alarm registers for the time we want the alarm interrupt to occur; this is handled on lines 11 through 25. In this example we utilize all of the alarm registers and set it to occur fifteen seconds after the initial time set by the clock. Take note on lines 19–25 that we set the enable bit for each of the regis- ters, otherwise they won’t be compared. Also take note that because the year alarm register encompasses an entire word and doesn’t have an extra bit set aside, there is a separate reg- ister we must set a 1 to in order to enable it, the RYRAREN register on line 25. After that we set the alarm enable bit in the RCR1 register on line 28. On line 29 we get stuck in a while loop until the bit gets set, because the RCR1 register only gets updated at the rate of the real time clocks internal clock. On line 32 through 34 we clear the periodic interrupt re- 1 quest flag and then set the periodic interrupt for ⁄64 of a second. 346 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Then we have a while loop that will hold the program until the periodic interrupt sets the request flag again. After all of this we can be assured that the alarm interrupt enable bit has been set and we enable and set a priority for the alarm interrupt on lines 40 and 41. That is all of the code we need to set our alarm, but in this program example we are also us- ing the periodic interrupt, so we include code to set that up for the rest of our program as well. On line 48 we set the periodic interrupt to occur at 0.5 second intervals. Then on lines 49 through 51 we clear the interrupt flag, and then enable it and set a priority level. Also before the next snippet of code make sure to insert our LED_Rotate() function from previous examples. We won’t cover it since we aren’t covering any older code.

1. //RTC PRD 2. #pragma interrupt (Excep_RTC_PRD(vect = VECT_RTC_PRD)) 3. void Excep_RTC_PRD(void); 4. 5. //RTC_ALM 6. #pragma interrupt (Excep_RTC_ALM(vect = VECT_RTC_ALM)) 7. void Excep_RTC_ALM(void); 8. 9. //RTC_PRD 10. void Excep_RTC_PRD(void){LED_Rotate();} 11. 12. //RTC_ALM 13. void Excep_RTC_ALM(void){ENABLE_LEDS;}

With any program using interrupt routines it is necessary to define where our interrupt is. On lines 2, 3, 6, and 7 we define the name of our interrupt service routines and their vec- tors, which are given in the RX62N Hardware Manual in Section 11.3. Then on lines 10 and 13 are our service routine functions. On line 10 is our periodic interrupt routine which will call our LED_Rotate() function, so once the LEDs are enabled they will blink in a ro- tating sequence at a rate of one LED per 0.5 s. On line 13 is our alarm interrupt function that contains our macro for enabling the LEDs, so no LEDs will light up from the periodic interrupts routine until the alarm interrupt enables them. Note once again this code in- cludes a function call in an ISR for simplicity and illustration purposes, however, in an ac- tual program this would be bad practice and should be avoided. Once this program is built and downloaded to the board, at first it will seem the same as our basic example where it begins to display the time starting with when we set the clock to. Then after fifteen seconds the alarm interrupt will call and enable the LEDs. Af- terwards the LEDs will blink in a circular sequence at a rate of one per 0.5 s for the dura- tion of the programs running time. CHAPTER 8 / EVENT COUNTERS, TIMERS, AND THE REAL TIME CLOCK 347

8.7 RECAP

In this chapter we covered the capabilities of the 8-bit timer peripherals on the Renesas RX62N. We started with a brief overview of the timer concepts. Then we covered how to cascade two 8-bit timers into one 16-bit unit. We also covered pulse output operation that allows us to generate a steady frequency square wave whose duty cycle and frequency are maintained by the timer unit. Additionally we covered the Real Time Clock feature, which allows the RX62N to easily and accurately track the time and date. In the advanced con- cepts section we showed how to take more control of a cascaded timer by using the 16-bit timer constant register. We then went over how to calculate and precisely control frequency in pulse output mode, and gave an example of controlling a servo motor. For our final ex- ample we showed how to set up and use the Real Time Clock’s alarm interrupt.

8.8 REFERENCES

Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print.

8.9 EXERCISES

1. What registers would you use when setting up the 8-bit timer unit 0 in cascaded mode? 2. Briefly describe three events that can happen when a compare match event occurs. 3. Explain the algorithm used and describe the purpose of the steps used when ini- tially setting the RTC. 4. Give sample code that will set up a basic 1 KHz square wave with a 40% duty cycle. 5. Assume you have set up a 16-bit cascaded timer and now you want its interrupt to occur every 3 seconds. Name the registers you would write to, and the values you would write to them. 6. Assume you have set up a 16-bit cascaded timer for pulse output mode, what reg- isters and what values would you write to them to get an output that is high for 3 ms and low for 18 ms? 7. Name two advantages to using the timer constant registers. 8. Give at least one advantage to using the periodic interrupt over setting up an 8-bit timer in order to get a 1 s recurring interrupt. 9. Besides triggering an ISR at the exact time specified by the real time clock alarm registers, what is another action the alarm interrupt performs?

Chapter Nine

Using Interrupts with Peripherals

9.1 LEARNING OBJECTIVES

No doubt so far in this book you have seen interrupts mentioned several times. This book is only meant to touch on and explain concepts having to do with embedded systems and the peripherals of the RX62N, yet in the case of most peripherals covered so far it has been impossible to give even a brief overview without using interrupts in some way. In this chapter we will be covering more thoroughly exactly what interrupts are and how they work on a microcontroller. Using interrupts in an embedded application gives a greatly in- creased capacity for efficiency over a purely linear program. In the basic concepts section we will give an in depth look at how an interrupt is trig- gered between a peripheral and the Interrupt Control Unit, and explain the process of set- ting up an interrupt and what is going on when we do so. In the advanced concepts section we will cover why keeping our code minimal in interrupts is important to prevent bugs. Also we will cover handling the passage of data from interrupts. After a brief overview of state machine programming design, we will pull all of this together by giving an example of a state machine whose state is controlled via interrupts.

9.2 BASIC CONCEPTS

Basic programs will read and execute in order from beginning to end in a mostly linear fashion save for control logic such as if() and while() loops. The problem with this is em- bedded systems are meant to interface with the real world, which does not often occur in such a predictable linear manner. Almost all embedded systems will depend on an external event and may even need to critically execute some given code immediately at that event, and we need a means to signal this in the program, stop what we are doing, handle another task, then return to the previous program execution. But how do we do that?

9.2.1 Using Interrupts for Tasks versus Other Methods

One method of gathering outside data into a program is via polling. For example, say you are getting ready for work in the morning and you want to brew a pot of coffee. The coffee

349 350 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

takes at least five minutes to boil and then steep. If we were to act in a manner similar to polling we would set the water in the pot then (poll) it until it is boiling. That is five minutes of time that we are staring at a pot and not getting other things done that we could potentially be doing. Instead, we can set a kettle and then go about our routine and don’t worry about ‘processing’ the coffee until the kettle whistles to signal the water is boiling. Once we are notified via this signal we ‘interrupt’ our routine to pour a cup and then return to what we were doing. There are also alternative methods of occasionally stepping back into the room to check if the water is boiling, which is similar to polling methods used for keypads. In more complex situations you will need to worry about multiple interrupts oc- curring; e.g., the dog wants out, the phone rings, someone knocks at the door. In a situation like this you will need some way to handle scheduling the interrupts and to make sure some lower priority interrupts don’t interrupt more critical code that needs to execute faster. In these situations it is handy to use a Real Time Operating System, which is covered in a later chapter. For now we will start with the simple single interrupt method.

Start preparing breakfast: Put water in kettle and turn on burner Put ground coffee in filter in cone Put cone on cup Get milk out of fridge Get cereal from cabinet

Water An Interrupt Occurs boils and kettle Interrupt Service Routine whistles Resume breakfast preparation: Put down whatever is in hands Get bowl from cabinet Turn off burner Pour cereal into bowl Pour boiling water into coffee filter Get spoon Pick up whatever was put down Put milk back in fridge

Figure 9.1 Preparing coffee flowchart.

9.3 INTERRUPTS

One good example of how interrupts are used is a robot with an IR sensor. Consider how the robot uses the IR sensor to detect and avoid obstacles. The robot continuously polls for a sig- nal from the IR sensor, which tells the robot when an obstacle is close. The robot may be run- ning lots of tasks, so if it gets stuck in a long process, the polling process is halted until the long task is executed. If the signal from the IR sensor occurs while the robot is processing, the robot will bump into the obstacle. Interrupts are an alternative to polling in these situations. An interrupt is an external or internal event that takes the Program Counter (PC) from the current point of the code to a subroutine in the code called the Interrupt Service Routine (ISR) which has a higher priority of execution. The address to the ISRs is listed out in the CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 351

Interrupt Vector Table (IVT) which is defined in each processor memory. Whenever an in- terrupt occurs, the processor goes to the IVT and determines the location of the ISR; it then executes the subroutine present at that address. For example, consider the above situation of polling the signal from the sensor for detecting the obstacle. Instead of polling the signal, we can setup an interrupt which runs a subroutine whenever there is a change in the logic level. When a processor is running a long task we do not need to worry that we would lose the sig- nal from the sensor as the interrupt is set up. The subroutine will be the ISR for the interrupt, and when the processor executes the ISR it means that an obstacle has occurred. So the function of the subroutine should be to avoid the obstacle, either change the path or stop the robot before bumping into the obstacle. The ISRs should contain very little code in them. There are two types of interrupts: Maskable and Non- Maskable. Non- Maskable inter- rupts (NMI) are interrupts that cannot be ignored by the processor. When a non- maskable in- terrupt occurs, the processor should stop whatever it is executing and attend it first. The non- maskable interrupts are usually used for non- recoverable errors and serious hardware errors that need immediate attention. One example of a non- maskable interrupt is the reset pin. The Interrupt Control Unit (ICU) receives signals from peripherals such as timers, ADCs, and external pins of the microcontroller. The interrupt sources available for the RX62N/RX621 group are listed in Table 9.1. The block diagram of the ICU is shown Figure 9.2. This chapter deals with the interrupts generated using software and the external pins of the microcontrollers.

The following registers are used to setup and read the status of the interrupts:

Ⅲ Interrupt Request Register (IRR) Ⅲ Interrupt Request Enable Register (IER) Ⅲ Interrupt Priority Register (IPR) Ⅲ Fast Interrupt Register (FIR) Ⅲ Software Interrupt Activation Register (SWINTR) Ⅲ IRQ Control Register (IRQCR) Ⅲ Non- Maskable Interrupt Status Register (NMISR) Ⅲ Non- Maskable Interrupt Enable Register (NMIER) Ⅲ Non- Maskable Interrupt Clear Register (NMICLR) Ⅲ NMI Pin Interrupt Control Register (NMICR)

(interrupt vector number ؍ Interrupt Request Register n (IRn) (n The least significant bit of the interrupt request register indicates the status of a particular interrupt source. The value n of the interrupt request register corresponds to different interrupt sources in the vector table. For the interrupt sources and corresponding interrupt vector numbers, refer to the Interrupt Vector Table of the hardware manual (Table 11.4, RX62N Group, RX621 Group Hardware Manual). 352 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER Re- Clock CPU DTC generator DMAC enable DTC response DTC DMAC response DMAC DMAC activation DMAC Interrupt request DTC start request DTC DMAC start request DMAC Interrupt acceptance Clock restoration request Clock restoration FIR Clock restoration enable level Clock restoration DTC DMAC control Non-maskable Interrupt request control judgment activation activation IPR CPU priority level Clear IR clear IR clear IR clear Destination switchover CPU to Destination switchover CPU to DTCER Clock judgment restoration DMASR RX62N Group, RX621 Group Hardware Manual: Manual, Cntl IER Source: Source: IR: IER: IPR: register Interrupt request FIR: enable register Interrupt request DTCER: priority register Interrupt source DMRSR: activation enable register DTC Interrupt set register Fast select activation register source DMAC Module data bus IR Interrupt status, destination switchover Interrupt status, ER NMI SR NMI Detection IRQCR CLR NMI IRQ0 to IRQ15 detectionIRQ0 to Interrupt control unit Interrupt control Detection CR NMI Interrupt source [Legend] NMIER: NMICR: Non-maskable enable register interrupt register NMICLR: register control NMI pin interrupt Non-maskable clear register interrupt control NMISR: IRQCR: IRQ Non-maskable status register interrupt IRQ0 IRQ15 NMI pin Block diagram of Interrupt Control Unit. Block diagram of Interrupt Control module Peripheral Oscillation stop destination Oscillation stop Low power-voltage destination power-voltage Low nesas Electronics America, Inc., 2010, page 11–2. nesas Electronics Figure 9.2 Figure CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 353

TABLE 9.1 Specifications of ICU.

ITEM DESCRIPTION Interrupts Peripheral Ⅲ Interrupts from peripheral modules function Ⅲ Number of sources: 146 interrupts Ⅲ Interrupt detection: Edge detection/level detection Edge detection or level detection is determined for each source of connected peripheral modules. External pin Ⅲ Interrupts from pins IRQ15 to IRQ0 interrupts Ⅲ Number of sources: 16 Ⅲ Interrupt detection: Low level, falling edge, rising edge, both rising and falling edges One of these detection methods can be set for each source. Software Ⅲ Interrupt generated by writing to a register interrupt Ⅲ One interrupt source Interrupt priority Specified by registers. Fast interrupt Faster interrupt processing of the CPU can be set only for a function single interrupt source. DTC/DMACA Ⅲ The DTC and DMACA can be activated by interrupt sources. control Ⅲ Number of DTC activating sources: 102 (85 peripheral function interrupts 16 external pin interrupts 1 software interrupt) Ⅲ Number of DMACA activating sources: 45(41 peripheral function interrupts 4 external pin interrupts) Non- maskable NMI pin Ⅲ Interrupt from the NMI pin interrupts interrupts Ⅲ Interrupt detection: Falling edge/rising edge Power-voltage Interrupt during power- voltage fall detection falling detection Oscillation stop Interrupt during oscillation stop detection detection Return from power- down modes Ⅲ Sleep mode: Return is initiated by non- maskable interrupts or any other interrupt source. Ⅲ All- module clock stop mode: Return is initiated by non- maskable interrupts, IRQ15 to IRQ0 interrupts, WDT interrupts, timer interrupts, USB resume interrupts, or RTC alarm interrupts. Ⅲ Software standby mode: Return is initiated by non- maskable interrupts, IRQ15 to IRQ0 interrupts USB resume interrupts, or RTC alarm interrupts. Source: RX62N Group, RX621 Group Hardware Manual,Table 11.1. 354 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 9.2 Bit Description of Interrupt Request Register.

BIT SYMBOL BIT NAME DESCRIPTION R/W b0 IR Interrupt status flag 0: No interrupt request is generated R/W* b7 to b1 — (Reserved) These bits are read as 0. The write R/W value should always be 0.

Note: *For edge- detected sources, only 0 can be written to this bit, which clears the flag, and writing 1 to the bit is prohibited. Writing is not possible if the source is level- detected.

Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.1.

IR Flag (Interrupt Status Flag) When a particular interrupt request is generated, the corresponding vector number IR flag will be set to 1. The interrupt request detection can be set to edge detection or level detec- tion for each interrupt by using the bits in IRQCRi (i 0 to 15).

Interrupt Request Enable Register m (IERm) (m 02 to 1Fh):

Address: 0008 7202h to 0008 721Fh b7 b6 b5 b4 b3 b2 b1 b0

IEN7 IEN6 IEN5 IEN4 IEN3 IEN2 IEN1 IEN1

Value after reset: 0 0 0 0 0 0 0 0

Figure 9.3 Interrupt Request Enable Register. Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.2.

The Interrupt Request Enable Register (IERm) is used to enable and disable the interrupt requests to the CPU. IENj bits (Interrupt Request Enable) ( j 0 to 7): When the IENj bit is set to 1, the CPU accepts that particular interrupt request and handles the interrupt. When this bit is set to 0, the CPU ignores that particular request. The m and j values in IERm and IENj are for en- abling and disabling particular interrupts that can be referenced in the Interrupt Vector Table in the hardware manual (Table 11.4, RX62N Group, RX621 Group Hardware Manual ). CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 355

EXAMPLE

External pin interrupt IRQ0 is referred using the IER register as IER08.IEN0. The Timer1 overflow interrupt OVI1 is referred using the IER register as IER16.IEN

(to 8Fh 00 ؍ Interrupt Priority Register m (IPRm) (m The Interrupt Priority Register is used to set the priority for each interrupt source. The in- terrupt source should be disabled while setting the priority level. The possible priority lev- els are listed in Table 9.3. Each interrupt source has its own reserved IPR bits. For the IPR bits of each interrupt source, refer to the Interrupt Vector Table in the hardware manual (Table 11.4, RX62N Group, RX621 Group Hardware Manual). The interrupt sources with a higher priority than the priority level set by IPL [3Ϻ0] bits in PSW are accepted. If the in- terrupt priority level of two interrupts are the same and are requested at the same time, then the interrupt source with the smallest vector number will have the higher priority.

TABLE 9.3 Bit Description of Interrupt Priority Register.

BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 IPR[3Ϻ0] Interrupt b3 b0 R/W Priority Level Select 0 0 0 0: Level 0 (interrupt prohibited) 0 0 0 1: Level 1 0 0 1 0: Level 2 : 1 1 1 1: Level 15 (highest) b7 to b4 — (Reserved) This bit is read as 0. The write value R/W should always be 0.

Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.3. 356 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Fast Interrupt Register (FIR)

Address: 0008 72F0h

b15 b14 b13 b12 b11 b10 b9 b8

FIEN — — — — — — —

Value after reset: 0 0 0 0 0 0 0 0

b7 b6 b5 b4 b3 b2 b1 b0

FVCT[7:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 9.4 Fast Interrupt Register. Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.5.

This FIR register is used to set a particular interrupt source as a fast interrupt. The fast in- terrupt function cannot be used to trigger the peripherals like DTC, DMAC, etc. The fast interrupt function should not be set up for reserved interrupts in the interrupt vector table.

FVCT [7Ϻ0]: These bits are used to mention the interrupt vector number of the interrupt source, which should function as a fast interrupt.

FIEN: This bit should be set to 1 for the interrupt source mentioned in FVCT [7Ϻ0] to func- tion as a fast interrupt.

Software Interrupt Activation Register (SWINTR)

TABLE 9.4 Bit Description of SWINTR.

BIT SYMBOL BIT NAME DESCRIPTION R/W b0 SWINT Software Interrupt This bit is read as 0. R/W* Activation Writing 1 issues a software interrupt request. Writing 0 to this bit has no effect. b7 to b1 — (Reserved) These bits are read as 0. The write R/W value should always be 0.

Note: Only 1 can be written. This bit is read as 0.

Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.5. CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 357

The Software Interrupt Activation Register (SWINTR) is used to create a software inter- rupt request. When the SWINT bit is set to 1, the interrupt occurs in vector 27 and the interrupt re- quest for vector 27 is also set to 1. If the DTC Activation Enable Register 27 (DTCER) is set to 0, then a CPU interrupt is generated. If it is cleared to 0, then a DTC activation re- quest is generated.

(to 15 0 ؍ IRQ Control Register i (IRQCRi) (i

IRQ Control Register i (IRQCRi) (i 0 to 15)

Address: 0008 7500h to 0008 750Fh

b7 b6 b5 b4 b3 b2 b1 b0

— — — — IRQMD[1:0] — —

Value after reset: 0 0 0 0 0 0 0 0

Figure 9.5 IRQ Control Register. Source: RX62N Group, RX621 Group Hardware Manual, page 336.

The IRQ Control Register (IRQCRi) is used to select the type of external interrupts, which are either edge detection or level detection. The IRQMD [1Ϻ0] bits in the IRQCR are used to set up the type of external interrupts. These settings should only be done when the inter- rupt is disabled and after the interrupt is set up. The interrupt request bit for the particular external interrupt should be cleared and the interrupt enable bit should be set to 1. IRQMD [1Ϻ0]: The possible values for the IRQMD [1Ϻ0] bits and the corresponding setting for the interrupts are shown in Table 9.5.

Non- Maskable Interrupt Enable Register (NMIER) The Non- Maskable Interrupt Enable Register (NMIER) is an 8-bit register that is used to enable or disable the NMI interrupts. The NMIER has control over three NMI interrupts: oscillation stop detection, power- voltage detection, and NMI pin interrupts.

Address: 0008 7581h

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — OSTEN LVDEN NMIEN

Value after reset: 0 0 0 0 0 0 0 0

Figure 9.6 Non- Maskable Interrupt Enable Register (NMIER). Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.10. 358 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 9.5 Bit Description for IRQ Control Register.

BIT SYMBOL BIT NAME DESCRIPTION R/W b1, b0 — (Reserved) These bits are read as 0. The R/W write value should always be 0. b3, b2 IRQMD[1:0] IRQ Detection Sense b3 b2 Select 0 0: Low level 0 1: Falling edge 1 0: Rising edge 1 1: Rising and falling edges b7 to b4 — (Reserved) These bits are read as 0. The R/W write value should always be 0.

Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.8.

NMIEN (Non- Maskable interrupt enable) bit: When this bit is set to 1, the interrupt re- quest from the NMI pin will be sent to the CPU; otherwise the request will be ignored.

LVDEN (Power- voltage falling detection enable) bit: When this bit is set to 1, the power voltage falling detection interrupt request will be sent to the CPU; otherwise the request will be ignored.

OSTEN (Oscillation stop detection enable) bit: When this bit is set to 1, the oscillation stop detection interrupt request will be sent to the CPU; otherwise the request will be ignored.

NOTE: For all of the bits described in Figure 9.6, writing “1” is accepted only once—subsequently writing 0 or 1 to these bits is disabled. In other words, we cannot disable the NMI inter- rupts after enabling them.

Non- Maskable Interrupt Status Register (NMISR) The Non- Maskable Interrupt Status register is a read only 8-bit register. This register is used to read the status of three non- maskable interrupts: oscillation stop detection interrupt (OSTST), power- voltage falling detection interrupt (LVDST), and non- maskable pin inter- rupt (NMIST). CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 359

Address: 0008 7580h

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — OSTST LVDST NMIST

Value after reset: 0 0 0 0 0 0 0 0

Figure 9.7 Non- Maskable Interrupt Status Register (NMISR). Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.9.

Figure 9.7 shows the following about the Non- Maskable Interrupt Status Register:

Ⅲ NMIST (NMI status flag) bit: This bit is set to 1 when the edge specified by the NMIMD bit in the NMICR occurs at the NMI pin. When this is bit is set to 1, the interrupt request from the NMI pin will be generated to the CPU. This bit is cleared to zero only when the NMICLR bit in NMICLR register is set to 1. Ⅲ LVDST (Power- voltage falling detection status flag) bit: This bit is set to “1” when the power- voltage falling detection interrupt is generated and is cleared to 0, and when the interrupt is cleared by the interrupt source. Ⅲ OSTST (Oscillation stop detection status flag) bit: This bit is set to 1 when the os- cillation stop detection interrupt is generated and is cleared to 0, and when the OSTCLR bit in NMICLR register is set to 1.

Non- Maskable Interrupt Clear Register (NMICLR) The Non- Maskable Interrupt Clear Register (NMICLR) is an 8-bit register that is used to clear the status flags of the NMI interrupts. The status flags of NMI pin and the oscillation stop detection interrupts can be cleared by this register.

Address: 0008 7582h

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — OSTCLR — NMICLR

Value after reset: 0 0 0 0 0 0 0 0

Figure 9.8 Non- Maskable Interrupt Clear Register (NMICLR). Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.11.

Figure 9.8 shows the following:

Ⅲ NMICLR (NMI clear) bit: When this bit is set to 1, the NMIST flag in the NMISR register will be cleared to 0. 360 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Ⅲ OSTCLR (OST clear) bit: When this bit is set to 1, the OSTST flag in the NMISR register will be cleared to 0.

NOTE: We do not need to clear the NMICLR and the OSTCLR bits to 0. As soon as the corre- sponding status flag goes to 0, the NMICLR and the OSTCLR bits are also cleared to 0.

NMI Pin Interrupt Control Register (NMICR) The NMI Pin Interrupt Control Register (NMICR) is an 8-bit register in which only one bit is used to set the type of edge detection of the interrupt to either the falling edge or the ris- ing edge. The edge detection should be set before enabling the NMI interrupt. Figure 9.9 illustrates how to address the NMI Pin Interrupt Control Register (NMICR). When this bit is set to 1, the interrupt request is generated on the rising edge input to the NMI pin. When this bit is cleared to 0, the interrupt request is generated on the falling edge input to the NMI pin.

Address: 0008 7583h b7 b6 b5 b4 b3 b2 b1 b0

— — — — NMIMD — — —

Value after reset: 0 0 0 0 0 0 0 0

Figure 9.9 NMI Pin Interrupt Control Register (NMICR). Source: RX62N Group, RX621 Group Hard- ware Manual, Section 11.2.12.

9.3.1 Interrupt Vector Table

The Interrupt Vector Table (IVT) in an RX62N microcontroller has 256 interrupts, with each interrupt source occupying four bytes in the table. In total, the size of IVT is 1024 bytes (4 bytes 256 sources). Each address space specifies the location of the interrupt ser vice routine for the interrupt. When the CPU accepts an interrupt, it acquires the four byte ad- dress from the IVT and executes the code specified at that particular interrupt service rou- tine. Refer to Table 11.4 located in the hardware manual of the RX62N microcontroller for the vector address for the interrupt sources.

9.3.2 Interrupt Operation

The interrupt control unit (ICU) performs the following operations while setting up the interrupts: CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 361

Ⅲ Detecting the interrupts. Ⅲ Enabling and disabling the interrupts. Ⅲ Selecting the interrupt destination. Ⅲ Determining the priority.

The ICU first detects the interrupts. Detecting the interrupt requests is by way of either edge detection of the interrupt signal (edge triggered interrupts), or level detection of the interrupt signal (level triggered interrupts).

Edge Detection The interrupt status flag is set to 1 when the microcontroller responds to the interrupt re- quest, and the bit is cleared to 0 when the particular module or I/O pin interrupt request is accepted. Figure 9.10 shows how the interrupt status flag operates for edge triggered inter- rupts. The IR flag for the particular interrupt is set to 1 as soon as the interrupt signal goes high. If the interrupt is a CPU interrupt, the IR flag is cleared to 0 when the interrupt is ac- cepted by the CPU. If the interrupt is a DMACA or DTC activation interrupt, the IR flag is cleared to 0 once the transfer by the DTC or DMACA has been completed.

Interrupt Signal

IRn.IR flag

Acceptance of the interrupt by the CPU or completion of transfer by the DTC or DMACA

Figure 9.10 Interrupt status flag for edge triggered interrupts. Source: RX62N Group, RX621 Group Hardware Manual, page 11–40.

If the source of the interrupt generation is disabled and after the interrupt status flag goes high, the IR flag remains in the high state. For example after the IR flag for DTC acti- vation interrupt goes high, if the DTC is disabled, then the IR flag of the DTC activation in- terrupt remains in the high state until the DTC is enabled and the transfer is done. Figure 9.9 shows how the IR flag operates when the source of the interrupt is disabled. 362 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Source for interrupt generation is enabled/disabled

Interrupt Signal

IRn.IR flag IRn.IR flag is not cleared even when the source is disabled

Figure 9.11 Interrupt status flag when the source of the interrupt is disabled. Source: RX62N Group, RX621 Group Hardware Manual, Figure 11.4.

Level Detection The interrupt status flag remains set to 1 when the interrupt is requested and being sent to the destination. The bit is cleared to 0 when the source of the interrupt request is cleared. Figure 9.11 shows the operation of the IR flag for level- triggered interrupts. As shown in Figure 9.12, the IR flag remains in the high state until the source of the device requesting the interrupt is cleared.

Interrupt source cleared

Interrupt Signal

IRn.IR flag

IRn.IR flag cleared

Figure 9.12 Interrupt status flag for level triggered interrupts. Source: RX62N Group, RX621 Group Hardware Manual, Figure 11.5.

The edge detection and the level detection of the interrupts can be selected using the IRQMD [1Ϻ0] bits in IRQ control register. When the level detection is selected for the in- terrupt requests, the interrupt status flag should not be cleared to 0. CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 363

After detecting the interrupts, the ICU checks to see if the interrupt is disabled or en- abled. Enabling and disabling the interrupts can be performed by using the bits in IERm register. Refer to Table 11.4 of the hardware manual for information about the correspon- ding bit for each interrupt. If the interrupt is disabled, the ICU ignores the interrupt. If the interrupt is enabled, the ICU checks for the destination of the interrupt. The possible desti- nations for the interrupt would be the CPU, or DTC or DMACA activation. The destination for any interrupt is the CPU by default. The destination of the interrupt can be modified us- ing the bits in the DTCER and DMRCR registers. For the interrupt vector number of a par- ticular interrupt, refer to Table 11.4 of the hardware manual (Table 11.4, RX62N Group, RX621 Group Hardware Manual). If two or more interrupts occur at the same time, the ICU fetches the interrupt re- quests based upon the interrupt priority set up by the IPR register. An interrupt selected as a fast interrupt will have the highest priority. After that, the highest value in the IPR [3Ϻ0] bits of IPRm will have the next highest priority. If interrupts with same priority level oc- cur at the same time, the interrupt source with smallest vector number will have higher priority.

9.3.3 Setting Up an Interrupt for a Peripheral

All interrupts in the RX62N are handled via the Interrupt Control Unit (ICU). When setting up an interrupt there are two places where we make configuration settings, in the peripheral itself and in the ICU. When an interrupt occurs a signal is sent from the pe- ripheral to the ICU, the ICU then processes the request and sends the interrupts to the CPU as needed.

Setting Up an Interrupt The steps to set up an interrupt for a peripheral are as follows:

1. The peripheral or port pin must be enabled and configured. 2. Set an interrupt priority for the interrupt source (IPR macro) to a value greater than zero (zero disabled). 3. Enable the interrupt in the peripheral (local enable bit). 4. Enable the interrupt in the ICU (IEN macro). (Conrad, J.)

NOTE: The procedure is slightly different for setting an I/O pin as an interrupt; refer to section Registers Set in the ICU for an Interrupt under the definition for the IRQCRi register.) 364 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER Clock CPU DTC generator DMAC Figure 11.1. Figure enable DTC response DTC DMAC response DMAC DMAC activation DMAC Interrupt request DTC start request DTC DMAC start request DMAC Interrupt acceptance Clock restoration request Clock restoration FIR Clock restoration enable level Clock restoration DTC DMAC control Non-maskable Interrupt request control judgment activation activation IPR CPU priority level Clear IR clear IR clear IR clear Destination switchover CPU to Destination switchover CPU to DTCER Clock judgment restoration DMASR Source: RX62N Group, RX621 Group Hardware Manual, Source: Cntl IER IR: IER: IPR: register Interrupt request FIR: enable register Interrupt request DTCER: priority register Interrupt source DMRSR: activation enable register DTC Interrupt set register Fast select activation register source DMAC Module data bus IR Interrupt status, destination switchover Interrupt status, ER NMI SR NMI Detection IRQCR CLR NMI IRQ0 to IRQ15 detectionIRQ0 to Interrupt control unit Interrupt control Detection CR NMI Interrupt source [Legend] NMIER: NMICR: Non-maskable enable register interrupt register NMICLR: register control NMI pin interrupt Non-maskable clear register interrupt control NMISR: IRQCR: IRQ Non-maskable status register interrupt Interrupt Control Unit Block Diagram. Interrupt Control IRQ0 IRQ15 NMI pin module Peripheral Oscillation stop destination Oscillation stop Low power-voltage destination power-voltage Low Figure 9.13 Figure CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 365

As can be seen, first off the peripheral must be enabled and configured; it can’t signal an interrupt if it isn’t on or configured to operate. The next steps don’t necessarily need to be handled in the given order. A priority must be set for the interrupt in the ICU, you may have noticed in previous chapters we have done this using the IPR() macro. Using the pro- vided macros from Renesas simplifies the process by only having us need to know the name of the peripheral and its interrupt in order to set its priority and enable it in the ICU. These can be found, along with the vector numbers for the interrupts, in the RX62N hard- ware manual or in Appendix A: Interrupt Vector Table of this text. We must also enable the interrupt in the peripheral itself. Where this is done is depen dent on the peripheral, and could vary from setting an enable bit in a control register to a variety of settings in a sepa- rate register specifically for the interrupt. The interrupt must also be enabled in the ICU it- self in order for the ICU to send it to the CPU. Besides enabling the registers for the interrupt we need to define the Interrupt Service Routine to be used when the interrupt is triggered. The vector for each interrupt is available in the Interrupt Vector Table. In the case of the interrupts we will be using, the location the vector points to is variable and can be defined using a #pragma and another macro feature provided by Renesas. We put the code we want to run as an ISR in a subroutine, and then we define the subroutine as an interrupt and place a pointer to its memory address with the following code, where SUBROUTINE_NAME is the name of the subroutine and VECTORNUMBER is the number of the vector located in the Interrupt Vector Table.

1. #pragma interrupt (SUBROUTINE_NAME(vect = VECTORNUMBER)) 2. void SUBROUTINE_NAME(void);

We place this code at the beginning of our program or in a separate .h file. Then we put the code for our ISR in the subroutine with the rest of our program’s functions or in a separate .c file allocated for our interrupt code.

1. //Name of Interrupt 2. void SUBROUTINE_NAME(void){ 3. //ISR Code 4. }

Registers Set in the ICU for an Interrupt Each of the following registers is not a single register, but a representation of a type of reg- ister. In the RX62N there are several of these. The one which services the interrupt we will use is determinable by looking in the Interrupt Vector Table. However, we need not worry about any details besides the abbreviation for the peripheral, the abbreviation for the inter- rupt, and the vector number, because everything is handled in the Renesas IR(), IPR(), and IEN() macros. We will cover the registers here just to help understand the interrupt process. 366 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Interrupt Request Register n (IRn) (n interrupt vector number)

Address: 0008 7010h to 0008 70FDh

b7 b6 b5 b4 b3 b2 b1 b0

— — — — — — — IR

Value after reset: 0 0 0 0 0 0 0 0

BIT SYMBOL BIT NAME DESCRIPTION R/W b0 IR Interrupt status flag 0: No interrupt request is generated R/W* 1: An interrupt request is generated b7 to b1 — (Reserved) These bits are read as 0. The write R/W value should always be 0.

Note: *For edge- detected sources, only 0 can be written to this bit, which clears the flag, and writing 1 to the bit is prohibited. Writing is not possible if the source is level- detected.

Figure 9.14 Interrupt Request Register. Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.1.

The Interrupt Request Register (shown in Figure 9.14) is merely a flag holder that in- dicates a request signal has been sent from the peripheral. When a signal is received in the ICU, the Interrupt Status Flag bit will be set to 1, and will return to 0 when the CPU ac- cepts the interrupt. In the event that an interrupt is enabled in a peripheral and not in the ICU, this flag can still be set. It is possible to clear this register to 0 before an interrupt oc- curs by writing a 0 to it. To clear a flag via the IR() macro we merely enter the code as:

1. IR(“PERIPHERAL”, “INTERRUPT”) = 0;

Where PERIPHERAL is the abbreviation of the peripheral and INTERRUPT is the abbre- viation for the interrupt name (available in the Interrupt Vector Table). To check a flag via the IR() macro we enter the code as:

1. VARIABLE = IR(“PERIPHERAL”, “INTERRUPT”);

or

1. if(IR(“PERIPHERAL”, “INTERRUPT”)) == 1){ 2. //Code if flag is set 3. } CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 367

Interrupt Request Register m (IERm) (m 02h to 1Fh)

Address: 0008 7202h to 0008 721Fh

b7 b6 b5 b4 b3 b2 b1 b0

IEN7 IEN6 IEN5 IEN4 IEN3 IEN2 IEN1 IEN0

Value after reset: 0 0 0 0 0 0 0 0

BIT SYMBOL BIT NAME DESCRIPTION R/W b0 IEN0 Interrupt Request Enable 0 0: Interrupt request is disabled R/W b1 IEN1 Interrupt Request Enable 1 1: Interrupt request is enabled R/W b2 IEN2 Interrupt Request Enable 2 R/W b3 IEN3 Interrupt Request Enable 3 R/W b4 IEN4 Interrupt Request Enable 4 R/W b5 IEN5 Interrupt Request Enable 5 R/W b6 IEN6 Interrupt Request Enable 6 R/W b7 IEN7 Interrupt Request Enable 7 R/W

Note: Write 0 to the bit that corresponds to the vector number for reservation. These bits are read as 0.

Figure 9.15 Interrupt Request Enable Register. Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.2.

The Interrupt request enable register (shown in Figure 9.15) enables whether the ICU will process the interrupt request flag once it is set by a signal from the peripheral. The address of the IEN register and the bit of the register that needs to be set for each interrupt is once again available in the Interrupt Vector Table, but we don’t need to worry about that. We only need to know the IEN() macro, which operates just like the IR() macro. To set or clear the bit corresponding to an interrupt in the IER register we only need to enter the following code, where PERIPHERAL and INTERRUPT are the abbreviations for the peripheral in the Interrupt Vector Table.

1. IEN(“INTERRUPT”, “PERIPHERAL”) = 1; 2. //‘1’ to enable, or ‘0’ to disable 368 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Interrupt Request Register m (IPRm) (m 00h to 8Fh)

Address: 0008 7300h to 0008 738Fh

b7 b6 b5 b4 b3 b2 b1 b0

— — — — IPR[3:0]

Value after reset: 0 0 0 0 0 0 0 0

BIT SYMBOL BIT NAME DESCRIPTION R/W b3 to b0 IPR[3:0] Interrupt Priority Level b3 b0 R/W Select 0 0 0 0: Level 0 (interrupt prohibited) 0 0 0 1: Level 1 0 0 1 0: Level 2 : 1 1 1 1: Level 15 (highest) b7 to b4 — (Reserved) This bit is read as 0. The write R/W value should always be 0.

Figure 9.16 Interrupt Priority Register. Source: RX62N Group, RX621 Group Hardware Manual, Section 11.2.3.

The Interrupt Priority Register (shown in Figure 9.16) allows the priority of the interrupt to be specified. A priority level from one to fifteen is allowed, fifteen being the highest. Interrupts with higher priority are handled first. If interrupts occur simultaneously with the same priority, the interrupt with the lower vector number is handled first. If a priority level isn’t set, the inter- rupt will not be handled. In case you are using an I/O pin to trigger an interrupt, you would use this register to de- termine how it is triggered. The number of the IRQ register for each I/O pin corresponds to the number of the interrupt request pin. Please refer to the RX62N schematic to determine where to connect to that pin physically. The only pins we are concerned with in this book are the pins connected to Switch 1, 2, and 3 which are IRQ pins; and 8, 9, and 10, respectively. Take note you must also enable the port as an input when using it to trigger an interrupt. It is important when setting up an I/O pin as an interrupt to do it in this order:

1. Clear the IEN bit. 2. Enable or confirm the I/O pin as an input. 3. Set the detection method in the IRQCR register. 4. Clear the IR flag. 5. Set the IEN bit. CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 369

Take note of Step 2. Alongside writing the ports data direction register to set it as an input, you must also write a 1 to the input buffer control register (ICR; RX62N Group, RX621 Group Hardware Manual, page 641) in the I/O registers. This must be done any time you are using an input pin to control a peripheral, in this case the peripheral is the ICU. You will have to refer to the schematic to see which port number and bit correspond to the IRQ in- put, and then write to that ICR bit. In the case of the three on board switches 1, 2, and 3, the ports are PORT4.0, PORT4.1 and PORT4.2 respectively. So for switch one you would write a 1 to PORT4.ICR.BIT.0.

9.3.4 How an Interrupt Operates

So, now that we know how to set up an interrupt and a bit of the inner workings of the ICU, we will briefly explain the process of what happens when an interrupt is triggered. When conditions are met in a peripheral to trigger an interrupt, the first process that happens is the sending of the request to, and the processing of that request by, the ICU.

1. Conditions met for interrupt in peripheral, peripheral flag set. 2. Signal sent to ICU, peripheral flag cleared. 3. IR flag set in ICU. 4. If the interrupt is enabled in the ICU and no higher priority interrupts are currently running, the interrupt is sent to the CPU. 5. Interrupt accepted by CPU, IR flag cleared.

Once the interrupt is sent to the CPU the following process occurs in the program:

1. Finish processing current instruction. 2. Save program counter and flags to memory. 3. Run interrupt ser vice routine. 4. Restore program counter and flags from stack. 5. Resume main program.

The stack is a dynamically allocated resource that contains current working data to do with our program. If too many interrupts occur, the stack can fill up pretty quickly and may overflow. This can become a problem if not well monitored. Another reason to keep ISRs small and short is so that they get back to the main program quickly and don’t interfere with other interrupts. This, of course, is just a very basic overview of the process that occurs. The detailed or- der of this process and instructions used to perform it are more complex and processor spe- cific. But hopefully this gives an overview and helps you understand the process involved with setting up and using interrupts. 370 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

9.4 BASIC EXAMPLES

9.4.1 Polling a Switch for Input versus Using an Interrupt

Aim: Demonstrate checking the status of a hardware switch via polling and with an interrupt.

Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, RX62N Development kit.

Details: In this example, we will setup the RX62N processor to check the status of switch one (SW1). If the switch is pressed, the lit LED will rotate clockwise once until the switch is pressed again. We will first do this via a polling method, and then with an interrupt. We will compare and contrast the differences.

Procedure: First we will set up SW1 and check it with a polling method.

1. #include “iodefine_RX62N.h” 2. 3. //Function definitions 4. void main(void); 5. void LED_Rotate(void); 6. 7. //Define global variables 8. int Current_LED; 9. 10. 11. void main(void){ 12. ENABLE_LEDS 13. ENABLE_SWITCHES 14. Current_LED = 1; 15. 16. while(1){ 17. if(SW1 == 0){ 18. LED_Rotate(); 19. while(SW1 == 0) //Note that this code does not handle switch debouncing. 20. ; 21. } 22. } 23. } CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 371

All of this should be familiar; the LED_Rotate function rotates the LEDs one step in a clock- wise sequence every time it is called. Current_LED is used to keep track of which LED is cur- rently lit. For more reference on how to implement this function, refer to Chapter 8 where it is first used. Lines 17 through 22 are where we check the status of SW1. SW1 is active low so once it is pressed the input will become a zero. Every time the program cycles through the while(1) loop it will check if SW1 is a zero yet. If it is a zero it will rotate the LED clock- wise and then get stuck in the while (SW 0); until the switch is released. Note that on line 19 there is a comment noting that this code does not account for debouncing. Debouncing accounts for how a switch will, for a brief time after being pressed, rapidly switch back and forth (or “bounce”) between an ON and OFF position rather than cleanly switching between states. Usually this state is accounted for by calling a brief timer loop before checking ON or OFF, and indicating pressed or depressed. This method was left out in this example for simplicity. Another method would be to replace lines 16 through 22 with the following code:

1. while(1){ 2. while(SW1 == 1); 3. LED_Rotate(); 4. while(SW1 == 0) 5. ; 6. } 7. }

With this method, we avoid problem number one of the last method by pausing the pro- gram until the switch is pressed. This solves that problem, but now this makes problem number two even worse. The program will be hung up entirely and no other calculations will be performed until the switch is pressed and released each time the while(1) loop re- peats. To solve both problems we will use an interrupt.

1. #include “iodefine_RX62N.h” 2. 3. //Define SW1 interrupt 4. #pragma interrupt(SW1_Int(vect = VECT_IRQ8)) 5. void SW1_Int(void); 6. 7. //Function definitions 8. void main(void); 9. void LED_Rotate(void); 10. void EnableIRQ8(void); 11. 372 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

12. //Define global variables 13. int Switch_Press = 0; 14. int Current_LED; 15. 16. void main(void) 17. { 18. ENABLE_LEDS 19. EnableIRQ8(); 20. Current_LED = 1; 21. 22. while(1) 23. { 24. if(Switch_Press) 25. { 26. LED_Rotate(); 27. Switch_Press = 0; 28. } 29. 30. } 31. }

First take note of the addition on lines 3 through 5. SW1 is connected to IRQ8, if we look up IRQ8 in the Interrupt Vector Table we will see that it is at vector 72. This code defines the ISR for IRQ8 as SW1_Int and places a pointer to its memory address at vector 72, and also defines the function SW1_Int. Also on line 10 we define a new function EnableIRQ8 which is called on line 19 to perform all of the necessary operations to set up the switch to trigger an interrupt. In our while(1) loop nothing will happen unless the Switch_Press flag is set in the switches interrupt routine. If it does, the LED_Rotate function is called and the flag is reset to 0.

1. void EnableIRQ8(void){ 2. IEN( ,IRQ8) = 0; 3. PORT4.ICR.BIT.B0 = 1; 4. ICU.IRQCR [8].BIT.IRQMD = 0x01; 5. ENABLE_SWITCHES 6. IPR( ,IRQ8) = 0x03; 7. IR( ,IRQ8) = 0; 8. IEN( ,IRQ8) = 1; 9. } CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 373

You may notice this code follows the procedure defined for setting a switch for an interrupt in Section 9.3.3 in the description of the IRQCRi register. First, as a precaution we disable the interrupt in the ICU in case it has been enabled in our program. This is on line 2. Then on line 3 we write a 1 to the input control register on Port4.0, the port that SW1 is con- nected to. This passes a signal to the ICU when the switch is pressed. Then we set the trig- gering method for IRQ8 on line 4. The switch is active when low, and it goes from a one to zero when pressed, so we set the trigger as a falling edge. Line 5 is our macro to set up the switches as inputs. By default the ports are inputs when the program starts, and we have also already called this macro in the main program; but this is a precautionary mea sure in case we decide to put this function in other programs where this hasn’t already been done. Now that all of this is done, all we have to do is set up the interrupt in the ICU by defining its priority level, clearing the request flag in case it has been generated during setup, and then enabling the interrupt on lines 7 through 9.

1. void SW1_Int(void) 2. { 3. Switch_Press = 1; 4. }

Our last piece of code is for the SW1 Interrupt Subroutine. This sets the flag indicating the interrupt was triggered then returns to the main function. Because we set the trigger for the interrupt as a falling edge on the switch, it will only trigger when the button is pushed. Once the button is pushed, the subroutine is called and whatever code we want to address is executed. The switch is not ignored. Also, there is no waiting because the main program is halted for only as long as it takes to address the ISR. Though the setup is slightly more complex, the interrupt method is superior in efficiency.

9.4.2 Setting up the ADC with an Interrupt

Aim: Demonstrate using the interrupt with a peripheral.

Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, RX62N Development kit, RX62N Graphical LCD Code package.

Details: In this example, we will set up the RX62N processor to read the value of the po- tentiometer. Our program will use an interrupt, a device interrupt as a trigger, and a sub- routine. TMR0 will trigger the A/D conversion every one second. When the A/D conver- sion is done it will call a subroutine to store the conversion in a variable. The main program will use this variable to display the conversion value on the LCD. 374 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Procedure: First we need to set up our definitions and global variables:

1. #include “iodefine_RX62N.h” 2. 3. //Glyph Includes 4. #include 5. #include 6. #include “src\Glyph\Glyph.h” 7. 8. //Define interrupt for AD1 9. #pragma interrupt (AD1_Interrupt(vect = VECT_AD1_ADI1)) 10. void AD1_Interrupt(void); 11. 12. //Function definitions 13. void main(void); 14. void InitADC(void); 15. void InitTimer(void); 16. void LED_Rotate(void); 17. void BSP_Display_String(int8_t aLine, char *aText); 18. #define LCD_LINE1 0 19. #define LCD_LINE2 1 20. #define LCD_LINE3 2 21. #define LCD_LINE4 3 22. 23. //Define global variables 24. T_glyphHandle G_lcd; 25. int Current_LED; 26. int ADCResult = 0; 27. char buffer [30];

From line 1 to 6 we have included all I/O files for the RX62N and the LCD. On line 8 through 10 we define our interrupt function for the A/D conversion done interrupt, and place a pointer at its vector in the interrupt table. Notice in our function definitions on lines 13 to 17 that we have made a function for initializing the ADC and timer. Also note on line 26 that we have made the global variable ADCResult, where we will hold the value read from the A/D con- version. The array on line 27 will be used to store the ASCII conversion of the ADCResult that is sent to the LCD. Next is our main function and while(1) loop:

1. void main(void) 2. { CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 375

3. float i; 4. InitADC(); 5. InitTimer(); 6. 7. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 8. /* use Glyph full access direct functions */ 9. GlyphNormalScreen(G_lcd); 10. GlyphSetFont(G_lcd, GLYPH_FONT_HELVR10); 11. GlyphClearScreen(G_lcd); 12. 13. BSP_Display_String(LCD_LINE1, “ADC Int Example”); 14. BSP_Display_String(LCD_LINE2, “Potentiometer Value:”); 15. 16. while(1){ 17. for(i = 0; i < 100000; i++); 18. sprintf(buffer, “%d”, ADCResult); 19. BSP_Display_String(LCD_LINE3, buffer); 20. } 21. } 22. else {} 23. 24. GlyphClose(&G_lcd); 25. 26. }

We create the variable i on line 3 to make our arbitrary delay loop on line 17. On lines 4 and 5 we call our functions to set up the timer and the AD converter. The code from lines 7 through 11 are initialization for the LCD. In lines 13 and 14 we display on the LCD some information concerning the program that is running. Then in our while(1) loop, repeatedly, after an arbitrary delay, we will convert our value from the A/D conversion to an ASCII string and write it to line 3 of the LCD. The rest of the code is LCD control code.

1. void InitADC(void){ 2. MSTP(AD1) = 0; 3. AD1.ADCSR.BIT.ADIE = 1; 4. AD1.ADCSR.BIT.ADST = 0; 5. AD1.ADCSR.BIT.CH = 0x000; 6. 7. AD1.ADCR.BIT.MODE = 0; 8. AD1.ADCR.BIT.CKS = 3; 9. AD1.ADCR.BIT.TRGS = 2; 376 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

10. IPR(AD1,ADI1) = 0x03; 11. IR(AD1,ADI1) = 0; 12. IEN(AD1,ADI1) = 1; 13. }

This is our function to set up the AD converter to read the value from the potentiometer. We will set it up to do a single conversion every time it receives a trigger from TMR0. First we enable the peripheral on line 2. Then on line 3 we enable the interrupt in the A/D peripheral; this will trigger the interrupt service routine every time a conversion finishes. We set the conversion to not start yet on line 4, and then select channel AN4 on line 5. It is indicated in the RX62N schematic that AN4 corresponds to the pin that is connected to the potentiome- ter. On line 7 we set the mode to single conversion, so every time the converter is triggered it will do one conversion then stop. We select the clock source for the AD converter as the peripheral clock on line 8. On line 9 we select the trigger as a Compare Match A event on TMR0. Every time a Compare Match A event occurs in TMR0 a signal will be sent to the A/D converter. This requires some set up in TMR0 as well; we will see that code shortly. On lines 10 through 12 we have the code to set the priority level, clear the request flag, and then enable the interrupt in the ICU.

1. void InitTimer(void){ 2. MSTP(TMR0) = 0; 3. MSTP(TMR1) = 0; 4. 5. TMR1.TCCR.BIT.CSS = 1; 6. TMR1.TCCR.BIT.CKS = 5; 7. 8. TMR0.TCCR.BIT.CSS = 3; 9. TMR0.TCR.BIT.CCLR = 1; 10. 11. TMR0.TCORA = 0x5B; 12. TMR1.TCORA = 0x6D; 13. 14. TMR0.TCSR.BIT.ADTE = 1; 15. }

Here is our code to set up a 16-bit cascaded timer that resets and generates a Compare Match A signal every one second. The code from lines 3 through 13 configures the timer to generate a one second interval; details are in the timer chapter of this text. The only code we need to examine here is on line 14, where we set the unit to send a trigger to the A/D converter every time there is a Compare Match A or every one second. CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 377

1. void AD1_Interrupt(void){ 2. ADCResult = AD1.ADDRA; 3. }

Our last bit of code is our interrupt subroutine for the A/D conversion. Every time a con- version finishes this routine will interrupt to write the latest conversion value to our vari- able, and then the program will return to its previous task. So, to review, this program begins by initializing the A/D converter and the TMR0. TMR0’s interrupt routine is not enabled, but the Compare Match A interrupt in the periph- eral will send a signal to the A/D converter every one second. Once triggered the A/D con- version will begin, and once finished it will trigger its own interrupt. This interrupts the main program for long enough to write the conversion value to a variable, then returns. In- side the main program there is a constant loop writing the A/D conversion to the LCD after a short delay. When run, the LCD screen should display “ADC Int Example” on line 1 of the LCD and “Potentiometer Value:” on line 2. On roughly one second intervals the screen should update with a new value for the potentiometer. This example illustrates two uses of interrupts, and an alternative use of interrupt sig- nals to triggering subroutines. By now you should be pretty familiar with the process of setting up an interrupt to trigger a subroutine as well as the concept of using them to trig- ger processes in other peripherals.

9.5 ADVANCED CONCEPTS

9.5.1 Minimizing the Amount of Code in Interrupts

In example 9.4.1, Polling a Switch for Input versus Using an Interrupt, it was pointed out that excessive function calls, or code in general, inside of an interrupt routine is bad. If a function call is made in an interrupt routine it requires that all the infor- mation be stored to the stack, which makes the compiler blind to register usage. Also, as mentioned several times in this book, it just simply adds more time and over head to the in- terrupt, and we want to avoid this as much as possible. So how do we do this? Often an ISR is used only to set flags or alter very small amounts of data. Then these flags or data are used to alter something in the main program. A flag can be a global variable that is toggled between one and zero. Once the program re- turns from the interrupt, some control statement will eventually use this as an indicator to change the program flow in some way. For example, say we have a program that is constantly checking the value of a ther- mistor but we only want it to update the value on the LCD screen every second. We would set up a timer to interrupt periodically every second, and when it interrupts it writes a one 378 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

to a variable named Timer_Flag. In our main program there is an if statement that checks the timer flag. When the Timer_Flag variable is 1 the function to write the value to the LCD is called. This way we still get the benefits of the interrupt, but keep our code in the interrupt minimal.

9.5.2 Brief Introduction to State Machines

In the next section we will cover how to make an interrupt controlled state machine. But first, in this section we need to give a brief overview of what a state machine is and how to program one. State machines are simply a method that makes it easier to abstract a process we want to perform in real life and convert it into a program. So far we have thought of programs as sequential processes. One process is executed, then some others, repeat. Sometimes that flow is altered slightly due to something happen- ing, such as an interrupt or control loops, but with an embedded system we still will restart in our while(1) loop eventually and the program will repeat and execute the same processes again. With state machines we think of our program as having ‘states.’ In each state there is a different flow of operations to perform. Depending on some change in data or a trigger- ing event, the state will change. The program will continue to perform the functions in this state until conditions are met to go into another state. We will implement the state machine by making a variable to represent the current state of the machine, and then using a switch statement to check that variable in the while(1) loop. If the variable is changed the state will change, otherwise the code in the current state will continue to run repeatedly. We can also make states that perform one task and then immediately switch to another state with- out to another state by default. In order to better understand a state machine, let’s imagine a vending machine as a state machine. The vending machine can be in a ‘state’ depending on what task it needs to perform at the current moment. In each state the program is focused on a particular func- tion such as accepting money, returning change, or vending drinks. In the case of the coin return state, it will return the proper amount of coins and then by default return to the Ac- cept Money state. The same for the vend state, which automatically goes to the Coin Re- turn state (which we assume simultaneously checks to see if coins are needed to be re- turned at all). In the case of the Accept Money state, the state will not change until a selection is made or the coin return button is pressed. In the case of the Check Correct Change state it will immediately go to either state 4 or 1, depending on if the right amount of change was deposited for the selection. This is how a state machine works on a very ba- sic level. A full implementation of a vending machine state machine would require many more states such as “jammed coin,” “machine tilt,” “coolant problem,” “out of order,” etc. In order to address the real world well embedded systems must get very intricate. This is just a simple illustrative example. CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 379

Switch(State)

Accept Check Correct Coin Money Change Return Vend

State 1 State 2 State 3 State 4

1. Get_Money() 1. Determine_ 1. Return_Change 1. Vend 2. if(selection_ Proper_ 2. {State = 1} (selection) made) Change() 2. {State = 3} 3. {State = 2} 2. if(proper_ 4. if(coin_ change) return) 3. State = 4 5. {State = 3} 4. Else { 5. Output “incorrect change” 6. {State = 1}

Figure 9.17 Vending machine state machine example.

9.5.3 State Machines and Using Them with Interrupts

So now that we know what a basic state machine looks like, we are going to demonstrate how to implement one effectively using interrupts to switch states. You’ll notice in the vend- ing machine examples that different actions triggered a state change, such as coin_return or selection made. These actions were represented as a variable of some sort and were checked by an If statement; if these variables were a one or higher the state was changed. Do these variables look familiar to something else we talked about in this chapter? These are simply the flags we talked about in Section 9.5.1, Minimizing the Amount of Code in Interrupts. So by setting flags with an interrupt we can have code in our states check these flags and change states based on input. Once again let’s use an example to illustrate. For this example let’s use the RX62N. We will make a state machine that will have three states. In one state the machine will rotate the LEDs in a circular sequence. In the second state we will display the value of the potentiometer on the LCD. In the third state the LCD will display the number of seconds elapsed since the program has started. Each time switch 380 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Switch(State)

Rotate Display A/D of Display LEDs Potentiometer Seconds

State 1 State 2 State 3

1. if(Second_Flag){ 1. if(AD_Flag){ 1. if(Second_Flag){ 2. DisplayLEDs(); 2. DisplayADC(); 2. DisplaySec(); 3. Second_Flag = 0; 3. Second_Flag = 0 3. Second_Flag = 0; 4. } 4. } 4. }

Figure 9.18 RX62N state machine example with interrupts.

one is pressed the board will cycle to the next state, once it goes beyond state three it will re- turn to state one. We will make it that each state performs its actions at one second intervals. With state machines this implementation is very simple. We only need three states as specified. The flag indicating which state is currently active is rotated using the ISR for switch one, defaulting to state one on start. Every second the timer will interrupt and set a flag that a second has passed, this flag will trigger actions in States 1 and 3. Note that the DisplayLEDs function in State 1 will include a function call to rotate the LEDs as well as display information on the LCD, thus rotating the LEDs. In the case of State 2 we are using the A/D converter, so we will use a flag set by its own ISR to trigger this state’s actions. This will occur on roughly one second intervals since the A/D itself will be set to be triggered by a signal from the Timer device. This is a full, very basic state machine that uses interrupts to switch states. We will give a coding example of this in the advanced examples section.

9.6 ADVANCED EXAMPLES

9.6.1 Using an ADC Interrupt with Flags to Process Data

Aim: Demonstrate using flags with an interrupt to minimize the time spent in an ISR.

Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, RX62N Development kit. CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 381

Details: In this example, we will set up the A/D converter once again to perform a con- version, except in this example the A/D will trigger an interrupt when the conversion is done. This interrupt will set a flag that is checked in the main code to trigger, writing the new data to the LCD.

Procedure: The code is mostly the same as our example in Section 9.4.2, Setting up the ADC with an Interrupt, except with modifications so that it now operates around the A/D interrupt. Our variable and function prototypes are mostly the same.

1. #include “iodefine_RX62N.h” 2. 3. //Glyph Includes 4. #include 5. #include . 6. #include “src\Glyph\Glyph.h” 7. 8. //Define interrupt for AD1 9. #pragma interrupt (AD1_Interrupt(vect = VECT_AD1_ADI1)) 10. void AD1_Interrupt(void); 11. 12. //Function definitions 13. void main(void); 14. void InitADC(void); 15. void InitTimer(void); 16. void LED_Rotate(void); 17. void BSP_Display_String(int8_t aLine, char *aText); 18. #define LCD_LINE1 0 19. #define LCD_LINE2 1 20. #define LCD_LINE3 2 21. #define LCD_LINE4 3 22. 23. //Define global variables 24. T_glyphHandle G_lcd; 25. int Current_LED; 26. int ADCResult = 0; 27. char AD_Flag = 0; 28. char buffer [30];

The only difference here is we have added the AD_Flag variable on line 27. It is initialized to zero to indicate the interrupt has not been triggered yet. 382 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

1. void main(void){ 2. ENABLE_LEDS 3. InitADC(); 4. InitTimer(); 5. 6. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 7. /* use Glyph full access direct functions */ 8. GlyphNormalScreen(G_lcd); 9. GlyphSetFont(G_lcd, GLYPH_FONT_HELVR10); 10. GlyphClearScreen(G_lcd); 11. 12. BSP_Display_String(LCD_LINE1, “ADC Int Flag Example”); 13. BSP_Display_String(LCD_LINE2, “Potentiometer Value:”); 14. 15. while(1){ 16. if(AD_Flag){ 17. ADCResult = AD1.ADDRA; 18. sprintf(buffer, “%d”, ADCResult); 19. BSP_Display_String(LCD_LINE3, buffer); 20. AD_Flag = 0; 21. } 22. } 23. } 24. else{} 25. 26. GlyphClose(&G_lcd); 27. 28. }

Our main code has only been modified so all code to do with reading the A/D conversion value and writing it to the LCD has been placed in an If statement. When the AD_Flag vari- able becomes a 1 or higher this will cue the code to execute, then the flag will be reset to 0. The code will not execute again until the flag has been set to 1 again. We won’t cover the InitADC or InitTimer functions again as they are identical to a pre- vious example. We are once again setting a one second interval timer. The timer generates a Compare Match A signal after one second that resets the timer and sends a signal to the AD converter to start converting. Once done, the A/D converter will trigger its own inter- rupt that will call an ISR.

1. void AD1_Interrupt(void){ 2. AD_Flag = 1; //Set A/D conversion flag 3. } CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 383

Now the A/D conversion ISR will set the flag to one, indicating the conversion is done.

Conclusion: We have effectively altered our old program to use an interrupt and a flag to indicate data is ready from an external device. The flag now triggers the execution of a large amount of code in the main program. Keeping this code out of the interrupt ser vice routine improves responsiveness for other ISRs.

9.6.2 A Simple State Machine Controlled by Interrupts

Aim: Demonstrate a state machine whose state is altered by an interrupt.

Requirements: PC with High-performance Embedded Workshop 4.0 or 4.0, RX62N Development kit, RX62N Graphical LCD Code package.

Details: In this example, we will set up a state machine on the RX62N. When SW1 is pressed, the machine will rotate states. In State 1 the LEDs will blink clockwise at a rate of one LED per second. In State 2 the LCD will display the current ADC reading across the board’s potentiometer every second. In State 3 the LCD will display the number of seconds elapsed since the program started. If the switch is pressed again the state will rotate back to State 1.

Procedure: First we once again need to set up our definitions and global variables:

1. #include “iodefine_RX62N.h” 2. 3. //Glyph Includes 4. #include 5. #include 6. #include “src\Glyph\Glyph.h” 7. 8. //Define SW1 interrupt 9. #pragma interrupt (SW1_Int(vect = VECT_IRQ8)) 10. void SW1_Int(void); 11. 12. //Define interrupt for TMR0 Compare Match A 13. #pragma interrupt (TMR0_CompareMatchA_Interrupt (vect = VECT_TMR0_CMIA0)) 14. void TMR0_CompareMatchA_Interrupt(void); 15. 16. //Define interrupt for AD1 384 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

17. #pragma interrupt (AD1_Interrupt(vect = VECT_AD1_ADI1)) 18. void AD1_Interrupt(void); 19. 20. //Function definitions 21. void main(void); 22. void InitADC(void); 23. void InitTimer(void); 24. void EnableIRQ8(void); 25. void LED_Rotate(void); 26. void DisplaySec(void); 27. void DisplayADC(void); 28. void DisplayLEDs(void); 29. void BSP_Display_String(int8_t aLine, char *aText); 30. #define LCD_LINE1 0 31. #define LCD_LINE2 1 32. #define LCD_LINE3 2 33. #define LCD_LINE4 3 34. 35. //Define global variables 36. T_glyphHandle G_lcd; 37. int Current_LED; 38. int State = 1; 39. int Second_Flag; 40. int AD_Flag; 41. int SecCount; 42. int ADCResult = 0; 43. char buffer [30];

For this example we will use three ISRs. One each for the switch interrupt, the A/D con- version interrupt, and the TMR0 interrupt. These are defined on lines 8 through 18. On lines 22 to 24 we define our functions to set up each of these peripherals. We have also de- fined functions to call to display these on lines 26 through 28. On line 38 we create our state variable; altering this variable will alter which state we are in. On lines 39 to 40 we create flags for each interrupt, so when the interrupt is triggered the ISRs will set these flags, and then the main program will use these to trigger code to handle the events. On line 41 we create a global variable that counts the number of seconds the program has run. Now we have our main program code, which is very simple.

1. void main(void){ 2. ENABLE_LEDS 3. InitADC(); CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 385

4. InitTimer(); 5. EnableIRQ8(); 6. 7. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 8. /* use Glyph full access direct functions */ 9. GlyphNormalScreen(G_lcd); 10. GlyphSetFont(G_lcd, GLYPH_FONT_HELVR10); 11. GlyphClearScreen(G_lcd); 12. 13. BSP_Display_String(LCD_LINE1, “State Machine”); 14. 15. while(1){ 16. switch(State){ 17. case 1: 18. if(Second_Flag){ 19. DisplayLEDs(); 20. Second_Flag = 0; 21. } 22. break; 23. case 2: 24. if(AD_Flag){ 25. DisplayADC(); 26. AD_Flag = 0; 27. } 28. break; 29. case 3: 30. if(Second_Flag){ 31. DisplaySec(); 32. Second_Flag = 0; 33. } 34. break; 35. default: 36. //In the off chance that the State variable is set to something other than 1 through 3 37. //we will be informed via this default state. 38. BSP_Display_String(LCD_LINE1, “Error”); 39. break; 40. } 41. } 42. } 43. else{} 44. 386 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

45. GlyphClose(&G_lcd); 46. 47. }

First on lines 2 through 5 we call our macros and functions to enable the LEDs and each of our peripherals (the A/D, timer and SW1). After the code to set up the LCD we enter our while(1) loop, where the only code we have is our state machine. This is implemented via a switch statement that uses the state variable to control it. In State 1 we will check the Second_Flag; every time it is set we will call the DisplayLEDs function which will update the LCD to display our state and then rotate the LEDs. In State 2 we check the A/D con- version finish flag, as the A/D conversion itself is trigger by the timer interrupt and we don’t want to write the A/D value until the conversion is finished. When the flag is set, we will call the DisplayADC function which updates the LCD for the state and displays the conversion of the voltage across the potentiometer. In State 3 we check the second flag and once it is set we call the DisplaySec function, which updates our LCD for the state and dis- plays the number of seconds elapsed on the screen. Now we will go over out peripheral setup functions.

1. void InitADC(void){ 2. MSTP(AD1) = 0; 3. AD1.ADCSR.BIT.ADIE = 1; 4. AD1.ADCSR.BIT.ADST = 0; 5. AD1.ADCSR.BIT.CH = 0x000; 6. 7. AD1.ADCR.BIT.MODE = 0; 8. AD1.ADCR.BIT.CKS = 3; 9. AD1.ADCR.BIT.TRGS = 2; 10. 11. IPR(AD1,ADI1) = 0x03; 12. IR(AD1,ADI1) = 0; 13. IEN(AD1,ADI1) = 1; 14. } 15. 16. void InitTimer(void){ 17. MSTP(TMR0) = 0; 18. MSTP(TMR1) = 0; 19. 20. TMR1.TCCR.BIT.CSS = 1; 21. TMR1.TCCR.BIT.CKS = 5; 22. CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 387

23. TMR0.TCCR.BIT.CSS = 3; 24. TMR0.TCR.BIT.CCLR = 1; 25. 26. TMR0.TCORA = 0x5B; 27. TMR1.TCORA = 0x6D; 28. 29. TMR0.TCSR.BIT.ADTE = 1; 30. TMR0.TCR.BIT.CMIEA = 1; 31. 32. IPR(TMR0,CMIA0) = 3; 33. IR(TMR0,CMIA0) = 0; 34. IEN(TMR0,CMIA0) = 1; 35. 36. } 37. 38. void EnableIRQ8(void){ 39. IEN( ,IRQ8) = 0; 40. PORT4.ICR.BIT.B0 = 1; 41. ICU.IRQCR [8].BIT.IRQMD = 0x01; 42. ENABLE_SWITCHES 43. IPR( ,IRQ8) = 0x03; 44. IR( ,IRQ8) = 0; 45. IEN( ,IRQ8) = 1; 46. }

Each of these peripherals is set up as in previous examples so we won’t have to review the code extensively. AD1 is set up to be triggered every time TMR0 sends it a Compare Match A signal, once triggered it will convert the voltage across the board’s potentiometer and then trigger its ISR. TMR0 will generate a Compare Match A signal and trigger its ISR every second. SW1 will trigger its ISR every time it is pressed via IRQ8.

1. void DisplayLEDs(void) 2. { 3. LED_Rotate(); 4. BSP_Display_String(LCD_LINE2, “State 1”); 5. BSP_Display_String(LCD_LINE3, “Rotating LEDs”); 6. BSP_Display_String(LCD_LINE4, “ ”); 7. } 8. 9. void DisplayADC(void){ 388 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

10. ADCResult = AD1.ADDRA; 11. sprintf(buffer, “%d”, ADCResult); 12. BSP_Display_String(LCD_LINE2, “State 2”); 13. BSP_Display_String(LCD_LINE3, “Potentiometer Value:”); 14. BSP_Display_String(LCD_LINE4, buffer); 15. } 16. 17. void DisplaySec(void){ 18. sprintf(buffer, “%d”, SecCount); 19. BSP_Display_String(LCD_LINE2, “State 3”); 20. BSP_Display_String(LCD_LINE3, “Seconds Count:”); 21. BSP_Display_String(LCD_LINE4, buffer); 22. }

Our display functions are quite similar. As said before, each one updates the LCD and per- forms necessary actions based on which interrupt it is related to. The DisplayLEDs func- tion calls the LED_Rotate function. The DisplayADC function updates the variable that contains the conversion result, and converts it to ASCII before sending it to the LCD. The DisplaySec function merely converts the seconds count variable to ASCII as the variable is updated in the ISR. Now we will cover our interrupt functions themselves.

1. //Timer 0 Compare Match A Interrupt 2. void TMR0_CompareMatchA_Interrupt(void){ 3. Second_Flag = 1; 4. SecCount++; 5. } 6. 7. //AD1 Conversion Finished Interrupt 8. void AD1_Interrupt(void){ 9. AD_Flag = 1; 10. } 11. 12. 13. //SW1 Interrupt 14. void SW1_Int(void){ 15. State++; 16. if(State >= 4){ 17. State = 1; 18. } 19. } CHAPTER 9 / USING INTERRUPTS WITH PERIPHERALS 389

Each ISR is kept very simple. The TMR0 ISR merely sets the second flag and increments the count of the number of seconds. The AD1 interrupt only sets its flag. The SW1 interrupt increments the state, if it is 4 or greater the state is reset to 1. Once compiled and run the state machine should start off in State 1. The LEDs will once again rotate on a one second interval with the state displayed on the LCD. Once SW1 is pressed, the state will increment to State 2 where the A/D conversion result from the po- tentiometer will update on the LCD every one second along with the state information. When SW1 is pressed again, the seconds count will be displayed on the screen along with State 3’s info.

9.7 RECAP

In this chapter we have made a broad overview of the interrupt features on the RX62N and how they can be used with the different peripherals. We started by covering reasons for us- ing an interrupt for tasks as compared to other techniques. Then we covered the full process of setting up an interrupt as it may apply to any peripheral. In the advanced con- cepts section we went over the reasons for keeping code minimal in interrupts. Then an ex- ample of a full implementation of interrupts was presented by introducing state machines and then describing a state machine controlled purely by peripheral interrupts.

9.8 REFERENCES

Conrad, James. ECGR 4101 Class Lecture; Topic: “Interrupts, and Using Them in C.” Charlotte, NC: Department of Electrical and , University of North Carolina at Charlotte; July, 2010. Lecture. RX62N Group, RX621 Group Hardware Manual: RX62N Hardware Manual. Renesas Electronics America, Inc., Feb, 2010. Print.

9.9 EXERCISES

1. You want to set up one of the switches on the RX62N board to trigger an interrupt. List the registers you need to modify and the values you need to assign to them. 2. List at least three advantages of using an interrupt to signal data ready from a de- vice rather than polling. 3. List at least five examples of an application where using an interrupt to signal data from a processor peripheral would greatly speed up a program. 390 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

4. Choose one of these examples and write pseudocode explaining how you would program this. Include descriptions of the interrupt function, your interrupt initial- ization function, and your main function. 5. Explain how you would use a flag to signal and process data from a device with an interrupt. 6. Why would you use a flag to signal processing of the data in the main program in- stead of placing all of the code in the interrupt? 7. What advantages does a state machine approach have over a purely sequential ap- proach to embedded programming? 8. Give some examples of where a state machine would be a good choice of design approach. 9. Choose one of those examples and make a simple state machine design such as the one in Section 9.5.2, Brief Introduction to State Machines. Chapter Ten

Floating Point Unit and Operations

10.1 LEARNING OBJECTIVES

All microprocessors can store and operate on integers. However, often we wish to operate on real numbers. We can represent these values with fixed- point or floating- point ap- proaches. Fixed- point math is nearly as fast as integer math. Its main drawback is that the designer must understand the sizes of the smallest and largest data values in order to deter- mine the appropriate fixed- point representation. Floating- point math automatically adjusts the scaling to account for large and small values. Generally floating- point math is emulated in software, but some microprocessors have special hardware called a Floating Point Unit (FPU) for executing these operations natively, greatly increasing the speed. Though the FPU varies with the microcontroller, or with dif- ferent families of microcontrollers, we will be discussing the FPU in the RX62N microcon- troller and comparing it with the software emulation of a FPU on the QSK62P board. In this chapter the reader will learn:

The Instruction Set Architecture (ISA) of the RX62N Floating Point Unit Differences between a fixed point and a floating point operation Handling floating point exceptions

10.2 BASIC CONCEPTS

10.2.1 Floating Point Basics

Floating Point Representation Before taking a look at the FPU in the RX62N, let’s look at the basics of floating point. Consider a floating point number, say 241.3247810. It denotes the following.

102 101 100 101 102 103 104 105

8 7 4 2 3 ؒ 1 4 2

Figure 10.1 Decimal floating point representation.

391 392 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The number in the box is the significand, 10 is the base and the power to which 10 is raised is the exponent. We can represent the above number in exponential form as 2.4132478 102. Consider a binary number, say 1011.01102. The number can be represented as:

23 22 21 20 21 22 23 24

0 1 1 0 ؒ 1 1 0 1

Figure 10.2 Binary floating point representation.

We can represent the above binary number in exponential form as 1.0110110 23. From the above notations, we can generalize the floating point expression as:

(1)sign Significand BaseExponent

Though the decimal floating point representation is simple, it cannot be used by microcon- trollers to work on floating point numbers. Since they work on binary digits, the IEEE 754 Floating Point Standard was introduced to represent decimal numbers as binary numbers.

IEEE 754 Floating Point Standard In order to standardize floating point arithmetic, the IEEE 754 floating point standard was first introduced in 1985. Though the current version of IEEE 754 is IEEE 754–2008, it in- cludes the original information in IEEE 754–1985 as well. The binary floating point numbers represented by IEEE 754 are in sign magnitude form where the most significant bit is the sign bit followed by the biased exponent and significand without the most significant bit. The field representation of IEEE 754 is as follows.

Sign Exponent Significand

Figure 10.3 IEEE 754 floating point representation.

The IEEE 754 defines four formats for representing floating point values.

Single- Precision (32 bit) Double Precision (64 bit) CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 393

Single Extended Precision ( 43 bit, not commonly used) Double Extended Precision ( 79 bit, not commonly used)

The IEEE 754 Floating Point Standard Though the number of bits varies in each precision, the format for representing the floating point number is the same. The format for representing a floating point number according to IEEE 754 is as follows.

(1)sign (1 Significand) 2Exponent-Bias

Since we will not be using Single Extended Precision and Double Extended Precision, we will look at Single Precision and Double Precision in detail.

Single Precision (32 bits) Single Precision consists of 4 bytes (or) 32 bits, where the 32 bits are divided into the fol- lowing fields.

1 bit 8 bits 23 bits

Sign Exponent Significand

Figure 10.4 IEEE 754 single precision floating point representation.

In order to obtain the Single Precision representation, a few general steps are to be followed.

Convert the decimal into a binary number. Express the binary number in normalized exponential notation. Since we are rep- resenting binary numbers, the power will be raised to 2, which is the base. Since we need to represent the exponent as an 8 bit binary number, we add 127 to the exponent in the normalized notation if the number we need to represent is positive. If the number we need to represent is negative, we subtract the exponent in the nor- malized notation from 127. Having done that, we add the significand bits by extending it to 23 bits. 394 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

EXAMPLE 1

A decimal number can be represented as a Single Precision number as follows. Consider a number, say 10.010

0 3 10.010 1010 2 or 1.010 2

In the above number 1.010 23, the significand is 010 as the number before the decimal point will always be 1. Since the significand here does not have a specific pattern of repeti- tion, the 23 bit significand field will be the significand appended with zeroes at the end. From the above number: Sign Bit: 0 (Since the number is positive). Exponent: 127 3 130. For simplification, let’s split 130 as 128 2. As 128 is nothing but 8-bit or 100000002

12810 210 100000002 000102 100000102

Significand: 0100 0000 0000 0000 0000 000 (010 appended with zeroes) From the Single Precision field representation, we can represent this number as:

1 bit 8 bits 23 bits

0 10000010 0100 0000 0000 0000 0000 000

Figure 10.5 Example 1; single precision conversion.

EXAMPLE 2

Consider a negative floating point number, say 0.110.

0 4 0.110 0.000110011 2 or 1.10011 2

In the binary number 1.10011, the 0011 pattern is repeated. Since the number has a pattern which gets repeated, the significand is 1 followed by a pattern of 0011.

Therefore, from the above number:

Sign Bit: 1 (Since the number is negative)

Exponent: 127 4 123 CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 395

Since 123 is less than 128, we cannot adopt the technique used in Example 10.1.

We know 12310 0111 10112

Significant: 1001 1001 1001 1001 1001 100

From the Single Precision field representation, we can represent this number as,

1 bit 8 bits 23 bits

1 0111 1011 1001 1001 1001 1001 1001 100

Figure 10.6 Example 2; single precision conversion.

Double Precision (64 bits) Double Precision consists of 8 bytes (or) 64 bits, where the 64 bits are divided into the fol- lowing fields.

1 bit 11 bits 52 bits

Sign Exponent Significand

Figure 10.7 IEEE 754 double precision floating point representation.

Obtaining the Double Precision numbers, follow the same steps we adopted for Single Pre- cision numbers but with different bits. In order to obtain the Double Precision representation, the following steps are adopted:

Convert the decimal into a binary number. Express the binary number in normalized exponential notation. Since we are rep- resenting binary numbers, the power will be raised to 2, which is the base. Since we need to represent the exponent as an 11 bit binary number, we add 1023 to the exponent in the normalized notation if the number we need to repre- sent is positive. If the number we need to represent is negative, we subtract the exponent in the nor- malized notation from 1023. Having done that, we add the significand bits which is 52 bits wide. 396 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

EXAMPLE 3

Consider Example 10.1. To represent the number 1010 to a Double Precision number, we do the following.

10 1010 20 or 1.010 23

In the above number 1.010 23, the significand is 010 as the number before the decimal point will always be 1. Since the significand here does not have a specific pattern of repeti- tion, the 52 bit significand field will be the significand appended with zeroes at the end.

From the above number,

Sign Bit: 0 (Since the number is positive).

Exponent: 1023 3 102610 100000000102 Significand: 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 (010 appended with zeroes) From the Double Precision field representation, we can represent this number as:

1 bit 11 bits 52 bits

0 10000000010 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

Figure 10.8 Example 3; double precision conversion.

EXAMPLE 4

Consider Example 10.2. To represent the number 0.110 to a Double Precision number, we do the following:

0.1 0.00011 20 or 1.10011 24

Therefore, from the above number,

Sign Bit: 1 (Since the number is negative)

Exponent: 1023 4 1019 101910 011111110112 CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 397

Significand: 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010

From the Double Precision field representation, we can represent this number as:

1 bit 11 bits 52 bits

1 01111111011 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010

Figure 10.9 Example 4; double precision conversion.

10.2.2 Pipelining Basics

In order to understand the floating point operations in microcontrollers and the difference between fixed point and floating point operations, it is necessary to take a look at the some of the basics of pipelining. Pipelining is the technique adopted for increasing the instruction throughout and reduc- ing the number of clock cycles required to execute an instruction by microprocessors. It is a method of realizing temporal parallelism, an assembly line processing technique. The in- struction is broken down into a sequence of sub- tasks, each of which can be executed con- currently with other stages in the pipeline. The basic consists of five stages:

Instruction Fetch Instruction Decode Execute Memory Access Write Back

IF ID EX MEM WB

Figure 10.10 A basic pipeline.

Instruction Fetch The Instruction Fetch (IF) cycle fetches the current instruction from the memory into the program counter (PC). It updates the PC to the next sequential instruction. 398 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Instruction Decode The Instruction Decode cycle (ID) decodes the instruction and reads the registers corresponding to the specified register source. It performs an equality test of registers for a possible branch. The decoding is done in parallel with reading registers.

Execution The Execution (EX) cycle does the following:

Memory Reference—Calculates effective address. Register—Register Operation—ALU performs the operation specified by the ALU opcode on the values read from the register file. Register- Immediate Operation—Operation specified by the ALU on the value read from the register and the sign- extended immediate.

Memory Access The Memory Access (MEM) cycle does the following operations:

Load—A read operation performed by the memory using the calculated effective address. Store—A write operation performed by the memory from the register read from the register file using the effective address.

Write- Back The Write- Back (WB) cycle writes the result into the register file, whether it comes from the memory system (load) or from the ALU (ALU instruction).

10.2.3 Floating Point in RX62N

In order to handle floating point operations, RX62N has the following:

A Floating Point Unit Floating Point Instructions Floating Point Registers Floating Point Exceptions CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 399

Floating Point Unit The Floating Point Unit (FPU) in RX62N operates on Single Precision floating point operands (32-bit) and the data- types and floating point exceptions conform to the IEEE 754 standard. This implementation facilitates the FPU to operate directly on the CPU registers rather than the dedicated register sets, thereby avoiding extra load/store operations and improving the per- for mance. Figure 10.11 shows the floating point unit architecture in RX62N.

General Traditional General register RX operation register FPU operation using general using No load/store registers dedicated instruction data registers needed

Load/store Floating- point unit

Dedicated data register

Floating- point unit

Figure 10.11 Architecture used by RX62N with dedicated registers for floating point operations.

Floating Point Registers The RX62N uses a single floating point register, Floating- Point Status Word (FPSW) to in- dicate the results of the floating- point operations. It is a 32-bit register consisting of flags, bits representing modes for rounding off floating point numbers, exception enable/disable bits and reserved bits. Figure 10.12 shows the FPSW bits and Table 10.1 shows the bit defi- nitions for the FPSW.

b31 b30 b29 b28 b27 b26 b25 b24 b23 b22 b21 b20 b19 b18 b17 b16

FS FX FU FZ FO FV — — — — — — — — — —

Value after reset: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0

— EX EU EZ EO EV — DN CE CX CU CZ CO CV RM[1:0]

Value after reset: 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0

Figure 10.12 Floating- point status word. Source: Software Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series, Renesas Electronics America, Inc., 2010, Section 2.2.2.8. 400 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 10.1 Floating- Point Status Word Bit Definition.

BIT SYMBOL BIT NAME DESCRIPTION R/W b1, b0 RM[1Ϻ0] Floating- point b1 b0 R/W rounding- mode 0 0: Round to the nearest value setting bits 0 1: Round towards 0 1 0: Round towards ϱ 1 1: Round towards ϱ b2 CV Invalid operation 0: No invalid operation has been R/(W)*1 cause flag encountered. 1: Invalid operation has been encountered. b3 CO Overflow cause 0: No overflow has occurred. R/(W)*1 flag 1: Overflow has occurred. b4 CZ Division- by- zero 0: No division- by- zero has occurred. R/(W)*1 cause flag 1: Division- by- zero has occurred. b5 CU Underflow cause 0: No underflow has occurred. R/(W)*1 flag 1: Underflow has occurred. b6 CX Inexact cause flag 0: No inexact exception has been generated. R/(W)*1 1: Inexact exception has been generated. b7 CE Unimplemented 0: No unimplemented processing has been R/(W)*1 processing cause encountered. flag 1: Unimplemented processing has been encountered. b8 DN 0 flush bit of 0: A denormalized number is handled as a R/W denormalized denormalized number. number 1: A denormalized number is handled R/W as 0.*2 b9 — Reserved When writing, write 0 to this bit. The value R/W read is always 0.

Source: Software Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series, Renesas Electronics America, Inc., 2010, Section 2.2.2.8. CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 401

Floating Point Instructions The RX62N uses eight floating point instructions to perform floating point operations. All floating point instructions work on single precision floating point operands conforming to IEEE754 standard. The floating point instructions are as follows:

FADD Function: Adds two floating point operands and stores the result in the register file. Operations performed: Immediate- Register and Register- Register. Number of cycles taken: Four.

FADD Operation:

FADD R2, R4 IF D E (mop) fadd-1 D E (mop) fadd-2 D E (mop) fadd-3 D E WB (mop) fadd-4 Write to R4

Figure 10.13 FADD Operation (Register-Register, Immediate- Register). Source: Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series, Renesas Electronics America, Inc., 2010, Figure 2.19.

FSUB Function: Subtracts the second floating point operand from the first floating point operand and stores the result in the register file. Operation performed: Immediate- Register, Register- Register. Number of cycles taken: Four.

FSUB Operation:

FSUB R2, R3 IF D E (mop) fsub-1 D E (mop) fsub-2 D E (mop) fsub-3 D E WB (mop) fsub-4 Write to R3

Figure 10.14 FSUB Operation (Register-Register, Immediate- Register). Source: Hardware Manual. 402 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 10.1 Floating- Point Status Word Bit Definition.—Continued

BIT SYMBOL BIT NAME DESCRIPTION R/W b10 EV Invalid operation 0: Invalid operation exception is masked. R/W exception enable 1: Invalid operation exception is enabled. bit b11 EO Overflow 0: Overflow exception is masked. R/W exception enable 1: Overflow exception is enabled. bit b12 EZ Division- by- zero 0: Division- by- zero exception is masked. R/W exception enable 1: Division- by- zero exception is enabled. bit b13 EU Underflow 0: Underflow exception is masked. R/W exception enable 1: Underflow exception is enabled. bit B14 EX Inexact exception 0: Inexact exception is masked. R/W enable bit 1: Inexact exception is enabled. b25 to — Reserved When writing, write 0 to these bits. The value R/W b15 read is always 0. b26 FV*3 Invalid operation 0: No invalid operation has been R/W flag encountered. 1: Invalid operation has been encountered.*8 b27 FO*4 Overflow flag 0: No overflow has occurred. R/W 1: Overflow has occurred.*8 b28 FZ*5 Division- by- zero 0: No division- by- zero has occurred. R/W flag 1: Division-by-zero has occured b29 FU*6 Underflow flag 0: No underflow has occurred. R/W 1: Underflow has occurred.*8 b30 FX*7 Inexact flag 0: No inexact exception has been generated. R/W 1: Inexact exception has been generated.*8 b31 FS Floating- point This bit reflects the logical OR of the FU, FZ, R error summary FO, and FV flags. flag CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 403

FCMP Function: Compares the floating point operands and updates the status register based on the results. The difference between FSUB and FCMP is that, FCMP does not store the re- sult anywhere.

Operation performed: Immediate- Register, Register- Register. Number of cycles taken: Four.

FSUB Operation:

FSUB R2, R3 IF D E (mop) fsub-1 D E (mop) fsub-2 D E (mop) fsub-3 D E WB (mop) fsub-4 Write to R3

Figure 10.15 FSUB Operation (Register-Register, Immediate- Register). Source: Hardware Manual.

Floating Point Exceptions The floating point exceptions are basically exceptions which arise due to inappropriate floating point operations. According to IEEE 754 standard, there are five floating- point ex- ceptions as follows:

Overflow Underflow Inexact Division- by- zero Invalid Operation

Overflow This exception occurs when the result of a floating- point operation is too large. Under such circumstances, the result cannot be represented as a single- precision floating point number (32 bit) or a double precision floating point number (64 bit).

The limits for signed single precision floating point numbers are 3.4E 38 to 3.4E 38. 404 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

The limits for unsigned single precision floating point numbers are 0 to 6.8E38. The limits for signed double precision floating point numbers are 1.7E 308 to 1.7E 308. The limits for unsigned double precision floating point numbers are 0 to 3.4E 308.

If the result exceeds these limits, an overflow exception is raised.

Underflow This exception occurs when the result is too small to be represented as a normalized floating- point number.

Inexact This exception occurs when the result is not a single- precision floating point number. Rounding off the result and using it as a single- precision floating point number may cause this exception.

Divide- By- Zero This exception occurs when a floating point number is divided by zero.

Invalid Operation This exception occurs when the result is ill- defined. For example, an operation leading to a result which is ϱ (Infinty) or NaN (Not a number) could cause this exception. For example, 1.0 / 0.0 ϱ, 0.0 / 0.0 NaN.

10.3 BASIC EXAMPLES

10.3.1 Operations Explaining Floating Point Exceptions

Before working on the RX62N’s FPU, it is important to take a look at the operations caus- ing Floating Point Exceptions, so that they can be handled efficiently. The Floating- point error summary flag (FS) notifies the programmer that an error (overflow, underflow, invalid operation, inexact, or division- by- zero) has occurred. CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 405

EXAMPLE 1

Overflow Exception

Consider the following example:

1. float a, c; 2. a = 999999969999999923.235; 3. c = a * 9999999999999969999999923.235;

The above operation causes an Overflow exception. To observe this exception, the contents of the FPSW can be viewed. Click on the (Registers icon) in the CPU Toolbox.

Figure 10.16 CPU toolbox.

For the above example, the FPSW was C8000100, where the Radix is Hexadecimal.

C 8 0 0 0 1 0 0

0000 0000

0001 DN 1 0000 0000 0000

1000 FO 1 1100 FX 1 FS 1 Figure 10.17 Example 1; FPSW. 406 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

From the above example:

DN 1, where a denormalized number is handled as 0. FO 1, where an overflow exception has occurred. FX 1, where an inexact exception has been generated. FS 1, where the logical OR of the exception flags, except inexact exception, is 1; meaning an overflow/underflow/divide- by- zero/invalid operation exception flag has been set.

EXAMPLE 2

Underflow Exception Consider the following example:

1. float a, c; 2. a = 0.00000000000000000000000000000005623; 3. c = a * 0.00000000000000000000000001235431435234;

The above operation causes an Underflow Exception. The FPSW has the following value.

A 0 0 0 0 1 2 0

0000

0010 CU 1 0001 DN 1 0000 0000 0000 0000

1010 FU 1 FS 1 Figure 10.18 Example 2; FPSW.

From the above example:

CU 1, where an underflow operation has occurred. DN 1, where a denormalized number is handled as 0. CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 407

FU 1, where an underflow exception has occurred and the underflow flag has been set. FS 1, where the logical OR of the exception flags, except inexact exception, is 1; meaning an overflow/underflow/divide- by- zero/invalid operation exception flag has been set.

EXAMPLE 3

Divide- by- Zero Exception Consider the following example:

1. float a, c; 2. a = 1.2; 3. c = a / 0;

The above code returns a divide- by- zero exception and the FPSW has the following value.

9 0 0 0 0 1 0 0

0000 0000

0001 DN 1 0000 0000 0000 0000

1001 FZ 1 FS 1 Figure 10.19 Example 3; FPSW.

From the above example:

DN 1, where a denormalized number is handled as 0. FZ 1, where Division- by- zero flag has been set. FS 1, where the Floating- point error summary flag has been set. 408 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

EXAMPLE 4

Invalid Operation Consider the following example:

1. float c; 2. c = 0.0 / 0.0;

The above code returns an Invalid Operation and the FPSW has the following value.

8 4 0 0 0 1 0 4

0100 CV 1 0000

0001 DN 1 0000 0000 0000 0100

1000 FV 1 FS 1 Figure 10.20 Example 4; FPSW.

From the above example:

CV 1, where an invalid operation has occurred. DN 1, where a denormalized number is handled as 0. FV 1, where an invalid operation exception has occurred and the invalid opera- tion flag has been set. FS 1, where the the floating- point error summary flag has been set.

10.4 ADVANCED CONCEPTS OF RX62N FLOATING POINT UNIT

10.4.1 FPSW in Detail

In order to perform complex floating point operations and handle floating point exceptions, a detailed knowledge about the FPSW is important. The bits in the FPSW can be catego- rized as follows: CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 409

Rounding- Modes Using the RM bits in the FPSW, the floating point value or the result can be rounded to 0, ϱ, ϱ or the nearest value. The bits b0 and b1 in the RM represent the rounding- mode. By default, the values are rounded towards the nearest absolute value. Consider Table 10.2, for RM bit definitions.

TABLE 10.2 RM Bit Definitions in FPSW.

BIT SYMBOL BIT NAME DESCRIPTION b1, b0 RM[1Ϻ0] Floating- point rounding- mode b1 b0 setting bits 0 0: Round to the nearest value 0 1: Round towards 0 1 0: Round towards ϱ 1 1: Round towards ϱ

Source: Software Manual, page 24.

Round to the nearest value: With this rounding- mode, the inexact value or the in- exact result is rounded to the nearest absolute value. If two absolute values are equally close, the result is the one with the even alternative. Round towards 0: With this rounding mode, the inexact value or the inexact result is rounded to the smallest available absolute value in the direction of zero. Round towards ϱ: The inexact value is rounded to the nearest available value in the direction of ϱ. Round towards ϱ: The inexact value is rounded to the nearest available value in the direction of ϱ.

Cause Flags In order to handle the floating point exceptions and floating point exceptions that are gen- erated upon detection of unimplemented processing, the cause flags are used. When a cause flag is set to 1, it means a corresponding exception has occurred. The bit that has been set to 1 is cleared to 0 when an FPU instruction is executed. The Cause Flags in the FPSW are:

Invalid Operation Exception Cause Flag (CV) Overflow Exception Cause Flag (CO) 410 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Underflow Exception Cause Flag (CU) Divide- By- Zero Exception Cause Flag (CZ) Inexact Exception Cause Flag (CX) Unimplemented Processing Cause Flag (CE)

Exception Flags The Exception Flags are used to indicate the occurrence of exceptions. If the exception flag is set to 1, it means the corresponding error has occurred. The exception flags available in the FPSW are:

Invalid Operation Flag (FV) Overflow Flag (FO) Underflow Flag (FU) Division- by- zero flag (FZ) Inexact Flag (FX)

Exception Handling Enable Bits When any of the five floating point exceptions occur, the bit decides whether the CPU will start handling the exception. When the bit is set to 0, the exception handling is masked. When the bit is set to 1, exception handling is enabled. The Exception Handling bits in the FPSW are:

Invalid Operation Exception Enable bit (EV) Overflow Exception Enable bit (EO) Underflow Exception Enable bit (EU) Divide- by- zero Exception Enable bit (EZ) Inexact Exception Enable bit (EX)

Denormalized Number Bit A denormalized number is a number of the form 1 an, where a is the base of the num- ber (2 for decimal numbers and 10 for binary numbers) and n is the exponent. When the denormalized number bit (DN) is set to 1, a denormalized number is handled as 0. When the DN bit is set to 0, the denormalized number is handled as a denormalized number. From the basic examples, it can be seen that the DN bit is set to 1 when an Overflow, Underflow, Invalid Operation, or a Divide- by- zero exception occurs. This denotes that the result of the operation cannot be handled as a denormalized number. CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 411

Floating Point Error Summary Flag The Floating Point Error Summary flag (FS) bit represents the logical OR of the following Exception flags:

Invalid Operation Exception Overflow Exception Underflow Exception Divide- by- Zero Exception

Since the occurrence of inexact operation is common and is taken care of by the RM bits under certain circumstances, the FS bit does not reflect the occurrence of an inexact operation.

Reserved Bits The reserved bits are restricted for the programmer, as they are used by the microcontroller itself. The reserved bits have a value of 0.

10.4.2 Floating Point Exception Handling Procedure

Though the floating- point exceptions appear similar to other exceptions, the handling rou- tine for the floating- point exceptions vary slightly from that of other instructions. Floating- point exceptions are of the lowest priority and handling the exceptions can be classified as follows:

Acceptance of the exception Hardware pre- processing Processing of the user- written code Hardware post- processing

Acceptance of the Exception When a floating- point exception occurs, the CPU suspends the execution of the current instruction and stores the PC value of the instruction that is generated by the exception on the Stack. It is for this reason; the floating- point instruction is of instruction cancel- ing type. 412 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Hardware Pre- Processing The following steps take place during hardware pre- processing:

Preserving the PSW The value of the PSW is stored in the stack. PSW V Stack Updating the PSW The following bits are updated: ▫ I V 0 ▫ U V 0 ▫ PM V 0 Preserving the PC The value of the PC is stored in the stack. PC V Stack Updating the PC The PC is updated with branch- destination address fetched from the vector address FFFFFFE4h in the fixed vector table. The processing is then shifted to the excep- tion handling routine.

Processing of User- Written Program Code The following steps take place while processing user- written code.

Preserving general purpose registers The contents of the general purpose registers are stored in the stack. General purpose registers V Stack User code execution Corresponding user code is executed. In general, the code is inserted in the Excep_FloatingPoint() interrupt/function. General Purpose registers restoration The contents of the general purpose registers are stored in the stack. Stack V General purpose registers RTE Execution After restoring the contents of the general- purpose registers, the Return from Ex- ception (RTE) is executed. This marks the end of exception handling. Following this step will be hardware post- processing. CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 413

Gereation of an exception event request

Exception request Restarting of the program Instruction Instruction Instruction Instruction Instruction . . . . . A B C The program is suspended C D and the exception is accepted • Instruction canceling type (UND, PIE, ACE, and FPE) Hardware pre-processing • Instruction suspending type (Reception of an EI during execution of the RMPA (For the fast interrupt) instruction or a string manipulation instruction) PC V BPC • Instruction completion type PSW V BPSW (EI and TRAP) U 0 Transition to the user mode when the I 0 PM bit in the PSW is 1 PM 0 Switch to the (For the fast interrupt) (For exceptions other than the fast interrupt) supervisor mode BPC V PC V PC Preserved on the stack (ISP) BPSW V PSW PSW V Preserved on the stack (ISP) U 0 (For exceptions other than the fast interrupt) I 0 Stack V PC PM 0 Stack V PSW

Hardware post-processing Read the vector. Processing of user-written program code Branch to the start of the handler. General- (For the fast interrupt) Restoration purpose RTFI instruction Exception handling Handler of general- registers (For exceptions other than routine other than processing purpose preserved on the fast interrupt) the non-maskable registers the stack RTE instruction interrupt

Non-maskable Non-maskable End of the program or resetting of the system interrupt interrupt processing

[Legend] UND: Undefined instruction exception PIE: Privileged instuction exception ACE: Access exception FPE: Floating-point exception EI: Interrupt TRAP: Unconditional trap

Figure 10.21 Exception handling procedure. Source: Software Manual, page 258. 414 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Hardware Post-Processing The following steps take place during hardware post- processing:

Restoring PC The contents of the PC are restored from the Stack. Stack V PC. Restoring PSW The contents of the PC are restored from the Stack. Stack V PC.

Following the exception handling routine, the program is restarted. Figure 10.21 explains the exception handling procedure.

10.5 ADVANCED EXAMPLES

10.5.1 Fixed- Point and Floating- Point Operation Time Calculation

This example calculates the time taken for a single fixed- point operation and the time taken for a single floating point operation based on switch presses. For example, if Switch 1 is pressed, an Integer operation is carried out and the time taken for the operation is displayed. In order to calculate the operation time, we need a timer. Let’s say we are using Timer 0 (TMR0), with a clock source of PCLK/2 (to be more precise). In order to calculate the time taken, we initialize the timer and reset the Timer Counter (TCNT). The following would be the function to initialize the timer.

1. void Init_Timer(void) 2. { 3. MSTP(TMR0) = 0; //Activate TMR0 4. TMR0.TCCR.BIT.CSS = 1; //Count source is PCLK/2 5. TMR0.TCCR.BIT.CKS = 1; 6. TMR0.TCNT = 0x00; //Reset TCNT 7. }

We will also need a function to reset the timer, which will deactivate the timer unit and re- set the timer counter.

1. void Reset_Timer(void) 2. { 3. MSTP(TMR0) = 1; //Deactivate TMR0 4. TMR0.TCNT = 0x00; //Reset TCNT 5. } CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 415

The following code would be the main function:

1. void main(void) 2. { 3. char str [30]; 4. int i; 5. long int int1, int2, int3; 6. float float1, float2, float3; 7. double double1, double2, double3; 8. 9. int1 = 2; int2 = 3; 10. float1 = 2.0; float2 = 3.0; 11. double1 = 2.0; double2 = 3.0; 12. 13. ENABLE_LEDS; 14. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 15. /* use Glyph full access direct functions */ 16. GlyphNormalScreen(G_lcd); 17. GlyphSetFont(G_lcd, GLYPH_FONT_6_BY_13); 18. GlyphClearScreen(G_lcd); 19. } 20. while(1) 21. { 22. if(SW1 == 0) //If SW1 pressed 23. { 24. Init_Timer(); 25. for(i = 0; i < 10; i++) 26. int3 = (int1 * int2); 27. sprintf((char *)str, “C:%d”, TMR0.TCNT); 28. Reset_Timer(); 29. BSP_Display_String(LCD_LINE3, str); 30. } 31. 32. else if(SW2 == 0) 33. { 34. Init_Timer(); 35. for(i = 0; i < 10; i++) 36. float3 = (float1 * float2); 37. sprintf((char *)str, “C:%d”, TMR0.TCNT); 38. Reset_Timer(); 39. BSP_Display_String(LCD_LINE3, str); 416 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

40. } 41. 42. else if(SW3 == 0) 43. { 44. Init_Timer(); 45. for(i = 0; i < 10; i++) 46. double3 = (double1 * double2); 47. sprintf((char *)str, “C:%d”, TMR0.TCNT); 48. Reset_Timer(); 49. BSP_Display_String(LCD_LINE3, str); 50. } 51. 52. else 53. { 54. sprintf((char *)str, “Press any Switch”); 55. BSP_Display_String(LCD_LINE1, str); 56. sprintf((char *)str, “to continue!”); 57. BSP_Display_String(LCD_LINE2, str); 58. } 59. } 60. 61. GlyphClose(&G_lcd); 62. }

In the previous code, consider the snippet from Line 22 to Line 30:

22. if(SW1 == 0) //If SW1 pressed 23. { 24. Init_Timer(); 25. for(i = 0; i < 10; i++) 26. int3 = (int1 * int2); 27. sprintf((char *)str, “C:%d”, TMR0.TCNT); 28. Reset_Timer(); 29. BSP_Display_String(LCD_LINE3, str); 30. }

Line 24 initiates the timer and starts counting. Line 25 and line 26 perform integer multi- plication for ten iterations. Since the time taken for iteration would be less, we consider ten iterations and divide the result by ten. Similar to the above code snippet, the multiplication operation is performed for float and double, and the value of the counter is found. CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 417

From the above code, it was found that the operations performed take the following time:

Int Timer Count 80

Timer Count Time Taken PCLK 10 a 2 b

PCLK Since we use clock and we perform ten iterations, we divide the timer count by 2 PCLK 10 and (PCLK 16.5 MHz here). 2 Therefore,

80 Time Taken 0.9696 microseconds 16.5 10 a 2 b

Float Timer Count 90

Therefore,

90 Time Taken 1.0909 microseconds 16.5 10 a 2 b

Double Timer Count 90

Therefore,

90 Time Taken 1.0909 microseconds 16.5 10 a 2 b 418 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

From the above example, the time taken for a floating point operation in the RX62N proces- sor was found to be 1.0909 micro- seconds. To observe the floating point instructions, one could follow the Source Address and view the corresponding Disassembly by clicking the (View Disassembly) icon. For example, consider the following figure.

266 FFFFCFFA f(i –0; i < 10; i++) 227 FFFFD006 float3 = (float1 * float2);

Figure 10.22 Code snippet in view source tab.

The above code generates the following assembly code after building/compilation:

FFFFD006 ED0E0C MOV.L 30H [R0],R14 FFFFD009 AB0D MOV.L 34H [R0],R5 FFFFD00B FC8FF5E FMUL R5,R14 FFFFD00E E70E0E MOV.L R14,38H [R0] FFFFD011 ED0E08 MOV.L 20H [RO],R14 FFFFD014 621E ADD #1H,R14 FFFFD016 E70E08 MOV.L R14,20H [R0] FFFFD019 ED0E08 MOV.L 20H [R0],R14 FFFFD01C 61AE CMP #0AH,R14 FFFFD01E 29E8 BLT.B 0FFFFD006H

Figure 10.23 Assembly code in view disassembly tab.

10.5.2 Matrix Multiplication Time Calculation

Similar to the above example, let’s examine the time taken to calculate a simple 3 3 matrix. In order to choose between int, float, and double, let’s use the following code for user- friendliness:

1. void Init_Display() 2. { 3. char str [30]; 4. sprintf((char *)str, “Matrix Mult”); 5. BSP_Display_String(LCD_LINE1, str); 6. 7. sprintf((char *)str, “SW1: Int”); CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 419

8. BSP_Display_String(LCD_LINE2,str); 9. 10. sprintf((char *)str, “SW2: Float”); 11. BSP_Display_String(LCD_LINE3,str); 12. 13. sprintf((char *)str, “SW3: Double”); 14. BSP_Display_String(LCD_LINE4,str); 15. }

The previous code allows the user to choose the operation to perform. Pressing SW1 per- forms matrix multiplication with integer variables, whereas pressing SW2 and SW3 per- forms matrix multiplication using single precision and double precision floating point variables.

16. void int_Multiply(int matA [3][3], int matB [3][3], int matC [3][3],) 17. { 18. int i, j, k; 19. for(i = 0; i < 3; i++) 20. for(j = 0; j < 3; j++) 21. for(k = 0; k < 3; k++) 22. matC [i][j]+= matA [i][k]* matB [k][j]; 23. } 24. 25. void float_Multiply(float matA [3][3], float matB [3][3], float matC [3][3]) 26. { 27. int i, j, k; 28. for(i = 0; i < 3; i++) 29. for(j = 0; j < 3; j++) 30. for(k = 0; k < 3; k++) 31. matC [i][j]+= matA [i][k]* matB [k][j]; 32. } 33. void dbl_Multiply(double matA [3][3], double matB [3][3], double matC [3][3]) 34. { 35. int i, j, k; 36. for(i = 0; i < 3; i++) 37. for(j = 0; j < 3; j++) 38. for(k = 0; k < 3; k++) 39. matC [i][j]+= matA [i][k]* matB [k][j]; 40. } 420 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

In the previous code, lines 16 through 23 perform matrix multiplication using integers, lines 24 through 31 perform matrix multiplication using single- precision floating- point numbers, and lines 32 through 39 perform matrix multiplication using double precision floating- point numbers. We use the Init_Timer() and Reset_Timer() functions discussed in the previous exam- ple to activate and deactivate the timer unit. The main function would be as follows:

41. void main(void) 42. { 43. char str [30]; 44. int i, j; 45. int Timer_Count; 46. float time; 47. int int_matA [3][3], int_matB [3][3]; 48. int int_matC [3][3], 49. float float_matA [3][3], float_matB [3][3]; 50. float float_matC [3][3], 51. double dbl_matA [3][3], dbl_matB [3][3]; 52. double dbl_matC [3][3], 53. for(i = 0; i < 3; i++) 54. for(j = 0; j < 3; j++) 55. int_matA [i][j]= j * 2; 56. for(i = 0; i < 3; i++) 57. for(j = 0; j < 3; j++) 58. int_matB [i][j]= (9 -j) * 2; 59. for(i = 0; i < 3; i++) 60. for(j = 0; j < 3; j++) 61. float_matA [i][j]= j * 1.1; 62. for(i = 0; i < 3; i++) 63. for(j = 0; j < 3; j++) 64. float_matB [i][j]= (9 -j) * 1.1; 65. for(i = 0; i < 3; i++) 66. for(j = 0; j < 3; j++) 67. dbl_matA [i][j]= j * 1.1; 68. for(i = 0; i < 3; i++) 69. for(j = 0; j < 3; j++) 70. dbl_matB [i][j]= (9 -j) * 1.1; 71. if(GlyphOpen(&G_lcd, 0) == GLYPH_ERROR_NONE){ 72. /* use Glyph full access direct functions */ 73. GlyphNormalScreen(G_lcd); 74. GlyphSetFont(G_lcd, GLYPH_FONT_6_BY_13); CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 421

75. GlyphClearScreen(G_lcd); 76. } 77. Init_Display(); 78. while(1) 79. { 80. if(SW1 == 0) 81. { 82. GlyphClearScreen(G_lcd); 83. Init_Timer(); 84. int_Multiply(int_matA, int_matB, int_matC); 85. Timer_Count = TMR0.TCNT; 86. Reset_Timer(); 87. sprintf((char *)str, “Count:%d”, Timer_Count); 88. BSP_Display_String(LCD_LINE3, str); 89. Timer_Count = 0; 90. } 91. if(SW2 == 0) 92. { 93. GlyphClearScreen(G_lcd); 94. Init_Timer(); 95. float_Multiply(float_matA, float_matB, float_matC); 96. Timer_Count = TMR0.TCNT; 97. Reset_Timer(); 98. sprintf((char *)str, “Count:%d”, Timer_Count); 99. BSP_Display_String(LCD_LINE3,str); 100. Timer_Count = 0; 101. } 102. if(SW3 == 0) 103. { 104. GlyphClearScreen(G_lcd); 105. Init_Timer(); 106. dbl_Multiply(dbl_matA, dbl_matB, dbl_matC); 107. Timer_Count = TMR0.TCNT; 108. Reset_Timer(); 109. sprintf((char *)str, “Count:%d”, Timer_Count); 110. BSP_Display_String(LCD_LINE3, str); 111. Timer_Count = 0; 112. } 113. } 114. GlyphClose(&G_lcd); 115. } 422 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

In the above code lines 52 through 69 initialize the matrices in corresponding data- type. When switch 1 is pressed, the code enters line 79. The integer matrix multiplication is per- formed at line 83 and the corresponding count is mea sured as the previous example. From the previous example, the following results were observed:

Int Timer Count 112

111 Time Taken 1.3454 microseconds 16.5 10 a 2 b

Float Timer Count 197

197 Time Taken 2.3878 microseconds 16.5 10 a 2 b

Double Timer Count 198

198 Time Taken 2.4 microseconds 16.5 10 a 2 b

From the example, time taken to perform matrix multiplication of two 3 3 matrices was found. Also, a slight difference in time taken to perform single- precision and double- precision floating point matrix multiplication operation was observed.

10.6 RECAP

In this chapter, the Floating Point Unit (FPU) used in the Renesas RX62N was analyzed in detail, where the floating point instructions, floating point exceptions and floating point registers were discussed. CHAPTER 10 / FLOATING POINT UNIT AND OPERATIONS 423

By applying this knowledge about the FPU, the RX62N board can be used in signal processing, image processing applications, and applications that require precise round- off (for example, in applications involving currency, floating- point rounding off errors should be considered in order to value currency as $$.cc where “$$” denotes the dollar value and “cc” denotes the cent value) with an understanding of the time- memory tradeoff between a microcontroller with an FPU and one without an FPU.

10.7 REFERENCES

Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print. Software Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print.

10.8 EXERCISES

1. Write a C program to identify different Floating Point Exceptions. 2. Consider the following operations:

Addition: 2.0 3.0 Multiplication: 2.0 * 3.0 Division: 2.0/3.0

Do different operations involving floating- point (addition, multiplication, and divi- sion) take the same time to complete? Justify your answer. Use single- precision floating point numbers for the operations. Use Switch 1 (SW1), Switch 2 (SW2), and Switch 3 (SW3) to perform Addition, Multiplication, and Division respec- tively and display the time taken as the result. 3. Write a C program on the RX62N to calculate the time taken to perform the oper- ations stated in problem 10.7.2. Use single- precision floating point numbers for the operations. 4. Implement problem 10.7.3 using double precision floating point numbers. Does it take the same time as single precision floating point numbers? Justify your answer. 5. Identify the floating point instructions involved in single precision and double pre- cision operations in problems 10.7.3 and 10.7.4 from the disassembly. Do they look alike? Explain your answer. 424 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

6. Write a C program on the RX62N to calculate the time taken to perform the in- verse of the given matrix A. (Note: The inverse of the matrix should be calculated in a different function other than “main.”)

12 0 A 361 12 1

7. Multiply the inverted A matrix with B matrix given below. Identify the floating point exceptions involved. (Note: Matrix Multiplication should be done in a differ- ent function other than “main.”)

0.001 2.400 0.120 B 3.143 2.743 4.901 0.917 0.008 2.001 Chapter Eleven

Watchdog Timer and Brown- Out Detector

11.1 LEARNING OBJECTIVES

Embedded systems are expected to work correctly. However, it is very difficult (even im- possible) to completely test a system in all possible environments. Hence embedded sys- tem designers usually rely on a watchdog timer (WDT) to reset the processor if the pro- gram runs out of control. They also use a brown- out (or low-voltage) detector to hold the processor in reset if the supply voltage is too low for correct operation. This chapter presents information on:

Ⅲ Basic watchdog timer concepts Ⅲ How application software and the WDT should interact Ⅲ How to configure the RX62N WDT Ⅲ Concepts for the brown- out detector

11.2 BASIC CONCEPTS OF WATCHDOG TIMER

Many embedded systems are built to operate without an operator, so there should be a mechanism that monitors the system for unexpected errors due to some hardware fault, an unusual endless loop, or other fatal software bug. The watchdog timer serves the purpose of automatically monitoring and recovering the system from such situations. The watchdog timer is an internal hardware timer peripheral in the CPU or an external device which resets the processor if it is not reset within a given period of time. The appli- cation software needs to periodically reset the watchdog timer. If the application software does not do this soon enough, the WDT overflows and the overflow signal is used to reset the system. So, the watchdog timer can only help the system recover from faults which pre- vent the timely refresh of the WDT. In a multitasking system, it is a best practice to have each task check in with a task which monitors system- wide task progress. This monitor task will only reset the WDT if all tasks are making adequate progress.

425 426 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

One should never build a system in which the WDT is reset automatically by a task or ISR which operates autonomously of the rest of the system. This defeats the purpose of the WDT.

11.2.1 Watchdog Timer (WDT)

The Watchdog timer in RX62N microcontroller is an 8-bit timer which outputs an overflow signal (WDTOVF), if the timer overflow occurs during general program flow, and it can also be set up to reset the processor whenever the overflow signal occurs. The watchdog timer can also be used as an interval timer which generates an interrupt each time the counter overflows.

11.2.2 Register Descriptions

The registers used for the watchdog timer are listed in Table 11.2. The Timer control/status register (TCSR) is used for selecting the timer operation and clock source for the timer. The Timer counter (TCNT) contains the count value for the timer. The Reset control/status register (RSTCSR) is used to reset the timer. Window A and Window B registers are used for writing data into TCNT, TCSR and RSTCSR.

TABLE 11.1 Specifications of WDT.

ITEM SPECIFICATIONS Count clocks PCLK/4, PCLK/64, PCLK/128, PCLK/512, PCLK/2048, PCLK/8192, PCLK/32768, and PCLK/131072 Number of channels 8 bits ϫ 1 channel Count clear Write to TCNT Operating modes Switchable between watchdog timer mode and interval timer mode Watchdog timer mode Outputs a WDTOVF# signal when the counter overflows. Selectable whether or not to internally reset the RX62N/RX621 at the same time. Interval timer mode Generates an interval timer interrupt (WOVI) when the counter overflows.

Source: Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010, Table 23.1. CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 427

Overflow PCLK/4 WOVI Interrupt PCLK/64 (Interrupt request signal) control PCLK/128 PCLK/512 Clock Clock selection PCLK/2048 PCLK/8192 WDTOVF# (Overflow signal) PCLK/32768 Reset control PCLK/131072 Internal reset signal* Internal clocks

RSTCSR TCNT TCSR Internal main bus

Peripheral bus Peripheral bus interface

WINB WINA

[Legend] TCSR: Timer control/status register TCNT: Timer counter RSTCSR: Reset control/status register WINA: Write window A register WINB: Write window B register

Note:* An internal reset signal can be generated depending on the register setting.

Figure 11.1 Block diagram of the WDT. Source: Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series, Renesas Electronics America, Inc., 2010, Figure 23.1.

TABLE 11.2 WDT Registers.

VALUE AFTER REGISTER NAME SYMBOL RESET ADDRESS ACCESS SIZE Timer control/status register TCSR x8h 0008 8028h*1 8 Timer counter TCNT 00h 0008 8029h*1 8 Reset control/satus register RSTCSR 1Fh 0008 802Bh*1 8 Write window A register WINA — 0008 8028h*2 16 Write window B register WINB — 0008 802Ah*2 16

Notes: 1. Read- only register 2. Write-only register

Source: Hardware Manual, Table 23.3. 428 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Window A Register (WINA): WINA is a 16-bit write- only register which is used to write the data into Timer Counter (TCNT) register and Timer Control/Status register (TCSR). To write to this register, use word access. The address of the WINA register is 0008 8082h.

Window B Register (WINB): WINB is a 16-bit write- only register and is used to write the data into Reset Control/Status register (RSTCSR). To write to this register, use word access. The address of WINB register is 0008 802Ah.

Timer Counter Register (TCNT) The timer counter register (TCNT) is an 8-bit register which contains the maximum up- count value for the internal clock. To write any value into TCNT register, data should be written into WINA register by word access. The value of the register after reset would be 00h. The address of the TCNT register is 0008 8029h. The following is a code snippet to write data into the TCNT register:

1. void write_TCNT (void){ 2. WINAL* = count_value; 3. WINAH* = 0x5Ah; 4. }

Explanation of the Code

Line 2: WINAL = count_value; The count value for the timer is set in the lower byte of the WINA register. Line 3: WINAH = 0x5Ah; To write the required data into the TCNT register, the upper byte of the WINA register is set to 5Ah.

Timer Control/Status Register (TCSR) Timer Control/Status Register is an 8-bit register which is used to select the clock source for the timer and type of operation of the timer.

*In the code snippets, for easy explanation of settings for WINA and WINB registers, they are not used through word access. WINAL/WINBL is the lower byte of the word and WINAH/WINBH is the upper byte of the word. The actual way of setting the registers will be in the code examples. CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 429

Address: 0008 8028h

b7 b6 b5 b4 b3 b2 b1 b0

—TMS TME — — CKS[2:0]

Value after reset: 0 0 0 0 0 0 0 0

[Legend] x: Undefined

Figure 11.2 Timer Control/Status Register (TCSR). Source: Hardware Manual, page 23–4.

Bit Description of TCSR

CKS [2:0] Bits: These bits are used to select the clock input to the timer in timer mode.

TME Bit (Timer Enable): This bit is used to start or stop the counting. When the bit is set to 1, TCNT starts counting. When the bit is cleared to 0, TCNT stops counting and is ini- tialized to 00h.

TMS Bit (Timer Select): This bit is used to select the operation of WDT as a Watchdog timer or Interval timer. When this bit is cleared to 0, Interval timer mode is selected and as the TCNT overflows, an interval timer interrupt is generated. When this bit is set to 1, Watchdog timer mode is selected and as the TCNT overflows WDTOVF signal goes high.

The importance of using the clock source:

Problem 1: Design an embedded system using RX62N microcontroller with a delay of 326.4 ms to a watchdog timer. (Given PCLK ϭ 50 MHZ)

Solution: The highest possible value the Timer count register (TCNT) can count up to 255 (FFh). So the delay we get with PCLK as the clock source is:

255 Delay ϭϭ(255 / 50) ms ϭ 5.1 ms (PCLK)

So with a maximum value in the TCNT register we only get a delay of 5.1 ms. To increase the delay the clock source frequency should be decreased. 1 Because 326.4 ms/5.1 ms ϭ 64, the clock source frequency should be reduced to ⁄64 of the original clock source PCLK. If PLCK/64 is used as a clock source:

Delay ϭ (255/(PCLK/64)) ϭ ((255 * 64)/PCLK) ϭ ((255 * 64)/50) ms ϭ 326.4 ms 430 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 11.3 Bit Description of TCSR.

BIT SYMBOL BIT NAME DESCRIPTION R/W b2 to b0 CKS[2Ϻ0] Clock select b2 b0 R/W 0 0 0: PCLK/4 (cycle: 20.4 ms) 0 0 1: PCLK/64 (cycle: 326.4 ms) 0 1 0: PCLK/128 (cycle: 652.8 ms) 0 1 1: PCLK/512 (cycle: 2.6 ms) 1 0 0: PCLK/2048 (cycle: 10.4 ms) 1 0 1: PCLK/8192 (cycle: 41.8 ms) 1 1 0: PCLK/32768 (cycle: 167.1 ms) 1 1 1: PCLK/131072 (cycle: 668.5 ms) Note: The overflow cycle for PCLK ϭ 50 MHz is indicated in parentheses. b4, b3 — (Reserved) These bits are always read as 1. The write value R/W should always be 1. b5 TME Timer enable 0: TCNT stops counting and is initialized to 00h. R/W 1: TCNT starts counting. b6 TMS Timer Mode 0: Interval timer mode R/W Select When TCNT overflows, an interval timer interrupt (WOVI) is requested. 1: Watchdog timer mode When TCNT overflows, WDTOVF# is output. b7 — (Reserved) If read, an undefined value will be read. The write R/W value should always be 1.

Source: Hardware Manual, page 23–4.

1 The following is a code snippet to start the timer in WDT mode with a clock source of ⁄64:

To write data to the TCSR register, data should be written into the WINA register by word access.

1. void write_TCNT (void){ 2. WINAL = data; 3. WINAH = 0xA5h; 4. } CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 431

Explanation of the Code

Line 2: WINAL = data; The value in data variable to—the timer counting in WDT mode with a 1 clock source of ⁄64—is F9h, so data = F9h. Line 3: WINAH = 0xA5h; To write the required data into the TCNT register, the upper byte of the WINA register is set to A5h.

Reset Control/Status Register (RSTCSR) Reset Control/Status Register is an 8-bit register which is used to control the internal reset signal when TCNT overflows and to select the type of internal reset signal. After the reset signal from the RES pin or a deep software standby reset, the register value is set to 1Fh but the value does not change when the WDT internal reset signal occurs.

Address: 0008 802Bh b7 b6 b5 b4 b3 b2 b1 b0

WOVF RSTE — — — — — —

Value after reset: 0 0 0 0 0 0 0 0

Figure 11.3 Reset Control/Status Register. Source: Hardware Manual, page 23–5.

Bit Description of RSTCSR RSTE Bit (Reset Enable): This bit is used to enable or disable the internal reset of the mi- crocontroller when TCNT overflows in watchdog timer mode. When the bit is set to 1, the internal reset of the microcontroller will be enabled.

WOVF Flag (Watchdog Timer Overflow): This bit is used to check the overflow of TCNT in watchdog timer mode. This bit cannot be set to 1 in interval timer mode. The WOVF flag is set to 1 when the TCNT overflows (changed from FFh to 00h) in watchdog timer mode. WOVF flag should be cleared to 0 by the software when it is read as 1. The following is a code snippet to start the timer in WDT mode with a clock source 1 of ⁄4, LSI internally reset and writing 0 to the WOVF flag:

To write data to the TCSR register, data should be written into the WINA register by word access. To write data to the RSTCSR data should be written into the WINB register by word access. 432 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

1. void write_RSTCSR (void){ 2. WINAL = data; 3. WINAH = 0xA5h; 4. WINBL = data1; 5. WINBH = 0x5Ah; 6. while((RSTCSR&0x80) != 0x80) 7. ; 8. WINBL = data2; 9. WINBH = 0x5Ah; 10. }

Explanation of the Code

Line 2: WINAL = data; The value in data variable to start counting the timer in WDT mode with a 1 clock source of ⁄4 is F8h. Line 3: WINAH = 0x5Ah; To write the required data into the TCNT register, the upper byte of the WINA register is set to 5Ah. Line 4: WINBL = data1; The value in the data1 variable to make the microcontroller reset internally is 5Fh. Line 5: WINBH = 0x5Ah; To write the required data into the RSTCSR, the upper byte of the WINB register is set to 5Ah. Line 7: while((RSTCSR&0x80) != 0x80); The program waits here until the WOVF flag is set. Line 8: WINBL = data2; When the WOVF flag is set, the program comes out of the while loop and clears the WOVF flag. To clear the flag, a value of 00h is written in the lower byte of the WINB register through the local variable data2. data2 ϭ 00h. Line 9: WINBH = 0x5Ah; To write into RSTCR, the upper byte of the WINB register should be set to a value of A5h.

11.2.3 Operation of WDT

Watchdog Timer Mode: To use the watchdog timer mode, the TMS bit and the TME bit should be set to 1. In watchdog timer mode, the TCNT overflows either when a system CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 433

goes unresponsive due to a software bugs or any other error. When the TCNT overflows, the WDTOVF signal goes high for 257 cycles of PCLK when the RSTE bit in RSTCSR is set to 1, and WDTOVF signal goes high for 256 cycles of PCLK when RSTE is cleared to 0. This signal can be used to reset the MCU internally in watchdog timer mode. TCNT overflows must be prevented in the software by rewriting the value of TCNT to 00h before overflow occurs. If TCNT overflows and the RSTE bit in RSTCSR is set to 1, the internal reset signal that resets the RX62N/RX621 and the WDTOVF signal are generated at the same time. If the external reset from the RES pin and the reset from the WDT occur at the same time, the RES pin gets the highest priority and the WOVF flag in RSTCSR is cleared to 0. The software should rewrite the TCNT value to 00h before the overflow occurs. Figure 11.4 shows an example of how the WDT operates. At the first arrow the TMS and TME bit are set to 1. At the next three arrows, the WDT is refreshed. WDT overflow occurs at WOVF arrow point so the internal reset signal goes high for 1027 cycles and the WDTOVF signal toggles for 257 or 256 cycles depending on the RSTE bit in RSTCSR.

TCNT value Overflow FFh

00h Time

TMS ϭ 1 Write 00h to WOVF ϭ 1 TMS ϭ 1 Write 00h to TME ϭ 1 TCNT TME ϭ 1 TCNT Generating WDTOVF# and internal reset

WDTOVF# signal

257 cycles*2

Internal reset signal*1

1027 cycles

Notes: 1. An internal reset signal is generated if TCNT overflows when the RSTE bit in RSTCSR is set to 1. 2. The WDTOVF# signal is output for 256 cycles when RSTE bit in RSTCSR is set to 0.

Figure 11.4 Watchdog timer mode operation. Source: Hardware Manual, page 23–7. 434 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

11.3 BASIC CODE EXAMPLES

11.3.1 Example 1: Setting Up Watchdog Timer Mode

In this example code a subroutine is provided with the watchdog timer set up for a delay time of FFh; i.e., equal to 5.1 ms. (PCLK ϭ 50 MHZ)

1. void Init_WDT(void){ 2. WDT.WRITE.WINA = 0x5A00; //Writing data into TCNT 3. WDT.WRITE.WINB = 0x5A5F; //Writing data into RSTCSR 4. WDT.WRITE.WINA = 0xA5FD; //Writing data into TCSR 5. }

Explanation of the Code

Line 2: WDT.WRITE.WINA = 0x5A00; A value of 00h is written into the TCNT register. Since we cannot directly write value into TCNT register, WINA register is used to write the value. To write data into the TCNT register, the upper byte of the word of WINA register should be set to 5Ah and then the data is written to the lower byte of the word of WINA register. Line 3: WDT.WRITE.WINB = 0x5A5F; A value of 5F is written into the RSTCSR using WINB register. To write data into the RSTCSR the upper byte of the word of WINB register should be set to 5Ah, and then the data is written to the lower byte of the word of WINB register. The internal reset enable (RSTE) pin is set to 1 to reset the microcontroller on the overflow of the watchdog timer. Line 4: WDT.WRITE.WINA = 0xA5FD; A value of FD is written into TCSR using the WINA register. To write data into the TCSR the upper byte of the word of the WINA register should be set to 5Ah and then the data is written to the lower byte of the word of the WINA register. The CKS [2Ϻ0] bits are set to a value of 7 selecting the prescaler division factor as 131072 with clock source as PCLK. The TMS bit in this register is set to 1 to select the watchdog timer mode, and the timer start enable bit is set to 1 to start counting.

11.3.2 Example 2: Application of a Watchdog Timer

Consider a software bug which leads the program into an infinite loop. This example shows how the watchdog timer brings the program out of the infinite loop. CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 435

1. void main(){ 2. int i; 3. ENABLE_LEDS; 4. while(1){ 5. Init_WDT(void); 6. ALL_LEDS_OFF(); 7. for(i = 0; i < 10000000; i++){ 8. i––; 9. } 10. ALL_LEDS_ON(); 11. WDT.WRITE.WINA = 0x5A00; //Clearing data into TCNT 12. } 13. }

In the above program, the LEDs should switch on and switch off with some delay, but due to the software bug the program enters into an infinite loop which eventually causes the overflow of the watchdog timer—and the overflow causes the internal reset of the micro- controller. If there is no infinite loop, the count of the watchdog timer is reset frequently to prevent the overflow.

Explanation of the Code

Line 3: ENABLE_LEDS; This macro enables the LEDs. Line 5: Init_WDT(void); Calls the subroutine to initialize the watchdog timer, which resets the system as the overflow occurs. Line 6: ALL_LEDS_OFF(); Switches off all the LEDs. Lines 7–9: These are the lines with the bug which takes the program into an infinite loop. We start the loop, decrement the counter variable, and then increment the counter variable—the counter variable will not be anything other than Ϫ1 or 0. Line 10: ALL_LEDS_ON(); Switches on all the LEDs. Line 11: WDT.WRITE.WINA = 0x5A00; This line is used to clear the value of TCNT periodically if the program executes without the infinite loop. If this line is not executed then the TCNT is not cleared to zero, which forces the overflow of the watchdog timer. 436 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

11.4 ADVANCED CONCEPTS OF THE WATCHDOG TIMER

11.4.1 Interval Timer Mode

To use WDT as an interval timer mode, set the TMS bit to 0 and the TME bit to 1 in TCSR. In interval timer mode, a timer interrupt WOVI is generated each time the TCNT overflows. As the TCNT overflows periodically, the timer interrupt is an interval timer interrupt.

TCNT value

Overflow Overflow Overflow Overflow FFh

00h Time

TMS ϭ 0 WOVI WOVI WOVI WOVI TME ϭ 1

WOVI: An interval timer interrupt request is generated.

Figure 11.5 Interval timer mode operation. Source: Hardware Manual, page 23–8.

11.4.2 Indepen dent Watchdog Timer (IWDT)

The inde pen dent watchdog timer (IWDT) is a watchdog timer for use inde pen dent of the conventional watchdog timer, which is for detecting programs with runaway execution and system crashes (Hardware Manual, page 1184). The IWDT is a 14-bit down counter which resets the system if an underflow of the timer count value occurs. The timer count value must be refreshed before the counter underflows.

Registers Used to Set Up IWDT: Table 11.5 shows the list of registers used to set up the IWDT.

IWDT Refresh Register (IWDTRR): The IWDT refresh register (IWDTRR) is used to refresh the timer down count value of the IWDT. The down count value of the IWDT is re- freshed by passing 00h and FFh as a sequence to the IWDTRR. After the writing of FFh to IWDTRR, refreshing the down counter takes up to four cycles of the signal for counting. CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 437

TABLE 11.4 Specification of IWDT.

ITEM SPECIFICATIONS Clock for counting OCOCLK, OCOCLK/16, OCOCLK/32, OCOCLK/64, OCOCLK/128, OCOCLK/256 Counter operation Counting down by a 14-bit down- counter Conditions for starting Counting can be started by refreshing the down- counter (write FFh the counter after 00h has been written to the IWDTRR register). Conditions for stopping Ⅲ Pin reset (the down- counter and other registers return to their initial the counter values) Ⅲ Generation of an underflow Window facility A refresh-permitted period and fresh- prohibited period may be set. Reset- output sources Underflow of the down- counter of the IWDT Reading the value The value reached in counting by the down- counter can be read out of the IWDT counter from a register (the IWDTSR).

Source: Hardware Manual, Table 24.1.

IWDT reset output

OCOCLK IWDT control circuit 14-bit down counter

OCOCLK I I I W W W OCOCLK/16 D D D Count clock Clock OCOCLK/32 PCLK T T T selec- R C S tion OCOCLK/64 R R R OCOCLK/128 OCOCLK/256

[Legend] IWDTRR: IWDT refresh register IWDTCR: IWDT control register Internal bus IWDTSR: IWDT status register

Figure 11.6 Block diagram of IWDT. Source: Hardware Manual, figure 24.1. 438 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 11.5 List of Registers.

REGISTER NAME SYMBOL VALUE AFTER RESET ADDRESS ACCESS SIZE IWDT refresh register IWDTRR FFh 0008 8030h 8 IWDT control register IWDTCR 3303h 0008 8032h 16 IWDT status register IWDTSR 0000h 0008 8034h 16

Source: Hardware Manual, Table 24.2.

After the counter value has been refreshed and the reset signal has been generated and re- leased, the timer starts to count down from the value set up in the TOPS [1Ϻ0] bits in IWDT Control Register (IWDTCR).

IWDT Control Register (IWDTCR): The IWDTCR is a sixteen bit register in which only six bits are used for setting up the IWDT. The IWDT Control register (IWDTCR) is used to specify the time- out period for the down count of the timer. The time- out period in the bits TOPS [1Ϻ0] can only be changed between the release from the reset state and the first time the counter is refreshed. The writing to the IWDTCR is locked otherwise, be- cause we don’t want to change the time out period of the timer after the counting has started. The writing is only unlocked by the reset signal generated by the IWDT.

Address: 0008 8032h

b15 b14 b13 b12 b11 b10 b9 b8

— — — — — — — —

Value after reset: 0 0 1 1 0 0 1 1

b7 b6 b5 b4 b3 b2 b1 b0

CKS[3:0] TOPS[1:0]

Value after reset: 0 0 0 0 0 0 1 1 Figure 11.7 IWDT Control Register (IWDTCR).

Bit Description for IWDTCR TOPS [1Ϻ0]: These bits in the IWDTCR are used to select the time- out period for the down count of the timer. The different possible values of the time- out period are 1024, 4096, CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 439

TABLE 11.6 Bit Description for IWDTCR.

BIT SYMBOL BIT NAME DESCRIPTION R/W b1, b0 TOPS[1Ϻ0] Time-out b1 b0 R/W period 0 0: 1024 cycles (03FFh) selection 0 1: 4096 cycles (0FFFh) 1 0: 8192 cycles (1FFFh) 1 1: 16384 cycles (3FFFh) b3, b2 — (Reserved) These bits are read as 0. The write value should be 0. R/W b7 to b4 CKS[3Ϻ0] Clock b7 b4 R/W selection 0 0 – –: OCOCLK 0 1 0 0: OCOCLK/16 0 1 0 1: OCOCLK/32 0 1 1 0: OCOCLK/64 0 1 1 1: OCOCLK/128 1 – – –: OCOCLK/256 b9, b8 — (Reserved) These bits are read as 1. The write value should be 1. R/W b11, b10 — (Reserved) These bits are read as 0. The write value should be 0. R/W b13, b12 — (Reserved) These bits are read as 1. The write value should be 1. R/W b15, b14 — (Reserved) These bits are read as 0. The write value should be 0. R/W

Source: Hardware Manual.

8192 and 16384. The number of cycles for the time- out period is determined by the clock source selected by the CKS [3Ϻ0] bits.

CKS [3Ϻ0]: These bits are used to select the clock source for the IWDT. A minimum of 1024 cycles to a maximum of 4194304 cycles time- out period of the LOCO signal can be selected with the combination of TOPS [1Ϻ0] and CKS [3Ϻ0] bits. The different combina- tions of the time- out period is shown in Table 11.7. 440 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

TABLE 11.7 Different Combinations of TOPS [1Ϻ0] and CKS [3Ϻ0], with Corresponding Number of Cycles of the LOCO Signal.

CYCLES OF COUNT TIME-OUT PERIOD THE LOCO CKS[3Ϻ0] TOPS[1Ϻ0] CLOCK (NUMBER OF CYCLES) SIGNAL 0 0 — — 0 0 OCOCLK 1024 1024 0 1 4096 4096 1 0 8192 8192 1 1 16384 16384 0 1 0 0 0 0 OCOCLK/16 1024 16384 0 1 4096 65536 1 0 8192 131072 1 1 16384 262144 0 1 0 1 0 0 OCOCLK/32 1024 32768 0 1 4096 131072 1 0 8192 262144 1 1 16384 524288 0 1 1 0 0 0 OCOCLK/64 1024 65536 0 1 4096 262144 1 0 8192 524288 1 1 16384 1048576 0 1 1 1 0 0 OCOCLK/128 1024 131072 0 1 4096 524288 1 0 8192 1048576 1 1 16384 2097152 1 — — — 0 0 OCOCLK/256 1024 262144 0 1 4096 1048576 1 0 8192 2097152 1 1 16384 4194304

Source: Hardware Manual, Table 24.3. CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 441

IWDT Status Register (IWDTSR): The IWDTSR is a sixteen bit register which contains the underflow information and the counter value of the down counter. This register is ini- tialized only by the IWDT reset source.

Address: 0008 8034h

b15 b14 b13 b12 b11 b10 b9 b8

— UNDFF CNTVAL[13:0]

Value after reset: 0 0 0 0 0 0 0 0

b7 b6 b5 b4 b3 b2 b1 b0

CNTVAL[13:0]

Value after reset: 0 0 0 0 0 0 0 0

Figure 11.8 IWDT Status Register (IWDTSR). Source: Hardware Manual.

Bit Description of IWDTSR CNTVAL [13Ϻ0]: These bits of IWDTSR can be read to check the count value of the down counter.

UNDFF: This bit of IWDTSR shows the state of underflow. If this bit is set to 1, the down counter has underflowed. If this bit is cleared to 0, the down counter has not underflowed.

Operation of Indepen dent Watchdog Timer The TOPS [1Ϻ0] bits of IWDTCR are used to select the time out period of the IWDT. The writing to IWDTCR is unlocked only after the reset from the IWDT. When the IWDT is re- freshed, the timer counts down from the value set in the TOPS [1Ϻ0] bits. In the normal execution of the program, the IWDT is refreshed at regular intervals. If the refresh of the IWDT does not occur, that shows that the program has entered into an infinite loop, has gotten stuck in a long process, or is not working in the desired man- ner. The underflow flag is set to 1 and the reset source from the IWDT is activated to re- set the system. After the output of the reset signal, the down counter is initialized and the writing to the IWDTCR is unlocked. After the system has been re- booted, counting down is again started by refreshing the counter. Figure 11.9 shows an example of the operation of the IWDT. 442 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER (2) Figure 24.2. Figure Counting starts Writing to the Writing The status is cleared register is valid. Underflow Source: Hardware Manual, Source: (2) Operation of IWDT. Operation of IWDT. Figure 11.9 Figure Counting starts Writing to the Writing register is valid. (1) 0% 75% 50% 25% 100% (1) Initial value (2) Set value Value in the down-counter Value Reset input Reset to the IWDT IWDTCR register Refreshing the Refreshing counter Underflow flag output Reset from the IWDT CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 443

11.5 COMPLEX EXAMPLES

11.5.1 Example 1: Interval Timer Mode of a Watchdog Timer

In the next example of code a subroutine has been provided for setting up the WDT as an interval timer. This function should be called before the main function to initialize the WDT in interval timer mode. The interval timer has been set up for a clock with a prescaler division factor of 8192 and an interrupt occurs as the timer overflows. Therefore, code can be added to the ISR if needed.

1. void init_WDT_intervaltimer(){ 2. IEN(WDT,WOVI) = 0; 3. IPR(WDT,WOVI) = 3; 4. IEN(WDT,WOVI) = 1; 5. WDT.WRITE.WINA = 0x5AFF; //Writing data into TCNT 6. WDT.WRITE.WINB = 0x5A1F; //Writing data into RSTCSR 7. WDT.WRITE.WINA = 0xA53D; //Starting the timer 8. }

Explanation of the Code

Line 2: IEN (WDT, WOVI) = 0; When setting the priority level for an interrupt, the interrupt source should be disabled. So this instruction disables the WDT overflow interrupt (WOVI). Line 3: IPR (WDT, WOVI) = 3; This instruction sets a priority level of 3 to the WDT overflow interrupt (WOVI). Line 4: IEN (WDT, WOVI) = 1; This instruction enables the WDT overflow interrupt. Line 5: WDT.WRITE.WINA = 0x5AFF; This instruction writes the timer count value to the timer counter register (TCNT) of WDT through WINA register. Line 6: WDT.WRITE.WINB = 0x5A1F; This instruction writes a value of 1Fh to RSTCSR register. The internal reset enable bit (RSTE) in RSTCSR is disabled. Line 7: WDT.WRITE.WINA = 0xA53D; This instruction is used to write the 3Dh value to the TCSR register. The CKS [2Ϻ0] bits are set to 101b for a prescaler division factor of 8192. The timer mode select (TMS) bit is cleared to 0, which selects the interval timer mode of WDT. The timer enable (TME) bit is set to 1 which starts the timer. 444 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

11.5.2 Example 2: Setting Up of IWDT

The following is the subroutine to set up the watchdog timer for a clock source of OCOCLK/16 with a time out period of 4096 cycles. The IWDT down counts from the value set up by the bits in IWDTCR register and as the underflow occurs the system will reset.

1. void Init_IWDT(void){ 2. IWDT.IWDTCR.BIT.CKS = 4; 3. IWDT.IWDTCR.BIT.TOPS = 1; 4. }

We can also use a single instruction by writing a word into the IWDTCR register.

IWDT.IWDTCR.WORD = 0x3340;

Explanation of the Code

Line 2: IWDT.IWDTCR.BIT.CKS = 4; This line is used to set up the value for CKS [3Ϻ0] bits in IWDTCR register; for selecting a prescaler division factor of 16 for clock source OCOCLK, a value 0100b should be written to CKS [3Ϻ0] bits. Line 3: IWDT.IWDTCR.BIT.TOPS = 1; This line is used to set up the value for TOPS [1Ϻ0] bits in IWDTCR register. For selecting a timeout period of 4096 cycles, a value 01b should be written to TOPS [1Ϻ0] bits.

11.6 BROWNOUT CONDITION

11.6.1 How Brownout Occurs

A brownout condition in a microcontroller occurs when the supply voltage for the micro- controller temporarily goes below a threshold value (Vdet). Below this threshold value, the microcontroller may malfunction. There is also a blackout condition in which the micro- controller will have a total loss of electricity. In a brownout condition, some operations may work but in a blackout condition none of the operations will be active.

11.6.2 Automatically Detecting a Brownout Condition

The main purpose of automatically detecting the brownout condition is to prevent the cor- ruption of processor critical information. Whenever the brownout condition is detected, the CHAPTER 11 / WATCHDOG TIMER AND B ROWN- OUT DETECTOR 445

internal reset from the voltage detection circuit should keep the processor in reset condition until the voltage increases above the threshold value (Vdet). The RX62N MCU group provides two low-voltage detection (LVD) circuits based on analog comparators. Each compares the supply voltage Vcc against a fixed reference volt- age (Vdet1 or Vdet2). If the supply voltage is not above the reference voltage, the LVD can reset the processor or generate an interrupt, based on the LVD configuration. Because there are two LVD comparators, one can be configured to warn of a likely impending power failure (when Vdet2 is reached) using an interrupt. This will trigger the saving of critical data and putting outputs into safe states (e.g. turning off motors). The second LVD can be configured to reset the processor when Vdet1 is reached.

11.7 RECAP

A watchdog timer is one of the tools in the microcontroller, which gets the system out of unexpected errors or infinite loops. The watchdog timer count is refreshed frequently so that the overflow does not occur in the general flow of the program. When the overflow oc- curs, it implies that the timer count has been not refreshed and the program is not function- ing in the way it should. So the watchdog timer resets the system whenever it overflows. The RX62N/RX621 group has two watchdog timers, WDT and IWDT. The WDT can be used in watchdog timer mode and interval timer mode. The registers are used to set up the WDT and IWDT. WINA and WINB registers are used to write data to WDT registers. To refresh the timer count for IWDT, two length sequence 00h and FFh should be written to the timer counter register of IWDT.

11.8 REFERENCES

Hardware Manual, Renesas 32-Bit Microcomputer, RX Family/RX600 Series. Renesas Electronics America, Inc., 2010. Print.

11.9 EXERCISES

1. List the registers used to set up the WDT and describe the importance of the registers. 2. List the registers used to set up the IWDT and describe the importance of theregisters. 3. What registers used to write data into RSTCR, TCNT, and TCSR registers with pseudo code? 4. Draw a flowchart explaining when and how a WDT resets the system. 446 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

5. What is the maximum interval time of the WDT in interval timer mode? Show with calculations. 6. Write pseudo code to reset the microcontroller when a brownout condition occurs (use the pins available on the microcontroller to detect the brownout condition). 7. Write the Code to set up the WDT in watchdog timer mode with a 167.1 ms clock, with no internal reset, and to start the counting of the timer. 8. Write the Code to refresh the timer counter register of the IWDT. 9. Write the Code to set up the WDT to reset the microcontroller every 1s. 10. Write the Code to set up the IWDT to reset the microcontroller every 1s. 11. Write a program to create a software bug, and reset the microcontroller using IWDT when the bug occurs. Chapter Twelve

Designing Responsive andReal- Time Systems

12.1 LEARNING OBJECTIVES

Most embedded systems have multiple indepen dent tasks running at the same time. Which activity should the microprocessor perform first? This decision determines how responsive the system is, which then affects how determines how fast a processor we must use, how much time we have for running intensive control algorithms, how much energy we can save, and many other factors. In this chapter we will discuss how the microprocessor schedules its tasks.

12.2 MOTIVATION

Consider an embedded system which controls a doorbell in a house. When a person at the front door presses the switch, the bell should ring inside the house. The system’s respon- siveness describes how long it takes from pressing the switch to sounding the bell. It is easy to create a very responsive embedded system with only one task. The scheduling ap- proach shown below is an obvious and simple approach.

1. void main (void){ 2. init_system(); 3. while(1){ 4. if(switch == PRESSED){ 5. Ring_The_Bell(); 6. } 7. } 8. }

Our doorbell is very responsive. In fact, we like it so much that we decide to add in a smoke detector and a very loud beeper so we can be warned about a possible fire. We also add a burglar detector and another alarm bell. This results in the code shown on the next page.

447 448 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

1. void main (void){ 2. init_system(); 3. while(1){ 4. if(switch == PRESSED){ 5. Ring_The_Doorbell(); 6. } 7. if(Burglar_Detected() == TRUE){ 8. Sound_The_Burglar_Alarm(); 9. } 10. if(Smoke_Detected() == TRUE){ 11. Sound_The_Fire_Alarm(); 12. } 13. } 14. }

Going from one task to three tasks has complicated the situation significantly.1 How should we share the processor’s time between these tasks?

How long of a delay are we willing to accept between smoke detection and the fire alarm sounding? And the delay between the switch being pressed and the doorbell sounding? Should the system try to detect smoke or burglars while the doorbell is playing? Should the doorbell work while the smoke alarm is being sounded? What about when the burglar alarm is sounding? Which subsystem should the processor check first: the doorbell, the smoke detec- tor, or the burglar detector? Or should it just alternate between them? Should the doorbell switch be checked as often as the smoke and burglar detectors, or at a different rate? What if the person at the door presses the switch again before the doorbell finishes sounding? Should that be detected?

Now that we have to share the processor, we have to worry about how long the bell rings and the alarms sound. If we use a doorbell ringtone which lasts for thirty seconds, then Ring_The_Bell will take at least thirty seconds to run. During this time, we won’t know if our house is burning or being robbed. Similarly, what if the firemen come when the alarm is sounding? How quickly should the doorbell respond in that case?

1 In fact, any number of tasks greater than one complicates the situation! CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 449

12.3 SCHEDULING FUNDAMENTALS

This example reveals the two fundamental issues in scheduling for responsive systems.

If we have multiple tasks ready to run, which one do we run first? This decision de- fines the ordering of task execution. Do we allow one task to interrupt or preempt another task (or even itself)?

Both of these decisions will determine the system’s responsiveness (measured by response time):

How long will it take for the most important task to start running? To finish running? Does this depend on how long any other tasks take to run, and how of- ten they run? How long will it take for the least important task to start running? To finish running? We expect it will depend on how long all the other tasks take to run, and how often they run. If we allow tasks to preempt each other, then a task may start running very soon but finish much later, after multiple possible preemptions.

These response times in turn affect many per for mance- related issues, such as these:

How fast must the processor’s clock rate be to ensure that nothing happens “late”? How much time do we have available for running compute- intensive algorithms? How much energy can we save by putting the processor to sleep? How much power can we save by slowing down the processor?

Figure 12.1 shows a visual representation of some arbitrary scheduling activity. Task A is released (becomes ready to run) at the first vertical bar. There is some latency be- tween the release and when the task starts running, due to other processing in the sys- tem and scheduler overhead. Similarly, there is a response time which mea sures how long it takes task A to complete its processing. Some scheduling approaches allow a task to be preempted (delayed) after it has started running, which will increase the re- sponse time.

12.3.1 Task Ordering

The first factor affecting response time is the order in which we run tasks. We could always follow the same order by using a static schedule. The code shown for the Doorbell/ 450 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Task A Current Task Task Time Scheduler Task A Latency

Response Time

Time

Figure 12.1 Diagram and definitions of scheduler concepts.

Friend rings doorbell

Burglar breaks in

Fire breaks out

Doorbell Burglar Alarm Fire Alarm Burglar Alarm Fire Alarm

30 seconds

60 seconds

Doorbell Fire Alarm Fire Alarm Fire Alarm Fire Alarm 30 seconds

Fire Alarm Fire Alarm Fire Alarm Fire Alarm Fire Alarm

Negligible delay Figure 12.2 Doorbell/fire alarm/burglar alarm system behavior with different scheduling approaches. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 451

Fire Alarm/Burglar Alarm uses a static schedule. Figure 12.2a shows an interesting case. If a burglar broke in and a fire broke out just after someone pressed the switch to ring the doorbell; we wouldn’t find out about the burglar for almost thirty seconds and the fire for about sixty seconds. We probably do not want these large delays for such critical notifications. We can change the order based on current conditions (e.g., if the house is on fire) using a dynamic schedule. An obvious way to do this is to reschedule after finishing each task. A dynamic schedule lets us improve the responsiveness of some tasks at the price of de- laying other tasks. For example, let’s prioritize fire detection over burglar detection over the doorbell.

1. void main (void){ 2. init_system(); 3. while(1){ 4. if(Smoke_Detected() == TRUE){ 5. Sound_The_Fire_Alarm(); 6. } else if (Burglar_Detected() == TRUE) { 7. Sound_The_Burglar_Alarm(); 8. } else if (switch == PRESSED) { 9. Ring_The_Doorbell(); 10. } 11. } 12. }

Notice how this code is different—there are else clauses added, which change the schedule to a dynamic one. As long as smoke is detected, Sound_The_Fire_Alarm() will run repeatedly. The burglar alarm and doorbell will be ignored until no more smoke is detected. Similarly, burglar detection will disable the doorbell. This is shown in Figure 12.2b. This strict prioritization may or may not be appropriate for a given system. We may want to ensure some fairness, perhaps by limiting how often a task can run. Later in this chapter we present a periodic table- based approach which is much better than this hard- coded design.

12.3.2 Task Preemption

The second aspect to consider is whether one task can preempt another task. Consider our thirty- second doorbell ringtone—the task Ring_The_Doorbell will run to completion without stopping or yielding the processor. 452 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

What if a burglar breaks the window a split second after an accomplice rings the door- bell? In this worst- case scenario, we won’t find out about the burglar (or a possible fire) for thirty seconds.2 Let’s say we’d like to find out within one second. We have several options:

Limit the maximum duration for the doorbell ringtone to one second. Add another microprocessor which is dedicated to playing the doorbell ringtone. This will raise system costs. Break the Ring_The_Doorbell function into thirty separate pieces (e.g., with a state machine or separate functions), each of which takes only one second to run. This code will be hard to maintain. Allow the smoke and burglar detection code to preempt Ring_The_Doorbell. We will need to use a more sophisticated task scheduler which can (1) preempt and re- sume tasks, and (2) detect events which trigger switching and starting tasks. We will not need to break apart any source code. This will make code maintenance easier. However, we introduce the vulnerability to race conditions for shared data, and we also will need more memory (enough to hold each task’s stack simultaneously).

Let’s apply this preemption option to our system. We assign the highest priority to fire de- tection, then burglar detection, and then the doorbell. Now we have the response timeline shown in Figure 12.2c. The system starts sounding the doorbell after the switch is pressed, but as soon as the fire is detected, the scheduler preempts the Ring_The_Doorbell and starts running Sound_The_Fire_Alarm. We find out about the fire essentially immediately, without having to wait for the doorbell to finish sounding. As with the previous example, we have strict prioritization without control of how of- ten tasks can run. As long as smoke is detected, Sound_The_Fire_Alarm() will run repeat- edly. The burglar alarm and doorbell will be ignored until no more smoke is detected. Sim- ilarly, burglar detection will disable the doorbell.

12.3.3 Fairness and Prioritization

These examples all show one weakness of our system: prioritizing some tasks over others can lead to starvation of lower priority tasks (they may never get to run). For some systems this is acceptable, but for others it is not. Here are two ways of providing some kind of fairness:

We can allow multiple tasks to share the same priority level. If both tasks are ready to run, we alternate between executing each of them (whether by allowing each task to run to completion, or by preempting each periodically).

2 Imagine what Thomas Crown, James Bond, or Jason Bourne could do in that time! CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 453

We can limit how often each task can run by defining the task frequency. This is the common approach used for designers of real- time systems. Note that we can still allow only one task per priority level.

12.3.4 Response Time and Preemption

For the two non- preemptive examples in Figure 12.2, notice how the response time for the fire alarm and the burglar alarm depends on how long the doorbell sounds. However, for the preemptive approach those response times are indepen dent of how long the doorbell sounds. This is the major benefit of a preemptive scheduling approach: it makes a task’s re- sponse time essentially indepen dent of all processing by lower priority tasks.3 Instead, only higher priority tasks can delay that task. In Figure 12.3 we present these relationships in a graph. Tasks and ISRs are nodes, while edges (or arcs) are timing dependences. For example, the edge from B to C indicates

Non-Preemptive Non-Preemptive Preemptive Static Scheduling Dynamic Scheduling Dynamic Scheduling

ISRs ISRs ISRs

A A A B B B

C C Task B’s response time depends on Task C is Task C’s duration slowest task C

9 dependences 8 dependences 6 dependences - Higher priority tasks and ISRs - Higher priority tasks and ISRs - Only higher priority tasks - Lower priority tasks - Slowest task and ISRs Figure 12.3 Timing dependences of different scheduling approaches.

3 There are exceptions when tasks can communicate with each other with semaphores and other such mecha- nisms, but that is beyond the scope of this introductory text. 454 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

that task B’s response time depends on task C’s duration. We can now compare timing de- pendences for these three classes of scheduler.

With the non- preemptive static scheduler, each task’s response time depends on the duration of all other tasks and ISRs, so there are nine dependences.4 With the non- preemptive dynamic scheduler, we assign priorities to tasks (A B C). In general, a task no longer depends on lower priority tasks, so we have more timing independence and isolation. This accounts for six dependences. The exception is the slowest or longest duration task, which is C in this example. If task C has started running, it will delay any other task, regardless of priority. So the higher priority tasks A and B each have a dependence edge leading to task C in Figure 12.3, which results in a total of eight dependences. With the preemptive dynamic scheduler, we also prioritize the tasks (A B C). Because a task can preempt any lower priority task, the slowest task no longer mat- ters. Each task can be preempted by an ISR, so there are three dependence edges to begin with. Task A cannot be preempted by B or C, so it adds no new edges. Task B can be preempted by task A, which adds one edge. Finally, task C can be pre- empted by task A or B, which adds two more edges. As a result we have only six dependences. Most importantly, these dependence edges all point upwards.5 This means that in order to determine the response time for a task, we only need to con- sider higher priority tasks. This makes the analysis much easier.

The real- time system research and development communities have developed extensive pre- cise mathematical methods for calculating worst- case response times, determining if dead- lines can ever be missed, and other characteristics of a system. These methods consider sem- aphores, task interactions, scheduler overhead, and all sorts of other complexities of practical implementations. We do not discuss them here as they are beyond the scope of this text.

12.3.5 Stack Memory Requirements

The non- preemptive scheduling approaches do not require as much data memory as the preemptive approaches. In particular, the non- preemptive approach requires only one call stack, while a preemptive approach typically requires one call stack per task.6

4 Of course, if task code can disable interrupts, then there will be three more edges leading from the ISRs back to the tasks! That would be a total of twelve dependences, which is quite a few to handle. 5 This is called a DAG or directed acyclic graph. 6 There are several ways to reduce the number of stacks needed for preemptive scheduling, but they are beyond the scope of this text. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 455

The function call stack holds a function’s state information such as return address and limited lifetime variables (e.g., automatic variables, which only last for the duration of a function). Without task preemption, task execution does not overlap in time, so all tasks can share the same stack. Preemption allows tasks to preempt each other at essentially any point in time. Trying to reuse the same stack space for different tasks would lead to cor- ruption of this information on the stack. For example, task B is running. Function B3 in task B calls function B4. The scheduler then preempts task B to run the higher priority task A, which was running function A2. Function A2 completes and it expects to return to func- tion A1, which called A2. However, the call stack has function B3’s information on the stack, so task A will start executing function B3! And so the system fails to operate correctly. As a result of these memory requirements for preemptive scheduling approaches, there are many cost- sensitive embedded systems which use a non- preemptive scheduler to mini- mize RAM sizes and therefore costs.

12.3.6 Interrupts

Interrupts are a special case of preemption with dedicated hardware and compiler support. They can be added to any of these scheduling approaches in order to provide faster, time- critical processing. In fact, for many systems only interrupt service routines are needed for the application’s work. The main loop is simply an infinite loop which keeps putting the processor into a low- power idle mode. When designing a system which splits between ISRs and task code, one must strike a balance. The more work which is placed in an ISR, the slower the response time for other processing (whether tasks or other ISRs7). The standard approach is to perform time- critical processing in the ISR (e.g., unloading a character from the UART received data buffer) and deferring remaining work for task code (pushing that character in a FIFO from which the task will eventually read). ISR execution duration affects the response time for other code, so it is included in the response time calculations described in Section 12.3.4 and in Figure 12.3. There are many good texts which suggest approaches for architecting ISRs; please see the references list.

7 It is possible to make ISRs interruptable, but this introduces many new ways to build the system wrong. Hence it is discouraged. 456 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

12.4 TASK MANAGEMENT

12.4.1 Task States

A task will be in one of several possible states. The scheduler and the task code itself both affect which state is active. With a non- preemptive dynamic scheduler, a task can be in any one of the states8 shown in Figure 12.4a:

Scheduler Tick Scheduler Tick Ready Ready ISR or other task ISR or other task marks this task marks this task as Ready as Ready

Scheduler selects Scheduler Scheduler selects highest priority finds a highest priority Waiting ready task and Waiting higher ready task and starts it running priority starts it running ready task Task function Task function completes completes Running Running

Non-preemptive Dynamic Scheduler Preemptive Dynamic Scheduler Figure 12.4 Task states and transitions for different schedulers.

Waiting for the scheduler to decide that this task is ready to run. For example, a task which asked the scheduler to delay it for 500 ms will be in this state for that amount of time. Ready to start running but not running yet. There may be a higher- priority task which is running. As this task has not started running, no automatic variables have been initialized, and there is no activation record. Running on the processor. The task runs to the completion of the task function, at which point the scheduler resumes execution and the task is moved to the wait- ing state. Automatic variables have been initialized, and there is at least one acti- vation record on the stack frame for this task. A single processor system can have only one task in this state.

8 We consider preemption by an ISR as a separate state. However, since it operates automatically and saves and restores system context, we consider it as a separate enhancement to the RTC scheduler and leave it out of our diagrams. In fact, the scheduler relies on a tick ISR to track time and move tasks between certain states. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 457

Consider a task which needs to write a block of data to flash memory. After issuing a write command to the flash , it may take some significant amount of time (e.g., 10 ms) to program the block. We have two options with a non- preemptive kernel:

Our task can use a busy wait loop until the flash block programming is complete. The task remains in the running state while programming. This approach delays other processing and wastes processor cycles. We can break the task into a state machine so that task state one issues the write command, task state two checks to see if the programming is done, and task state three continues with the task’s processing. The task executes task state two each time it is called as long as programming is not done. The task spends most of its time waiting, with occasional brief periods running when executing the code for task state two. This approach complicates program design but is practical for smaller systems. However, it grows unwieldy for complex systems.

Allowing tasks to preempt each other reduces response time and simplifies application de- sign. With preemption, each task need not be built with a run- to- completion structure. In- stead, the task can yield the processor to other tasks, or it can be preempted by a higher- priority task with more urgent processing. For example, our task can tell the scheduler “I don’t have anything else to do for the next 10 ms, so you can run a different task.” The scheduler then will save the state of this task, and swap in the state of the next highest pri- ority task which is ready to run. This introduces another way to move from running to wait- ing, as well as a way to move from running to ready. We examine these in detail next.

12.4.2 Transitions between States

We now examine the ways in which a task can move between the various states. These rules govern how the system behaves, and therefore set some ground rules for how we should design our system.

The transition from ready to running: ▫ In a non- preemptive system, when the scheduler is ready to run a task, it se- lects the highest priority ready task and moves it to the running state, typically by calling it as a subroutine (as there is no context to restore). ▫ In a preemptive system, when the kernel is ready to run a task, it selects the highest priority ready task and moves it to the running state by restoring its context to the processor. The transition from running to waiting: ▫ In a non- preemptive system, the only way a task can move from running to waiting is if it completes (returns from the task function). At this point there is 458 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

no more execution context for the task (return addresses, automatic variables), so there is no data to save or restore. ▫ In a preemptive system, the task can yield the processor.9 For example, it can request a delay (“Hey, RTOS! Wake me up in at least 10 ms!”) or it can wait or pend on an event (“Hey, RTOS! Wake me up when I get a message in my mailbox called foo!”). This makes application programming much easier, as mentioned before. At this point there still is execution context, so the kernel must save it for later restoration. The transition from waiting to ready: ▫ In a non- preemptive system such as the RTC scheduler above, the timer tick ISR moves the task by setting the run flag. Alternatively, another task can set the run flag to request for this task to run. ▫ In a preemptive system, the kernel is notified that some event has occurred. For example, time delay has expired, or a task has sent a message to the mail- box called foo. The kernel knows which task is waiting for this event, so it moves that particular task from the waiting state to the ready state. The transition from running to ready: ▫ In a non- preemptive system this transition does not exist, as a task cannot be preempted. ▫ In a preemptive system, when the kernel determines a higher priority task is ready to run, it will save the context of the currently running task, and move that task to the ready state.

12.4.3 Context Switching for Preemptive Systems

In preemptive systems, some of these state transitions require the scheduler to save a task’s execution context and restore another task’s context to ensure programs execute correctly. This is called context switching and involves accessing the processor’s general- purpose registers. Figure 12.5 shows a view of a processor and its memory as it is executing task A in a system with two tasks (A and B). The CPU uses the program counter PC to fetch the next instruction to execute, and various pointer registers refer to locations in memory such as the task’s stack, etc. The CPU also has general purpose registers which are used to hold the programs data and intermediate computation results. In order to perform a from task A to task B correctly, we must first copy all of this task- specific processor register information to a storage location (e.g., task

9 What happens if the task function finishes executing depends on the RTOS. The task could move to the wait- ing state, or to a terminated state. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 459

Memory Figure 12.5 Saving task 0x000000 A’s context from the CPU.

global data CPU R0 R1 R2 R3 heap A0 A1 FLG USP

PC FB ISP SB

TCB A

R0 R1 R2 R3 B Stack A0 A1 FLG USP

PC FB ISP SB

A Stack

Task A

instructions

Task B

0xFFFFFF

Memory Figure 12.6 Restoring 0x000000 task B’s context to the CPU.

global data CPU R0 R1 R2 R3 heap A0 A1 FLG USP

PC FB ISP SB

TCB A

R0 R1 R2 R3 B Stack A0 A1 FLG USP

PC FB ISP SB

A Stack

Task A

TCB B instructions R0 R1 R2 R3 Task B A0 A1 FLG USP

PC FB ISP SB 0xFFFFFF 460 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

control block (TCB) A). Second, we must copy all of the data from TCB B into the CPU’s registers. This operation is shown in Figure 12.6. Now the CPU will be able to resume ex- ecution of task B where it left off.

12.5 SHARING DATA SAFELY

Preemption among tasks introduces a vulnerability to data race conditions. Now a task can be considered to be as bug- prone and difficult to debug as an ISR! The system can fail in new ways when:

Multiple tasks or ISRs share data,10 or Multiple instances of a function can execute concurrently.

In order to prevent these failures we need to be careful when designing our system.

12.5.1 Data Shared Objects

If a data object is accessed by code which can be interrupted (is not atomic), then there is a risk of data corruption. Atomic code is the smallest part of a program that executes without interruption. Generally a single machine instruction is atomic,11 but sequences of instruc- tions are not atomic unless interrupts are disabled. Consider an example where task A starts modifying object O. Task B preempts it be- fore it finishes. At this point in time object O is corrupted, as it is only partially updated. If task B needs to read or write O, the computation results will be incorrect and the system will likely fail.

1. unsigned time_minutes, time_seconds; 2. void task1 (void){ 3. time_seconds++; 4. if(time_seconds >= 60){ 5. time_minutes++; 6. time_seconds = 0; 7. } 8. }

10 Hardware registers which change outside of the program’s control also introduce problems but we do not dis- cuss them further here. 11 Some instruction sets have long instructions (e.g., string copy, block move) which can be interrupted, in which case those instructions are not atomic. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 461

9. void task2 (void){ 10. unsigned elapsed_sec; 11. elapsed_seconds = time_minutes * 60 + time_seconds; 12. }

Here is a more specific example. Our shared object is a pair of variables which measure the current time in minutes and seconds. Task1 runs once per second to increment the seconds, and possibly the minutes as well. Task2 calculates how many total seconds have elapsed since time zero. There are data races possible:

If task1 is preempted between lines 4 and 5 or lines 5 and 6, then when task2 runs it will only have a partially updated version of the current time, and elapsed_ seconds will be incorrect. If task2 is preempted during line 11, then it is possible that timeinutes is read be- fore task1 updates it and time_seconds is read after task 1 updates it. Again, this leads to a corrupted elapsed_seconds value.

12.5.2 Function Reentrancy

Another type of shared data problem comes with the use of non- reentrant functions. In this case, the problem arises from multiple instances of the same function accessing the same object. Consider the following example:

1. void task1 ( ){ 2...... 3. swap(&x, &y); 4...... 5. } 6. void task2 ( ){ 7...... 8. swap(&p, &q); 9...... 10. } 11. int Temp; 12. void swap (*i, *j ){ 13. Temp = *j; 14. *j = *i; 15. *i = Temp; 16. } 462 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Suppose task1 is running and calls the swap function. After line 13 is executed, task2 be- comes ready. If task2 has a higher priority, task1 is suspended and task2 is serviced. Later, task1 resumes to line 14. Since Temp is a shared variable, it is not stored in the TASK sub- routine shared data stack. When task1 line 15 is executed, variable x (of task1 pointed by variable pointer i) gets the wrong value. Such function executions should not be suspended in between or shared by more than one task. Such functions are called non- reentrant. The code which can have multiple simultaneous, interleaved, or nested invocations which will not interfere with each other is called reentrant code. These types of code are important for parallel processing, recursive functions or subroutines, and for interrupt handling. An ex- ample of a reentrant code is as follows:

1. void swap (*i, *j ){ 2. static int Temp; 3. Temp = *j; 4. *j = *i; 5. *i = Temp; 6. }

Since the variable Temp is declared within the function, if any other task interrupts the exe- cution of the swap function, the variable Temp will be stored in the corresponding task’s stack and will be retrieved when the task resumes its function. In most cases, especially in a multi- processing environment, the non- reentrant functions should be eliminated. A func- tion can be checked for its reentrancy based on these three rules:

1. A reentrant function may not use variables in a non- atomic way unless they are stored on the stack of the calling task or are the private variables of that task. 2. A reentrant function may not call other functions which are not reentrant. 3. A reentrant function may not use the hardware in a non- atomic way.

12.5.3 High-Level Languages and Atomicity

We can identify some but not all non- atomic operations by examining high- level source code. Since the processor executes rather than a high- level language such as C or Java, we can’t identify all possible non- atomic operations just by examining the C source code. Something may seem atomic in C but actually be implemented by multiple machine instructions. We need to examine the assembly code to know for sure. Let’s ex- amine the following function and determine whether it is reentrant or not: CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 463

EXAMPLE 1

1. static int event_count; 2. void event_counter (void){ 3. ++event_count; 4. }

Example 1 in assembly language:

1. MOV.L #0000100CH, R4 2. MOV.L [R4], R5 3. ADD #1H, R5 4. MOV.L R5, [R4] 5. RTS

Consider example 1, and then apply the first rule. Does it use shared variable event_count in an atomic way? The ++event_count operation is not atomic, and that single line of C code is implemented with three lines of assembly code (lines two through four). The processor loads R4 with a pointer to event_count, copies the value of event_count into register R5, adds 1 to R5, and then stores it back into memory. Hence, example 1 is non- reentrant. However, what if the processor instruction set supports in- place memory operations? The RX architecture does not, but many others do. In that case, the assembly code could look like this: Example 1 in assembly language, compiled for a different processor architecture:

1. MOV.L #0000100CH, A0 2. ADD #1H, [A0] 3. RTS

This code is reentrant, since there is only one instruction needed to update the value of the event count. Instruction 1 is only loading a pointer to the event count, so interrupting be- tween 1 and 2 does not cause a problem.

EXAMPLE 2

1. void add_sum (int *j){ 2. ++(*j); 3. DisplayString(LCDLINE1, Int_to_ascii(*j); 4. } 464 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Now consider example 2. Even though line 2 in this example is not atomic, the variable *j is task’s private variable, hence rule 1 is not breached. But consider line 3. Is the function DisplayString reentrant? That depends on the code of DisplayString, which depends on the user. Unless we are sure that the DisplayString function is reentrant, example 2 is considered to be non- reentrant. So every time a user codes a function, he has to make sure the function is reentrant to avoid erroneous results.

12.5.4 Shared- Data Solutions and Protection

In the previous section, we discussed the problems of using shared data in a RTOS envi- ronment. In this section we shall study some methods to protect the shared data. The solu- tions provided in this section may not be ideal for all applications. The user must judge which solution may work best for the application.

Disable Interrupts One of the easiest methods is to disable the interrupts during the critical section of the task. Disabling the interrupts may not take more than one machine cycle to execute, but will in- crease the worst case response time of all other code, including other interrupt ser vice rou- tines. Once the critical section, or shared variable section, of the code is executed, the in- terrupt masking be restored to its previous state (either enabled or disabled). The user must be cautious while disabling or enabling interrupts, because if interrupts are disabled for too long, the system may fail to meet the timing requirements. See Chapter 9, Using Interrupts with Peripherals, to find out how to disable and restore interrupt masking state. A simple example of disabling interrupts is as follows:

1. #define TRUE 1 2. #define FALSE 0 3. static int error; 4. static int error_count; 5. void error_counter ( ){ 6. if(error == TRUE){ 7. SAVE_INT_STATE; 8. DISABLE_INTS; 9. error_count++; 10. error = FALSE; 11. RESTORE_INT_STATE; 12. } 13. } CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 465

Disabling and restoring the interrupt masking state requires only one or a few machine cy- cles. Disabling interrupts must take place only at critical sections to avoid increasing re- sponse time excessively. Also, while restoring the interrupt masking state the user must keep in mind the need to enable only those interrupts that were active (enabled) before they were disabled. Determining the interrupt masking status can be achieved by referring to the interrupt mask register. The Interrupt mask register keeps track of which interrupts are enabled and disabled.

Use a Lock Another solution is to associate every shared variable with a lock variable, which is also declared globally. If a function uses the shared variable, then it sets the lock variable and once it has finished process, it resets the lock variable. Every function must test the lock variable before accessing it. If the lock variable is already set, the task should in- form the scheduler to be rescheduled once the variable becomes available. Since only one variable has to be checked every time before accessing the data, using lock vari- ables simplifies the data structure and I/O devices access. Consider the following ex- ample for using a lock:

1. unsigned int var; 2. char lock_var; 3. void task_var ( ){ 4. unsigned int sum; 5. if(lock_var == 0){ 6. lock_var = 1; 7. var = var + sum; 8. lock_var = 0; 9. } 10. else { 11. /* message to scheduler to check var 12. and reschedule */ 13. } 14. }

Since it takes more than one clock cycle to check whether a variable is available and use a lock on it, the interrupts have to be disabled. Once again when the lock has to be released, the interrupts should be disabled since locking and releasing the variable is a critical part of the code. Interrupts must be enabled whenever possible to lower the interrupt service re- sponse time. If the variable is not available, the scheduler is informed about the lock and the task goes into a waiting state. 466 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Microprocessors such as the Renesas RX support Bit Test and Set instructions can per- form a test and set in one atomic machine instruction, and therefore do not require an interrupt disable/enable lock around semaphore usage. The challenge with this approach is determining what to do in lines 11 and 12 if there is no scheduler support. There may be no easy way to tell the scheduler to reschedule this task when the lock variable becomes available again.

RTOS-Provided Semaphore Most operating systems provide locks to shared variables through the use of semaphores. A semaphore is a mechanism that uses most of the multitasking kernels to protect shared data and to synchronize two tasks. A semaphore is very much similar to the variable lock process explained in the Section 12.4.3. The main difference is that the OS takes care of initializing and handling the locks, so the implementation is much more likely to be correct than if you try to create your own lock. There are two types of semaphores—binary semaphores and counting semaphores. Binary semaphores take two values, 0 or 1. A counting semaphore takes a value between 0 and 2N 1, where N is the number of bits used for the semaphore. In this book we con- sider only the binary semaphore. A semaphore usually has three tasks: initialization/create, wait, and signal. A non- zero number or value is assigned to the semaphore once it is created. At this point no task is waiting for the semaphore. Once a task requires a data, the task performs a wait operation on the semaphore. The OS checks the value of the semaphore; for example, if the semaphore is available (semaphore value is non- zero), the OS changes the value of the semaphore to zero and assigns the semaphore to the task. If the semaphore value is zero during the wait operation, the task that requested the wait operation is placed on the sema- phore’s waiting list. Once the semaphore becomes available based on the priority of the tasks waiting for it, the OS decides which task to assign to the semaphore. The tasks added to the semaphore’s waiting list wait only for a certain amount of time. If the time expires, the task sends an error code to the semaphore seeking function and re- sumes its work. When the task has attained the semaphore and all its operations are com- plete, the task performs a signal operation, announcing that the semaphore is free. The OS checks if any other task is waiting for the semaphore and then transfers the semaphore to the task without changing the semaphore’s value. If no task is waiting for the semaphore, the semaphore is incremented to a non- zero number. The wait operation is also referred to as Take or Pend or P and signal operation is referred to as Release or Post or V. The fol- lowing example shows how wait and signal operations are performed:

1. typedef int semaphore; 2. float temp; 3. semaphore var_temp 4. void Task1 (void){ CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 467

5. wait (var_temp); 6. temp = (9/5)(temp + 32); /* Celsius into Fahrenheit */ 7. Signal (var_temp); 8. } 9. void Task2 (void){ 10. wait(var_temp); 11. temp = ADDR0; /* Read ADC value from thermistor */ 12. temp = ADCtotemp_conversion(); 13. Signal (var_temp); 14. }

In the previous example two tasks share the variable temp. The Task2 subroutine reads the temperature value from a thermistor and saves it on temp, while Task1 converts the tem- perature from Celsius to Fahrenheit. Just before the tasks enter the critical section, they re- quest the semaphore and only then perform the operation on the shared variable.

RTOS-Provided Messages The RTOS provides other mechanisms besides semaphores for allowing tasks to communi- cate, such as message queues and mailboxes. It may be possible to structure your program to use messages to pass information rather than sharing data objects directly. We leave further discussion of this approach to the many RTOS- oriented books and articles already available.

Disable Task Switching If no other method seems to work, one unattractive option is to disable the scheduler. If the scheduler is disabled, the task switching does not take place and the critical sections or shared data can be protected by other tasks. This method is counter- productive; disabling the sched- uler increases response times and makes analysis much more difficult. This is considered bad practice and must be properly justified; hence consider this method as a last resort.

12.6 NONPREEMPTIVE DYNAMIC SCHEDULER

12.6.1 Concepts

We will now examine a flexible nonpreemptive scheduler for periodic and aperiodic tasks. We call it the RTC (run- to- completion) scheduler. This simple tick- based scheduler is quite flexible and offers the following major benefits:

We can configure the system to run each task with a given period (e.g., every 40 ms) mea sured in time ticks. This simplifies the creation of multi- rate systems. 468 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

We can define task priorities, allowing us to design the system’s response (which tasks are executed earlier) when there are multiple tasks ready to run. We can selectively enable and disable tasks.

This scheduler has three fundamental parts.

Task Table: This table holds information on each task, including: ▫ The address of the task’s root function. ▫ The period with which the task should run (e.g., 10 ticks). ▫ The time delay until the next time the task should run (mea sured in ticks). ▫ A flag indicating whether the task is ready to run. Tick ISR: Once per time tick (say each 1 millisecond) a hardware timer triggers an interrupt. The interrupt service routine decrements the time delay (timer) until the next run. If this reaches zero, then the task is ready to release, so the ISR sets its run flag. Task Dispatcher: The other part of the scheduler is what actually runs the tasks. It is simply an infinite loop which examines each task’s run flag. If it finds a task with the run flag set to 1, the scheduler will clear the run flag back to 0, execute the task, and then go back to examining the run flags (starting with the highest- priority task in the table).

Figure 12.7 shows a simple example of how this works with three tasks. Task 1 becomes active every twenty time intervals, and takes one time interval to complete. Task 2 is active every ten time intervals, and takes two time intervals to complete. Task 3 becomes active every five time intervals and takes one time interval to complete. If more than one task becomes ready simultaneously (as seen at elapsed time ten), the higher priority task is serviced first. When the higher priority task finishes, the next highest ready task is executed. This repeats until there are no ready tasks. Another example of a run- to- completion dynamic scheduling with interrupts is shown in Figure 12.8. A new task, Task 4, is added, which becomes active every three time inter- vals and runs for one time interval. As shown in Figure 12.8, at time 20, tasks T1, T2, T3 all become active and T2 is run based on priority. At time 21, task T4 becomes active and is scheduled to run at time 22. T1 runs at time 23, but before T3 gets a chance to run, T4 becomes active again and gains the processor. At time 25, T3 misses a turn since T3 becomes active again and the T3 is serviced as if it were active only once. This is an example of an over- load situation which leads to one of the tasks missing its turn.12

12 We could use a counter rather than a flag for the run variable, to allow for processing backlogs. In this case the ISR would increment run rather than set it, and the scheduler function would decrement it rather than clear it. This could be useful in some situations, but it would complicate the analysis. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 469

Priority Length Frequency Task 1 2 1 20 Task 2 1 2 10 Task 3 3 1 5

Elapsed time 0 1 2345678910111213141516171819202122232425 Task executed T3 T2 T3 T3 T2 T1 T3 T3

Task T1 20 19 18 17 16 15 14 13 12 11 10 987654321201918171615 Task T2 10 9 87654321109876543211098765 Task T3 5 4 321543215432154321543215

Run T1 WW R Run T2 R R Run T3 R WWRR WWWRR R Running on processor W Ready and waiting for processor Figure 12.7 Simple run- to- completion dynamic scheduling.

Priority Length Frequency Task 1 2 1 20 Task 2 1 2 10 Task 3 3 1 5 Task 4 0 1 3

Elapsed time 012345678910111213141516171819202122232425 Task executed T4 T3 T4 T4 T2 T4 T3 T4 T3 T4 T2 T4 T1 T4 T3

Task T1 20 19 18 17 16 15 14 13 12 11 10 987654321201918171615 Task T2 10 987654321109876543211098765 Task T3 54321543215432154321543215 Task T4 32132132132132132132132132

Run T1 WWW R Run T2 R R Run T3 R WWWRWR WWWWW R Run T4 RRRRRRWRR R Running on processor W Ready and waiting for processor Figure 12.8 Complex run- to- completion dynamic scheduling. 470 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Priority Length Frequency Task 1 2 1 20 Task 2 1 2 10 Task 3 3 1 5 Task 4 0 23

Elapsed time 0123456789101112131415161718192021222324252627282930 Task executed T4 T3 T4 T4 T2 T4 T4 T3 T4 T2 T4 T4 T1 T4 T3 T4

Task T1 20 19 18 17 16 15 14 13 12 11 10 9876543212019181716151413121110 Task T2 10 987654321109876543211098765432110 Task T3 5432154321543215432154321543215 Task T4 3213213213213213213213213213213

Run T1 WWWWWW R Run T2 WR R W Run T3 R WWWWWWW R WWWWWWWWW R W Run T4 RRRWRRRWRRRR R Running on processor W Ready and waiting for processor Figure 12.9 Overload example of run-to- completion dynamic scheduling.

Figure 12.9 shows a complex overloaded example where the scheduler fails to service every task that is ready.

12.6.2 Implementation

Task Table A scheduler uses a table to store information on each task. Each task has been assigned a timer value. A task becomes active at regular intervals based on this value. This timer value is decremented each tick by the timer tick ISR. Once the timer value reaches zero, the task becomes ready to run. To reset this value after it has reached zero, an initial Timer Value variable is used to store the time at which the task has to be active. Two variables, enabled and run, are used to signal when a task is enabled and when it is ready to run. Variables enabled and run are used to indicate to the scheduler if a task is enabled and if it is ready to run. The function pointer *task indicates to the scheduler which function to perform. The task’s priority is defined by its position within this array. Entry 0 has the highest priority; whenever the scheduler needs to find a task to run, it begins at entry 0 and then works its way through the table. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 471

The scheduler’s task table is defined as follows:

1. #define MAX_TASKS 10 2. #define NULL ((void *)0) 3. typedef struct { 4. int initialTimerValue; 5. int timer; 6. int run; 7. int enabled; 8. void (* task)(void); 9. } task_t; 10. task_t GBL_task_table [MAX_TASKS];

Before running the scheduler, the application must initialize the task table as follows:

1. void init_Task_Timers(void){ 2. int i; 3. /* Initialize all tasks */ 4. for(i = 0; i < MAX_TASKS; i++){ 5. GBL_task_table [i].initialTimerValue = 0; 6. GBL_task_table [i].run = 0; 7. GBL_task_table [i].timer = 0; 8. GBL_task_table [i].enabled = 0; 9. GBL_task_table [i].task = NULL; 10. } 11. }

Managing Tasks Once the initialization is completed, tasks must be added to the task structure. The new tasks can be added before starting the scheduler or during the scheduler’s execution time. When adding a task, the following must be specified: the time interval in which the task has to be active, its priority, and the function on which the task has to operate. The following code shows how adding a task is added:

1. int Add_Task(void (*task)(void), int time, int priority){ 2. /* Check for valid priority */ 3. if(priority >= MAX_TASKS || priority < 0) 4. return 0; 5. /* Check to see if we are overwriting an already scheduled task */ 6. if(GBL_task_table [priority].task != NULL) 472 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

7. return 0; 8. /* Schedule the task */ 9. GBL_task_table [priority].task = task; 10. GBL_task_table [priority].run = 0; 11. GBL_task_table [priority].timer = time; 12. GBL_task_table [priority].enabled = 1; 13. GBL_task_table [priority].initialTimerValue = time; 14. return 1; 15. }

We can remove an existing task:

1. void removeTask(void (* task)(void)){ 2. int i; 3. for(i = 0; i < MAX_TASKS; i++){ 4. if(GBL_task_table [i].task == task){ 5. GBL_task_table [i].task = NULL; 6. GBL_task_table [i].timer = 0; 7. GBL_task_table [i].initialTimerValue = 0; 8. GBL_task_table [i].run = enabled = 0; 9. return; 10. } 11. } 12. }

We can also selectively enable or disable a task by changing its enabled flag:

1. void Enable_Task(int task_number){ 2. GBL_task_table [task_number].enabled = 1; 3. } 4. 5. void Disable_Task(int task_number){ 6. GBL_task_table [task_number].enabled = 0; 7. }

Finally, we can change the period with which a task runs:

1. void Reschedule_Task(int task_number, int new_timer_val){ 2. GBL_task_table [task_number].initialTimerValue = 3. new_timer_val; 4. GBL_task_table [task_number].timer = new_timer_val; 5. } CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 473

Tick Timer Configuration and ISR A run- to- completion dynamic scheduler uses a timer to help determine when tasks are ready to run (are released). A timer is set up to generate an interrupt at regular intervals. Within the interrupt service routine the timer value for each task is decremented. When the timer value reaches zero, the task becomes ready to run. In this code we have configured the 8-bit timer to generate an interrupt every 0.5 milliseconds. For details on how to set up a timer see Chapter 8.

1. void Init_RTC_Scheduler(void){ 2. IEN(TMR0,CMIA0) = 0; 3. IPR(TMR0,CMIA0) = 3; 4. MSTP(TMR0) = 0; 5. TMR0.TCNT = 0x00; 6. TMR0.TCORA = 78; 7. TMR0.TCSR.BYTE = 0xE2; 8. IEN(TMR0,CMIA0) = 1; 9. TMR0.TCCR.BYTE = 0x0C; 10. TMR0.TCR.BYTE = 0x48; 11. }

In the next example Timer 0 is set to compare the match mode with timer constant A. An interrupt occurs every 0.5 millisecond. The timer is configured in a continuous mode and resets every time a compare match is made.

1. void Excep_TMR0_CMI0A(void){ 2. int i; 3. for(i = 0; i < MAX_TASKS; i++){ 4. if(GBL_task_table [i].task != NULL) && 5. (GBL_task_table [i].enabled == 1) && 6. (GBL_task_table [i].timer > 0)) 7. { 8. if(––GBL_task_table [i].timer == 0){ 9. GBL_task_table [i].run = 1; 10. GBL_task_table [i].timer = 11. GBL_task_table [i].initialTimerValue; 12. } 13. } 14. } 15. } 474 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

Scheduler The scheduler looks for ready tasks starting at the top of the table (highest priority task). It runs every ready task it finds, calling it as a function (in line 16).

1. void Run_RTC_Scheduler(void){ 2. int i; 3. /* Loop forever */ 4. while(1){ 5. /* Check each task */ 6. for(i = 0; i < MAX_TASKS; i++){ 7. /* check if valid task */ 8. if(GBL_task_table [i].task != NULL){ 9. /* check if enabled */ 10. if(GBL_task_table [i].enabled == 1){ 11. /* check if ready to run */ 12. if(GBL_task_table [i].run == 1){ 13. /* Reset the run flag */ 14. GBL_task_table [i].run = 0; 15. /* Run the task */ 16. GBL_task_table [i].task(); 17. /* break out of loop to start at entry 0 */ 18. break; 19. } 20. } 21. } 22. } 23. } 24. }

12.6.3 Example Application using RTC Scheduler

Let’s use the RTC scheduler to create a toy with red and green LEDs flashing at various fre- quencies. The grnLED task toggles a green LED (on board LED 6) every one second, and the redLED task toggles a red LED (on board led 12) every 0.25 seconds. The grn_redLED task toggles one red LED and one green LED (on board led 7 and led 8 respectively) every 0.5 seconds. The tasks and the main program are shown below:

1. void grnLED(void){ 2. if(LED3 == LED_ON) CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 475

3. LED3 = LED_OFF; 4. else 5. LED3 = LED_ON; 6. } 7. void redLED(void){ 8. if(LED4 == LED_ON) 9. LED4 = LED_OFF; 10. else 11. LED4 = LED_ON; 12. } 13. void grn_redLED(void){ 14. if(LED5 == LED_ON) 15. LED5 = LED9 = LED_OFF; 16. else 17. LED5 = LED9 = LED_ON; 18. } 19. void main(void){ 20. ENABLE_LEDS; 21. init_Task_Timers(); 22. Add_Task(grnLED,10000,0); 23. Add_Task(redLED,2500,1); 24. Add_Task(grn_redLED,5000,2) 25. Init_RTC_Scheduler(); 26. Run_RTC_Scheduler(); 27. }

12.7 REFERENCES

Simon, David E. An Embedded Software Primer. Indianapolis: Addison- Wesley Professional, 1999. Print. Labrosse, J. MicroC/OS II: The Real- Time Kernel, 2nd Ed. Lawrence, KS: Newnes, 2002. Print. Labrosse, J., Ganssle, J., Oshana, R., Walls, C., Curtis, K., Andrews, J., Katz, D., Gentile, R., Hyder, K., and B. Perrin. Embedded Software: Know it All. Burlington, MA: Newnes, 2008. Print. Labrosse, J. MicroC/OS- III: The Real- Time Kernel, or a High Performance, Scalable, ROMable, Preemptive, Multitasking Kernel for Microprocessors, Microcontrollers & DSPs. Weston, FL: Micrium Press, 2009. Print. 476 EMBEDDED SYSTEMS USING THE RENESAS RX62N MICROCONTROLLER

12.8 EXERCISES

1. For some task sets, changing from static to dynamic task ordering in a scheduler will provide a major response time improvement for the highest priority task, while for other task sets it will not. Give an example of each and explain the difference. 2. For some task sets, adding preemption to a scheduler will provide a major re- sponse time improvement for the highest priority task, while for other task sets it will not. Give an example of each and explain the difference. 3. Write C code to implement run- to- completion dynamic scheduling without inter- rupts to poll the following tasks: a. If switch 1 is pressed Toggle the RED LEDs. b. If switch 2 is pressed read the temperature value from the onboard thermistor and display on LCD. c. If switch 3 is pressed read the potentiometer value and display on the LCD. d. If no switch is pressed Toggle the GREEN LEDs. 4. Write an algorithm which implements the below functionality using run- to- completion dynamic scheduling with interrupts: a. Toggle RED LEDs every 0.5 seconds. b. Toggle GREEN LEDs every 0.25 seconds. c. Read temperature value from onboard thermistor and display on LCD every 1.0 seconds. d. Read potentiometer value and display on LCD every 2.5 seconds. 5. Write a C code to implement round- robin with interrupts algorithm to perform the following tasks: a. Toggle RED LEDs every 0.5 seconds. b. Toggle GREEN LEDs every 0.25 seconds. c. Read temperature value from onboard thermistor and display on LCD every 1.0 seconds. d. Read potentiometer value and display on LCD every 2.5 seconds. 6. Fill in the following table to show which tasks the processor will execute and when, as well as scheduler table contents. Assume that timer tick interrupts occur every 1 millisecond, all tasks take 1.2 milliseconds to complete, and initialTimerValue for tasks A, B, and C are 2, 4, and 5 respectively. Note that the entries in the table in col- umn “Right before n” (e.g., timer, run, enabled) show the variable’s value right be- fore the timer tick interrupt occurs. This means that a task will run on the tick when its timer reaches 0 (but show the value after the tick and after the ISR executes). As- sume task A has the highest priority, followed by task B, and then C. CHAPTER 12 / DESIGNING RESPONSIVE AND R EAL- TIME SYSTEMS 477

RIGHT N N N N N N N N N N N N N TASK BEFORE ؉ ؉ ؉ ؉ ؉ ؉ ؉ ؉ ؉ ؉ ؉ ؉ ؉ NAME N N 1 2 3 4 5 6 7 8 9 10 11 12 13 A timer 2 run 0 enabled 1 B timer 3 run 0 enabled 1 C timer 1 run 0 enabled 1 Activity —

7. Fill in the table in Exercise 4, if timer tick interrupts occur every 0.5 milliseconds and all tasks take 1.25 milliseconds to complete.

Appendix A

Interrupt Vector Table

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High — Reserved 0 0000 — ϫ ϫ ϫ ϫ ϫ — — — Reserved 1 0004 — ϫ ϫ ϫ ϫ ϫ — — — Reserved 2 0008 — ϫ ϫ ϫ ϫ ϫ — — — Reserved 3 000C — ϫ ϫ ϫ ϫ ϫ — — — Reserved 4 0010 — ϫ ϫ ϫ ϫ ϫ — — — Reserved 5 0014 — ϫ ϫ ϫ ϫ ϫ — — — Reserved 6 0018 — ϫ ϫ ϫ ϫ ϫ — — — Reserved 7 001C — ϫ ϫ ϫ ϫ ϫ — — — Reserved 8 0020 — ϫ ϫ ϫ ϫ ϫ — — — Reserved 9 to 15 0024 to 003C — ϫ ϫ ϫ ϫ ϫ — — Bus error BUSERR 16 0040 Level ⅙ ϫ ϫ ϫ ϫ IER02. IEN0 IPR00 — Reserved 17 0044 — ϫ ϫ ϫ ϫ ϫ IER02. IEN1 — — Reserved 18 0048 — ϫ ϫ ϫ ϫ ϫ IER02. IEN2 — — Reserved 19 004C — ϫ ϫ ϫ ϫ ϫ IER02. IEN3 — — Reserved 20 0050 — ϫ ϫ ϫ ϫ ϫ IER02. IEN4 — FCU FIFERR 21 0054 Level ⅙ ϫ ϫ ϫ ϫ IER02. IEN5 IPR01 Reserved 22 0058 — ϫ ϫ ϫ ϫ ϫ IER02. IEN6 — FRDYI 23 005C Edge ⅙ ϫ ϫ ϫ ϫ IER02. IEN7 IPR02 — Reserved 24 0060 — ϫ ϫ ϫ ϫ ϫ IER03. IEN0 — — Reserved 25 0064 — ϫ ϫ ϫ ϫ ϫ IER03. IEN1 — — Reserved 26 0068 — ϫ ϫ ϫ ϫ ϫ IER03. IEN2 — ICU SWINT 27 006C Edge ⅙ ⅙ ϫ ϫ ϫ IER03. IEN3 IPR03 CMT Unit 0 CMI0 28 0070 Edge ⅙ ⅙ ⅙ ϫ ϫ IER03. IEN4 IPR04 Low CMI1 29 0074 Edge ⅙ ⅙ ⅙ ϫ ϫ IER03. IEN5 IPR05

⅙: Selectable ϫ: Not Selectable

Source: RX62N Group, RX621 Group Hardware Manual, page 342-355.

479 480 APPENDIX A

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High CMT Unit 1 CMI2 30 0078 Edge ⅙ ⅙ ⅙ ϫ ϫ IER03. IEN6 IPR06 CMI3 31 007C Edge ⅙ ⅙ ⅙ ϫ ϫ IER03. IEN7 IPR07 Ether EINT 32 0080 Level ⅙ ϫ ϫ ϫ ϫ IER04. IEN0 IPR08 USB0 D0FIFO0 36 0090 Edge ⅙ ⅙ ⅙ ϫ ϫ IER04.IEN4 IPR0C D1FIFO0 37 0094 Edge ⅙ ⅙ ⅙ ϫ ϫ IER04.IEN5 IPR0D USBI0 38 0098 Edge ⅙ ϫ ϫ ϫ ϫ IER04.IEN6 IPR0E USB1 D0FIFO1 40 00A0 Edge ⅙ ⅙ ⅙ ϫ ϫ IER05. IEN0 IPR10 D1FIFO1 41 00A4 Edge ⅙ ⅙ ⅙ ϫ ϫ IER05. IEN1 IPR11 USBI1 42 00A8 Edge ⅙ ϫ ϫ ϫ ϫ IER05. IEN2 IPR12 RSPI0 SPEI0 44 00B0 Level ⅙ ϫ ϫ ϫ ϫ IER05. IEN4 IPR14 SPRI0 45 00B4 Edge ⅙ ⅙ ⅙ ϫ ϫ IER05. IEN5 SPTI0 46 00B8 Edge ⅙ ⅙ ⅙ ϫ ϫ IER05. IEN6 SPII0 47 00BC Level ⅙ ϫ ϫ ϫ ϫ IER05. IEN7 RSPI1 SPEI1 48 00C0 Level ⅙ ϫ ϫ ϫ ϫ IER06. IEN0 IPR15 SPRI1 49 00C4 Edge ⅙ ⅙ ⅙ ϫ ϫ IER06. IEN1 SPTI1 50 00C8 Edge ⅙ ⅙ ⅙ ϫ ϫ IER06. IEN2 SPII1 51 00CC Level ⅙ ϫ ϫ ϫ ϫ IER06. IEN3 — Reserved 52 00D0 — ϫ ϫ ϫ ϫ ϫ IER06. IEN4 — — Reserved 53 00D4 — ϫ ϫ ϫ ϫ ϫ IER06. IEN5 — — Reserved 54 00D8 — ϫ ϫ ϫ ϫ ϫ IER06. IEN6 — — Reserved 55 00DC — ϫ ϫ ϫ ϫ ϫ IER06. IEN7 — CAN0 ERS0 56 00E0 Edge ⅙ ϫ ϫ ϫ ϫ IER07. IEN0 IPR18 RXF0 57 00E4 Edge ⅙ ϫ ϫ ϫ ϫ IER07. IEN1 TXF0 58 00E8 Edge ⅙ ϫ ϫ ϫ ϫ IER07. IEN2 RXM0 59 00EC Edge ⅙ ϫ ϫ ϫ ϫ IER07. IEN3 TXM0 60 00F0 Edge ⅙ ϫ ϫ ϫ ϫ IER07. IEN4 RTC PRD 62 00F8 Edge ⅙ ϫ ϫ ϫ ϫ IER07. IEN6 IPR1E CUP 63 00FC Edge ⅙ ϫ ϫ ϫ ϫ IER07. IEN7 IPR1F External pins IRQ0 64 0100 Edge/level ⅙ ⅙ ⅙ ⅙ ⅙ IER08. IEN0 IPR20 Low IRQ1 65 0104 Edge/level ⅙ ⅙ ⅙ ⅙ ⅙ IER08. IEN1 IPR21 APPENDIX A 481

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High IRQ2 66 0108 Edge/level ⅙ ⅙ ⅙ ⅙ ⅙ IER08. IEN2 IPR22 IRQ3 67 010C Edge/level ⅙ ⅙ ⅙ ⅙ ⅙ IER08. IEN3 IPR23 IRQ4 68 0110 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER08. IEN4 IPR24 IRQ5 69 0114 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER08. IEN5 IPR25 IRQ6 70 0118 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER08. IEN6 IPR26 IRQ7 71 011C Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER08. IEN7 IPR27 IRQ8 72 0120 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN0 IPR28 IRQ9 73 0124 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN1 IPR29 External pins IRQ10 74 0128 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN2 IPR2A IRQ11 75 012C Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN3 IPR2B IRQ12 76 0130 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN4 IPR2C IRQ13 77 0134 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN5 IPR2D IRQ14 78 0138 Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN6 IPR2E IRQ15 79 013C Edge/level ⅙ ⅙ ϫ ⅙ ⅙ IER09. IEN7 IPR2F — Reserved 80 to 87 0140 to 015C — ϫ ϫ ϫ ϫ ϫ — — — Reserved 88 0160 — ϫ ϫ ϫ ϫ ϫ IER0B. IEN0 — — Reserved 89 0164 — ϫ ϫ ϫ ϫ ϫ IER0B. IEN1 — USB_resume USBR0 90 0168 Level ⅙ ϫ ϫ ⅙ ⅙ IER0B. IEN2 IPR3A USBR1 91 016C Level ⅙ ϫ ϫ ⅙ ⅙ IER0B. IEN3 IPR3B RTC ALM 92 0170 Edge ⅙ ϫ ϫ ⅙ ⅙ IER0B. IEN4 IPR3C Reserved 93 0174 — ϫ ϫ ϫ ϫ ϫ IER0B. IEN5 — Reserved 94 0178 — ϫ ϫ ϫ ϫ ϫ IER0B. IEN6 — Reserved 95 017C — ϫ ϫ ϫ ϫ ϫ IER0B. IEN7 — WDT WOVI 96 0180 Edge ⅙ ϫ ϫ ϫ ⅙ IER0C. IEN0 IPR40 Reserved 97 0184 — ϫ ϫ ϫ ϫ ϫ IER0C. IEN1 — AD0 ADI0 98 0188 Edge ⅙ ⅙ ⅙ ϫ ϫ IER0C. IEN2 IPR44 AD1 ADI1 99 018C Edge ⅙ ⅙ ⅙ ϫ ϫ IER0C. IEN3 IPR45 — Reserved 100 0190 — ϫ ϫ ϫ ϫ ϫ IER0C. IEN4 — — Reserved 101 0194 — ϫ ϫ ϫ ϫ ϫ IER0C. IEN5 — Low S12AD ADI12_0 102 0198 Edge ⅙ ⅙ ⅙ ϫ ϫ IER0C. IEN6 IPR48 482 APPENDIX A

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High — Reserved 103 to 113 019C to 01C4 — ϫ ϫ ϫ ϫ ϫ — — MTU0 TGIA0 114 01C8 Edge ⅙ ⅙ ⅙ ϫ ϫ IER0E. IEN2 IPR51 TGIB0 115 01CC Edge ⅙ ⅙ ϫ ϫ ϫ IER0E. IEN3 TGIC0 116 01D0 Edge ⅙ ⅙ ϫ ϫ ϫ IER0E. IEN4 TGID0 117 01D4 Edge ⅙ ⅙ ϫ ϫ ϫ IER0E. IEN5 TCIV0 118 01D8 Edge ⅙ ϫ ϫ ϫ ϫ IER0E. IEN6 IPR52 TGIE0 119 01DC Edge ⅙ ϫ ϫ ϫ ϫ IER0E. IEN7 TGIF0 120 01E0 Edge ⅙ ϫ ϫ ϫ ϫ IER0F. IEN0 MTU1 TGIA1 121 01E4 Edge ⅙ ⅙ ⅙ ϫ ϫ IER0F. IEN1 IPR53 TGIB1 122 01E8 Edge ⅙ ⅙ ϫ ϫ ϫ IER0F. IEN2 TCIV1 123 01EC Edge ⅙ ϫ ϫ ϫ ϫ IER0F. IEN3 IPR54 TCIU1 124 01F0 Edge ⅙ ϫ ϫ ϫ ϫ IER0F. IEN4 MTU2 TGIA2 125 01F4 Edge ⅙ ⅙ ⅙ ϫ ϫ IER0F. IEN5 IPR55 TGIB2 126 01F8 Edge ⅙ ⅙ ϫ ϫ ϫ IER0F. IEN6 MTU2 TCIV2 127 01FC Edge ⅙ ϫ ϫ ϫ ϫ IER0F. IEN7 IPR56 TCIU2 128 0200 Edge ⅙ ϫ ϫ ϫ ϫ IER10. IEN0 MTU3 TGIA3 129 0204 Edge ⅙ ⅙ ⅙ ϫ ϫ IER10. IEN1 IPR57 TGIB3 130 0208 Edge ⅙ ⅙ ϫ ϫ ϫ IER0E. IEN2 TGIC3 131 020C Edge ⅙ ⅙ ϫ ϫ ϫ IER10. IEN3 TGID3 132 0210 Edge ⅙ ⅙ ϫ ϫ ϫ IER10. IEN4 TGIV3 133 0214 Edge ⅙ ϫ ϫ ϫ ϫ IER10. IEN5 IPR58 MTU4 TGIA4 134 0218 Edge ⅙ ⅙ ⅙ ϫ ϫ IER10. IEN6 IPR59 TGIB4 135 021C Edge ⅙ ⅙ ϫ ϫ ϫ IER10. IEN7 TGIC4 136 0220 Edge ⅙ ⅙ ϫ ϫ ϫ IER11. IEN0 TGID4 137 0224 Edge ⅙ ⅙ ϫ ϫ ϫ IER11. IEN1 TCIV4 138 0228 Edge ⅙ ⅙ ϫ ϫ ϫ IER11. IEN2 IPR5A MTU5 TGIU5 139 022C Edge ⅙ ⅙ ϫ ϫ ϫ IER11. IEN3 IPR5B TGIV5 140 0230 Edge ⅙ ⅙ ϫ ϫ ϫ IER11. IEN4 TGIW5 141 021C Edge ⅙ ⅙ ϫ ϫ ϫ IER10. IEN7 Low MTU6 TGIA6 142 0238 Edge ⅙ ⅙ ⅙ ϫ ϫ IER11. IEN6 IPR5C APPENDIX A 483

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High TGIB6 143 023C Edge ⅙ ⅙ ϫ ϫ ϫ IER11. IEN7 TGIC6 144 0240 Edge ⅙ ⅙ ϫ ϫ ϫ IER12. IEN0 MTU6 TGID6 145 0244 Edge ⅙ ⅙ ϫ ϫ ϫ IER12. IEN1 IPR5C TCIV6 146 0248 Edge ⅙ ϫ ϫ ϫ ϫ IER12. IEN2 IPR5D TGIE6 147 024C Edge ⅙ ϫ ϫ ϫ ϫ IER12. IEN3 TGIF6 148 0250 Edge ⅙ ϫ ϫ ϫ ϫ IER12. IEN4 MTU7 TGIA7 149 0254 Edge ⅙ ⅙ ⅙ ϫ ϫ IER12. IEN5 IPR5E TGIB7 150 0258 Edge ⅙ ⅙ ϫ ϫ ϫ IER12. IEN6 TCIV7 151 025C Edge ⅙ ϫ ϫ ϫ ϫ IER12. IEN7 IPR5F TCIU7 152 0260 Edge ⅙ ϫ ϫ ϫ ϫ IER13. IEN0 MTU8 TGIA8 153 0264 Edge ⅙ ⅙ ⅙ ϫ ϫ IER13. IEN1 IPR60 TGIB8 154 0268 Edge ⅙ ⅙ ϫ ϫ ϫ IER13. IEN2 TCIV8 155 026C Edge ⅙ ϫ ϫ ϫ ϫ IER13. IEN3 IPR61 TCIU8 156 0270 Edge ⅙ ϫ ϫ ϫ ϫ IER13. IEN4 MTU9 TGIA9 157 0274 Edge ⅙ ⅙ ⅙ ϫ ϫ IER13. IEN5 IPR62 TGIB9 158 0278 Edge ⅙ ⅙ ϫ ϫ ϫ IER13. IEN6 TGIC9 159 027C Edge ⅙ ⅙ ϫ ϫ ϫ IER13. IEN7 TGID9 160 0280 Edge ⅙ ⅙ ϫ ϫ ϫ IER14. IEN0 TCIV9 161 0284 Edge ⅙ ϫ ϫ ϫ ϫ IER14. IEN1 IPR63 MTU10 TGIA10 162 0288 Edge ⅙ ⅙ ⅙ ϫ ϫ IER14. IEN2 IPR64 TGIB10 163 028C Edge ⅙ ⅙ ϫ ϫ ϫ IER14. IEN3 TGIC10 164 0290 Edge ⅙ ⅙ ϫ ϫ ϫ IER14. IEN4 TGID10 165 0294 Edge ⅙ ⅙ ϫ ϫ ϫ IER14. IEN5 TCIV10 166 0298 Edge ⅙ ⅙ ϫ ϫ ϫ IER14. IEN6 IPR65 MTU11 TGIU11 167 029C Edge ⅙ ⅙ ϫ ϫ ϫ IER14. IEN7 IPR66 TGIV11 168 02A0 Edge ⅙ ⅙ ϫ ϫ ϫ IER15. IEN0 TGIW11 169 02A4 Edge ⅙ ⅙ ϫ ϫ ϫ IER15. IEN1 POE OEI1 170 02A8 Level ⅙ ϫ ϫ ϫ ϫ IER15. IEN2 OEI2 171 02AC Level ⅙ ϫ ϫ ϫ ϫ IER15. IEN3 Low OEI3 172 0280 Level ⅙ ϫ ϫ ϫ ϫ IER15. IEN4 484 APPENDIX A

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High OEI4 173 02B4 Level ⅙ ϫ ϫ ϫ ϫ IER15. IEN5 TMR0 CMIA0 174 02B8 Edge ⅙ ⅙ ϫ ϫ ⅙ IER15. IEN6 IPR68 CMIB0 175 02BC Edge ⅙ ⅙ ϫ ϫ ⅙ IER15. IEN7 OVI0 176 02C0 Edge ⅙ ϫ ϫ ϫ ⅙ IER16. IEN0 TMR1 CMIA1 177 02C4 Edge ⅙ ⅙ ϫ ϫ ⅙ IER16. IEN1 IPR69 CMIB1 178 02C8 Edge ⅙ ⅙ ϫ ϫ ⅙ IER16. IEN2 OVI1 179 02CC Edge ⅙ ϫ ϫ ϫ ⅙ IER16. IEN3 TMR2 CMIA2 180 02D0 Edge ⅙ ⅙ ϫ ϫ ⅙ IER16. IEN4 IPR6A CMIB2 181 02D4 Edge ⅙ ⅙ ϫ ϫ ⅙ IER16. IEN5 OVI2 182 02D8 Edge ⅙ ϫ ϫ ϫ ⅙ IER16. IEN6 TMR3 CMIA3 183 02DC Edge ⅙ ⅙ ϫ ϫ ⅙ IER16. IEN7 IPR6B CMIB3 184 02E0 Edge ⅙ ⅙ ϫ ϫ ⅙ IER17. IEN0 OVI3 185 02E4 Edge ⅙ ϫ ϫ ϫ ⅙ IER17. IEN1 — Reserved 186 02E8 — ϫ ϫ ϫ ϫ ϫ IER17. IEN2 — Reserved 187 02EC — ϫ ϫ ϫ ϫ ϫ IER17. IEN3 — Reserved 188 02F0 — ϫ ϫ ϫ ϫ ϫ IER17. IEN4 — Reserved 189 02F4 — ϫ ϫ ϫ ϫ ϫ IER17. IEN5 — Reserved 190 02F8 — ϫ ϫ ϫ ϫ ϫ IER17. IEN6 — Reserved 191 02FC — ϫ ϫ ϫ ϫ ϫ IER17. IEN7 — Reserved 192 0300 — ϫ ϫ ϫ ϫ ϫ IER18. IEN0 — Reserved 193 0304 — ϫ ϫ ϫ ϫ ϫ IER18. IEN1 — Reserved 194 0308 — ϫ ϫ ϫ ϫ ϫ IER18. IEN2 — Reserved 195 030C — ϫ ϫ ϫ ϫ ϫ IER18. IEN3 — Reserved 196 0310 — ϫ ϫ ϫ ϫ ϫ IER18. IEN4 — Reserved 197 0314 — ϫ ϫ ϫ ϫ ϫ IER18. IEN5 DMACA DMAC0I 198 0318 Edge ⅙ ⅙ ϫ ϫ ϫ IER18. IEN6 IPR70 DMAC1I 199 031C Edge ⅙ ⅙ ϫ ϫ ϫ IER18. IEN7 IPR71 DMAC2I 200 0320 Edge ⅙ ⅙ ϫ ϫ ϫ IER19. IEN0 IPR72 DMAC3I 201 0324 Edge ⅙ ⅙ ϫ ϫ ϫ IER19. IEN1 IPR73 Low EXDMAC EXDMAC0I 202 0328 Edge ⅙ ⅙ ϫ ϫ ϫ IER19. IEN2 IPR74 APPENDIX A 485

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High EXDMAC1I 203 032C Edge ⅙ ⅙ ϫ ϫ ϫ IER19. IEN3 IPR75 Reserved 204 0330 — ϫ ϫ ϫ ϫ ϫ IER19. IEN4 Reserved 205 0334 — ϫ ϫ ϫ ϫ ϫ IER19. IEN5 — Reserved 206 0338 — ϫ ϫ ϫ ϫ ϫ IER19. IEN6 — Reserved 207 033C — ϫ ϫ ϫ ϫ ϫ IER19. IEN7 — Reserved 208 0340 — ϫ ϫ ϫ ϫ ϫ IER1A. IEN0 — Reserved 209 0344 — ϫ ϫ ϫ ϫ ϫ IER1A. IEN1 — Reserved 210 0348 — ϫ ϫ ϫ ϫ ϫ IER1A. IEN2 — Reserved 211 034C — ϫ ϫ ϫ ϫ ϫ IER1A. IEN3 — Reserved 212 0350 — ϫ ϫ ϫ ϫ ϫ IER1A. IEN4 — Reserved 213 0354 — ϫ ϫ ϫ ϫ ϫ IER1A. IEN5 SCI0 ERI0 214 0358 Level ⅙ ϫ ϫ ϫ ϫ IER1A. IEN6 IPR80 RXI0 215 035C Edge ⅙ ⅙ ⅙ ϫ ϫ IER1A. IEN7 TXI0 216 0360 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1B. IEN0 TEI0 217 0364 Level ⅙ ϫ ϫ ϫ ϫ IER1B. IEN1 SCI1 ERI1 218 0368 Level ⅙ ϫ ϫ ϫ ϫ IER1B. IEN2 IPR81 RXI1 219 036C Edge ⅙ ⅙ ⅙ ϫ ϫ IER1B. IEN3 TXI1 220 0370 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1B. IEN4 TEI1 221 0374 Level ⅙ ϫ ϫ ϫ ϫ IER1B. IEN5 SCI2 ERI2 222 0378 Level ⅙ ϫ ϫ ϫ ϫ IER1B. IEN6 IPR82 RXI2 223 037C Edge ⅙ ⅙ ⅙ ϫ ϫ IER1B. IEN7 TXI2 224 0380 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1C. IEN0 TEI2 225 0384 Level ⅙ ϫ ϫ ϫ ϫ IER1C. IEN1 SCI3 ERI3 226 0388 Level ⅙ ϫ ϫ ϫ ϫ IER1C. IEN2 IPR83 RXI3 227 038C Edge ⅙ ⅙ ⅙ ϫ ϫ IER1C. IEN3 TXI3 228 0390 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1C. IEN4 TEI3 229 0394 Level ⅙ ϫ ϫ ϫ ϫ IER1C. IEN5 — Reserved 230 0398 — ϫ ϫ ϫ ϫ ϫ IER1C. IEN6 — Reserved 231 039C — ϫ ϫ ϫ ϫ ϫ IER1C. IEN7 Low — Reserved 232 03A0 — ϫ ϫ ϫ ϫ ϫ IER1D. IEN0 — 486 APPENDIX A

Selectable Interrupt Request Source of Vector Destination Interrupt Vector Adress Form of Sstb Sacs Priority Generation Name No. Offset Detection CPU DTC DMA Return Return IER IPR High Reserved 233 03A4 — ϫ ϫ ϫ ϫ ϫ IER1D. IEN1 SCI5 ERI5 234 03A8 Level ⅙ ϫ ϫ ϫ ϫ IER1D. IEN2 IPR85 RXI5 235 03AC Edge ⅙ ⅙ ⅙ ϫ ϫ IER1D. IEN3 TXI5 236 03B0 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1D. IEN4 TEI5 237 03B4 Level ⅙ ϫ ϫ ϫ ϫ IER1D. IEN5 SCI6 ERI6 238 03B8 Level ⅙ ϫ ϫ ϫ ϫ IER1D. IEN6 IPR86 RXI6 239 03BC Edge ⅙ ⅙ ⅙ ϫ ϫ IER1D. IEN7 TXI6 240 03C0 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1E. IEN0 TEI6 241 03C4 Level ⅙ ϫ ϫ ϫ ϫ IER1E. IEN1 — Reserved 242 03C8 — ϫ ϫ ϫ ϫ ϫ IER1E. IEN2 — Reserved 243 03CC — ϫ ϫ ϫ ϫ ϫ IER1E. IEN3 — Reserved 244 03D0 — ϫ ϫ ϫ ϫ ϫ IER1E. IEN4 — Reserved 245 03D4 — ϫ ϫ ϫ ϫ ϫ IER1E. IEN5 — RIIC0 ICEEI0 246 03D8 Level ⅙ ϫ ϫ ϫ ϫ IER1E. IEN6 IPR88 ICRXI0 247 03DC Edge ⅙ ⅙ ⅙ ϫ ϫ IER1E. IEN7 IPR89 ICTXI0 248 03E0 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1F. IEN0 IPR8A ICTEI0 249 03E4 Level ⅙ ϫ ϫ ϫ ϫ IER1F. IEN1 IPR8B RIIC1 ICEEI1 250 03E8 Level ⅙ ϫ ϫ ϫ ϫ IER1F. IEN2 IPR8C ICRXI1 251 03EC Edge ⅙ ⅙ ⅙ ϫ ϫ IER1F. IEN3 IPR8D ICTXI1 252 03F0 Edge ⅙ ⅙ ⅙ ϫ ϫ IER1F. IEN4 IPR8E ICTEI1 253 03F4 Level ⅙ ϫ ϫ ϫ ϫ IER1F. IEN5 IPR8F — Reserved 254 03F8 — ϫ ϫ ϫ ϫ ϫ IER1F. IEN6 IPR90 Low — Reserved 255 03FC — ϫ ϫ ϫ ϫ ϫ IER1F. IEN7 IPR91 Index

A readings, fig, 25 ADCSR, 170–71, 178, 179 A/D control extended reference voltage of, 162 ADDIAGR, 181–82 register, 173 resolution of, 162 ADDPR, 181 A/D control/status register, 173 sample and hold circuit, ADDRn, 170, 178 A/D conversion start, 171, 180 fig, 163 ADI, 180 A/D converted value addition sampling state register ADIE, 171, 175, 178, 180 count select register and, 165 ADSSTR, 165, 166 (ADADC), 172–73 step size, ex, 167 ADST, 171, 180 A/D converted value addition successive approximation, ADSTRGR, 173–75 mode select register fig, 164 Agile development method(s), (ADADS), 171–72 successive approximation and, 157–58 A/D converter(s), 24–25, 161 163–65 Air to fuel mass ratio, 3 10-bit converter, ex, 188–90 A/D data placement register, 181 AL, 234 10-bit converter, fig, 179 A/D data registers n, 170, 178 Alarm interrupt, 336 10-bit converter and, 168, A/D scan conversion end Algorithm(s) 178–83 interrupt, 180 I2C and, 269–75 12-bit converter, ex, 186–88 A/D scan conversion end for SPI, 266–68 12-bit converter, fig, 169 interrupt enable (ADIE), ALIE, 232 12-bit converter and, 168–78 171, 175, 178, 180 ALU, 37, 38, 66 ADADC converters, A/D scan conversion mode Amplifier(s), 31 tab, 173 select, 171 Analog signal(s), 24–28 clock selection, tab, 171 A/D self-diagnostic register, Analog to digital converter. See operation of, 175–78 181–82 A/D converter(s) trigger selection, tab, 174 A/D start bit, 171, 180 Anode, 16 ADSSR settings, tab, 166 A/D start trigger select register, ANSI standards, 87 channels of, 168 173–75 Arithmetic and logic unit (ALU), concepts of, 161–63 AAS0, 233 37, 38, 66 conversion chart, 2-bit, fig, 24 AAS1, 233 Assembler, 87 conversion speed, ex, 166 AAS2, 233 Assembly language, 151 conversion speed of, 165 Accumulator (ACC), 52 Asynchronous, 41, 194 conversion time, 166 ACKBR, 230 Atomic code, 460 conversion timing, fig, 165 ACKBT, 230 Automobiles, MCU and, 2–3 default peripherals of, 168 ACKWP, 230 digital value, ex, 166 Actuator, 20 B frequencies of, 162–63, 170 ADADC, 172–73 Backup PC (BPC), 45, 48 header files and, 128–29 ADADS, 171–72 Backup PSW (BPSW), 45, 48 mathematical calculation of, ADANS, 171, 175, 178 Battery(ies), 29 165–67 ADCER, 173 Baud rate, 194 MCU architecture and, 41 ADCR, 180–81 BBSY, 225, 226 output code and, 24, 25, 162 ADCS, 171 BC, 228

487 488 INDEX

BCLK. See external bus clock C mechanical and, 30–31 BCWP, 228 C/Cϩϩ compiler, 87 QUART/USARTz crystals BEREN, 63 features of, 88 and, 30 Better Embedded System header files of, 95–96 RC, fig, 30 Software (Koopman), 142 C/Cϩϩ function, 88 Clock synchronous, 41 Bi-endian, 88 C Flag, 46 CM, 202 Big bang test(s), 154 C language, 85, 151 CMOS, 15 Big up-front design, 144, 155 Cϩϩ language, 151 CNTVAL, 441 Binary number, multi-bit, 24 C program, 85 Coding standard(s), 151 Bit rate register (BRR), 200, 204 Call walker, 88 Coil driver, fig, 22 Bit(s). See individual bits CAN, 3, 12, 41 Common expression, 87 Bitwise operation(s), 54 Capacitors Communication and Black box testing, 152, 153 debounding solutions and, 18 networking, 5 Boot mode, 73 loads of, 30, 31 Communication format(s), 41 BPC, 45, 48 power supplies and, 29 Communication function(s), 39 BPSW, 45, 48 Carry flag, 46 Communication mode (CM), 202 BRDV, 219 Carry interrupt, 323, 336 Communication protocol, 2, 5 Brownout condition, 444–45 CAS latency, 62 Compare match timer, 39 Brownout detector, 425 Cascading timer(s), 310–11, Compilation mechanism, 85–86 BRR, 200, 204 323–26, 333–34, 337–40. Compiler package Buffer function, 62 See also event counter(s); assembler and, 87 Bus(es), 194 pulse output operation; C/Cϩϩ compiler and, 87 configuration of, fig, 60 timer(s) HEW and, 88 CPU and, 57–58, 58–59 Cathode, 16 IDE and, 88 description of, 58–63 Cause flag(s), 51, 409–11 optimizing linkage editor error monitoring and, 63 Ceramic resonator(s), 31 and, 87 error monitoring enable Channel select register simulator debugger and, 88 register, 63 (ADANS), 171, 175, 178 standard library generator error types of, 63–64 Chartplotter, fig, 144 and, 87 external bus and, 62–63 Chip select, 126 utilities and, 88 internal main and, 58, 59 Chip(s), 2, 8 Compiler(s), 85 internal peripheral bus and, Circuit(s), reset, 11 embedded systems and, 87 58, 61 Cj, 48 input/output, tab, 86 of MCU board, 57–64 CKS, 227, 439 optimization of, 88 memory and, 58, 59 CKS bit, 429 Computer(s), 35–38 operand and, 57 Clear box testing, 152, 153–54 components of, 36–38 peripheral modules, tab, 61 Clock enable bit(s), 202 example, fig, 36 priority of, tab, 59 Clock generation circuit, 38 functions of, 35–36 specifications of, 57–58 Clock signal generator(s), 11 IAS and, 37–38 types of, 57–58 ceramic resonators and, 31 von Neumann, John and, Button connection, fig, 17 crystal clock generator chip, 37–38 BYP, 66 fig, 31 Conditional assembly Bypass process, 66 electrical and, 30 function, 87 Byte addressing, 75–76 external IC chips and, 31 Config.h, 118 INDEX 489

Const variable, 152 D Data sharing, 460–67 Constraint(s), of embedded D/A control register (DACR), disabling interrupts and, systems, 6 184, 185 464–65 Contact bounce, 18 D/A data placement register, 184 function reentrancy and, Continuous scan mode, 177–78 D/A data register, 184 461–62 Control area network (CAN), 3, D/C converter(s), 26–28, 161 lock use and, 465–66 12, 41 4-bit binary weighted, fig, 26 messages and, 467 Control hazard, 67 binary weighted and, 26–27 protection and, 464–67 Control mechanism(s), 36 ex, 190–91 semaphores and, 466–67 Control method(s), 1 MCU architecture and, 41 source code and, 462–64 Control mode(s), 4 operation of, fig, 185 task switching and, 467 Control system(s), 4 output voltage, formula of, 28 Data transfer controller, 39 Control unit, 37, 38 pulse width modulation DC motor(s), 20–21, 28, 312 Controller(s) and, 28 DCLS, 228 CAN module and, 41 R-2R and, 27–28 DDR, 12–13, 20 DMAs and, 38–39 registers of, 183–84 Debouncing solution, 18 ethernet and, 39 resistor networks and, Debugger, 89 I2C bus interfaces and, 41 26–28 Debugging USB 2.0 host/funciton module successive approximation I/O registers and, 115–17 and, 39 and, 163 I/O registers selection, Conversion rate, 162–63 D flip-flop, 198 fig, 116 Conversion time (tCONV), 165 DACR, 184, 185 I/O window and, 114–15 Converter(s). See individual DADPR, 184 memory address and, 110–12 converters DADRm, 184 memory and, 112–14 Cost, 2, 3, 6 DADRn, 185 memory window and, 109 Counter(s). See cascading Data, computers and operating memory of, 108–9 timer(s); event counter; arrangement, fig, 57 options in HEW and, 106 pulse output operation; arrangement of, 56–57 sessions and, 106–8 timer(s) control and, 36 tools for, 89 CPHA, 218 movement and, 35–36 Debugging function, 88 CPU, 36 processing and, 35 Decomposition, 144 bus error type and, 64 storage and, 35 Default session, 94 bus-master modules and, 63 types of, 52–55 Denormalized number components of, 37 Data acquisition, 194 bit(s), 410 features of, fig, 43 Data direction register (DDR), Design margin, 152 MCU architecture and, 38, 12–13, 20 DID, 233 42–52 Data flash memory, 58 DIDE, 231 PSW, fig, 45 Data hazard, 67 Digital converters. See A/D register sets of, 43–52 Data movement block, 35 converter(s) CRC calculator, 41 Data register (DR), 12, 13–14 Digital signals, 11–23 Crystal oscillator, 8 A/D converters and, 170, 175 Digital to analog conversion. See CSC (area controller), 62 BIT syntax of, 14 D/C converter(s) Current-limiting resistor, 16 LEDs and, 20 Direct current motor(s), 20–21, Current rating(s), 29 pin selection and, 13 28, 312 490 INDEX

Direct memory access (DMA), Event counter(s). See also FIR, 351, 356 38–39 cascading timer(s); pulse 5PE20V chip, 8 Divide-by-zero exception, 404, output operation; timer(s) Fixed point math, 391 407, 410 clock input to TCNT, tab, 308 time calculation, ex, 414–18 DMA, 38–39 concepts of, 302–10 Flag status bit (Fj), 48, 52 DMACA, 59, 63 specification of timers, FLASH chip, 8 DN flag, 51 tab, 303 Flash conversion, 163 Double precision, 395–97 TCCR description, tab, 307 Floating point. See also FPU DR. See data register TCNT, fig, 305 data type and, 53–54 Driving motor and coil(s), 20–22 TCR description, fig/tab, 306 exception handling and, 411–14 DTC, 59 TCSR, fig, 309 exceptions, ex, 404–8 DTCER, 129 TCSR description, tab, 309 exceptions of, 403–4 Dual slope integrating, 163 timer unit 0, fig, 304 FPSW bit definition, tab, Duplex communication, 194 Evolutionary prototype, 158 400, 402 Dynamic schedule, 451 Exception cause bit (Cj), 48 instructions of, 401–3 Exception flag(s), 410 math of, 391–97 E Exception handle bit, 51–52 matrix multiplication, ex, E stage, 66, 398 Exception handling enable 418–22 EDMAC, 58, 59 bit(s), 410 registers of, 399–400 EIN GreenEval Zigbee Module, EXDMA controller, 39, 62 representation of, 391–92 7–8 Execution stage (E stage), in RX62N, 398–404 Ej, 48, 52 66, 398 standard of, 392–97 Electromechanical control(s), 1 Extended function(s), 87 time calculation, ex, 414–18 Embedded product lifecycle, External bus clock (BCLK), 38, 61 Floating point error summary fig, 143 error type and, 63–64 flag, 411 Embedded system(s) specifications and, 58 Floating point status word attributes of, 5–6 External trigger, 174, 175 (FPSW), 45, 48–52, benefits of, 2–4 Extreme programming, 157 399–400, 402, 408–11 constraints of, 6 Floating-point summary bit (FS designing of, 6–7 F bit), 52, 234 EIN GreenEval Zigbee Module FADD, 401 Flyback diode, 22 and, 7–8 Fast interrupt vector register, FMPE, 230 functions of, 4–5 45, 48 FO flag, 52 manufacturing of, 6–7 Fault handling, 5 Format and save data task, 148 summary of, 9 Fault tolerant system(s), 194 Formula(s) Enable bit (Ej), 48, 52 FCMP, 403 of A/D conversion time, 166 ENABLE_LEDS, 19 FEM, 8 of A/D converters digital ENABLE_SWITCHES, 20 FIEN, 356 output, 166–67 Endianness, 55–56, 72 FIFO data structures of A/D converters output Enum keyword, 119–20 I2C and, 269 code, 25 Enumeration(s), 129–30 UART/USART and, 262–64 of battery life, 29 Error signal flag bit, 203 File inclusion function, 87 of frequency, 311 ETHERC, 58 Finite state machine, 149–50 of output voltage for D/C Ethernet controller(s), 39 FINTV, 45, 48 converters, 28 INDEX 491

of quanitzation error, 162 editing operations of, tab, 103 IAS computer, 37 of resistor, 16 glyph.h, 118–23 IC. See integrated circuit of resolution, 24 iodefine_RX62N.h, 127–30 ICBRH, 235 of TCORA, 335 register description, tab, 129 ICBRL, 235 of TCORB, 335 library types, tab, 95 ICCR1, 224 of timers, 301–2 macros, tab, 96 ICCR2, 225–27 FPSW. See floating point status preamble.h, 123–24 ICDRR, 236 word (FPSW) removal of, fig, 105 ICDRS, 236 FPU, 399. See also floating point sbrk.h, 126 ICDRT, 235 concepts of, 391–404 st7579_lcd.h, 124–25 ICFER, 230–31 FWSP and, 51 stacksct.h, 127 ICIER, 232 math basics of, 391–97 typedef.h, 126 ICLK, 58 MCU architecture and, 38 used in demo program, tab, 96 ICMR1, 227–28 Front end module (FEM), 8 vect.h, 126–27 ICMR2, 228–29 FS bit, 52, 234 YRDKRX62N_RSPI0.h, ICMR3, 229–30 FSUB, 401 125–26 ICR. See input buffer control FU flag, 52 HEW. See high performance register (ICR) Full duplex mode, 194, 206 embedded workshop ICSER, 231–32 FV flag, 52 (HEW) ICSR1, 232–33 FVCT, 356 Hierarchical system(s), 35 ICSR2, 233–34 FZ flag, 52 High performance embedded ICU. See interrupt control unit workshop (HEW), 88 ID Stage, 66, 398 G concepts of, 89–94 IDE, 88 Ganssle, Jack G., 141, 142, 144, configuration of, 94 Idle mode, 5 145, 146, 151, 152 configuration selection, fig, 93 IDLNF, 213 GCAE, 231, 233 creation of, 90–91 IEEE 754, 392–97, 399, Generic API for Graphics LCD creation/running of, ex, 97–101 401, 403 (Glyph), 118, 120 debugging options and, IEN register, 64 Glyph.h, 118–23 106–17 IENj, 354 GUI display function, 88 fig, 89 IER, 351 opening of, 91 IER (interrupt request enable H overview of, 89 register), 129 H-bridge, 312 project and, 89 IERm, 354, 367 H-bridge motor driver, fig, 21 sessions of, 94 IF Stage, 65–66, 397 Half duplex communication, 194 windows of, 92–93 IGAEN, 63 Hardware post-processing, 414 workspace and, 89 Illegal address access, 63 Hardware preprocessing, 412 HOA, 233 Independent watchdog timer Hazards(s), of pipelining, 67 HOAE, 231 (IWDT), 39, 436–42 Header file(s), 94 Inexact exception, 404, 410 C/Cϩϩ compiler and, 95–96 I Input buffer control register config.h, 118 I Bit, 46 (ICR), 12 creation of, ex, 102–6 I/O. See input/output (I/O) A/D converters and, 168 description of types used, I2C. See inter integrated example of, fig, 15 118–30 circuit (I2C) PORT and, 14 492 INDEX

Input/output (I/O) setting up interrupts and, triggering of, 369 computers and, 36, 38 363–71 vector table and, 360 MCU architecture and, 39 triggering of interrupt, 369 Invalid operation exception, 404, pins and, 16, 18–19, 20 Interrupt enable (I bit), 46 408, 410 ports, 11–12 Interrupt flag register, 465 Iodefine.h, 130 registers and, 76–79 Interrupt register (IR), 129 Iodefine_RX62N.h, 12, 14, Input sample time (tSPL), 165 Interrupt service routine 127–30 Instruction decode stage (ID (ISR), 149 IPL bit, 46–47 stage), 66, 398 header files and, 126 IPR, 129, 351 Instruction fetch stage (IF stage), monitor and, 89 IPRm, 355, 368 65–66, 397 responsiveness and, 453–54, IR flag, 354 Instruction set architecture 455, 458 IR1, 129 (ISA), 391 UART/USART and, 263–64 IRN, 351 compilers and, 87 Interrupt source priority register IRn, 366 RX CPU and, 42 (IPR), 129, 351 IRQCR, 351 INTB, 45 Interrupt stack pointer (ISP), IRQCRi, 354, 357 Integer, data type, 53 42–43, 45 IRR, 351 Integrated circuit (IC), 2 Interrupt vector table, 360 ISA. See instruction set external chips and, 31 Interruption function architecture (ISA) high voltage sensors and, 22 description, 87 ISO standards, 87 stepper motors and, 21 Interrupt(s), 350–51. See also ISP, 42–43, 45 Integration test(s), 152, 154 individual interrupts ISR. See interrupt service routine Inter integrated circuit (I2C), 194, A/D converters, setting up, ex, Iterative process, 156 297. See also Renesas 373–77 IWDT, 39, 436–42 inter integrated chip code, amounts of, 377 IWDTCR, 438–39 algorithms and, 269–75 concepts of, 349–50 IWDTRR, 436–38 bus interface and, 196–97 control unit, fig, 352 IWDTSR, 441 buses and, 41 flags to process data, ex, concept of, 221–23 380–83 J data transfers and, 268–75 flowchart example, fig, 350 J-link debugger, 117–18 master receiver mode, fig, ICU, fig, 364 274–75 IRR, tab, 354 K master transmitter mode and maskable and, 351 Keypad(s), 22–23 module of, fig, 272 non-maskable and, 351 Koopman, Phil, 141, 142, 143, operation of, fig, 271 operation of, 360–63 145, 148, 151, 152 start/stop condition, polling, ex, 370–73 fig, 222 registers of, 351–60, 365–71 L Interconnection(s), 37 responsiveness and, 455 L293 IC, 21 Internal clock module, 38 setting up and, 363–71 Language specification, 88 Internal clock signal(s), 39 specifications of ICU, LC, 30 Interrupt control unit (ICU), 351, tab, 353 Lean development, 157 360–63. See also state machine, ex, 383–89 LED_OFF, 20 interrupt(s) state machine and, 378–80 LEDs fig, 364 status flag, figs, 361–62 as outputs, 16–17, 20 INDEX 493

pulse width modulation Memory map, fig, 77 embedded systems and, 6 and, 28 Microcontroller board features of, 4 RSK_RX62N, 19 A/D converter and, 41 Microprocessor, 1, 2 sinking current, fig, 17 architecture terms, definitions MISO, 206, 207 sourcing current, fig, 16 of, 41–42 MISOE bit, 220 switches as inputs and, 19–20 bus error monitoring, 63 Mode pins, operating modes, YRD RX62N, 19 bus error types and, 63–64 tab, 72 Library file(s), 87 bus specifications and, 57–64 MODF, 213 LIFO data structure, 262 clock generation circuit MODFEN, 210 Light-emitting diodes. See LEDs and, 38 Module tree, 88 Limp-home modes, 4 communication function Monitor, 89 Linker, 85, 86, 88 and, 39 MOSI, 206 Load modules, 88 components of, 38–52 MOSIE bit, 220 Logic, 17, 22, 23 CPU and, 38, 42–52 Motor control circuitry, 21 LSBF, 219 CRC calculator and, 41 Motorola, 206 LVDEN, 358 D/A converter and, 41 MOVIFE, 212 LVDST, 359 data arrangement and, 56–57 MOVIFV, 212 data types and, 52–55 MST, 225, 226 M DMA and, 38–39 MSTPCRA, 130 M stage, 398 endianness and, 55–56 MSTPCRB, 130 Macro function, 87 external bus extension MSTPCRC, 130 Magic number(s), 151 and, 38 MSTPCRD, 130 MALE, 231 I/O ports and, 39 MSTPRA, 168 Map viewer, 88 I/O registers and, 76–79 MSTPRB, 168 Master algorithm, 266–67 memory and, 38 MSTR, 210 Master device(s), 206, 207 memory map of, 76–77 MTU, 174, 175 Master in slave out (MISO), memory organization of, MTWP, 227 206, 207 75–76 Multifunction timer pulse unit, Master out slave in (MOSI), 206 operating modes and, 71–74 39, 174, 175 Master receiver, 223 pipelining and, 65–71 Multiprocessor bit, 203 Master/slave selectable register sets and, 42–52 Multiprocessor communication, communication reset and, 38 201–2, 264–68 format, 41 terms and, 41–42 Multiprocessor interrupt enable Master transmitter, 222 timers and, 39 bit, 203 Matrix multiplication, ex, 418–22 voltage detection circuit MCU. See microcontroller(s) and, 38 N Memory Microcontroller(s) (MCU), 1–2, NACKE, 231 computers and, 36 11–33 NACKF, 234 contents as waveforms, ex, board organization and, 35–84 NAKI, 232 135–36 dependability and, 4 NAKIE, 232 MCU architecture and, 38 digital I/O ports and, 11–12 NALE, 231 Memory access (M stage), economies and, 2–3 Nested union(s), 128 66, 398 EIN GreenEval Zigbee Module NFE, 231 Memory block, fig, 75 and, 7–8 9 bit wake-up mode, 201 494 INDEX

NMEA flowchart, fig, 150 Overflow flag (O flag), 46 memory organization of, NMI, 351 Overrun error flag, 203 75–76 NMICLR, 351, 359 OVRF, 213 operating modes of, 71–74 NMICR, 351, 360 operation of, 67–71 NMIEN, 358 P stages of, 65–66 NMIER, 351, 357–58 P-channel transistor(s), 15 word addressing, fig, 76 NMISR, 351, 358–59 Parallel communication, 193 PISO, 199 NMIST, 359 Parallel computation, 194 PM bit, 46 NMOS, 15 Parallel in serial out, 199 Polling, 349–51 Node(s), 2 Parity bit, 194, 202 Port function control register G, Non-preemptive dynamic Parity enable, 202 219–20 scheduler, 454, 456 Parity error flag bit, 203 Port output enable timer, 39 concepts of, 467–70 PC, 45 PORT register(s), 12–13, 14–15 implementation and, 470–74 PCB, 6–7 PORTx.DDR.BIT.BN, 13 RTC scheduler, ex, 474–75 PCLK. See peripheral module PORTx.DR.BIT.Bn, 14 scheduling, figs, 469–70 clock (PCLK) PORTx.ICR.BIT.Bn, 15 task management and, 471–73 PCR, 12, 16 PORTx.ODR.BIT.Bn, 15 task table and, 468, 470–74 PERF, 213 PORTx.PCR.BIT.Bn, 16 tick ISR and, 468, 473 Periodic interrupt, 336 PORTx.PCR.BYTE, 16 Non-preemptive static Peripheral module clock PORTx.PORT.BIT.Bn, 14 scheduler, 454 (PCLK) Power-on reset, 38 Non-reentrant function(s), 461, A/D converters and, 165, 170 Power supply(ies), 11, 28–29 462, 463 bus specifications and, 58 Preamble.h, 118, 123–24 Nyquist frequency, 163, 183 clock generation circuit and, Preemptive dynamic 38, 39 scheduler, 454 O header files and, 126 Preprocessor, 85, 86 O flag, 46 UART/USART and, 201 Preprocessor #define, 152 Object code, 85 Peripheral module(s), 12 Primary user interface task, 148 ODR, 12, 15 Peripheral modules(s), 58 Printed circuit board (PCB), 6–7 On-chip ROM disabled extended PFGSPI, 219–20 Process NMEA data task, mode, 73 Philips Electronics, 221 148, 149 On-chip ROM enabled extended Piezoelectric ceramic element, 31 Processor interrupt priority level mode, 73 Piezoelectric effect, 30 (IPL bit), 46–47 1-bit A/D converter(s), 25 Pipeline processing Processor mode select (PM Open drain control register, block of memory layout, bit), 46 12, 15 fig, 75 Processor status word (PSW), 43, Operation code, 5 byte addressing, fig, 76 45–47 Optimizing linkage editor, 87 concepts of, 397–98 Processor(s) Oscillating digital output, 27 configuration and operation of, compilation mechanism and, OSTEN, 358 fig, 67 85–86 OSTST, 359 CPU and, 42, 65–71 embedded architecture and, 87 Output. See input/output example of, fig, 397 input/output, tab, 86 Overflow exception, 403, flow with stalls, figs, 68–69 Program code, 412 405, 410 I/O registers and, 76–79 Program counter, 45 INDEX 495

Program performance evaluation Real time clock (RTC), 313–23 registers of, 224–36 function, 88 interrupts, ex, 343–46 transmission/reception, ex, Programmable pulse generator interrupts of, 323, 336–37 248–61 timer, 39 reading of, 322–23 Renesas serial peripheral Prototyping, 2, 158 registers of, 314–21 interface (RSPI). See PSPIS bit, 220 scheduler and, 467 serial peripheral interface PSW, 43, 45–47 setting of, 321 Reserved bit(s), 411 PTE, 211 setting up/reading, ex, 328–33 DDR and, 13 Pull-up MOS control register Receive data register, 200, 205 Reset circuit, 31 (PCR), 12, 16 Receive enable bit, 203 Reset pin(s), 38 Pull-up resistor, 17 Receive interrupt bit, 203 Resistor-capacitor (RC), 30, 31 Pulse output operation, 311–13. Reentrant function(s) Resistor(s) See also cascading Reference voltage, 24 debouncing circuits and, 18 timer(s); event counter(s); Register(s), 12. See also formula of, 16 timer(s) individual bits; individual networks and, 26–28 example of, fig, 313 registers Resolution, of A/D frequency and, 311, 334–36 A/D converters and, 168, converter(s), 162 setting up of, ex, 327–28 170–75, 178–82 Resolution formula, 24 setting up/servo motor, ex, ACC and, 52 Resonant oscillator, 31 340–42 control and, 43–52 Responsiveness, 447 square wave attributes, fig, 312 CPU and, 37, 42–52 context and, figs, 459 Pulse width modulation (PWM) CPU and, fig, 44 context switching and, 458–60 D/C converters and, 28 D/C converters and, 183–84 dynamic schedule and, 451 fig, 28 general-purpose and, 42–43 interrupts and, 455 header files and, 129–30 prioritization and, 452–53 Q interrupts and, 351–60 scheduler classes and, 454 Quantization error, 162 IWDT and, 436–42 scheduling, figs, 450 QUART/USARTz crystal, 30, 31 operating modes and, tab, 72 scheduling approach and, of RIIC, 224–36 447–48 R RTC and, 314–21 scheduling concepts of, R-2R D/C converter(s), 27–28 SPI and, 208–20 447–55 R64CNT, 314, 317 UART/USART and, 200–203 stack memory and, 454–55 Radix, 131–32 viewing CPU contents of, ex, state transitions and, 457–58 RAM 130–35 static schedule and, 449 buses and, 57–59, 63 WDT and, 426–32 task ordering and, 449–51 controllers and, 39 Regression test(s), 152, 154 task preemption and, 449, MCU architecture and, 38 Relay(s), 21 451–52, 457 RC, 30, 31 Renesas inter integrated chip task states of, 456–57 RCR1, 319, 321 (RIIC), 196–97. See also timing and, 449, 453–54 RCR2, 320, 321 inter integrated circuit R5FF36B3, 8 RDAYCNT, 317 (I2C) RHRCNT, 314 RDR, 200, 205 bit counter indications, fig, 318 RDRF, 234 tab, 228 fig and tab, 316 RDRFS, 230 clock source selection, tab, 227 RIE, 232 496 INDEX

RIIC. See Renesas inter SCLK. See serial clock Serial communication interface integrated chip SCMR, 200, 201 (SCI), 196 Risk reduction, 141–42 SCR, 200, 202–3 Serial control register, 200, 202–3 RM bit(s), 51, 409 Scrum, 157–58 Serial extended mode RMINCNT, 314 SDA, 221, 222 register, 200 fig and tab, 315 SDCLK, 58, 61 Serial in parallel out, 199 RMONCNT, 317 SDDL, 228 Serial mode register, 200 ROM SDRAM, 58, 61 UART/USART and, 201–2 buses and, 58–59, 63 controller and, 62 Serial peripheral bit rate register, MCU architecture and, 38 external bus and, 62 214–15 RS, 226 pipeline processing and, 76 Serial peripheral clock delay RS-232, 200, 297 Secondary user interface register, 217 RSECCNT, 314 task, 148 Serial peripheral command fig and tab, 315 Semaphore(s), 466–67 register, 218–19 RSK_RX62N LEDs, 19 SEMR, 200 Serial peripheral control register, RSPCKE bit, 220 Sensor(s) 208–10 RSPI. See serial peripheral A/D converters and, 24–25 fig, 210 interface driving motor, coils and, 22 Serial peripheral data control RSTCSR, 426, 431 Sequencing, 4 register, 215–16 RSTE bit, 431 Serial clock (SCLK) Serial peripheral data register RTC. See real time clock SPI and, 206, 207, 208 (SPDR), 213–14, RWKCNT, 314, 316 UART/USART and, 202 216, 266 RX compiler package. See Serial communication Serial peripheral interface (SPI), compiler package concepts of, 193–95 8, 194, 196, 205–20, 297 RYAREN, 317 I2C and, 221–36, 248–61 algorithms and, 266–68 RYRCNT, 317, 318 data transfer and, 268–75 bit rate settings, ex, 215 interface controllers and, 41 block diagram of, fig, 243 S interfacing and, 196–97 configurations of, 208 S flag, 46 modes and, 41 functioning of, 207–8 SALE, 231 peripheral interface and, 41 master/slave, fig, 209–10 Sample and hold circuit, fig, 163 protocols of, tab, 298 multiprocessor communication Sampling frequency, 162–63 SPI and, 205–20 and, 264–68, 280–97 SAR0E, 232 ex, 242–48 registers of, 208–20 SAR1E, 232 multiprocessor single master single slave SAR2E, 231 communication, ex, mode, 220 SARLm, 234 280–97 transmission, ex, 242–48 SARUm, 234 multiprocessor Serial peripheral next access Sbrk.h, 126 communication and, delay register, 218 Scan mode, 182 264–68 Serial peripheral pin control Scanning matrix keypad(s), terminologies of, 194–95 register, 212 22–23 UART/USART and, 198–205, Serial peripheral sequence SCI, 196 236–42 control, 214 SCL, 221, 222 data structures, ex, 276–79 Serial peripheral sequence SCLE, 231 data structures for, 262–64 status, 214 INDEX 497

Serial peripheral status, 212–13 development of lifecycle SPNDEN, 219 Serial port, 194 models and, 155–58 SPOE, 211 Serial status register (SSR), 203 development plan and, 142 SPOM, 212 Servo motor, 312, 335 development stages of, 142–55 SPPCR, 212 Servos, 21 embedded product lifecycle, SPPE, 211 754410 IC, 21 fig, 143 SPRI, 266 SH-4 simulator, 94 finite state machine, fig, 150 SPRIE, 210 Shift register, 198–99, 201 implementation of, 151–52 SPRIx, 264 Sign flag, 46 iterative process and, 156 SPSCR, 214 Signal processing, 5 peer reviews and, 147 SPSR, 212–13 SimDebug_SH-4, 94 processing and, 148–49 SPSSR, 214 Simplex communication, 194 prototyping and, 158 SPTI, 266 SimSessionSH-4, 94 requirements of, 145–46 SPTIE, 210 Simulator debugger, 88 risk reduction and, 141–42 SPTIx, 264 Single-chip mode, 73 spiral process and, 156–57 SSL. See slave select Single mode, 182 subsystem design and, 149–51 SSL0E bit, 220 Single-precision, 392–95 system architecture, fig, 147 SSL1E bit, 220 Single scan mode, 175–76, 183 system architecture and, SSL2E bit, 220 SIPO, 199 147–49 SSL3E bit, 220 64 Hz counter, 314, 317 testing of, 152–55 SSLA, 219 Slave algorithm, 267–68 V model, fig, 143 SSLKP, 219 Slave device, 206, 207, 297 V model and, 143 SSLND, 217–18 Slave receiver, 223 waterfall process and, 155 SSLP, 211 Slave select (SSL), 206, 217 Software trigger, 174 SSR, 200 Slave select line negation delay, SP, 226 ST, 226 217–18 SPB, 219 st7579 graphics display, 126 Slave select polarity, 211 SPBR, 214–15 st7579_lcd.h, 124–25 Slave transmitter, 223 SPCKD, 217 Stack memory, 454–55 Smart card interface, 41, 200, 297 SPCMDx, 218–19 Stack pointer select (U bit), 46 Smart card mode register, SPCR, 208–10 Stack value display function, 88 200, 201 SPCR2, 210–11 Stacksct.h, 127 Smart transducer(s), 194 SPDCR, 215–16 Standard library, 87, 94 SMBus communication SPDR, 213–14, 216, 266 Standard library generator, 87 format, 41 SPE, 210 START bit, 194, 199, 234 SMDS, 230 SPEIE, 210 State machine(s), 378–80 SMR, 200, 201–2 SPI. See serial peripheral State of responsiveness, 456–58 Software configuration interface Static analysis, 151 management, 152 SPIE, 232 Static schedule, 449 Software engineering SPIIE, 211 Stepper motor(s), 21 agile development methods Spiral process, 156–57 STI, 232 and, 157–58 SPLP, 212 STOP bit, 194, 200, 202, 234 chartplotter, fig, 144 SPLP2, 212 String(s), data type, 54–55 coding and, 146–47 SPMS, 208 Struct, 121 designing and, 146–47 SPND, 218 Structural hazard, 67 498 INDEX

Structure, 12 Throw away prototype, 158 single-cycle scan mode and, Successive approximation, Tick ISR, 468 175–76, 178 163–65 TIE, 232 trigger selection, tab, 174 Successive conversion time Time out, 63–64 2.4 GHz radio, 8 (tSAM), 165 Timer control register TXMD, 210, 211 SVA, 234 description, tab, 306 Typedef.h, 126 SWINTR, 351, 356–57 fig, 306 Switch(es), 17–20 Timer counter control U Synchronous, 194 register, 307 U Bit, 46 System command description, 87 Timer(s), 39, 301–2. See also UART receive data ISR, 149 System interconnection, 36 event counter(s); pulse UNDEF, 441 output operation Underflow exception, 403, T TME bit, 429 406, 410 T_Comm_API, 122 TMOE, 231 Union, 12 T_glyphhandle, 119 TMOF, 234 Unit test(s), 152, 153 T_glyphVersionInfo, 121 TMOH, 229 Universal asynchronous T_glyphworkspace, 122 TMOIE, 232 transmitter/receiver T_LCD_API, 121 TMOL, 229 (UART/USART), Task dispatcher, 468 TMOS, 229 194, 297 Task table, 468, 470–71 TMR, 174, 175, 303 data structures, ex, 279 TCCR, 307 TMS bit, 429 registers and, 200–203 TCNT, 305, 308, 312, 313, TOEN, 63–64 SCI and, 196 426, 428 Top-down design, 144 shift register and, 198–99 TCORA, 307, 313, 335 TOPS, 438–40 transmission/receiving, ex, TCORB, 307, 313, 335 Trace(s), 6, 7 236–42 TCR, 306 Transducer(s), 11 USB, 12, 58 TCSR, 307, 309, 426, 428–31 Transformer(s), 29 2.0 host/funciton module TDR. See transmit data register Transistor(s), 22 and, 39 TDRE, 234 Transmit data register (TDR), boot mode, 73 TEIE, 232 200, 201, 203, 205 User stack point (USP), 43, 45 10-bit A/D converter(s), 168, Transmit end flag bit, 203 Utilities, 88 178–83 Transmit end interrupt enable channel selection and, 180 bit, 202 V diagram of, fig, 179 Transmit interrupt enable bit, 203 V model, 143 ex, 188–90 Triac(s), 21 fig, 143 MCU architecture and, 41 TRS, 225 Vect.h, 126–27 operation of, 182–83 TSam, 165 Vector(s), 129–30 registers of, 178–82 12-bit A/D converter(s), 168–78 header files and, 126 test voltage setting, tab, 182 continuous scan mode and, Voltage trigger selection and, 181 177–78 A/D converters and, 24 10-bit D/A converter(s), 183–85 diagram of, fig, 169 analog comparator and, 25 TEND, 234 ex, 186–88 D/C converters and, 27–28 Testing, software, 152–55 MCU architecture and, 41 detection circuit and, 38 32-bit RX CPU, 38 registers and, 170–75 driving motors, coils and, 22 INDEX 499

LEDs as outputs and, 16 interval timer mode, ex, 443 Wired-OR connection, 15 microprocessor and, 28 interval timer mode and, 436 Word addressing, 75–76 monitoring reset and, 38 MCU architecture and, 39 WOVF flag, 431–32 regulator of, 29 operation of, 432–35 Write-back stage (WB stage), serial communication and, 200 registers of, 426–32 66, 398 Voltage- mode binary weighted registers of, tab, 427 D/C converter(s), 27 reset and, 38 X Von Neumann, John, 37–38 specifications of, tab, 426 XCHG instruction, 59 Von Neumann machine, fig, 37 timer mode, ex, 434–35 timer mode and, 433 Y W Waterfall process, 155 Y Renesas development kit WAIT, 230 WB stage, 66, 398 (RDK), 125 Watchdog timer (WDT) WDT. See watchdog timer YRD RX62N LEDs, 19 brownout condition and, WDTOVF, 426 YRDKRX62N_RSPI0.h, 125–26 444–45 While (1) loop, 20, 378 concepts of, 425–35 White box testing, 152, 153–54 Z independent timer and, 436–42 WINA, 428 Zero flag (Z flag), 46 operation of, 441–42 WINB, 428 Zigbee radio, 7 registers of, tab, 438 setting up, ex, 444 Product Development from Start to Success™

Product Development Engineering Since 1990, we have designed some of the most exciting technologies for Fortune 500 and small companies alike in the medical, video and portable wireless markets. We specialize in product development services from start to success, including electrical, software, mechanical and indus- trial design services.

Paragon has been developing products around Renesas seminconductors since its inception. At Paragon Innovations, we get excited about technology.

Medical Wireless/Portable Video

• Infusion pumps • Insulin pumps • Video projectors • Pulse oximeters • Gas compressor lubrica on • Extreme off axis • Electropora on devices monitor projec on • Surgical lasers • GPS based tracking devices • Rear Projec on HDTV • Con nuous Cardiac • GSM telephony • Video compression Output Monitor • Insulin pumps • CDMA telephony • Video scaling • Breathalyzers • Electropora on devices • Set top box • Wireless & bar coding • Panasonic PDA • Flight Informa on devices Display Systems • Breathalyzers • Smart phone medical • Airline Video Docking applica ons • Weather sta ons Systems (VDOCKS) • Pneumothorax detec on • Automo ve OBD-II Products • Ear effusion • LED displays How often do you experience this?

Innovation Delivered™ Contact us for more information: www.ParagonInnovations.com 866-242-1062 [email protected]