The XA Single Board Computer from HI-TECH Software is designed to allow a potential user of the XA microcontroller to evaluate the chip, or implement a first prototype without the time and expense of producing a custom PCB. Included on the board are:
The XA Single Board Computer is approximately 4 inches (10cm) square. On one side are two DB9 connectors for serial interfacing. Each connector is a female DB9 wired as a DCE, and thus requiring only a straight cable to plug into a standard PC 9 pin serial connector (supplied). Adjacent to the serial connectors is a coaxial DC power connector, with a 2.1mm centre pin. This is wired to a bridge rectifier, so the DC power supply polarity does not have to be specific.
Behind the serial connectors are 8 LEDs, for debugging purposes. The lower third of the board is a prototyping area with an unconnected hole matrix, and ground and power holes. Provided on the board are two 20 way connector pads for connecting parallel input and output, and access to the data bus. The XA EX0 and EX1 pins (labelled as INT0 and INT1 respectively on the board), and T0 and T1 are accessible via pads at the top of the prototyping area.
The board requires 7 to 9V DC, supplied to the coaxial DC connector. Included is a single phase diode bridge to allow either polarity from the power supply. Current drain is approximately 300mA. A 7805 regulator is provided on board, next to the power connector. This is not provided with a heatsink and should not require one unless the input voltage is higher than 9V or the current drain is significantly increased by additional components.
To set the board up, it may be useful to mount it on insulating standoffs with the four holes at the corners of the board. Plug the supplied EPROM into the ROM socket, if not already installed. Note that the socket is a 32 pin socket, but the supplied EPROM has 28 pins (27256). It should be plugged into the socket bottom-aligned, i.e. there should be four spare pins adjacent to the LEDs.
Plug the supplied straight cable (i.e. not a null-modem cable) with a DB9 male connector into the DB9 connector J2 (on the opposite side of the board from the power connector). The other end of this cable should plug into COM1 or COM2 of your PC.
Connect a plug-pack or other DC power supply, providing 7-9V at 300mA, into the DC power connector.
Turn the plug-pack on. The LEDs will sweep up and down once, and then leave at least one LED illuminated. If you do not see this, check the power supply.
The XA Single Board Computer is supplied with an EPROM containing a board diagnostics program and a r emote debugger . The board diagnostics program may be invoked by running a terminal on the host computer. The only way to communicate to the remote debugger is via Lucifer , a program which runs on the host.
The software on the EPROM communicates at 57,600 baud (no parity, 8 data bits, 1 stop bit), so when connecting the host to the board, ensure that the terminal or Lucifer is set up to this baud rate.
The board diagnostics program is accessed by running a terminal on the host computer. With the XA Single Board Computer powered up and the terminal running, hit Enter a few times. When the communications link is up, the following prompt will appear:
HI-TECH Software XA Dev. board diagnostics
cmd?
The following board diagnostics program commands are available:
If, at the end of running diagnostics, you wish to run Lucifer to talk to the remote debugger, you must first reset the board, either using the `x' command to reset via software, or by pressing the reset button.
The remote debugger is accessed by running Lucifer on the host computer. The Lucifer program (lucxa.exe and lucxant.exe) will be found on the disk provided.
Copy the files on the provided 3.5" floppy disk onto your PC. For the remainder of this document, it will be assumed you have copied them into a directory called XA. From a DOS prompt, in this directory, type the command:
substituting com2 for com1 if you have plugged the board into COM2. You should see the following
LUCIFER SOURCE LEVEL DEBUGGER (XA) V4.00
Copyright (C) 1989-1996 HI-TECH SOFTWARE
Machine = XA, target identifies as XA Lucifer Monitor (+ diagnostics) V4.2
:
You may see one or two " No resonse from target " messages first - this is quite normal. If you are using Windows NT, then use the program lucxant.exe instead of lucxa.exe . (You can rename it if you wish.) If it does not work, check your serial connection - this is the most likely cause of problems. Make sure you are using the appropriate COM port.
Exit from the debugger, by typing the command q then pressing Enter. Now run the debugger again, but supply a program name argument:
Now Lucifer will start up as before, then load the symbol file mtest.sym and download the hex file mtest.hex to the board. You will see a disassembled line of code, representing the start address of the program. Run the program by typing the g command. You will get a message and prompt, and be able to type commands to the test program. Just press Enter to see a list of commands.
To stop the program, press ctrl-C or ctrl-Break . If the test program is waiting for input at this time, you will need to press Enter after ctrl-C . You will get a " Stopped " message and the registers will be dumped.
To compile your own programs, use HPDXA as supplied with the HI-TECH C compiler for the XA. You must select Large model from the Options/Memory model and chip type dialog, and you should set the following memory addresses:
ROM vectors: 88000
Bit RAM: 20
Near RAM: 0
Extended RAM: 0
Initial stack: 7F00
NVRAM: 0
Far RAM:   0
Far NVRAM: 0
This will allow you to access nearly 32K bytes of data memory (Lucifer uses 7F00-7FFF) and 96K bytes of code memory. Note that the data memory at 0 is also mapped as code memory at 80000h, which is why the ROM address should be set at 88000h, to avoid conflict with RAM used as data memory.
Most of the XA I/O pins are used for address and data lines on the board. The remaining I/O pins are either connected to the serial ports, or brought out to labelled pads at the top right of the breadboard area. These pins allow access to the external interrupts and timer inputs.
Additional I/O is provided with 74HC373 latches, and a 74HC244 input buffer. The LEDs are driven by a latch at address E0000h (note that two of the LED bits are shared with the ADC). Writing to address E8000h will latch data into another 74HC373, while reading the same address will gate data in through a 74HC244. These input and output lines are available on J1 along with power and ground. There is no handshaking on these ports.
For further I/O expansion, J5 provides access to the data bus, 5 address lines, a select signal and read and write strobes. You can use these to address up to 32 bytes of data at address F0000h.
Once you fit the ADC, the Maxim MAX186 may be accessed using the following I/O addresses - note that the CS pin is driven directly from the XA I/O pin T1, at bit address 0x39D:
ADC Pin Address Bit
SSTRB F8000h 1
DOUT F8000h 2
SCLK E0000h 2
DIN E0000h 1
/CS T1 0x39D
Sample code for accessing the ADC is included in mtest.c on the disk supplied. Important note: the output bits used to drive the ADC (SCLK and DIN) are shared with the LED drivers - if you are using the LEDs as well, you must make sure you do not drive the LEDs while you are accessing the ADC. With T1 high, the ADC will be deselected and will ignore the state of the LED lines.
Note that T1 is pulled down by a 2.7K resistor - this forces the XA to use an 8 bit data bus. The T1 pin is also connected to the chip select (/CS) of the ADC.
If the ADC is being used, T1 may not be used for anything else. If the ADC is being used or T1 is to be an output, it must be set to push-pull mode. If the ADC is not being used and T1 is to be an input, drive it only with an active driver, which must be either tri-stated or driven low at reset time.
The EPROM size is selected using the block of 4 jumpers labelled ROM Size located to the right of the EPROM socket. See ROM Size Selection shows the jumper configuration for all possible EPROMS from 32kbyte to 512kbyte.
A15 |
|||||
A17 |
|||||
28pin |
|||||
A18 |
By setting the jumper labelled ON = /EA , all program instruction fetches will be external to the chip. This should be used for all ROMLESS chips as well as ROM chips when you do not want to use the on-board ROM.
You should open the jumper only if you are using an XA with on-board ROM which you want to utilise.
If the ADINTR jumper is set, the SSTRB pin on the Analog-to-Digital converter is connected to the XA's INT0 pin. However, because the ADC is so fast, it is unlikely that interrupt-driven code to drive the ADC will be necessary.
Lucifer is a source level remote debugger for use with the HI-TECH C compilers. It consists of a program which runs on a host machine (usually MS-DOS or UNIX) and communicates with an XA- based microcontroller system via a serial line. The host program provides the user interface, including source code display, disassembly, displaying memory etc. The target system must have logic to read and write memory and registers, and implement single stepping. With each version of Lucifer a small program is provided which can be compiled and placed in a ROM in a target system to implement these features. The standard host program is set up to communicate with this ROM program via a serial line.
To use Lucifer you will need to have the compiler generate a symbol file, with symbol name, line number and file name symbols included. This can be produced using the XAC -G option. If you use the -H option you will get a symbol file which can be used by Lucifer, but which does not contain any source code level information.
You can also use HPDXA to produce HEX and symbol files suitable for use with Lucifer. The LUCIFER directory contains luctest.prj, a sample project file which you can use as a guide to compiling your own programs with HPDXA. See the Using HPDXA chapter for more details. The basic option needed is Options/Source level debug info. Lucifer can be invoked from the Run/Download ... menu item. Otherwise once you have produced HEX and symbol files, invoke Lucifer as follows:
If you are using an MS-DOS system, COMn should be COM1 or COM2. Lucifer will access a standard serial port addressed as either port. For UNIX simply specify the name of the serial port connected to your target, for example -p/dev/tty006 .
The default baud rate is 38400 for both MS-DOS and UNIX. The default serial port is COM1 for MS-DOS and /dev/ttya for UNIX. The -s (speed) and -p (port) options may be used to access ports other than the default. For UNIX /dev may be left off the device name and will automatically added, thus -ptty0 and -p/dev/tty0 will access the same device. For example, under MS-DOS, lucxa -s9600 -pcom2 will access COM2 at 9600 baud.
New default speed and port values may be set using the environment variable LUCXA_ARGS . LUCXA_ARGS may specify any mixture of valid Lucifer ` - ' options except filename options. For example, if you want the default options to be 4800 baud on port COM2, add the following line to your AUTOEXEC.BAT file:
In addition to the speed and port options Lucifer takes two optional arguments which are, in order of appearance, the name of the symbol file to use and the name of the .hex or .bin file to download. If no download file is specified, Lucifer will automatically search for .sym , .hex and .bin files which the same base name as the symbol name given. Thus the command:
would automatically locate and use test.sym and test.hex or test.bin . If you do not want to autoload your HEX or BIN file, give your symbol file a different base name to your HEX file.
When downloading binary files, Lucifer normally prompts for the download address. When downloading directly from the command line you can override this prompting by adding the option -Baddr[:end] to the LUCXA command line. For example, if you want to download a file test.bin at address $2000, you could use the command:
The optional :end value is the address at which the download should be terminated. For example, if you want to load the first $2000 bytes of test.bin from address $4000 to address $6000, use the command:
Lucifer should announce itself, then attempt to communicate with the target. If successful it prints a message sent by the target, identifying itself, e.g:
XA Lucifer Monitor (+ diagnostics) V4.3
Lucifer will then display a prompt : and wait for commands. For a list of commands, type ? and press return. Note that all commands should be in lower case.
Where Lucifer commands take numeric values or addresses as arguments; symbol names, register names and line numbers may be used. Symbols should be entered in exactly the same case as they were defined in the source code. Note that Lucifer cannot access auto variables or parameters by name. Where an expression is required, it may be of the forms in See Lucifer expression forms .
By default, in the b (breakpoint) command any decimal number will be interpreted, as a line number. However, in the u (unassemble) command any number will be interpreted, by default, as a hex number representing an address. These assumptions can always be overridden by using the colon or dollar prefixes. When entering a symbol, it is not necessary to type the underscore prepended by the C compiler. However, when printing out symbols the debugger will always print the underscore. Any register name may also be used where a symbol is expected.
Auto variables and parameters cannot be accessed by name with Lucifer. To examine the contents of an auto variable or parameter, the best approach is to disassemble (with the u command) a line of code referencing the variable, and dump the corresponding memory location (e.g. sp+4 ).
Lucifer recognizes the commands listed in See Lucifer Command Set .
The b command is used to set and display breakpoints. If no expression is supplied after the b command, a list of all currently set breakpoints will be displayed. If an expression is supplied, a breakpoint will be set at the line or address specified. If you attempt to set a breakpoint which already exists, or enter an expression which Lucifer cannot understand, an appropriate error message will be displayed. Note: by default, any decimal number specified will be interpreted as a line number. If you want to specify an absolute address, prefix it with a dollar sign. For example:
: b 10
Set breakpoint at _main+$28
:
Breakpoints can also include a semicolon separated list of Lucifer commands, which will be executed when the breakpoint is encountered. This makes it possible to create breakpoints which stop, display a value and then restart execution. For example, the command:
creates a breakpoint which stops, displays the value of global variable pi and then continues execution.
The c command is used to display the assembler instruction and C source line addressed by the current value of the program counter. This is useful if you have been using other Lucifer commands and aren't quite sure where in the program the program counter is pointing. For example:
The d command is used to display a hex dump of the contents of memory on the target system. If no expressions are specified, 16 bytes are dumped from the address reached by the last d command. If one address is specified, 16 bytes are dumped from the address given. If two addresses are specified, the contents of memory from the first address to the second address are displayed. Dump addresses given can be symbols, line numbers, register names or absolute memory addresses.
The e command is used to examine the C source code of a function or file. If a function name is given, Lucifer will locate the source file containing the function requested and display from just above the start of the function. If a file name is given, Lucifer will display from line 1 of the requested file. For example:
: e main
2:
3:int value, result;
4:
5:main()
6:{
7: scanf("%d",&value);
8: result = (value << 1) + 6;
9: printf("result = %d\n",result);
10:}
:
The g command is used to commence execution of code on the target system. If no expression is supplied after the g command, execution will commence from the current value of PC (the program counter). If an expression is supplied, execution will commence from the address given. Execution will continue until a breakpoint is reached, or the user interrupts with control -C . After a breakpoint has been reached, execution can be continued from the same place using the g , s and t commands.
The i command is used to toggle instruction trace mode. If instruction trace mode is enabled, each instruction is displayed before it is executed while stepping by entire C lines with the s command. For example, with instruction trace disabled, step behaves like this:
: s
result = 20
Stepped to
10:}
:
With instruction trace enabled, step will instead behave like this:
: s
_memtest+30H push r4
_memtest+32H mov r0,#04A2H
_memtest+36H push r0
_memtest+38H fcall _printf
_memtest+3CH adds r7,#4
result = 20
Stepped to
10:}
:
Note that the library function printf() was not traced and thus operated properly and at full speed.
The l command is used to load object files into the target system. Lucifer correctly handles Motorola S-record format object files, Intel HEX files and binary images.
The m command is used to write one or more values or ascii strings into memory at a specified address. This command takes the form:
where addr is the address to write to and all following arguments are values or strings to write to memory. Strings may use either single or double quotes. For example:
The q command is used to exit from Lucifer to the operating system. Note: the q command does not stop the target system (that is, the Lucifer monitor running on the target system), so it is possible to re-enter Lucifer without re-initializing the target.
The r command is used to remove breakpoints which have been set with the b command. If no arguments are given the user is prompted for each breakpoint in turn. For example:
: r
Remove _main+$28 ? y
Remove _main+$44 ? n
Remove _test ? n
: r main+$44
Removed breakpoint _main+$44
:
The s command is used to step by one line of C or assembler code. For example:
: s
Stepped to
7: scanf("%d", &value);
: s
Target wants input: 7
Stepped to
8: result = (value << 1) + 6;
: s
Stepped to
9: printf("result = %d\n",result);
: s
result = 20
Stepped to
10:}
:
This is normally implemented by executing several machine instruction single steps, and therefore can be quite slow. If Lucifer can determine that there are no function calls or control structures (break, continue, etc.) in the line, it will set a temporary breakpoint on the next line and execute the line at full speed. When single stepping by machine instructions, the step command will execute subroutine calls to external and library functions at full speed. This avoids the slow process of single stepping through complex library routines like printf(). Normal library console I/O works correctly during single stepping using the s command. Where no line number information is available, such as inside library routines, the s command becomes an assembler step like the t command.
The t command is used to trace one machine instruction on the target. The current value of PC (the program counter) is used as the address of the instruction to be executed. After the instruction has been executed, the next instruction and the contents of all registers will be displayed.
The u command disassembles object code from the target system's memory. For example:
: u
9: printf("result = %d\n", result);
_memtest+30H push r4,r5
_memtest+32H mov r0,#04A2H
_memtest+36H push r0
_memtest+38H fcall _printf
_memtest+3CH adds r7,#6
If an expression is supplied, the disassembly commences from the address supplied. If an address is not supplied, the disassembly commences from the instruction where the last disassembly ended. The disassembler automatically converts addresses in the object code to symbols if the symbol table for the program being disassembled is available. If the source code for a C program being disassembled is available, the C lines corresponding to each group of instructions are also displayed. Note: by default, any values specified will be interpreted as absolute addresses. If you want to specify a line number, prefix it with a colon.
The w command is used to upload and write a chunk of target memory as a binary file. This command takes three arguments: filename, start address and length. The start address and length values are in hex. For example, if the Lucifer monitor ROM were at $7000 to $7FFF in the target system, it could be uploaded to a binary file with the command:
: w lucrom.bin 7000 1000
........
Uploaded 4096 (0x1000) bytes to lucrom.bin
:
The x command is used to examine and change the contents of the target CPU registers. If no parameters are given, the registers are displayed without change. To change the contents of a register, two parameters must be supplied, a valid register name and the new value of the register. After setting a new register value, the contents of the registers are displayed. For example:
Any valid XA register name may be used. The PSW may be accessed as PSW for the entire 16 bit value, or as PSWL and PSWH for the low and high bytes respectively.
The @ command is used to examine the contents of memory interpreted as one of the standard C types. The form of the @ command is:
where t is the type of the variable to be displayed, * consists of zero or more indirection operators (" * " or " n* "), and expr is the address of the variable to be displayed. See Lucifer @ command variants , shows the available @ command variants.
For example, to display a long variable longvar in hex:
To display a character, pointed to by a pointer cptr :
To de-reference ihandle : a pointer to a pointer to an unsigned int:
After displaying the variable, the current address is advanced by the size of the type displayed. This, makes it possible to step through arrays by repeatedly pressing return. On-line help for the @ command may be obtained by entering ?@ at the " : " prompt.
The . command is used to set a temporary breakpoint and resume execution from the current value of PC (the program counter). Execution continues until any breakpoint is reached or the user interrupts with control -C , then the temporary breakpoint is removed. Note: the temporary breakpoint is removed even if execution stops at a different breakpoint or is interrupted. If no breakpoint address is specified, the . command will display a list of active breakpoints.
: . 10
Target wants input: 7
result = 20
Breakpoint
10:}
main+$28 RET
:
The ; command is used to display 10 lines of source code from a specified position in a source file. If the line number is omitted, the last page of source code displayed will be re-displayed. For example:
: ; 4
4:
5: main()
6: {
7: scanf("%d",&value);
8: result = (value << 1) + 6;
9: printf("result = %d\n",result);
10:}
The = command is used to display the next 10 lines of source code from the current file. For example, if the last source line displayed was line 7, = will display 10 lines starting from line 8.
The - command is used to display the previous 10 lines of source code from the current file. For example, if the last page displayed started at line 15, - will display 10 lines starting from line 5.
The / command is used to search the current source file for occurrences of a sequence of characters. Any text typed after the / is used to search the source file. The first source line containing the string specified is displayed. If no text is typed after the / , the previous search string will be used. Each string search starts from the point where the previous one finished, allowing the user to step through a source file finding all occurrences of a string.
: /printf
10: printf("Enter a number:");
: /
14: printf("Result = %d\n",answer);
: /
Can't find printf
:
The ! command is used to execute an operating system shell command line without exiting from Lucifer. Any text typed after the ! is passed through to the shell without modification.
In addition to the commands listed above, Lucifer will interpret any valid decimal number typed as a source line number and attempt to display the C source code for that line.
Pressing return without entering a command will result in re-execution of the previous command. In most cases the command resumes where the previous one left off. For example, if the previous command was d 2000 , pressing return will have the same effect as the command d 2010 .
If return is pressed after a breakpoint or . command has executed, it is equivalent to disassembling from the breakpoint address.
The standard versions of the console I/O routines putch(), getch(), getche() and init_uart() are configured to work automatically with LUCIFER. Code which is downloaded under LUCIFER may use the standard I/O routines like printf() without any library modifications. Once you have finished debugging your code, you will need to insert into the library console, I/O routines suitable for your hardware. You can use the file sources/getch.c as a starting point.
In order to use Lucifer on your target system, you will need to compile the Lucifer monitor and place it in a ROM. If your XA system already has a monitor in ROM, it is also possible to download the Lucifer target code into RAM. In most cases you will be able to use the Lucifer monitor program supplied without much modification.
Normally the only changes required will be the baud rate initialization in init_uart(). This requires modification for different baud rates or different clock frequencies. There are self-explanatory comments, in the code, at that point.
If you do not wish to use one of the XA internal serial ports you will need to modify the target code to access a different serial port.
Most modifications to target.c will be made to the serial I/O functions, putch(), getch() and init_uart(). For Lucifer to work correctly, you will need to have a system with common code and external RAM space as it is not possible to write to code memory on the XA. This can be achieved by mapping 32K of ROM from 0000h to 7FFFh and 32K of static RAM from 8000h to FFFFh and using PSEN and RD NOR'ed together for chip select.
Since the XA has separate, overlapping address spaces for code and data, special memory mapping is required to allow code to be downloaded and executed. It is important to map RAM into the first 64K of the data space, since the stack pointer in system mode is only 16 bits. Therefore a suggested arrangement is as follows. A ROM (size not important) is mapped into code space at 0. This will hold the Lucifer target program. A RAM of adequate size (say 128K bytes for example purposes) is mapped into data space at two locations; at 0, and at a higher address, say 80000h. It is also mapped into code space at the higher address, i.e. at 80000h it appears as both code and data.
This now allows Lucifer to download code into the ROM at the high address, and execute it from there. A portion of the RAM is reserved for data. The target code as supplied reserves 32K bytes of RAM for data, so user programs are downloaded at 88000h. The monitor program uses RAM from 7F00h to 7FFFh, so RAM from 20h (above the registers) to 7EFFh is available for the user program. With this arrangement, you would compile the Lucifer target program with the following addresses:
ROM address 0 RAM address 7F00 RAM size 100
and when compiling your application program you will compile with these addresses:
ROM address 88000 RAM address 20 RAM size 7EE0
Target.c reflects all unused interrupt vectors to the start of the user program area (88000 in the example above). This address is selected by the macro RAMBASE in target.c . All interrupts will be reflected to RAMBASE +vector, for example interrupt vector 84h will be reflected to 88084h. This means you do not have to change your program whether it is compiled to run under Lucifer or stand-alone in ROM, since the vector addresses are interpreted as being relative to the ROM start address.
Pin connections for the various connectors on the XA Single Board Computer are shown in the diagram below.
Table 3 - 1
|
Table 3 - 2
|
| J2 (Serial 0) & J3 (Serial 1) | |
|---|---|
| Pin | Signal |
| 1 | NC |
| 2 | Transmit data |
| 3 | Receive data |
| 4 | NC |
| 5 | GND |
| 6 | NC |
| 7 | NC |
| 8 | NC |
| 9 | NC |
The circuit diagram of the XA Single Board Computer is included in the centre of this manual.
The memory map of the XA Single Board Computer is shown below. Note that the RAM that appears at 0 in data space is duplicated at 80000 in data and code space. The I/O devices in the space above E0000 are not fully decoded; e.g. accessing any address in the range E0000-E7FFF will access the LED latch.