Hit achi Eu rop e Lt d . ISS U E : TU T/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
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
Introduction
The following tutorials will be used as a basis for training in the process of code creation, debugging and
runn ing in the SH envir onment. In short they should provide a mechanism to examine the ar chitecture 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 tutor ials are sh own 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. Simple code to toggle green LED using port B pin 15
2. ITU interrupt driven toggling of the green LED again using port B pin 15.
3. A/D code to provide interrupt driven conversion of a con nected potentiometer. The resultant digital value
displayed as an LED frequency.
4. A/D code exten d ed t o use IT U to flash l ed a t sp ecific fr equ ency p l u s t he DMAC is used t o t ra nsfer t he rea d
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 envir onment. 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 C code files
*.S Assembly only files
*.LNK Input files for the linker software
*.MAP Output from linker file defining symbols and segment addresses
*.SR Output object code from linker
*.O 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
Hit achi Eu rop e Lt d . ISS U E : TU T/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 with in 1 cycle due to the pipelined architecture. Care
should be taken to avoid pipeline disruption from con ditional branchin g which can r educe the efficien cy 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 stor ed as literal
constants. For example immediate data above th e byte size will be accessed via first a PC relative move then
the actual operation performed upon it :
ADD.W #H’1234,R1 ------------> MOV.W @(disp,PC), R0
ADD.W R1,R0
‘’
‘’
.DATA.W H’1234
Another area of interest is the declarations of sections within the GNU development system. Where created
object code is partition ed into four basic types of segment, the dot definin g a location counter incremen ted for
each assembled byte within the section :
1. .text : holds all program code and constant data always relocatable
2. .bss : Uninitialised data section of module scope only and static variables
3. .data : Initialised data variable section
4. COMMON : Unitiliased data of system scope (i.e. extern variables)
5. User defined sections : Using the keyword directive .section
Apart from the a bove sections it is als o pos s ible to su bdivid e the text and data sections furth er such th at 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 : compile or assemble source files but do not link
-g : produce debugging information in the object code
-O : Optimising compilation - levels up to 3
-S : stop after compilation and do not assemble - output assembler equivalent of C code
-l : define output list file
-d : produce debugging info. y suffix for standard errors.
-m1 : Generate code for normal SH1 chip
Linker
The fin al major compon ent 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 lin k
file and resolving symbol addresses. Example command line execution is shown below :
disp
length
USER CODE ACTUAL CODE
Hit achi Eu rop e Lt d . ISS U E : TU T/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 th eir text and data segment area addresses defin ed by th e
linkfile.lnk file producing a map file for control purposes and the actual object file for execution.
The main concern within th e linker stage is th at of th e creation of the linkfile.lnk file whi ch defines where ea ch
segment in the input files should be placed in the address range.
To begin with before any examples ar e sh own a small amount of syntax must be r emembered to decode and to
create new linker files :
1. ‘.’ or dot variable is used throughout and refers to the current location counter (or address)
within a section
2. ‘*’ followed by a section name means all files with th is section n ame to be included. Apart from
the ones already previously used.
3. { } 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.
Figure 2 : Linker file
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 mean s that a ROM image can be built for
the variables to enable initialisation.
.text : Code section
.data : initialised data section
.mdata : ROM image of initialised data section
.bss : Zeroed out data of module scope or statics.
.vects : User defined constant area for vector table
.stack : User defined variable area for stack, includes pointer to start of stack.
COMMON : Unitialised data of system scope (resolves externs between modules)
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
ENTRY(_start)
OUTPUT_FORMAT(srec)
SECTIONS
{.vects 0X0A002000 : {*(.vects);}
.text 0X0A004000 : {*(.text) _mdata = . ;}
.mdata 0X0A006000 : AT (ADDR(.text) + SIZEOFF (.text))
{ _data = . ; *(.data) _edata = . ; }
.bss . : {_bss =.; *(.bss) *(COMMON) _ebss =.;}
.stack 0X0A00F000 : { _stack =.; *(.stack) }
}
First executable
address is startup S-record output object
file, not for gdb use
Declare vector table to start
at addres A002000. User
defined section
User code and consts in
.text at addr A004000.
_mdata indicates end of
section
common refers to
unitialised data
Data stored at A006000
but const init. data stored
after the code area as
marked by AT (
ADDR...)
.bss section includes
unitialised data. Placed at
end of initialised data
marked by _bss and _ebss,
for the purposes of the
startup code.
Hit achi Eu rop e Lt d . ISS U E : TU T/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 th e sections and the address pointers which ar e used by the star t-up code to initialise data areas
and the stack pointers. Further details of this will be shown in the following start-up code section.
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
Monitor vector table .
Monitor
code area
Un-used
external
area
0000000
0000255
0010000
A000000
Un-used data area
Un-used data area
Un-used data area
Un-used
external
area
User vector table
User code
Initialising data store
Initialised data
Unitialised data
Stack area
On-chip RAM
A002255
A004000
A006000
A00F000
A010000
F000000
FFFFFFF
EPROM
2 x SRAM
mdata
_
data
_edata & _bss
_ebss
_stack
Const init data copied
at startup
Data cleared at startup
Stack grows down
through address range
Accessed in 1-state
Monitor data area
Copy monitor
vectors to user
vector table.
A0001300
Hit achi Eu rop e Lt d . ISS U E : TU T/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 :
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. Th e operation of th e code is detailed below in th e algorith m. However, for
further details please refer to the supplied assembly code in start.s
1. Set-up stack pointer for user application (SP = _stack as defined in *.LNK)
2. Set-up bus controller on SH to ensure correct state access to SRAM.
3. Copy the monitor vectors (address 0 to 100) across to the start of the user vector area (A002000)
4. 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.
5. 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 tar get it would be a copy
from ROM to RAM. The relevant poin ters ar e : _mdata for start of initialising data; _data for start of data
variable locations; _edata for end of data variable locations.
6. Obtain start and end addresses of .bss section (_bss and _ebss) to permit clearing of all the data variables.
7. Jump to the main routine to execute the user code.
8. 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.
define attribute .vects
const fp HardwareVectors[] _attribute_ ((section (“.vects”))) =
{
startaddr,
stackpntr,
startaddr2,
stackpntr2,
.
(fp)0L,
.
I
SRrout,
.
.
}
constant array of function
pointers.
startup code and stack for
cold reset
startup code and
stack for warm reset
NULL function pntr
cast to long value.
ISR position defined by
no. of longs in array
#pragma interrupt
void ISRrout(void)
{
}
For this ISR routine
255
addr.
long
defines
all
vects.
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
Intrinsic function Specification Parameters Return
set_cr Setting the status register int SR void
get_cr Referencing the status register void int SR
set_imask Setting the level in the interrupt mask int IMASK void
get_imask Referencing the interrupt mask void int IMASK
set_vbr Setting the vector base register
get_vbr Referencing the VBR
set_gbr Setting global base register
get_gbr Reference GBR
gbr_read_byte Reference byte data at address indicated by GBR and
offset
(Offset must be constant) int
OFFSET char
VALUE
gbr_read_word Reference word data at address indicated by GBR and
offset int
OFFSET int
VALUE
gbr_read_long Reference long data at address indicated int
OFFSET long
VALUE
gbr_write_byte Write byte to address indicated by GBR and offset int
OFFSET
char DATA
void
gbr_write_word Write word to address indicated by GBR and offset int
OFFSET
short
DATA
void
gbr_write_long Write long to address indicated by GBR and offset. int
OFFSET
long DATA
void
gbr_and_byte AND supplied mask with byte indicated by GBR and
offset. int
OFFSET
char MASK
void
gbr_or_byte OR supplied mask with byte indicated by GBR and
offset int
OFFSET
char MASK
void
gbr_xor_byte XOR mask with byte data at address indicated by GBR
and offset. int
OFFSET
char MASK
void
gbr_tst_byte Check if byte data at address indicated by GBR and
offset is 0, set T bit accordingly. int
OFFSET
char MASK
(T bit in
SR)
sleep Execute CPU sleep instruction void void
tas Read byte from supplied address and set Tbit if zero. char
*ADDR void
trapa Starts trap exception processing depending on the trap
number int
TRAP_NO
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)
Hit achi Eu rop e Lt d . ISS U E : TU T/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 tutor ial 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 arr ay of decreasing long values to be used as fr equen cy control of the led. Produce an arr ay 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.
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 furth er poin t to n ote about this tutor ial and for further reference in others is th at 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. User code created as specified above.
2. Vector code created to include start and stack definitions no ISR required for this application.
start.s vects.s user code
jtut.c
7030.h
GCC
LD
A
S
OUTPUT OBJECT FILE
inline.s
Hit achi Eu rop e Lt d . ISS U E : TU T/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 inlin e 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 makin g sure of 5volts on the board and the serial cable con nect ed 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 th e CMON debugger is ver y pedant ic an d can onl y accept synt actically
correct commands.
9. Another option for higher level debugging is using the GNU debugger gdb. (See below)
10. Move onto tutorial 2.
In or der to use a more sophisticated debug option it is necessary to use th e GNU tool gdb wh ich 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. Cr eate code an d then complie and link making sure that th e -g option is used for compiling and th e 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.
2. Ensure that the particular commmunication port used is set up correctly (9600,n,8,1,p)
3. Load the supplied port driver software asynctsr to interface with EVB.
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.
5. Now setup gdb in r emote mode (ie non -simulator mode), target remote com1. Th is procedure may need to
be repeated several times to obtain a valid communication link.
6. The final step before running the code is to download the object file
C:\> mode com1:9600,n,8,1,p
C:\> asynctsr 1
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 <i386-go32 --target sh-hms>,
Copyright 1994 Free Software Foundation, Inc...
sol1.sr: .
<gdb>
(gdb) target remote com1
Remote Debugging using com1
0xc3c in ?? ()
(gdb) Value depends on what was
previously downloaded to EVB
(gdb) load sol1.sr
Loading section .text, size 0x220 vma 0xa004000
Loading section .data, size 0x15 vma 0xa006000
(gdb)
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
7. The program is now ready for debug an d execution so use help for a list of valid commands, although the
quick list below details some of the more usual commands.
help <subject> - as suggested invokes help info. on requested subject
info <subject> - Displays information on loaded program - args, registers, program, breakpoints
break <field> - Breakpoint set on symbol name, line, address or offset.
watch <expr> - 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 <expr> - Display lines from source file
print <expr> - Examine data as specified by expr.
examine <expr> - 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 fr om 0xA002000) or using all on-ch ip RAM (0xF000000-F001FFF). T he r eason bein g th a t it
will be possible to ben chmark the SH runn ing 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.
2. Edit the linker file to link the code within the on-chip RAM area
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 on-
chip RAM with the SH using non-32 bit off-chip RAM.
mov.l offset,r0
ldc r0,vbr
offset: .long 0xF000000
Change offset to
point to beginning
of on_chip RAM.
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) }
}
Hit achi Eu rop e Lt d . ISS U E : TU T/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
function ality of the progr am with respect to the SH chip should be noted on but also the basic method of using
interrupts in the SH/EVB environment.
As men tion ed ear lier, in the tutorial over view, to use in terr upts with in th e EVB system it is necessa r y to cr eat e
entries in the vector table. The vector table consists of a number of function pointers, or more simply addresses,
to load the progr am counter for execution of the ISR. An extra point to note for the purposes of th e EVB on ly,
is that it is necessary to alter the vector base register (VBR). The reasoning beh ind 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 alterin g within th e 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. Write initialisation code to access port B pin 15 as the control line for the LED.
2. Write initialisation code for the ITU timing unit to enable an interrupt controlled LED flash.
3. 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.
4. 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. ITU channel 0 to be used
2. Operation of counter should be as an up counter.
3. GRA compare match should trigger the interrupt to CPU.
4. After toggling the LED the ITU compare register should be reloaded with new count value and
then ITU enabled again.
5. The ITU unit should be completely disabled after the final LED flash.
Registers required to be set-up are :
1. TCNT0 : Timer counter cleared for initialisation
2. GRA0 : General reg A for channel 0 used as output compare - set with delay val.
3. TCR0 : Timer control reg - TCNT cleared by GRA, Internal clock /8
4. TIOR0 : Timer I/O control - No output from GRA match
5. TSR0 : Timer status register - Clear overflow, GRB and GRA matches
6. TIER0 : Timer interrupt enable - Enable channel 0 only.
7. IPRC : Interrupt priority reg C - ITU mid priority
8. TSTR : Timer start register - enable only TCNT0
The final point to n ote about this tutorial is that uses the inline function set_interr upt_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
pri ori ty inter rupts. T he ITU in t errupt should be made a mid-pr i ori ty interrupt a nd t hus the i nter rupt ma sk l evel
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 pr ocedure as tutor ial 1 should be utilised although tr y settin g a breakpoin t in th e 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.
Hit achi Eu rop e Lt d . ISS U E : TU T/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 r ead an analogue value from 0 to 5 volts, conver t the value to a digital equivalent an d th en display value as
a particular LED flash frequen cy. 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.
The software algorithm for this tutorial is as shown below :
1. Initialise Port B pin 15 to be used as control of the green LED.
2. Initialise analogue port to use AN7 to read pot. voltage value in scan mode, interrupt driven.
3. Enable the Analogue interrupt and ensure interrupt mask level set accordingly.
4. 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
5. Infinite loop
The choice of constant to multiply with th e obtained digital equivalent is up to the user s discr etion. However, it
must produce a visible LED toggle remembering that it will be multiplied by a value from 0 to FFFF hex.
Also, note th at the LED fr equen cy should show be gr eater for a higher applied analogue voltage ie. LED flash
delay = full scale value - read digital value
The basic operation of the An alogue 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
per iods bet ween toggl in g th e LED. Before l eavin g th e ISR it is n ecessar y t o clea r th e flag ADF i n th e ADCSR
register but since the mode is scan it is not necessary to set ADST again.
1
3
25 SH7032
P.
C
RS232 to PC
Potentiometer
(0 to 5Volts)
EVB
AN7
AVcc
Vref
Vcc
GND
Vcc
Vvar
5volts
0volts
J
P5
3
J
P6
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
The register list below should aid in detailing the operation of the AD for this application
1. ADDRD : A/D data register for AN7 - Cleared to zero at init, holds AD value thereafter.
2. ADCSR : A/D control/status register - Interupt enabled, scan mode, 134 state conversion time,
AN7 used only.
3. 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.
Hit achi Eu rop e Lt d . ISS U E : TU T/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 :
It should be noted how little CPU activity is required for controlling this application. The majority of the
processing is automatically han dled by the on-chip modules although th e ITU unit depen ds on an ISR to toggle
th e LED an d th en r eload i ts coun ter value GRA. Al so a sim ple DMAC I SR is u sed to ma ke sur e th at th e count
register never stays at 0 i.e. DMAC always operational.
1. Set-up IO ports to enable Port B pin 15 as the LED control
2. 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.
3. 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
4. Set-up AD to use AN7 scan mode with out a external tr igger. Priority of ADI should be lower than Imask
such that CPU is not interrupted by ADI, only DMAC
5. 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. SAR : Source address register - AD data register D
2. DAR : Destination address register - address of ad_value
3. CHCR : Channel control register - Fixed destn., Fixed source, ADI enables, word, interrupt to reload TCR
4. TCR : Transfer count register - Always kept ongoing
5. DMAOR : DMA operation register - Enable all channels with fixed priority
This concludes th e specifications of tutorial 4, alth ough time permitting this tutor ial can be further exten ded to
use the ITU/DMAC in a manner that does not require CPU intervention after set-up. For example using an
A/D DMAC ITU
Pot.
AN7 ADI
Transfer data
IMIA0
ITU_
ISR
LED Toggle LED
*MULTI
ADDRD ad_value
Control
Data
CPU
Module
ITU_
DMAC
DEIO
Hit achi Eu rop e Lt d . ISS U E : TU T/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 for toggling led */
#define MULT 0x900
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<period;i++)
{
}
}
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
main()
{unsigned char j,k =0 ; /* Count of number of times led goes */
long wait = 0; /* Temp for wait period */
io_init() ;
for(j=0;j<26;j++)
{ /*Flash LED 26 times with increasing delay between flashes*/
PBDR &= ~(LED_ON) ; /*Toggle LED*/
wait = delay_vals[j] ; /*Obtain wait period from array*/
flash_wait(wait) ; /*Delay for a time */
PBDR |= LED_ON; /*Toggle LED*/
flash_wait(wait) ;
}
}
/**************************************************************************
SH 7000/7600 APPLICATION CODE FOR TUTORIAL 2 - SOLUTION
CREATED : J.D. 25/9/95
FUNCTION : Simple code designed to toggle green LED with decreasing cadence
Under the control of the ITU timer module. Updating the counts
for the ITU will provide the cadence response.
***************************************************************************/
/*Entry point is main called from startup code*/
/*Memory areas initialised along with stack pointer*/
#include "iosh7030.h" /*on-chip register definitions*/
extern inline set_interrupt_mask(char);
#define LED_ON 0x8000 /*Define for toggling led */
#define MULT 300
#define CONST 10
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*/
volatile unsigned char flash_cnt =0 ; /* Count of number of times led goes */
/*Volatile */
unsigned char count = 0; /*Count to slow down timed flash*/
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
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 enable_flash(void)
/*Function to setup ITU and enable timed flashing*/
{set_interrupt_mask(0); /*Intetrupt mask at 0 - all ints accepted*/
ITU_TCNT0 = 0x0000; /*Clear up counter before start*/
ITU_GRA0 = delay_vals[flash_cnt] ; /*Get first count value - const.*/
ITU_TCR0 = 0x23; /*TCNT cleared by GRA using internal/8 */
ITU_TIOR0 = 0; /*GRA used but with no inputs/output pins*/
ITU_TSR0 = 0; /*Make sure all status flags cleared*/
ITU_TIER0 |= 0X01; /*Enable Interrupt from GRA compare match*/
INTC_IPRC = 0x0000 ; /*Set ITU priority midway*/
INTC_IPRC |= 0x0070 ;
ITU_TSTR |= 0X01; /*Start the counter*/
}
#pragma interrupt
void timed_flash(void)
{count++;
if (count == 30)
{
PBDR ^= LED_ON ; /*Toggle led*/
count = 0; /*reset slow down count*/
ITU_GRA0= delay_vals[flash_cnt] ; /*Now load new value of AD from AN7*/
flash_cnt ++ ; /*Increment count*/
}
ITU_TSR0 &= 0XFE ; /*Clear flag */
}
main()
{unsigned char *endit = 0 ;
flash_cnt = 0 ; /*26 periods in delay array for LED flash*/
io_init() ;
enable_flash();
while (flash_cnt <26)
{
} /*WAIT FOR ALL THE LED FLASHES TO BE COMPLETED*/
ITU_TIER0 &= 0xFE; /*Disable interrupt*/
set_interrupt_mask(16); /*Disable all interrupts*/
PBDR |= LED_ON; /*Turn led on */
ITU_TSTR &= 0xFE; /*Stop the counter*/
}
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
/**************************************************************************
SH7000/7600 APPLICATION CODE FOR TUTORIAL 3 - SOLUTION
CREATED: 29/9/95 BY JD
FUNCTION: Software designed to control the AD convertor on the SH. Such
that an analogue value is read on the EVB, translated to an equivalent
digital value and then displayed as an LED cadence.
***************************************************************************/
#include "iosh7030.H" /*Include port definitions for SH7032*/
#define SCOTLAND 1
#define CONQUERED 0
#define LED_ON 0x8000
#define MULT_VAL 10
#define FULL 0xffff
extern inline set_interrupt_mask(char);
volatile unsigned long ad_value = 0 ; /*Variable to store read pot. value*/
/*Global since written by ISR and
volatle */
void flash_wait()
/* Time unit to delay for different periods between LED flashes */
{
long i = 0 ;
long j = 0 ;
long period = 0 ;
PBDR ^= LED_ON ; /*Toggle led*/
period = FULL - ad_value ; /*Calculate period to wait*/
period = period * 3;
while(i<period)
{ i++;
while (j<period)
{ j++;
}
}
}
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
void setup_io(void)
/*Function : Routine to setup pin PB-15 for led toggle*/
{
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 setup_ad(void)
/*Function : Sets up A/D for AN7 channel for Potentiometer reading*/
{set_interrupt_mask(0); /*Intetrupt mask at 0 - all ints accepted*/
INTC_IPRE = 0x0700; /*Give AD interrupt mid priority */
ad_value = 0 ; /*Clear AD value to hold most recent pot.val*/
ADCSR = 0x57 ; /*Setup = scan/int enabled/134 conv./AN7 */
ADCR = 0 ; /*A/D conversion not enabled by external trig.*/
ADCSR |= 0x20 ; /*Enable A/D conversion */
}
#pragma interrupt
void ad_isr(void)
/*Function : ISR to read value recently read from pot. and update cadence
value to toggle leds. */
{ad_value = AD_DRD ; /*Obtain new cadence value for led toggle*/
ADCSR &= 0x7f; /*Clear AD flag since data been read*/
ADCSR |= 0x20; /*Enable A/D conversion again */
}
main()
{setup_io(); /*Setup PB-15 as led control*/
setup_ad(); /*Setup AD to read pot. value*/
/*Loop forever reading analogue values and translating to LED cadence*/
while (SCOTLAND != CONQUERED)
{ if (ad_value < 100)
{ PBDR |= 0x80; /*Keep led off for 0volts*/
}
else /*Produce visble led flash*/
{ flash_wait(); /*Toggle led at cadence of ad_value*/
}
}
}
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
/**************************************************************************
SH7000/7600 APPLICATION CODE FOR TUTORIAL 4 - SOLUTION
CREATED: 29/9/95 BY JD
FUNCTION: Software designed to control the AD convertor on the SH. Such
that an analogue value is read on the EVB, translated to an equivalent
digital value and then displayed as an LED cadence.
***************************************************************************/
#include "iosh7030.H" /*Include port definitions for SH7032*/
#define SCOTLAND 1
#define CONQUERED 0
#define LED_ON 0x8000
#define MULT_VAL 100
#define FULL 0xffff
extern inline set_interrupt_mask(char);
volatile unsigned short ad_value = 0 ; /*Variable to store read pot. value*/
/*Global since written by ISR*/
unsigned char count = 0; /*used to slow down ITU timer*/
void setup_io(void)
/*Function : Routine to setup pin PB-15 for led toggle*/
{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 setup_ad(void)
/*Function : Sets up A/D for AN7 channel for Potentiometer reading*/
{
INTC_IPRE = 0x0000; /*Give AD interrupt low priority - no cpu interrupt*/
ad_value = 0 ; /*Clear AD value to hold most recent pot.val*/
ADCSR = 0x57 ; /*Setup = single/int enabled/134 conv./AN7 */
ADCR = 0 ; /*A/D conversion not enabled by external trig.*/
ADCSR |= 0x20 ; /*Enable the AD */
}
void setup_dmac(void)
/*Function : Setup DMAC to act on ADI and transfer read value to var. */
{
unsigned short temp = 0;
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
INTC_IPRC |= 0x8000 ; /*Set DMAC at mid priority interrupt*/
temp = DMA_CHCR0 ; /*Read register before writing to it*/
DMA_CHCR0 = 0x0d0c ; /*Destn. address fixed, source address fixed
ADI interrupt enables, cycle steal, word transfer
interrupt at end of transfer, channel 0 DMAC */
temp = DMAOR ; /*Read register before writing to it*/
DMAOR &= 0x0000 ;
DMAOR |= 0x0001 ; /*Clear error flags and enable DMAC transfer*/
DMA_TCR0 = 0xaaaa; /*Max number of transfers*/
DMA_DAR0 = (long)&ad_value ; /*Start address of memory to store mssg */
DMA_SAR0 = 0x5fffee6 ; /*Source of data is AN7 thus ADDRD*/
temp = DMA_CHCR0 ;
DMA_CHCR0 |= 0x0001 ; /*Set DE bit to enable DMA*/
}
void setup_itu(void)
/*Function : Setup ITU to handle the flashing of the LED*/
{
ITU_TCNT0 = 0x0000; /*Clear up counter before start*/
ITU_GRA0 = MULT_VAL; /*Get first count value - const.*/
ITU_TCR0 = 0x23; /*TCNT cleared by GRA using internal/8 */
ITU_TIOR0 = 0; /*GRA used but with no inputs/output pins*/
ITU_TSR0 = 0; /*Make sure all status flags cleared*/
ITU_TIER0 |= 0X01; /*Enable Interrupt from GRA compare match*/
INTC_IPRC |= 0x0070 ; /*Set ITU priority just under DMAC*/
ITU_TSTR |= 0X01; /*Start the counter*/
}
#pragma interrupt
void dmac_end(void)
/*Function: Ensures that count of dmac variables does not reach zero*/
{
unsigned short temp = 0;
DMA_TCR0 = 0xffff; /*Reset count to start DMAC again*/
temp = DMA_CHCR0 ; /*Read register before writing to it*/
DMA_CHCR0 &= 0xfffD ; /*Clear Transfer flag bit*/
DMA_CHCR0 |= 0x0001 ; /*Set DE bit to enable DMA*/
}
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
#pragma interrupt
void flash_isr(void)
/*Function : ISR to toggle the LED at cadence determined by ad_value*/
{
unsigned short temp=0 ;
count ++ ; /*slow down ITU for visible flash*/
if (count > 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)
{
}
}
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
SH/EVB Tutori al 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 accompanyin g disk should be used for r eference wh en completing th e tutor ials. The
actual contents of the disk may vary from that published in th is documen t - in th is case the release n otes 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 n ot a supported product by Hitachi, an d
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
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
A PPENDIX A : Tutorial Disk
The supplied disk along with the tutorial n otes contains the required source, build and in clude files to complete
the tutorials. Solutions are also provided, although it is strongly recommended to first try the tutorials before
resorting to the solutions.
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)}
}
A:
PRES.
TUTS
ANSWERS
TUT1
TUT2
TUT3
TUT4
BUILD.BAT
FRAME1.C
IOSH7030.H
TUT1.LNK
VECTS.C
START.S
INLINES.S
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
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 !get data from monitor vector table
mov.l r2,@r1 !write data to new vector table
add #4,r0 !next vector from monitor
add #4,r1 !next vector to write to
cmp/gt r0,r3 !only write vectors up to external interrupts
bt nextvec !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
Hit achi Eu rop e Lt d . ISS U E : TU T/005/1.0
! 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
Hit achi Eu rop e Lt d . ISS U E : TU T/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