Hitachi Europe Ltd. ISSUE : TUT/005/1.0 TUTORIAL DATE : 15/11/95 SH1 EVALUATION BOARD TUTORIAL ABSTRACT The following tutorial is designed for someone using the gnu software development tools to generate code for the SH1-evaluation board from Hitachi Europe. It contains code examples which are useful for the development of SH1 and describes how certain on-board peripherals and features, eg. A/D converter, interrupts and Direct Memory Access Channels (DMACs) are set up using these tools. Contents INTRODUCTION 3 GNU DEVELOPMENT TOOLS OVERVIEW 3 Assembler 3 Compiler 4 Linker 4 START-UP CODE 6 Vector table 7 Start code 7 Inline Intrinsic functions 7 TUTORIAL 1 - NON-INTERRUPT DRIVEN LED FLASH 10 TUTORIAL 2 : ITU CONTROLLED LED FLASH 13 TUTORIAL 3 : AD CONVERSION OF POTENTIOMETER 14 TUTORIAL 4 : AD CONVERSION OF POT. + TIMED FREQUENCY 16 CODE LISTINGS 17 SH/EVB TUTORIAL SUMMARY 25 APPENDIX A : TUTORIAL DISK 26 Hitachi Europe Ltd. ISSUE : TUT/005/1.0 Introduction The following tutorials will be used as a basis for training in the process of code creation, debugging and running in the SH environment. In short they should provide a mechanism to examine the architecture of the SH and also the GNU/EVB environment for code development as detailed below : * * * * * Features of Hitachi SH1 low cost evaluation board GNU C-compiler, Assembler and Linker Inclusion and use of start-up code, vector table and intrinsic functions De-bugging using the CMON monitor commands or GNU gdb tool. Plus general features of the SH core and peripherals The task requirements of the tutorials are shown below; please refer to the relevant tuturial section for further details. All code for the tutorials will be compiled and linked in the GNU environment to provide robust and correct embedded code that can be downloaded to the EVB and de-bugged using the CMON monitor commands or the GNU debugger gdb. 1. 2. 3. 4. Simple code to toggle green LED using port B pin 15 ITU interrupt driven toggling of the green LED again using port B pin 15. A/D code to provide interrupt driven conversion of a connected potentiometer. The resultant digital value displayed as an LED frequency. A/D code extended to use ITU to flash led at specific frequency plus the DMAC is used to transfer the read value from the AD to the ITU. Included within this SH tutorial guide are details of startup and inline instrisic functions. This has been included to show a framework that could be used for running GNU devloped SH code on the evaluation board . GNU Development tools overview The following section attempts to give a brief outline to the GNU development environment. Focusing on the Assembler, Compiler and Linker software tools, gdb will be examined in the tutorial sections. Please note that the file extensions for code developed in the GNU environment adhere to the following convention: *.C *.S *.LNK *.MAP *.SR *.O C code files Assembly only files Input files for the linker software Output from linker file defining symbols and segment addresses Output object code from linker Output file from compilation or assembly Build.bat has been provided in the tutorial directory to aid as a framework for assembling/compiling and linking the created code for these tutorials. The build file includes the recommended switches which are explained in the following text. Assembler The GNU assembler is invoked using the command as typical invocation is shown below in the example command line where -o specifies the output object file. e.g. as test.s -o start.o Hitachi Europe Ltd. ISSUE : TUT/005/1.0 The GNU assembler enables the programmer to make full use of the SH RISC instruction set where all instruction opcodes are 16 bit long and can be executed within 1 cycle due to the pipelined architecture. Care should be taken to avoid pipeline disruption from conditional branching which can reduce the efficiency of the SH CPU, simply due to bad programming It should be remembered that longword is the standard for data length for all instructions and thus byte and word data will be sign extended. Also immediate values greater than byte value will have to be stored as literal constants. For example immediate data above the byte size will be accessed via first a PC relative move then the actual operation performed upon it : USER CODE ADD.W #H'1234,R1 ------------> ACTUAL CODE MOV.W @(disp,PC), R0 ADD.W R1,R0 `' `' .DATA.W H'1234 disp length Another area of interest is the declarations of sections within the GNU development system. Where created object code is partitioned into four basic types of segment, the dot defining a location counter incremented for each assembled byte within the section : 1. 2. 3. 4. 5. .text : holds all program code and constant data always relocatable .bss : Uninitialised data section of module scope only and static variables .data : Initialised data variable section COMMON : Unitiliased data of system scope (i.e. extern variables) User defined sections : Using the keyword directive .section Apart from the above sections it is also possible to subdivide the text and data sections further such that certain types of data or code can be separated from each other in the object file. (.text0, .data0, .text1, .data1, etc...) The .bss section cannot be used to dictate where variables are stored, instead .bss is simply used by the assembler to keep unitialised or zeroed variables away from initialised variables. Initialised variables require the initialising value to be kept in a ROM store for copying across to the RAM area at start-up. Compiler The GNU C-compiler for the SH is invoked via the command gcc. It is possible to use the GNU CC to complete pre-processing, compilation, assembly and linking. However, we shall use the -c option always to stop just before linking to enable greater flexibility and control over the final stage. e.g. gcc test.c -g -O -c -o test.o In general the GNU compiler conforms to all ANSI procedures although the following switches should be remebered for use in the tutotials later on: * * * * * * * -c : -g : -O : -S : -l : -d : -m1 : compile or assemble source files but do not link produce debugging information in the object code Optimising compilation - levels up to 3 stop after compilation and do not assemble - output assembler equivalent of C code define output list file produce debugging info. y suffix for standard errors. Generate code for normal SH1 chip Linker The final major component of the GNU toolset is the linker. This is used to link all the object files created by the assembler and compiler along with the include files locating the code and data areas as specified by a link file and resolving symbol addresses. Example command line execution is shown below : Hitachi Europe Ltd. ISSUE : TUT/005/1.0 e.g. ld test1.o test2.o -Tlinkfile.lnk -MAPsymbols.map -o testout.sr It can be seen that two files are linked together with their text and data segment area addresses defined by the linkfile.lnk file producing a map file for control purposes and the actual object file for execution. The main concern within the linker stage is that of the creation of the linkfile.lnk file which defines where each segment in the input files should be placed in the address range. To begin with before any examples are shown a small amount of syntax must be remembered to decode and to create new linker files : 1. 2. 3. `.' or dot variable is used throughout and refers to the current location counter (or address) within a section `*' followed by a section name means all files with this section name to be included. Apart from the ones already previously used. { } brackets delimit the range of input files or areas for a particular section name To understand the operation of the lnk file, which is used in the tutorials, the figure below details each part. First executable address is startup Figure 2 : Linker file Data stored at A006000 but const init. data stored after the code area as marked by AT ( ADDR...) S-record output object file, not for gdb use User code and consts in Declare vector table to start ENTRY(_start) .text at addr A004000. at addres A002000. User OUTPUT_FORMAT(srec) _mdata indicates end of defined section section SECTIONS { .vects 0X0A002000 : {*(.vects);} .text 0X0A004000 : {*(.text) _mdata = . ;} refers to .mdata 0X0A006000 : AT (ADDR(.text) + SIZEOFF (.text)) common unitialised data { _data = . ; *(.data) _edata = . ; } .bss . : {_bss =.; *(.bss) *(COMMON) _ebss =.;} .stack 0X0A00F000 : { _stack =.; *(.stack) } } User defined stack section at address A00F000 and extends to an address depending on the user size setting of stack prior. _stack used as stack pointer .bss section includes unitialised data. Placed at end of initialised data marked by _bss and _ebss, for the purposes of the startup code. Note. The keyword AT is used to force the load addresses (i.e the actual location of the variable values) to be linked at a different area from the actual variable reference addresses. This means that a ROM image can be built for the variables to enable initialisation. .text .data .mdata .bss .vects .stack COMMON : Code section : initialised data section : ROM image of initialised data section : Zeroed out data of module scope or statics. : User defined constant area for vector table : User defined variable area for stack, includes pointer to start of stack. : Unitialised data of system scope (resolves externs between modules) Hitachi Europe Ltd. ISSUE : TUT/005/1.0 Use -fno-common when compiling to force global data into the .bss section, and thus enable the linker to resolve conflicts between variables declared in two different modules. To fully understand the output of the previous linkfile.lnk file included below is the memory map showing the load areas for the sections and the address pointers which are used by the start-up code to initialise data areas and the stack pointers. Further details of this will be shown in the following start-up code section. 0000000 Monitor vector table . 0000255 Monitor code area EPROM 0010000 Un-used external area Copy monitor vectors to user vector table. A000000 A0001300 A002255 Monitor data area User vector table Un-used data area A004000 2 x SRAM User code mdata Initialising data store Un-used data area _data A006000 Initialised data _edata & _bss _ebss _stack A00F000 A010000 Const init data copied at startup Unitialised data Data cleared at startup Stack area Stack grows down through address range Un-used data area Un-used external area F000000 FFFFFFF On-chip RAM Accessed in 1-state Start-up code Start-up has been provided for every application to ensure correct operation of the SH evaluation board and handling of exceptions. Also included within this section there are details on the inline intrinsic functions which provide access to the status register, vector base register, global base register etc. In general the example start-up code has the following features : * * * Vector table to enable inclusion of interrupt service routines (ISR) for the corresponding CPU exceptions Start-up code from reset to initialise both data segments types and set-up stack pointer for user application. Also the user and monitor vector tables are combined within SRAM to enable simultaneous user and monitor interrupts. Inline functions defined to enable manipulation of status and control registers for the SH from C Hitachi Europe Ltd. ISSUE : TUT/005/1.0 Vector table A vector table is included in the EVB system by declaring a new section .vects (__attribute__ section() ). Within this section there is an array of function pointers which are either set to NULL if the vector is not used, or set to the ISR address by the user including the ISR name. For example to include a C interrupt routine the following set-up is required : define attribute .vects constant array of function pointers. const fp HardwareVectors[] _attribute_ ((section (".vects"))) = { 255 addr. long defines all vects. startaddr, stackpntr, startaddr2, stackpntr2, . (fp)0L, . ISRrout, . . startup code and stack for cold reset #pragma interrupt void ISRrout(void) { * * } startup code and stack for warm reset NULL function pntr cast to long value. For this ISR routine ISR position defined by no. of longs in array } Start code To enable correct debugging and operation of the user code on the evaluation board it is necessary to include start-up code to initialise the system. The operation of the code is detailed below in the algorithm. However, for further details please refer to the supplied assembly code in start.s 1. 2. 3. 4. 5. 6. 7. 8. Set-up stack pointer for user application (SP = _stack as defined in *.LNK) Set-up bus controller on SH to ensure correct state access to SRAM. Copy the monitor vectors (address 0 to 100) across to the start of the user vector area (A002000) Set the vector base register (VBR) to show the correct offset to the user vector table remembering the relevant formula : Exception vector address = VBR + (vector number)x4. Obtain pointers to initialised data section to copy initialising data values to the address of the reference location variables. In this case this is a copy from RAM to RAM where in a real target it would be a copy from ROM to RAM. The relevant pointers are : _mdata for start of initialising data; _data for start of data variable locations; _edata for end of data variable locations. Obtain start and end addresses of .bss section (_bss and _ebss) to permit clearing of all the data variables. Jump to the main routine to execute the user code. Finally an infinite loop is included to catch programs that terminate from the main loop Inline Intrinsic functions Included within the start-up code section are the inline functions, which enable a C-program to access the status and control registers without dropping into assembly language. The table below details the provided functions, what they do, parameters required and data returned. Hitachi Europe Ltd. Intrinsic function set_cr get_cr set_imask get_imask set_vbr get_vbr set_gbr get_gbr gbr_read_byte ISSUE gbr_read_long Specification Setting the status register Referencing the status register Setting the level in the interrupt mask Referencing the interrupt mask Setting the vector base register Referencing the VBR Setting global base register Reference GBR Reference byte data at address indicated by GBR and offset (Offset must be constant) Reference word data at address indicated by GBR and offset Reference long data at address indicated gbr_write_byte Write byte to address indicated by GBR and offset gbr_write_word Write word to address indicated by GBR and offset gbr_write_long Write long to address indicated by GBR and offset. gbr_read_word gbr_and_byte gbr_or_byte gbr_xor_byte gbr_tst_byte sleep tas trapa : TUT/005/1.0 Parameters int SR void int IMASK void Return void int SR void int IMASK int OFFSET int OFFSET int OFFSET int OFFSET char DATA int OFFSET short DATA char VALUE int VALUE long VALUE void int OFFSET long DATA AND supplied mask with byte indicated by GBR and int offset. OFFSET char MASK OR supplied mask with byte indicated by GBR and int offset OFFSET char MASK XOR mask with byte data at address indicated by GBR int and offset. OFFSET char MASK Check if byte data at address indicated by GBR and int offset is 0, set T bit accordingly. OFFSET char MASK Execute CPU sleep instruction void Read byte from supplied address and set Tbit if zero. char *ADDR Starts trap exception processing depending on the trap int number TRAP_NO void void void void void (T bit SR) in void void To access the intrinsic functions declare the prototype of the relevant function and link with the intrinsic.s at the linker stage. eg. extern inline set_imask(char) Hitachi Europe Ltd. ISSUE : TUT/005/1.0 Tutorial 1 - Non-interrupt driven LED flash The first tutorial within the set of SH EVB tutorials will be used to gain exposure and practice in using the EVB and the GNU toolset. As such the code requirements within this tutorial are trivial requiring little effort in coding time. The downside being that little real knowledge of the SH processor itself will be gained although this will remedied in later work. The functional requirements of this tutorial are specified below : 1. Set-up port B pin 15 as the control pin for the green led on the EVB, see EVB user manual and SH manual. 2. Initialise an array of decreasing long values to be used as frequency control of the led. Produce an array of around 30 values where the mechanism of producing the delays is left up to your particular choice, remembering the speed of the SH and the necessity to make the led flash visible. 3. Enter for loop that will toggle the led around 30 times with the following spec-- * load delay value from array * turn led on * delay for specified amount * turn led off * delay for same specified amount * return and repeat 30 times 4. Exit main loop with the led still on and return to CMON prompt using trap function trap(00). Application code has been produced as the figure below demontstrates, although it should be noted that although the vector table has been included it is not required for this application. inline.s start.s vects.s user code jtut.c 7030.h AS GCC LD OUTPUT OBJECT FILE The included module IOSH7030.H has been used in the application code to enable access to port B control registers, and all other on-chip registers. A further point to note about this tutorial and for further reference in others is that the LED flash should be of an order of 20Hz. Thus, with the SH1 running at 16MHz there must be a wait of 800K clock cycles until the next LED flash. The order by which this tutorial has been completed is detailled below, examine ANSWERS/SOL1 for the resultant code and object files. 1. 2. User code created as specified above. Vector code created to include start and stack definitions no ISR required for this application. Hitachi Europe Ltd. ISSUE : TUT/005/1.0 3. Code built using supplied build.bat file that is invoked as build sol1. Build compiles C-code and vector table, assembles the start and inline code and finally links object files producing a sol1.sr object file and a map file sol1.map. 4. Examine sol1.map file to find the start and end addresses of the created code, initialised data and the unitialised data. Taking note of these addresses may be of use later on in the debugging process where unfortunately no symbolic debugging is possible within CMON. 5. Set-up EVB making sure of 5volts on the board and the serial cable connected to the monitor port with the correct RS-232 set-up . 6. Invoke hint from the user code directory (ANSWERS/SOL1). 7. Download code using l : sol1.sr 8. Debug and run code using the CMON commands. Examining the on-line help will show the allowable commands. It should be noted that the CMON debugger is very pedantic and can only accept syntactically correct commands. 9. Another option for higher level debugging is using the GNU debugger gdb. (See below) 10. Move onto tutorial 2. In order to use a more sophisticated debug option it is necessary to use the GNU tool gdb which can be used as a stand alone simulator or in conjuction with the EVB as a debugger. To use the gdb as the frontend to the EVB the below should be followed. For a complete list of commands either access the online help or the supplied GNU manual. 1. 2. Create code and then complie and link making sure that the -g option is used for compiling and the SREC output format is not used in the linker file. The reason for this being that GDB requires the COFF output format to enable C-debugging, other formats are not compatable. Ensure that the particular commmunication port used is set up correctly (9600,n,8,1,p) C:\> mode com1:9600,n,8,1,p 3. Load the supplied port driver software asynctsr to interface with EVB. C:\> asynctsr 1 4. Invoke the GDB debugger with the required download file, gdb sol1.x, the gdb banner should now be displayed along with prompt waiting for next command. If not then check compilation of tut1.c to ensure s-record format has not been selected. C:\> gdb sol.x GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show coping" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details GDB 4.13-94q4 , Copyright 1994 Free Software Foundation, Inc... sol1.sr: . 5. Now setup gdb in remote mode (ie non-simulator mode), target remote com1. This procedure may need to be repeated several times to obtain a valid communication link. (gdb) target remote com1 Remote Debugging using com1 0xc3c in ?? () (gdb) 6. Value depends on what was previously downloaded to EVB The final step before running the code is to download the object file (gdb) load sol1.sr Loading section .text, size 0x220 vma 0xa004000 Loading section .data, size 0x15 vma 0xa006000 (gdb) Hitachi Europe Ltd. 7. ISSUE : TUT/005/1.0 The program is now ready for debug and execution so use help for a list of valid commands, although the quick list below details some of the more usual commands. * * * * * * * * * * * help - as suggested invokes help info. on requested subject info - Displays information on loaded program - args, registers, program, breakpoints break - Breakpoint set on symbol name, line, address or offset. watch - Set watchpoint on variable name and break and display when value changed continue - Resume execution until next break or exception. step - Run program until it reaches next line next - Run program until next line including complete function calls stepi - Run line and break and display next line to execute list - Display lines from source file print - Examine data as specified by expr. examine - Examine memory contents The final part of this tutorial is to compare the operation of the SH using external memory for program code and data (SRAM from 0xA002000) or using all on-chip RAM (0xF000000-F001FFF). The reason being that it will be possible to benchmark the SH running at full speed with 32bit data and code memory against using the 16 bit SRAM memory. The list below details the necessary actions to enable benchmarking 1. Edit start.s code to alter the setup of the vector base register (VBR) to point to the beginning of on-chip RAM. mov.l ldc offset,r0 r0,vbr Change offset to point to beginning of on_chip RAM. offset: .long 0xF000000 2. Edit the linker file to link the code within the on-chip RAM area ENTRY(_start) OUTPUT_FORMAT(srec) SECTIONS { .vects 0xF000000 : {*(.vects);} .text 0xF000300 : {*(.text) _mdata=. ;} .mdata 0xF001000 : AT (ADDR(.text) + SIZEOFF(.text)) {_data=. ; *(.bss) *(COMMON) _ebss=. ;} .bss . : {_bss=. ; *(.bss) *(COMMON) _ebss=. ;} .stack 0xF001FFE : {_stack=. ; *(.stack) } } 3. Re-build the software and download as previously demonstrated. It should now be possible to attempt a simple benchmark by comparing the speed of the LED flash in onchip RAM with the SH using non-32 bit off-chip RAM. Hitachi Europe Ltd. ISSUE : TUT/005/1.0 Tutorial 2 : ITU controlled LED flash The second tutorial for the SH evaluation board uses an ITU interrupt for timed LED flashing. Not only functionality of the program with respect to the SH chip should be noted on but also the basic method of using interrupts in the SH/EVB environment. As mentioned earlier, in the tutorial overview, to use interrupts within the EVB system it is necessary to create entries in the vector table. The vector table consists of a number of function pointers, or more simply addresses, to load the program counter for execution of the ISR. An extra point to note for the purposes of the EVB only, is that it is necessary to alter the vector base register (VBR). The reasoning behind this is that on an exception (interrupt or reset) the SH CPU will access an address between 00000 and 255H for the pertinent exception handler address. This mechanism is fine for a normal application where the vector table is stored in ROM along with the execution code. However, for the purposes of the EVB our exception table can only reside in the user RAM area which has addresses A000000 to A010000, thus an offset must be made of A002000 to access vectors (A000000 to A001300 is taken by monitor data). This can made by altering within the start-up code the VBR to show the correct offset for all other exceptions except reset which does not use the VBR offset. Apart from making the necessary changes to the vector table this tutorial has the following functional requirements. 1. 2. 3. 4. Write initialisation code to access port B pin 15 as the control line for the LED. Write initialisation code for the ITU timing unit to enable an interrupt controlled LED flash. Provide an array of integer values to be used as count values to provide a decreasing cadence in the LED flash. This array can be the same as that used in tutorial 1. Enable the LED flash and ensure ITU loads with correct frequency value and the program terminates correctly with green LED still on. Before examining the tutorial work the following notes on the operation of the ITU should be remembered. 1. 2. 3. 4. 5. ITU channel 0 to be used Operation of counter should be as an up counter. GRA compare match should trigger the interrupt to CPU. After toggling the LED the ITU compare register should be reloaded with new count value and then ITU enabled again. The ITU unit should be completely disabled after the final LED flash. Registers required to be set-up are : 1. 2. 3. 4. 5. 6. 7. 8. TCNT0 : Timer counter cleared for initialisation GRA0 : General reg A for channel 0 used as output compare - set with delay val. TCR0 : Timer control reg - TCNT cleared by GRA, Internal clock /8 TIOR0 : Timer I/O control - No output from GRA match TSR0 : Timer status register - Clear overflow, GRB and GRA matches TIER0 : Timer interrupt enable - Enable channel 0 only. IPRC : Interrupt priority reg C - ITU mid priority TSTR : Timer start register - enable only TCNT0 The final point to note about this tutorial is that uses the inline function set_interrupt_mask (set_imask). This function can set the four I bits to provide an interrupt mask level from 0 to 15 and thus only enable certain priority interrupts. The ITU interrupt should be made a mid-priority interrupt and thus the interrupt mask level should be se accordingly, value of 7 is suitable. Application code is shown in ANSWERS/SOL2 along with the necessary link and build files. The same tutorial procedure as tutorial 1 should be utilised although try setting a breakpoint in the ISR to trace correct action of SH EVB. Again the SH can be benchmarked by enabling the code to run in on-chip RAM, as shown in tutorial1. Hitachi Europe Ltd. ISSUE : TUT/005/1.0 Tutorial 3 : AD conversion of Potentiometer The third tutorial for the SH/EVB system is based upon using the SH on-chip Analogue to Digital converter. This tutorial will use one of the A/D channels to monitor a potentiometer connected to the SH/EVB. The SH will read an analogue value from 0 to 5 volts, convert the value to a digital equivalent and then display value as a particular LED flash frequency. This tutorial will be a useful tool in understanding the operation of the A/D and of the hardware constructs of the EVB to enable access to the A/D channels. Again the operation of this software will be interrupt driven and thus again the vector table must be altered accordingly. The figure below represents the hardware set-up for this tutorial which must be verified against the set-up of your own EVB before proceeding any further with this tutorial. RS232 to PC Potentiometer (0 to 5Volts) Vcc Vcc JP6 JP5 25 5volts 0volts 3 P. C Vref J3 AVcc SH7032 AN7 1 Vvar GND EVB The software algorithm for this tutorial is as shown below : 1. 2. 3. 4. 5. Initialise Port B pin 15 to be used as control of the green LED. Initialise analogue port to use AN7 to read pot. voltage value in scan mode, interrupt driven. Enable the Analogue interrupt and ensure interrupt mask level set accordingly. Loop forever with analogue ISR periodically updating the most recently read pot. voltage value. * If analogue_value = 0 then keep LED off. * Turn LED on * wait for period specified by analogue_value * constant * Turn LED off * wait for period specified by analogue_value * constant Infinite loop The choice of constant to multiply with the obtained digital equivalent is up to the users discretion. However, it must produce a visible LED toggle remembering that it will be multiplied by a value from 0 to FFFF hex. Also, note that the LED frequency should show be greater for a higher applied analogue voltage ie. LED flash delay = full scale value - read digital value The basic operation of the Analogue ISR will be to read a value from analogue result register ADDRD, which stores digital equivalent for AN7, and then write this value to a global variable that will be used for the wait periods between toggling the LED. Before leaving the ISR it is necessary to clear the flag ADF in the ADCSR register but since the mode is scan it is not necessary to set ADST again. Hitachi Europe Ltd. ISSUE : TUT/005/1.0 The register list below should aid in detailing the operation of the AD for this application 1. 2. 3. ADDRD : A/D data register for AN7 - Cleared to zero at init, holds AD value thereafter. ADCSR : A/D control/status register - Interupt enabled, scan mode, 134 state conversion time, AN7 used only. ADCR : A/D control register - External trigger not used. To complete this tutorial requires the same software procedures as the previous two. However, it is also necessary to ensure the following hardware setup is followed. * * * * * Connect jumpers JP5 and JP6 to ensure that AVcc and Vref are connected directly to Vcc. Connect jumper JP7 to ensure AVss is connected directly to ground (Vss) Connect potentiometer inputs Vcc to pin 26 of jumper J3 (high voltage of pot. = 5 volts) Connect potentiometer output to pin 3 of jumper J3 which connects directly to AN7 of the SH1. If is also good practice to use a multimeter to ensure good connections before attempting to run the software. This concludes the necessary stages to complete tutorial 3. Hitachi Europe Ltd. ISSUE : TUT/005/1.0 Tutorial 4 : AD conversion of pot. + Timed frequency The final tutorial is a further extension of the previous tutorials combining the use of the AD, DMAC, ITU and the pin control functions of the SH. The basic specification will be again to produce a LED flash in response to a read analogue voltage from the potentiometer. However, this will be extended to use DMAC to auto update the read analogue value and then to use the ITU with an interrupt to handle the LED flash. The hardware set-up for this is identical to that produced for tutorial 3, although the algorithm below along with functional block diagram details the new software operation : CPU Control Module Data Pot. ADDRD ad_value Transfer data AN7 *MULTI ADI A/D ITU DMAC DEIO ITU_ DMAC IMIA0 LED ITU_ ISR Toggle LED It should be noted how little CPU activity is required for controlling this application. The majority of the processing is automatically handled by the on-chip modules although the ITU unit depends on an ISR to toggle the LED and then reload its counter value GRA. Also a simple DMAC ISR is used to make sure that the count register never stays at 0 i.e. DMAC always operational. 1. 2. 3. 4. 5. Set-up IO ports to enable Port B pin 15 as the LED control Set-up DMAC to be invoked by A/D interrupt with fixed source (ADDRD) and fixed destn. of result variable. Remembering that the transfer is a word of data. Set-up ITU to use GRA channel 0 as upcounter to interrupt on compare match. The GRA register is loaded with a value calculated by a constant * result of AD conversion Set-up AD to use AN7 scan mode without a external trigger. Priority of ADI should be lower than Imask such that CPU is not interrupted by ADI, only DMAC Loop forever only being interrupted by ITU ISR to toggle LED. The register set-up for the on-chip modules are as specified by earlier tutorials and is noted below : * ITU set-up as tutorial 2 although GRA loaded by ad_value rather than constant * A/D set-up as tutorial 3 although priority of interrupt changed to below mask level of CPU The DMAC operation is more thoroughly explained through the register set-up below : 1. 2. 3. 4. 5. SAR : Source address register - AD data register D DAR : Destination address register - address of ad_value CHCR : Channel control register - Fixed destn., Fixed source, ADI enables, word, interrupt to reload TCR TCR : Transfer count register - Always kept ongoing DMAOR : DMA operation register - Enable all channels with fixed priority This concludes the specifications of tutorial 4, although time permitting this tutorial can be further extended to use the ITU/DMAC in a manner that does not require CPU intervention after set-up. For example using an Hitachi Europe Ltd. ISSUE : TUT/005/1.0 extra DMAC channel to auto transfer on an ITU GRA interrupt the resultant AD value to the GRA counter register. CODE LISTINGS /************************************************************************** SH 7000/7600 APPLICATION CODE FOR TUTORIAL 1 - SOLUTION CREATED : J.D. 25/9/95 FUNCTION : Simple code designed to toggle green LED with decreasing cadence ***************************************************************************/ /*Entry point is main called from startup code*/ /*Memory areas initialised along with stack pointer*/ #include "iosh7030.h" /*on-chip register definitions*/ #define LED_ON 0x8000 #define MULT 0x900 /*Define for toggling led */ long delay_vals[26]= {500,1000,1500,2000,2500,3000,3500,4000,4500,5000,5500,6000, 6500,7000,7500,8000,8500,9500,10000,20000,30000,40000, 50000,60000,70000,80000}; /*Array of 26 flash delays*/ void io_init(void) /* Simply set-up LED IO port - port B pin15 */ { PFC_PBIOR |= 0x8000 ; /*Pin 15 set as ouput*/ PFC_PBCR1 &= ~0xC000 ; /*Top two bits cleared - pin 15 normal I/O */ PBDR |= LED_ON; /*Turn led on */ } void flash_wait(long period) /* Time unit to delay for different periods between LED flashes */ { long i = 0 ; for(i=0;i 25) { count = 0 ; if (ad_value < 20) /*Allow for pot margin*/ { PBDR &= 0xef; /*Keep led off for 0volts*/ } else { if (ad_value > 0xfe00) { PBDR |= 0x10; /*Keep LED on*/ } else { PBDR ^= LED_ON ; /*Toggle led*/ } } } temp = FULL - ad_value ; ITU_GRA0= temp; /*Now load new value of AD from AN7*/ ITU_TSR0 &= 0XFE ; /*Clear flag */ } main() { set_interrupt_mask(3); /*Intetrupt mask at 5 - adi not accepted*/ setup_io(); /*Setup PB-15 as led control*/ setup_dmac(); /*Setup and enable DMAC to control AD*/ setup_itu(); /*Setup ITU to control flash rate*/ setup_ad(); /*Setup AD to read pot. value*/ /*Loop forever reading analogue values and translating to LED cadence*/ while (SCOTLAND != CONQUERED) { } } Hitachi Europe Ltd. ISSUE : TUT/005/1.0 SH/EVB Tutorial Summary The examples in this document should be used in conjunction with the supplied disk, to supplement the information provided by the US7032EVB1 Users Manual. The information and examples provided by this document have been specifically aimed at those users wishing to create real code for an embedded system which will take advantage of the SH series interrupt controller and on-chip peripherals. The code supplied on the accompanying disk should be used for reference when completing the tutorials. The actual contents of the disk may vary from that published in this document - in this case the release notes should be used as the de-facto reference. Hitachi contact numbers and addresses will also be supplied with the release notes for updates to examples and documentation, and for device specific help. The GNU C compiler is not a supported product by Hitachi, and thus the supplied contact addresses should be used for device related enquiries only. Commercial support for the GNU toolset can be obtained from Cygnus Support, please use the below contact addresses to obtain a quotation. Cygnus Support 1937 Landings Drive Mountain View California 94043 USA email: info@cygnus.com Hitachi Europe Ltd. ISSUE : TUT/005/1.0 APPENDIX A : Tutorial Disk The supplied disk along with the tutorial notes contains the required source, build and include files to complete the tutorials. Solutions are also provided, although it is strongly recommended to first try the tutorials before resorting to the solutions. PRES. TUT1 A: TUTS TUT2 TUT3 TUT4 ANSWERS FILES USED LINKER COMMAND FILE ENTRY(_start) OUTPUT_FORMAT(srec) SECTIONS { .vects 0x0A002000 : { *(.vects);} .text 0x0A004000 : { *(.text) _mdata = .;} .mdata 0x0A006000 : AT(ADDR(.text) + SIZEOF(.text)) { _data = .; *(.data) _edata = .;} .bss . : { _bss = .; *(.bss) *(COMMON) _ebss = .;} .stack 0x0A00F000 : { _stack = .; *(.stack)} } * * * * * * * BUILD.BAT FRAME1.C IOSH7030.H TUT1.LNK VECTS.C START.S INLINES.S Hitachi Europe Ltd. ISSUE STARTUP CODE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! Start.s !! !! Reset initialisation code !! !! PBB .section .text .global _start .extern _stack _start: !Initialise stack pointer to new user stack mov.l stack_k,r15 !Setup monitor vectors from A000000 onwards !Basically copy 00-100 to a000000-a000100 mov #0,r0 !setup pointer to monitor vector table mov.l test,r1 !setup pointer to new vector table mov #100,r3 !address 100 stop value nextvec: mov.l @r0,r2 mov.l r2,@r1 add #4,r0 add #4,r1 cmp/gt r0,r3 bt nextvec !get data from monitor vector table !write data to new vector table !next vector from monitor !next vector to write to !only write vectors up to external interrupts !if less than 100 next vector write !else now update VBR to show new adddress of vector table mov #0xa000000,r0 !get offset to start of vector table ldc r0,vbr !load value in VBR !now initialise data segments - either clear or set values mov.l data_k,r0 mov.l edata_k,r1 mov.l mdata_k,r2 start_l: mov.l @r2,r3 !get from src mov.l r3,@r0 !place in dest add #4,r2 !inc src add #4,r0 !inc dest cmp/gt r0,r1 !dest == edata? bt start_l ! zero out bss mov.l bss_k,r0 mov.l ebss_k,r1 mov #0,r2 start_2: mov.l r2,@r0 add #4,r0 cmp/ge r0,r1 bt start_2 ! call main mov.l main_k,r0 jsr @r0 or r0,r0 : TUT/005/1.0 Hitachi Europe Ltd. ! call exit mov r0,r4 mov.l exit_k,r0 jsr @r0 or r0,r0 _exit: nop bra _exit nop .align 2 mdata_k: .long _mdata data_k: .long _data edata_k: .long _edata bss_k: .long _bss ebss_k: .long _ebss main_k: .long _main exit_k: .long _exit stack_k: .long _stack test: .long 167772160 INLINE FUNCTIONS USED .text .global _set_interrupt_mask ! value passed in r4 _set_interrupt_mask: mov.l r14,@-r15 mov r15,r14 mov.l r0,@-r15 mov.l r1,@-r15 stc sr,r0 !get current SR value mov.l __mask,r1 and r1,r0 !clear the old imask bits shll2 r4 shll2 r4 not r1,r1 and r1,r4 !clear all but the imask bits or r4,r0 !set the new imask bits ldc r0,sr !load new SR value mov.l @r15+,r1 mov.l @r15+,r0 rts mov.l @r15+,r14 .align 4 __mask: .long 0xffffff0f ISSUE : TUT/005/1.0 Hitachi Europe Ltd. ISSUE : TUT/005/1.0 BUILD DOS BATCH FILE gcc %1.c -g -O -c -m1 as start.s -o start.o gcc vects.c -g -O -c ld %1.o vects.o start.o -T%1.lnk -o %1.sr -Map %1.map INTERRUPT VECTOR AND INTERNAL REGISTER FILES CAN BE FOUND ON THE TUTORIAL DISK - PLEASE CALL YOUR REGIONAL OFFICE FOR A COPY When using this document, keep the following in mind, 1, This document may, wholly or partially, be subject to change without notice. 2, All rights are reserved: No one is permitted to reproduce or duplicate, in any form, the whole or part of this document without Hitachi's permission. 3, Hitachi will not be held responsible for any damage to the user that may result from accidents or any other reasons during the operation of the user's unit according to this document. 4, Circuitry and other examples described herein are meant only to indicate the characteristics and performance of Hitachi's semiconductor products. Hitachi assumes no responsibility for any intellectual property claims or other problems that may result from applications based on the examples therein. 5, No license is granted by implication or otherwise under any patents or other rights of any third party or Hitachi, Ltd. 6, MEDICAL APPLICATIONS: Hitachi's products are not authorised for use in MEDICAL APPLICATIONS without the written consent of the appropriate officer of Hitachi's sales company. Such use includes, but is not limited to, use in life support systems. Buyers of Hitachi's products are requested to notify the relevant sales office when planning to use the products in MEDICAL APPLICATIONS. Copyright Hitachi, Ltd.,1995. All rights reserved