The last two bytes in the listing are the reset vector, hence $E000 is the entry point to Buffalo. Next, use the ASM command to examine machine code at the actual entry point.>md fff0 ffff FFF0 00 EB 00 EE 00 F1 00 F4 00 F7 00 FA 00 FD E0 00
The value $100A is the address of the port E data register. Port E is an input only port, the BRCL instrution reads from port E and applys the mask $01. If pin E0 is logic low, Buffalo jumps to $E00A to continue its initialization. Said another way, following reset if pin E0 is logic high, a jump is made to $B600, thus starting the program in EEPROM.>asm E000 E000 LDX #$100A > E003 BRCL $00,X $01 $E00A > E007 JMP $B600 >
It is important to note that in transferring control to the program in EEPROM, almost nothing is initialized. The stack pointer, serial communications port, and pseudovector table are not initialized. None of Buffalo's data structures are initialized. Consider that your program is only three assembly language instructions away from the actual system reset. With this in mind, your program is responsible for initializing 'things.'
So, consider "What things need to be initialized?" and "How do the things become initialized?" We must first consider the system configuration settings. System configuration registers like BPROT have default values assigned at reset, for most cases the default values are acceptable. However to change the values, a write must be performed within 64 clock cycles, following system reset. In the case of BPROT, the default value is acceptable if the application is not going to program EEPROM or otherwise reconfigure the system.
Initialize the stack by assigning a valid address to the S register. After the stack, the Buffalo trace command has a special consideration. Our boards have a jumper that when in the TRACE position allows buffalo to regain control by forcing an interrupt. However, such an interrupt is not normally needed. The following clears the corresponding negative logic interrupt request.
* Just a hany equate TCTL1: EQU $1020 * Code to clear interrupt request LDAA TCTL1 ORAA #$03 STAA TCTL1
Next, perform any additional initialization that your program requires. If you plan to use the serial port, be sure to initialize the UART device. An example is presented below.
During the download operation, Buffalo examines on a byte-by-byte basis whether or not the corresponding write will be to RAM or EEPROM and decides whether or not an erasure is first required. Since the EEPROM erasure and programming steps each require 10msec, a slow Baud rate must be used. To transfer each byte, the serial communications format calls for the addition of one start bit, one stop bit, but no parity bit, yielding 10 bits. Thus to satisfy the above conditions, a rate less than 500 Baud must be used. Assuming an 8MHz crystal, the most convenient rate is 300 Baud. Use the MM command to change the Baud rate;
>MM 102B 102B 30 35
The cursor will appear frozen as it will not move to the next line and a new prompt will not appear. Change the terminal program Baud rate to 300 to match Buffalo. If you are using Tera-term, select:
In the pop-up window set the value in the Baud rate field to 300 and click 'OK'. Pressing the enter key should cause the prompt to reappear. If the MM command repeats, just press the enter key a second time. With Buffalo and the terminal emulator program communicating at this slow Baud rate, simply use the LOAD command as you did before. Enter the command;Setup => Serial port...
Below the title bar for Tera-Term, select:>LOAD T
In the pop-up window select the file to send and click OK. As a spot-check to convince yourself, you can use the md command to examine the first few bytes of EEPROM. Remember that the Buffalo system reset causes the Baud rate to revert to 9600. If you press the reset button, be sure to adjust Tera-Term to the same rate as Buffalo.File => Send File
For practice, save the following program in a file named blink2.asm and assemble it, producing an .S19 file and a list file. Use the technique described above to download the program into EEPROM. To run the program, attach a wire from PE0 (pin 23) to +5V (pin 2 or pin 49) and then either recycle the power or press the reset button.
* blink2.asm - a simple embedded application * The 68HC11E9 has 512 bytes EEPROM starting at $B600 CODESEG: EQU $B600 N1: EQU $64 N2: EQU $09C4 PORTA: EQU $1000 TCTL1: EQU $1020 TOS: EQU $41 ORG CODESEG Start: lds #TOS ; Initialize the stack ldaa TCTL1 ; Get timer register value oraa #$03 ; set bits to force timer output staa TCTL1 ; to remove interrupt and update Main: ldaa #$10 ; Load the mask value and staa PORTA ; assign to the output Top: jsr Delay ; wait some ldaa PORTA ; Load the current output eora #$10 ; use the mask to toggle bit/bits staa PORTA ; and update the output bra Top ; Go back *========================== * Simple delay subroutine *========================== Delay: psha pshx * Repeat the outer loop N1 times LDAA #N1 ; 2 cycles * Inner delay loop - ten milliseconds L1: LDX #N2 ; 3 cycles L2: NOP ; 2 cycles DEX ; 3 cycles BNE L2 ; 3 cycles * Rest of the outer loop DECA ; 2 cycles BNE L1 ; 3 cycles * Done for now - restore and return pulx pula rts
This example program make use of a number of topics discussed earlier. The initialization code is discussed earlier in this part of the tutorial. An LED attached to port A is toggled, using a technique discussed earlier. The delay subroutine causes a one second update behavior.
* blink3.asm - an embedded application from blink2.asm * The 68HC11E9 has 512 bytes EEPROM starting at $B600 CODESEG: EQU $B600 N1: EQU $64 N2: EQU $09C4 PORTA: EQU $1000 TCTL1: EQU $1020 IODEV: EQU $00A5 TOS: EQU $41 INIT: EQU $FFA9 OUT1BY: EQU $FFBB OUTCRL: EQU $FFC4 VECINIT: EQU $FFD0 ORG $100 Count: RMB 1 TmpByte: RMB 1 *========================================= * Initial Code - This can start up 'cold' *========================================= ORG CODESEG Start: lds #TOS ; Initialize the stack ldaa TCTL1 ; Get timer register value oraa #$03 ; set bits to force timer output staa TCTL1 ; to remove interrupt and update clr IODEV ; Clear to indicate SCI I/O device jsr INIT ; Initialize the SCI serial I/O Main: ldaa #$10 ; Load the mask value and staa PORTA ; assign to the output clr Count ; Clear the Count *================== * The central loop *================== Top: jsr Delay ; wait some ldaa PORTA ; Load the current output eora #$10 ; use the mask to toggle bit/bits staa PORTA ; and update the output ldaa Count ; Get the count inc Count ; Increment the stored value staa TmpByte ; Save previous value in temp. place jsr OUTCRL ; Move cursor to next line ldx #TmpByte ; load address into X jsr OUT1BY ; and report the value bra Top ; Go back *========================== * Simple delay subroutine *========================== Delay: psha pshx * Repeat the outer loop N1 times LDAA #N1 ; 2 cycles * Inner delay loop - ten milliseconds L1: LDX #N2 ; 3 cycles L2: NOP ; 2 cycles DEX ; 3 cycles BNE L2 ; 3 cycles * Rest of the outer loop DECA ; 2 cycles BNE L1 ; 3 cycles * Done for now - restore and return pulx pula rts
In this new example each time the LED toggles, Buffalo utilities are called to output the byte-sized count value in hexadecimal. Don't forget that in initializing the serial port, INIT changes the Baud rate back to 9600.
This tutorial page was written for EE332, the Introduction to Microprocessors
course offered by the Electrical Engineering Department in the College of
Engineering at the University of Hartford.
Copyright is dated October 18, 2001 and is reserved by the author,
Jonathan Hill.
Permission is granted to make copies of this document for educational use
as-is, provided that this statement remains attached.
I do strive to improve this document, so please forward constructive
criticism and suggestions.
Credits will be added as improvements are made.
Original Author: Jonathan Hill (jmhill@mail.hartford.edu)
Last Modified: Fri Dec 13 17:05:34 EST 2002