mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-28 07:02:55 +08:00
1836 lines
106 KiB
Plaintext
1836 lines
106 KiB
Plaintext
; KCPSM3 Program - Communication with DS2432 secure memory on the Spartan-3E Starter Kit.
|
|
;
|
|
; Ken Chapman - Xilinx Ltd
|
|
;
|
|
; Version v1.00 - 5th April 2006
|
|
;
|
|
; This program uses a 9600 baud UART connection to allow communication with the
|
|
; 1-wire interface of the DS2432 memory device from Dallas Semiconductor.
|
|
;
|
|
; The program only supports a limited number of the DS2432 commands but is intended
|
|
; to guide you through the state machine of the device as well as show how
|
|
; 1-wire communication is achieved. The DS2432 also uses 8 and 16 bits CRC checks and
|
|
; this program includes these calculations to validate the communications.
|
|
;
|
|
; Commands supported include read ROM, write scratchpad memory and read scratchpad
|
|
; memory. These allow you to confirm the ability to both read and write data but
|
|
; at no time modify the actual EEPROM secure memory or secret.
|
|
;
|
|
; There are then two manual commands which allow you to write any byte value that
|
|
; you enter and to read a byte from the DS2432 device. At this point you are free
|
|
; to experiment and this may result in the device contents being altered. You also
|
|
; become responsible for tracking the states but remember that a master reset will
|
|
; always return you to a known starting point again.
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Port definitions
|
|
;**************************************************************************************
|
|
;
|
|
;
|
|
CONSTANT status_port, 00 ;UART status input
|
|
CONSTANT tx_half_full, 01 ; Transmitter half full - bit0
|
|
CONSTANT tx_full, 02 ; FIFO full - bit1
|
|
CONSTANT rx_data_present, 04 ; Receiver data present - bit2
|
|
CONSTANT rx_half_full, 08 ; FIFO half full - bit3
|
|
CONSTANT rx_full, 10 ; full - bit4
|
|
CONSTANT spare1, 20 ; spare '0' - bit5
|
|
CONSTANT spare2, 40 ; spare '0' - bit6
|
|
CONSTANT spare3, 80 ; spare '0' - bit7
|
|
;
|
|
CONSTANT UART_read_port, 01 ;UART Rx data input
|
|
;
|
|
CONSTANT UART_write_port, 04 ;UART Tx data output
|
|
;
|
|
;
|
|
CONSTANT DS_wire_in_port, 02 ;Read signal from DS2432 device
|
|
CONSTANT DS_wire_out_port, 08 ;Drive signal to DS2432 device (open collector)
|
|
CONSTANT DS_wire, 01 ; Signal is bit0 in both cases
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Special Register usage
|
|
;**************************************************************************************
|
|
;
|
|
NAMEREG sF, UART_data ;used to pass data to and from the UART
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Scratch Pad Memory Locations
|
|
;**************************************************************************************
|
|
;
|
|
; Scratch pad memory provides 64 bytes in the address range 00 to 3F hex.
|
|
;
|
|
;
|
|
; Locations for device family code, serial number and 8-bit CRC value
|
|
;
|
|
CONSTANT family_code, 00
|
|
CONSTANT serial_number0, 01 ;48-bit serial number LS-Byte first
|
|
CONSTANT serial_number1, 02
|
|
CONSTANT serial_number2, 03
|
|
CONSTANT serial_number3, 04
|
|
CONSTANT serial_number4, 05
|
|
CONSTANT serial_number5, 06
|
|
CONSTANT read_ROM_CRC, 07 ;8-bit CRC
|
|
;
|
|
;
|
|
; Locations to store all bytes in a command communication for 16-bit CRC calculation
|
|
;
|
|
CONSTANT command_start, 08
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Useful data constants
|
|
;**************************************************************************************
|
|
;
|
|
; Constant to define a software delay of 1us. This must be adjusted to reflect the
|
|
; clock applied to KCPSM3. Every instruction executes in 2 clock cycles making the
|
|
; calculation highly predictable. The '6' in the following equation even allows for
|
|
; 'CALL delay_1us' instruction in the initiating code.
|
|
;
|
|
; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
|
|
;
|
|
; Example: For a 50MHz clock the constant value is (10-6)/4 = 11 (0B Hex).
|
|
; For clock rates below 10MHz the value of 1 must be used and the operation will
|
|
; become lower than intended.
|
|
;
|
|
CONSTANT delay_1us_constant, 0B
|
|
;
|
|
;
|
|
;
|
|
;ASCII table
|
|
;
|
|
CONSTANT character_a, 61
|
|
CONSTANT character_b, 62
|
|
CONSTANT character_c, 63
|
|
CONSTANT character_d, 64
|
|
CONSTANT character_e, 65
|
|
CONSTANT character_f, 66
|
|
CONSTANT character_g, 67
|
|
CONSTANT character_h, 68
|
|
CONSTANT character_i, 69
|
|
CONSTANT character_j, 6A
|
|
CONSTANT character_k, 6B
|
|
CONSTANT character_l, 6C
|
|
CONSTANT character_m, 6D
|
|
CONSTANT character_n, 6E
|
|
CONSTANT character_o, 6F
|
|
CONSTANT character_p, 70
|
|
CONSTANT character_q, 71
|
|
CONSTANT character_r, 72
|
|
CONSTANT character_s, 73
|
|
CONSTANT character_t, 74
|
|
CONSTANT character_u, 75
|
|
CONSTANT character_v, 76
|
|
CONSTANT character_w, 77
|
|
CONSTANT character_x, 78
|
|
CONSTANT character_y, 79
|
|
CONSTANT character_z, 7A
|
|
CONSTANT character_A, 41
|
|
CONSTANT character_B, 42
|
|
CONSTANT character_C, 43
|
|
CONSTANT character_D, 44
|
|
CONSTANT character_E, 45
|
|
CONSTANT character_F, 46
|
|
CONSTANT character_G, 47
|
|
CONSTANT character_H, 48
|
|
CONSTANT character_I, 49
|
|
CONSTANT character_J, 4A
|
|
CONSTANT character_K, 4B
|
|
CONSTANT character_L, 4C
|
|
CONSTANT character_M, 4D
|
|
CONSTANT character_N, 4E
|
|
CONSTANT character_O, 4F
|
|
CONSTANT character_P, 50
|
|
CONSTANT character_Q, 51
|
|
CONSTANT character_R, 52
|
|
CONSTANT character_S, 53
|
|
CONSTANT character_T, 54
|
|
CONSTANT character_U, 55
|
|
CONSTANT character_V, 56
|
|
CONSTANT character_W, 57
|
|
CONSTANT character_X, 58
|
|
CONSTANT character_Y, 59
|
|
CONSTANT character_Z, 5A
|
|
CONSTANT character_0, 30
|
|
CONSTANT character_1, 31
|
|
CONSTANT character_2, 32
|
|
CONSTANT character_3, 33
|
|
CONSTANT character_4, 34
|
|
CONSTANT character_5, 35
|
|
CONSTANT character_6, 36
|
|
CONSTANT character_7, 37
|
|
CONSTANT character_8, 38
|
|
CONSTANT character_9, 39
|
|
CONSTANT character_colon, 3A
|
|
CONSTANT character_fullstop, 2E
|
|
CONSTANT character_semi_colon, 3B
|
|
CONSTANT character_minus, 2D
|
|
CONSTANT character_plus, 2B
|
|
CONSTANT character_comma, 2C
|
|
CONSTANT character_less_than, 3C ;'<'
|
|
CONSTANT character_greater_than, 3E ;'>'
|
|
CONSTANT character_open, 28 ;'('
|
|
CONSTANT character_close, 29 ;')'
|
|
CONSTANT character_divide, 2F ;'/'
|
|
CONSTANT character_equals, 3D
|
|
CONSTANT character_space, 20
|
|
CONSTANT character_CR, 0D ;carriage return
|
|
CONSTANT character_LF, 0A ;line feed
|
|
CONSTANT character_question, 3F ;'?'
|
|
CONSTANT character_dollar, 24
|
|
CONSTANT character_exclaim, 21 ;'!'
|
|
CONSTANT character_BS, 08 ;Back Space command character
|
|
CONSTANT character_XON, 11 ;Flow control ON
|
|
CONSTANT character_XOFF, 13 ;Flow control OFF
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Initialise the system and welcome message
|
|
;**************************************************************************************
|
|
;
|
|
cold_start: CALL DS_wire_init ;Ensure DS_wire is not driven (pulled High)
|
|
CALL delay_1s ;Allow everything to settle!
|
|
welcome_start: CALL send_welcome ;start up message and version number
|
|
;
|
|
;
|
|
;
|
|
; The main program guides the user to follow the command state machine of the
|
|
; DS2432 device by only offering those choices that are valid at each stage.
|
|
; This program only offers a limited choice and it is left as an exercise to
|
|
; the user to modify or expand this choice as required.
|
|
;
|
|
;**************************************************************************************
|
|
; Reset Main menu and command selection
|
|
;**************************************************************************************
|
|
;
|
|
; Initially the only action available is a master reset and test for a presence
|
|
; pulse response from the DS2432.
|
|
;
|
|
reset_menu: CALL send_reset_menu ;Menu and command selection
|
|
CALL send_CR
|
|
;
|
|
reset_prompt: CALL menu_prompt ;prompt for user input
|
|
COMPARE s0, character_H ;test for commands and execute as required
|
|
JUMP Z, reset_menu
|
|
COMPARE s0, character_1
|
|
JUMP Z, master_reset_regular
|
|
CALL no_valid_input
|
|
JUMP reset_prompt ;Try again!
|
|
;
|
|
; The master reset should result in a presence pulse.
|
|
; This will be reported and control passed to the appropriate
|
|
; menu in the sequence.
|
|
;
|
|
master_reset_regular: CALL send_CR
|
|
CALL DS_init_regular_mode
|
|
JUMP NC, reset_passed ;test for presence pulse
|
|
CALL send_Fail
|
|
JUMP reset_menu ;fail stays in reset menu
|
|
reset_passed: CALL send_Pass ;pass progresses to ROM menu
|
|
JUMP ROM_menu
|
|
;
|
|
; After a valid master reset, the only commands available are the ROM
|
|
; commands of which only Read ROM and Skip ROM are currently supported.
|
|
; Another master reset can be issued is so desired.
|
|
;
|
|
ROM_menu: CALL send_ROM_menu ;Menu and command selection
|
|
CALL send_CR
|
|
;
|
|
ROM_prompt: CALL menu_prompt ;prompt for user input
|
|
COMPARE s0, character_H ;test for commands and execute as required
|
|
JUMP Z, ROM_menu
|
|
COMPARE s0, character_1
|
|
JUMP Z, master_reset_regular ;repeat reset as before
|
|
COMPARE s0, character_2
|
|
JUMP Z, read_ROM_command
|
|
COMPARE s0, character_3
|
|
JUMP Z, skip_ROM_command
|
|
CALL no_valid_input
|
|
JUMP ROM_prompt ;Try again!
|
|
;
|
|
;
|
|
;
|
|
; After a valid ROM command the DS2432 specific memory commands and SHA-1
|
|
; functions become accessible. Each of these end with the DS2432 returned
|
|
; back to the waiting for ROM command state completing the menu sequence.
|
|
;
|
|
DS2432_menu: CALL send_DS2432_menu ;Menu and command selection
|
|
CALL send_CR
|
|
;
|
|
DS2432_prompt: CALL menu_prompt ;prompt for user input
|
|
COMPARE s0, character_H ;test for commands and execute as required
|
|
JUMP Z, DS2432_menu
|
|
COMPARE s0, character_1
|
|
JUMP Z, master_reset_regular ;repeat reset as before
|
|
COMPARE s0, character_2
|
|
JUMP Z, read_memory_command
|
|
COMPARE s0, character_3
|
|
JUMP Z, write_scratchpad_command
|
|
COMPARE s0, character_4
|
|
JUMP Z, read_scratchpad_command
|
|
COMPARE s0, character_5
|
|
JUMP Z, write_byte_command
|
|
COMPARE s0, character_6
|
|
JUMP Z, read_byte_command
|
|
CALL no_valid_input
|
|
JUMP DS2432_prompt ;Try again!
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Prompt and selection tasks used in menus.
|
|
;**************************************************************************************
|
|
;
|
|
; Prompts for input with > character and waits for key stroke which is
|
|
; returned in upper case in register s0
|
|
;
|
|
menu_prompt: CALL send_CR
|
|
CALL send_CR
|
|
LOAD UART_data, character_greater_than ;prompt for input
|
|
CALL send_to_UART
|
|
CALL read_upper_case
|
|
RETURN
|
|
;
|
|
no_valid_input: CALL send_CR ;no valid command input
|
|
LOAD UART_data, character_question ;display ???
|
|
CALL send_to_UART
|
|
CALL send_to_UART
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; DS2432 Read ROM Command.
|
|
;**************************************************************************************
|
|
;
|
|
; The read ROM command (33 hex) allows the 8-bit family code, 48-bit unique serial
|
|
; number and 8-bit CRC to be read from the DS2432 device.
|
|
;
|
|
; This routine reads the values and places them in KCPSM3 scratch pad memory
|
|
; locations for future reference. These locations should be defined with constants
|
|
; as follows and MUST be in consecutive ascending locations.
|
|
;
|
|
; family_code
|
|
; Location to store family code which should be 33 hex
|
|
; serial_number0 to serial_number5
|
|
; 6 bytes to hold 48-bit serial number (LS-byte first).
|
|
; read_ROM_CRC
|
|
; 8-bit CRC value for the above data.
|
|
;
|
|
;
|
|
; The routine also displays the values read and performs a verification of the
|
|
; 8-bit CRC displaying a 'pass' or 'fail' message as appropriate.
|
|
;
|
|
read_ROM_command: LOAD s3, 33 ;Read ROM Command
|
|
CALL write_byte_slow ;transmit command
|
|
LOAD s5, family_code ;memory pointer
|
|
read_ROM_loop: CALL read_byte_slow ;read response into s3
|
|
STORE s3, (s5) ;store value
|
|
COMPARE s5, read_ROM_CRC ;8-bytes to read
|
|
JUMP Z, display_ROM
|
|
ADD s5, 01
|
|
JUMP read_ROM_loop
|
|
display_ROM: CALL send_CR
|
|
CALL send_code ;'code=' to display family code
|
|
FETCH s0, family_code
|
|
CALL send_hex_byte
|
|
CALL send_CR
|
|
CALL send_serial ;'serial=' to display family code
|
|
LOAD s5, serial_number5 ;memory pointer starting MS-byte first
|
|
disp_serial_loop: FETCH s0, (s5)
|
|
CALL send_hex_byte
|
|
COMPARE s5, serial_number0
|
|
JUMP Z, end_serial
|
|
SUB s5, 01
|
|
JUMP disp_serial_loop
|
|
end_serial: CALL send_CR
|
|
CALL send_CRC ;'CRC=' to display CRC value
|
|
FETCH s0, read_ROM_CRC
|
|
CALL send_hex_byte
|
|
CALL send_CR
|
|
CALL compute_CRC8 ;compute CRC value in s0
|
|
FETCH s1, read_ROM_CRC ;compare with received value
|
|
COMPARE s0, s1
|
|
JUMP NZ, crc8_fail
|
|
CALL send_Pass
|
|
JUMP DS2432_menu ;now in memory and SHA-1 functions level
|
|
crc8_fail: CALL send_Fail
|
|
JUMP ROM_menu ;can not proceed to next level
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; DS2432 Skip ROM Command.
|
|
;**************************************************************************************
|
|
;
|
|
; The skip ROM command (CC hex) is a short cut to the memory commands and SHA-1
|
|
; functions which means that the 64 bit ROM contents do not have to be read.
|
|
;
|
|
;
|
|
skip_ROM_command: LOAD s3, CC ;Skip ROM Command
|
|
CALL write_byte_slow ;transmit command
|
|
CALL send_OK
|
|
JUMP DS2432_menu
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; DS2432 Read Memory Command.
|
|
;**************************************************************************************
|
|
;
|
|
; The read memory command (F0 hex) allows the entire memory contents to be read
|
|
; except for the secret. This routine displays the address followed by 8 bytes
|
|
; of data on each line until the address 0097 is reached.
|
|
;
|
|
; The initial 'F0' command must be followed by the 16-bit start address transmitted
|
|
; LS-byte first. Then reads must continue until address 0097 has been read for the
|
|
; command to complete naturally (otherwise a master reset is required).
|
|
;
|
|
;
|
|
;
|
|
read_memory_command: LOAD s3, F0 ;read memory Command
|
|
CALL write_byte_slow ;transmit command
|
|
LOAD s5, 00 ;initial address in [s5,s4]=0000
|
|
LOAD s4, 00
|
|
LOAD s3, s4 ;transmit address
|
|
CALL write_byte_slow
|
|
LOAD s3, s5
|
|
CALL write_byte_slow
|
|
rmc_line_loop: CALL send_CR
|
|
LOAD s0, s5 ;display 16-bit address
|
|
CALL send_hex_byte
|
|
LOAD s0, s4
|
|
CALL send_hex_byte
|
|
CALL send_space
|
|
CALL send_space
|
|
rmc_data_loop: CALL send_space
|
|
CALL read_byte_slow ;read data into s3
|
|
LOAD s0, s3 ;display byte
|
|
CALL send_hex_byte
|
|
ADD s4, 01 ;increment address
|
|
ADDCY s5, 00
|
|
TEST s4, 07 ;test for 8-byte boundary
|
|
JUMP NZ, rmc_data_loop
|
|
COMPARE s4, 98 ;test for last address
|
|
JUMP NZ, rmc_line_loop
|
|
CALL send_OK
|
|
JUMP reset_menu ;needs master reset next
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; DS2432 Write Scratchpad Memory Command.
|
|
;**************************************************************************************
|
|
;
|
|
; The write scratchpad memory command (0F hex) allows 8-bytes of data to be written
|
|
; together with a target address for final storage in the main memory map.
|
|
;
|
|
; The DS2432 provides an initial confirmation of the write by returning a 16-bit CRC
|
|
; value which KCPSM3 tests. The CRC is computed based on the command, address and
|
|
; data transmitted (11 bytes). To achieve this, all bytes transmitted to the DS2432
|
|
; are recorded in KCPSM3 scratch pad memory in ascending locations starting at
|
|
; the location defined by constant 'command_start'.
|
|
;
|
|
; This routine prompts the user to enter the 16-bit target address is to be loaded
|
|
; into the target address registers TA2 and TA1 in the DS2432 device. Note that only
|
|
; address values below 0090 hex are valid. If the address is too high, then the
|
|
; DS2432 aborts the command and this routine will too.
|
|
;
|
|
; Also note that the address will be forced internally to the DS2432 to match an
|
|
; 8-byte boundary address in which the least significant 3-bits are reset to '000'
|
|
; regardless of the address provided. The CRC still reflects the transmitted address.
|
|
;
|
|
; After providing a valid address, the routine then prompts the user to enter
|
|
; 8 bytes of data which are written to the DS2432.
|
|
;
|
|
;
|
|
;
|
|
write_scratchpad_command: LOAD sE, command_start ;pointer to memory
|
|
LOAD s3, 0F ;write scratchpad memory Command
|
|
STORE s3, (sE) ;record command sequence
|
|
ADD sE, 01 ;increment pointer
|
|
CALL write_byte_slow ;transmit command
|
|
wsc_addr_loop: CALL send_address ;obtain 16-bit address 0000 to FFFF in [s5,s4]
|
|
CALL obtain_8bits
|
|
JUMP C, wsc_addr_loop ;bad input address
|
|
LOAD s5, s0
|
|
CALL obtain_8bits
|
|
JUMP C, wsc_addr_loop ;bad input address
|
|
LOAD s4, s0
|
|
LOAD s3, s4 ;transmit target address TA1 (LS-Byte)
|
|
STORE s3, (sE) ;record command sequence
|
|
ADD sE, 01 ;increment pointer
|
|
CALL write_byte_slow
|
|
LOAD s3, s5 ;transmit target address TA2 (MS-Byte)
|
|
STORE s3, (sE) ;record command sequence
|
|
ADD sE, 01 ;increment pointer
|
|
CALL write_byte_slow
|
|
COMPARE s5, 00 ;check address less than 0090 hex
|
|
JUMP NZ, end_write_scratchpad ;DS2432 aborts command and so
|
|
COMPARE s4, 90 ;no need to read data bytes.
|
|
JUMP NC, end_write_scratchpad
|
|
LOAD s4, 00 ;initialise byte counter
|
|
wsc_data_loop: CALL send_data ;obtain a byte of data
|
|
LOAD UART_data, s4 ;display which byte requested
|
|
ADD UART_data, character_0 ;convert to ASCII
|
|
CALL send_to_UART
|
|
CALL send_equals
|
|
CALL obtain_8bits
|
|
JUMP C, wsc_data_loop ;bad input data
|
|
LOAD s3, s0 ;transmit byte
|
|
STORE s3, (sE) ;record command sequence
|
|
ADD sE, 01 ;increment pointer
|
|
CALL write_byte_slow
|
|
ADD s4, 01 ;count bytes
|
|
COMPARE s4, 08
|
|
JUMP NZ, wsc_data_loop
|
|
CALL read_byte_slow ;read back the 16-bit CRC into [s5,s4]
|
|
LOAD s4, s3
|
|
CALL read_byte_slow
|
|
LOAD s5, s3
|
|
STORE s4, (sE) ;record command sequence
|
|
ADD sE, 01 ;increment pointer
|
|
STORE s5, (sE) ;record command sequence
|
|
CALL send_CR
|
|
CALL send_CRC ;'CRC=' to display CRC value
|
|
LOAD s0, s5
|
|
CALL send_hex_byte
|
|
LOAD s0, s4
|
|
CALL send_hex_byte
|
|
CALL send_CR
|
|
LOAD s2, 0B ;11 (0B hex) bytes transmitted in this command
|
|
CALL compute_CRC16 ;compute CRC value in [s1,s0]
|
|
FETCH s5, (sE) ;compare with received value
|
|
SUB sE, 01
|
|
FETCH s4, (sE) ;compare with received value
|
|
COMPARE s5, s1
|
|
JUMP NZ, wsc_crc16_fail
|
|
COMPARE s4, s0
|
|
JUMP NZ, wsc_crc16_fail
|
|
CALL send_Pass
|
|
JUMP reset_menu ;needs master reset next
|
|
wsc_crc16_fail: CALL send_Fail
|
|
end_write_scratchpad: JUMP reset_menu ;needs master reset next
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Write Byte Command.
|
|
;**************************************************************************************
|
|
;
|
|
; This routine simply allows you to specify any byte and write it to the DS2432 device.
|
|
; Apart from checking that the value is in the range 00 to FF hex, there is no checking
|
|
; of the meaning of the value to the DS2432 device and all attempts to track the
|
|
; state machine will be lost.
|
|
;
|
|
;
|
|
write_byte_command: CALL send_CR
|
|
CALL send_Byte ;obtain a byte of data
|
|
CALL send_equals
|
|
CALL obtain_8bits
|
|
JUMP C, write_byte_command ;bad input data
|
|
LOAD s3, s0 ;transmit byte
|
|
CALL write_byte_slow ;transmit byte
|
|
CALL send_OK
|
|
JUMP DS2432_menu ;remain in memory and function menu
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Read Byte Command.
|
|
;**************************************************************************************
|
|
;
|
|
; This routine will attempt to read a single byte from the DS2432 device.
|
|
; The results will be displayed on the terminal. There is no checking of the meaning
|
|
; of the value received from the DS2432 device and all attempts to track the
|
|
; state machine will be lost.
|
|
;
|
|
;
|
|
read_byte_command: CALL send_CR
|
|
CALL send_Byte ;obtain a byte of data
|
|
CALL send_equals
|
|
CALL read_byte_slow ;receive byte
|
|
LOAD s0, s3 ;display value
|
|
CALL send_hex_byte
|
|
CALL send_OK
|
|
JUMP DS2432_menu ;remain in memory and function menu
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; DS2432 Read Scratchpad Memory Command.
|
|
;**************************************************************************************
|
|
;
|
|
; The read scratchpad memory command (AA hex) allows the 8-bytes of data previously
|
|
; to be written into the scratchpad memory to be read back for verification together with
|
|
; the target address, a transfer status register and a 16-bit CRC value.
|
|
;
|
|
; The 16-bit CRC is formed of the command byte, address TA1 and TA2, E/S byte and 8 data
|
|
; bytes as transmitted (12 bytes). These may not be the same as the values provided
|
|
; during a previous write to scratchpad memory. All these bytes are recorded in KCPSM3
|
|
; scratch pad memory in ascending locations starting at the location defined by
|
|
; constant 'command_start'.
|
|
;
|
|
;
|
|
read_scratchpad_command: LOAD sE, command_start ;pointer to memory
|
|
LOAD s3, AA ;read scratchpad memory Command
|
|
STORE s3, (sE) ;record command sequence
|
|
ADD sE, 01 ;increment pointer
|
|
CALL write_byte_slow ;transmit command
|
|
CALL send_address ;display 'Address='
|
|
CALL read_byte_slow ;read address into [s5,s4]
|
|
LOAD s4, s3
|
|
CALL read_byte_slow
|
|
LOAD s5, s3
|
|
STORE s4, (sE) ;record sequence
|
|
ADD sE, 01 ;increment pointer
|
|
STORE s5, (sE) ;record sequence
|
|
ADD sE, 01 ;increment pointer
|
|
LOAD s0, s5 ;display address
|
|
CALL send_hex_byte
|
|
LOAD s0, s4
|
|
CALL send_hex_byte
|
|
CALL send_ES ;display 'E/S='
|
|
CALL read_byte_slow ;read E/S register
|
|
STORE s3, (sE) ;record sequence
|
|
ADD sE, 01 ;increment pointer
|
|
LOAD s0, s3 ;display value
|
|
CALL send_hex_byte
|
|
CALL send_data ;display 'Data='
|
|
CALL send_equals
|
|
LOAD s4, 08 ;8 bytes to read
|
|
rsc_loop: CALL send_space
|
|
CALL read_byte_slow ;read data byte
|
|
STORE s3, (sE) ;record sequence
|
|
ADD sE, 01 ;increment pointer
|
|
LOAD s0, s3 ;display value
|
|
CALL send_hex_byte
|
|
SUB s4, 01 ;count bytes
|
|
JUMP NZ, rsc_loop
|
|
CALL read_byte_slow ;read 16-bit CRC into [s5,s4]
|
|
LOAD s4, s3
|
|
CALL read_byte_slow
|
|
LOAD s5, s3
|
|
STORE s4, (sE) ;record command sequence
|
|
ADD sE, 01 ;increment pointer
|
|
STORE s5, (sE) ;record command sequence
|
|
CALL send_CR
|
|
CALL send_CRC ;'CRC=' to display CRC value
|
|
LOAD s0, s5
|
|
CALL send_hex_byte
|
|
LOAD s0, s4
|
|
CALL send_hex_byte
|
|
CALL send_CR
|
|
LOAD s2, 0C ;12 (0C hex) bytes in this command
|
|
CALL compute_CRC16 ;compute CRC value in [s1,s0]
|
|
FETCH s5, (sE) ;compare with received value
|
|
SUB sE, 01
|
|
FETCH s4, (sE) ;compare with received value
|
|
COMPARE s5, s1
|
|
JUMP NZ, rsc_crc16_fail
|
|
COMPARE s4, s0
|
|
JUMP NZ, rsc_crc16_fail
|
|
CALL send_Pass
|
|
JUMP reset_menu ;needs master reset next
|
|
rsc_crc16_fail: CALL send_Fail
|
|
JUMP reset_menu ;needs master reset next
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Compute 8-bit CRC used by DS2432.
|
|
;**************************************************************************************
|
|
;
|
|
; The DS2432 computes an 8-bit CRC using the polynomial X8 + X5 + X4 + 1.
|
|
; See the DS2432 data sheet for full details.
|
|
;
|
|
; Test input value of value 00 00 00 01 B8 1C 02
|
|
; should produce CRC=A2.
|
|
;
|
|
; This routine computes the same CRC based on the values stored in the KCPSM3
|
|
; scratch pad memory by the read ROM command. The result is returned in register s0.
|
|
;
|
|
; Registers used s0,s1,s2,s3,s4,s5,s6,s7,s8,s9
|
|
;
|
|
;
|
|
;Start by loading family code and serial number (56-bits) into
|
|
;register set [s9,s8,s7,s6,s5,s4,s3] so they can be shifted out
|
|
;LSB first.
|
|
;
|
|
compute_CRC8: FETCH s3, family_code
|
|
FETCH s4, serial_number0
|
|
FETCH s5, serial_number1
|
|
FETCH s6, serial_number2
|
|
FETCH s7, serial_number3
|
|
FETCH s8, serial_number4
|
|
FETCH s9, serial_number5
|
|
LOAD s2, 38 ;56 bits to shift (38 hex)
|
|
LOAD s0, 00 ;clear CRC value
|
|
crc8_loop: LOAD s1, s0 ;copy current CRC value
|
|
XOR s1, s3 ;Need to know LSB XOR next input bit
|
|
TEST s1, 01 ;test result of XOR in LSB
|
|
JUMP NC, crc8_shift
|
|
XOR s0, 18 ;compliment bits 3 and 4 of CRC
|
|
crc8_shift: SR0 s1 ;Carry gets LSB XOR next input bit
|
|
SRA s0 ;shift Carry into MSB to form new CRC value
|
|
SR0 s9 ;shift input value
|
|
SRA s8
|
|
SRA s7
|
|
SRA s6
|
|
SRA s5
|
|
SRA s4
|
|
SRA s3
|
|
SUB s2, 01 ;count iterations
|
|
JUMP NZ, crc8_loop
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Compute 16-bit CRC used by DS2432.
|
|
;**************************************************************************************
|
|
;
|
|
; The DS2432 computes a 16-bit CRC using the polynomial X16 + X15 + X2 + 1.
|
|
; See the DS2432 data sheet for full details.
|
|
;
|
|
; Note that the value formed in the CRC shift register is inverted to give the
|
|
; same value as that sent from the DS2432 during scratchpad write, scratchpad read
|
|
; and read auth page commands.
|
|
;
|
|
; This routine computes the CRC based on the values stored in the KCPSM3
|
|
; scratch pad memory starting at address defined by constant 'command_start'.
|
|
; register 's2' must specify how many bytes are to be used in the calculation
|
|
; and the CRC is returned in register pair [s1,s0] once it has been inverted.
|
|
;
|
|
; Registers used s0,s1,s2,s3,s4,s5,s6
|
|
;
|
|
;
|
|
;Start by loading family code and serial number (56-bits) into
|
|
;register set [s9,s8,s7,s6,s5,s4,s3] so they can be shifted out
|
|
;LSB first.
|
|
;
|
|
compute_CRC16: LOAD s5, command_start ;memory pointer
|
|
LOAD s0, 00 ;clear CRC value
|
|
LOAD s1, 00
|
|
crc16_byte_loop: FETCH s4, (s5) ;read input byte
|
|
LOAD s3, 08 ;8-bits to shift
|
|
crc16_bit_loop: LOAD s6, s0 ;copy current CRC value
|
|
XOR s6, s4 ;Need to know LSB XOR next input bit
|
|
TEST s6, 01 ;test result of XOR in LSB
|
|
JUMP NC, crc16_shift
|
|
XOR s0, 02 ;compliment bit 1 of CRC
|
|
XOR s1, 40 ;compliment bit 14 of CRC
|
|
crc16_shift: SR0 s6 ;Carry gets LSB XOR next input bit
|
|
SRA s1 ;shift Carry into MSB to form new CRC value
|
|
SRA s0
|
|
SR0 s4 ;shift input value
|
|
SUB s3, 01 ;count bits
|
|
JUMP NZ, crc16_bit_loop ;next bit
|
|
ADD s5, 01 ;increment memory pointer
|
|
SUB s2, 01 ;count bytes
|
|
JUMP NZ, crc16_byte_loop ;next byte
|
|
XOR s0, FF ;1's complement of CRC value
|
|
XOR s1, FF
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Initialise the DS2432 1-wire interface.
|
|
;**************************************************************************************
|
|
;
|
|
; The 1-wire interface is an open-collector communication scheme employing an external
|
|
; pull-up resistor of 680 Ohms.
|
|
;
|
|
; The hardware section of this translates the one bit signal from PicoBlaze such that
|
|
; when this signal is Low the output is driven Low, but when it is High, it turns off
|
|
; the output buffer and the signal is pulled High externally.
|
|
;
|
|
; This initialisation routine simply ensures that the line is High after configuration.
|
|
; It is vital that DS_wire is generally in the High state because it is the only way in
|
|
; which the DS2432 device derives power to operate.
|
|
;
|
|
; Registers used s0
|
|
;
|
|
DS_wire_init: LOAD s0, DS_wire
|
|
OUTPUT s0, DS_wire_out_port
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; DS2432 initialisation - Regular Speed.
|
|
;**************************************************************************************
|
|
;
|
|
; The initialisation sequence must be performed before any communication can be
|
|
; made with the DS2432 device. This involves the application of an active Low master
|
|
; reset pulse.
|
|
;
|
|
; The regular (slow) speed communication is established by transmitting an active
|
|
; Low reset pulse for a duration of at least 480us. This design generates a 500us pulse.
|
|
;
|
|
; The DS2432 acknowledges the reset and the setting of regular mode by generating an
|
|
; active Low 'Rx Presence Pulse'. This presence pulse can start 15 to 60us after the
|
|
; reset pulse and will end between 120 and 300us after the reset pulse.
|
|
;
|
|
; To confirm that regular mode has been set, this routine confirms that the presence pulse
|
|
; is active only after 60us have elapsed since the reset pulse. This ensures that the
|
|
; faster presence pulse of overdrive mode can not be detected.
|
|
;
|
|
; The carry flag will be set if no valid presence pulse was received (wire remained High) and
|
|
; can be used to indicate an initialisation failure or success.
|
|
;
|
|
; The routine only completes 300us after the presence pulse to ensure the DS2432 has
|
|
; completed the presence pulse and is ready for the first operation.
|
|
;
|
|
; Registers used s0,s1,s2
|
|
;
|
|
DS_init_regular_mode: LOAD s0, 00 ;transmit reset pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
;Delay of 500us is equivalent to 12500 instructions at 50MHz.
|
|
;This delay loop is formed of 28 instructions requiring 446 repetitions.
|
|
LOAD s2, 01 ;[s3,s2]=445 decimal (01BD hex)
|
|
LOAD s1, BD
|
|
rm_wait_500us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
SUBCY s2, 00
|
|
JUMP NC, rm_wait_500us ;repeat until -1
|
|
LOAD s0, 01 ;end of regular reset pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
;Delay of 60us is equivalent to 1500 instructions at 50MHz.
|
|
;This delay and is formed of 27 instructions requiring 56 repetitions.
|
|
LOAD s1, 38 ;56 (38 hex)
|
|
rm_wait_60us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, rm_wait_60us ;repeat until zero
|
|
;The DS_wire is now checked at approximately 1us intervals for the next 240us looking
|
|
;to detect an active Low presence pulse. The 240us is equivalent to 6000 instructions
|
|
;at 50MHz and this polling loop is formed of 33 instructions requiring 182 repetitions.
|
|
LOAD s2, 01 ;set bit which will be reset by a presence pulse
|
|
LOAD s1, B6 ;182 (B6 hex)
|
|
rm_poll_240us: CALL delay_1us ;25 instructions including CALL
|
|
CALL read_DS_wire ;read wire - 5 instructions including CALL
|
|
AND s2, s0 ;clear flag if DS_wire was Low
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, rm_poll_240us ;repeat until zero
|
|
TEST s2, 01 ;set carry flag if no pulse detected
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Read the DS_wire
|
|
;**************************************************************************************
|
|
;
|
|
; The DS_wire signal is read and returned in bit0 of register 's0'.
|
|
; Additionally the carry flag is set if the signal is High and reset if Low
|
|
;
|
|
; Registers used s0
|
|
;
|
|
read_DS_wire: INPUT s0, DS_wire_in_port
|
|
AND s0, DS_wire ;ensure only bit0 is active
|
|
TEST s0, DS_wire ;set carry flag if DS_wire is High
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Write a byte to DS2432 in regular speed mode.
|
|
;**************************************************************************************
|
|
;
|
|
; Bytes are written to the DS2432 with LSB first.
|
|
;
|
|
; The byte to be written should be provided in register 's3' and this will be preserved.
|
|
;
|
|
; Registers used s0,s1,s2,s3
|
|
;
|
|
write_byte_slow: LOAD s2, 08 ;8 bits to transmit
|
|
wbs_loop: RR s3 ;test next bit LSB first
|
|
JUMP C, wbs1 ;transmit '0' or '1'
|
|
CALL write_Low_slow
|
|
JUMP next_slow_bit
|
|
wbs1: CALL write_High_slow
|
|
next_slow_bit: SUB s2, 01 ;count bits
|
|
JUMP NZ, wbs_loop ;repeat until 8-bits transmitted
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Write a '0' to DS_wire in regular speed mode.
|
|
;**************************************************************************************
|
|
;
|
|
; To write a '0' to the DS_wire the signal must be Low for 60 to 120us. This design
|
|
; generates a 78us active Low pulse.
|
|
;
|
|
; The DS2432 then requires at least 1us of recovery time for which this routine
|
|
; provides a 2us delay such that the entire write Low process (slot time) is 80us.
|
|
; A recovery time of 1us was also found to be marginal in practice probably due
|
|
; to the rise time of the DS_wire via the external pull up resistor.
|
|
;
|
|
; Registers used s0,s1
|
|
;
|
|
write_Low_slow: LOAD s0, 00 ;transmit Low pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
;Delay of 78us is equivalent to 1950 instructions at 50MHz.
|
|
;This delay loop is formed of 27 instructions requiring 72 repetitions.
|
|
LOAD s1, 48 ;72 (48 hex)
|
|
wls_wait_78us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, wls_wait_78us ;repeat until zero
|
|
LOAD s0, 01 ;end of Low pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
CALL delay_1us ;2us recovery time
|
|
CALL delay_1us
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Write a '1' to DS_wire in regular speed mode.
|
|
;**************************************************************************************
|
|
;
|
|
; To write a '1' to the DS_wire the signal must be Low for 1 to 15us to instigate the
|
|
; write of the data. This design generates an 8us active Low pulse for this purpose.
|
|
;
|
|
; Then the output must be High for 53 to 114us to provide the '1' for the DS2432 to
|
|
; read and then provide recovery time. This design implements a 72us delay such that
|
|
; the entire write High process (slot time) is 80us
|
|
;
|
|
; Registers used s0,s1
|
|
;
|
|
write_High_slow: LOAD s0, 00 ;transmit Low pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
;Delay of 8us is equivalent to 200 instructions at 50MHz.
|
|
;This delay loop is formed of 27 instructions requiring 8 repetitions.
|
|
LOAD s1, 08 ;8 (08 hex)
|
|
whs_wait_8us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, whs_wait_8us ;repeat until zero
|
|
LOAD s0, 01 ;end of Low pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
;Delay of 72us is equivalent to 1800 instructions at 50MHz.
|
|
;This delay loop is formed of 27 instructions requiring 67 repetitions.
|
|
LOAD s1, 43 ;67 (43 hex)
|
|
whs_wait_72us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, whs_wait_72us ;repeat until zero
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Read a byte from DS2432 in regular speed mode.
|
|
;**************************************************************************************
|
|
;
|
|
; Bytes are read from the DS2432 with LSB first.
|
|
;
|
|
; The byte read will be returned in register 's3'.
|
|
;
|
|
; Registers used s0,s1,s2,s3
|
|
;
|
|
read_byte_slow: LOAD s2, 08 ;8 bits to receive
|
|
rbs_loop: CALL read_bit_slow ;read next bit LSB first
|
|
SUB s2, 01 ;count bits
|
|
JUMP NZ, rbs_loop ;repeat until 8-bits received
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Read a data bit sent from the DS2432 in regular speed mode.
|
|
;**************************************************************************************
|
|
;
|
|
; To read a bit, PicoBlaze must initiate the processed with an active Low pulse of
|
|
; 1 to 15us. This design generates a 4us active Low pulse for this purpose.
|
|
;
|
|
; Then DS2432 responds to the Low pulse by diving DS_wire in two differet ways
|
|
; depending on the logic level it is trying to send back.
|
|
;
|
|
; For a logic '0' the DS2432 will drive the DS-wire Low for up to 15us after
|
|
; the start of the instigating pulse. Therefore PicoBlaze must read the DS-wire
|
|
; before this time has elapsed but only after it has itself released the wire.
|
|
;
|
|
; For a logic '1' the DS2432 will do nothing and hence the DS-wire will be pulled
|
|
; High by the external resistor after PicoBlaze has released the wire. PicoBlaze
|
|
; will sample the wire and detect the High level.
|
|
;
|
|
; In this design, PicoBlaze needs to detect the logic state of the wire after
|
|
; releasing the wire at 4us. Sampling the wire too quickly would not provide
|
|
; adequate time for a High signal to be formed by the pull up resistor. However, it
|
|
; must sample the wire before 15us have elapsed and any potential Low is removed.
|
|
; This design samples the wire at 12us which is 8us after the initiation pulse ends.
|
|
;
|
|
; A further delay of 68us is then allowed for the DS2432 to stop transmitting and
|
|
; to recover. This also mean that the entire read process (slot time) is 80us.
|
|
;
|
|
; The received data bit is SHIFTED into the MSB of register 's3'. In this way
|
|
; the reception of 8-bits will shift the first bit into the LSB position of 's3'.
|
|
;
|
|
; Registers used s0,s1,s3
|
|
;
|
|
read_bit_slow: LOAD s0, 00 ;transmit Low pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
;Delay of 4us is equivalent to 100 instructions at 50MHz.
|
|
;This delay loop is formed of 27 instructions requiring 4 repetitions.
|
|
LOAD s1, 04 ;4 (04 hex)
|
|
rbs_wait_4us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, rbs_wait_4us ;repeat until zero
|
|
LOAD s0, 01 ;end of Low pulse
|
|
OUTPUT s0, DS_wire_out_port
|
|
;Delay of 8us is equivalent to 200 instructions at 50MHz.
|
|
;This delay loop is formed of 27 instructions requiring 8 repetitions.
|
|
LOAD s1, 08 ;8 (08 hex)
|
|
rbs_wait_8us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, rbs_wait_8us ;repeat until zero
|
|
CALL read_DS_wire ;sample wire (carry = state)
|
|
SRA s3 ;shift received bit into MSB of s3
|
|
;Delay of 68us is equivalent to 1700 instructions at 50MHz.
|
|
;This delay loop is formed of 27 instructions requiring 63 repetitions.
|
|
LOAD s1, 3F ;63 (3F hex)
|
|
rbs_wait_68us: CALL delay_1us ;25 instructions including CALL
|
|
SUB s1, 01 ;decrement delay counter
|
|
JUMP NZ, rbs_wait_68us ;repeat until zero
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Software delay routines
|
|
;**************************************************************************************
|
|
;
|
|
; Delay of 1us.
|
|
;
|
|
; Constant value defines reflects the clock applied to KCPSM3. Every instruction
|
|
; executes in 2 clock cycles making the calculation highly predictable. The '6' in
|
|
; the following equation even allows for 'CALL delay_1us' instruction in the initiating code.
|
|
;
|
|
; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
|
|
;
|
|
; Register used s0
|
|
;
|
|
delay_1us: LOAD s0, delay_1us_constant
|
|
wait_1us: SUB s0, 01
|
|
JUMP NZ, wait_1us
|
|
RETURN
|
|
;
|
|
; Delay of 40us.
|
|
;
|
|
; Registers used s0, s1
|
|
;
|
|
delay_40us: LOAD s1, 28 ;40 x 1us = 40us
|
|
wait_40us: CALL delay_1us
|
|
SUB s1, 01
|
|
JUMP NZ, wait_40us
|
|
RETURN
|
|
;
|
|
;
|
|
; Delay of 1ms.
|
|
;
|
|
; Registers used s0, s1, s2
|
|
;
|
|
delay_1ms: LOAD s2, 19 ;25 x 40us = 1ms
|
|
wait_1ms: CALL delay_40us
|
|
SUB s2, 01
|
|
JUMP NZ, wait_1ms
|
|
RETURN
|
|
;
|
|
; Delay of 20ms.
|
|
;
|
|
; Registers used s0, s1, s2, s3
|
|
;
|
|
delay_20ms: LOAD s3, 14 ;20 x 1ms = 20ms
|
|
wait_20ms: CALL delay_1ms
|
|
SUB s3, 01
|
|
JUMP NZ, wait_20ms
|
|
RETURN
|
|
;
|
|
; Delay of approximately 1 second.
|
|
;
|
|
; Registers used s0, s1, s2, s3, s4
|
|
;
|
|
delay_1s: LOAD s4, 14 ;50 x 20ms = 1000ms
|
|
wait_1s: CALL delay_20ms
|
|
SUB s4, 01
|
|
JUMP NZ, wait_1s
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; UART communication routines
|
|
;**************************************************************************************
|
|
;
|
|
; Read one character from the UART
|
|
;
|
|
; Character read will be returned in a register called 'UART_data'.
|
|
;
|
|
; The routine first tests the receiver FIFO buffer to see if data is present.
|
|
; If the FIFO is empty, the routine waits until there is a character to read.
|
|
; As this could take any amount of time the wait loop could include a call to a
|
|
; subroutine which performs a useful function.
|
|
;
|
|
;
|
|
; Registers used s0 and UART_data
|
|
;
|
|
read_from_UART: INPUT s0, status_port ;test Rx_FIFO buffer
|
|
TEST s0, rx_data_present ;wait if empty
|
|
JUMP NZ, read_character
|
|
JUMP read_from_UART
|
|
read_character: INPUT UART_data, UART_read_port ;read from FIFO
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
; Transmit one character to the UART
|
|
;
|
|
; Character supplied in register called 'UART_data'.
|
|
;
|
|
; The routine first tests the transmit FIFO buffer to see if it is full.
|
|
; If the FIFO is full, then the routine waits until it there is space.
|
|
;
|
|
; Registers used s0
|
|
;
|
|
send_to_UART: INPUT s0, status_port ;test Tx_FIFO buffer
|
|
TEST s0, tx_full ;wait if full
|
|
JUMP Z, UART_write
|
|
JUMP send_to_UART
|
|
UART_write: OUTPUT UART_data, UART_write_port
|
|
RETURN
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Useful ASCII conversion and handling routines
|
|
;**************************************************************************************
|
|
;
|
|
; Convert value provided in register s0 into ASCII characters
|
|
;
|
|
; The value provided must in the range 0 to 99 and will be converted into
|
|
; two ASCII characters.
|
|
; The number of 'tens' will be represented by an ASCII character returned in register s1.
|
|
; The number of 'units' will be represented by an ASCII character returned in register s0.
|
|
;
|
|
; The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex added to
|
|
; the actual decimal value.
|
|
;
|
|
; Registers used s0 and s1.
|
|
;
|
|
decimal_to_ASCII: LOAD s1, 30 ;load 'tens' counter with ASCII for '0'
|
|
test_for_ten: ADD s1, 01 ;increment 'tens' value
|
|
SUB s0, 0A ;try to subtract 10 from the supplied value
|
|
JUMP NC, test_for_ten ;repeat if subtraction was possible without underflow.
|
|
SUB s1, 01 ;'tens' value one less ten due to underflow
|
|
ADD s0, 3A ;restore units value (the remainder) and convert to ASCII
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
; Convert character to upper case
|
|
;
|
|
; The character supplied in register s0.
|
|
; If the character is in the range 'a' to 'z', it is converted
|
|
; to the equivalent upper case character in the range 'A' to 'Z'.
|
|
; All other characters remain unchanged.
|
|
;
|
|
; Registers used s0.
|
|
;
|
|
upper_case: COMPARE s0, 61 ;eliminate character codes below 'a' (61 hex)
|
|
RETURN C
|
|
COMPARE s0, 7B ;eliminate character codes above 'z' (7A hex)
|
|
RETURN NC
|
|
AND s0, DF ;mask bit5 to convert to upper case
|
|
RETURN
|
|
;
|
|
;
|
|
; Convert character '0' to '9' to numerical value in range 0 to 9
|
|
;
|
|
; The character supplied in register s0. If the character is in the
|
|
; range '0' to '9', it is converted to the equivalent decimal value.
|
|
; Characters not in the range '0' to '9' are signified by the return
|
|
; with the CARRY flag set.
|
|
;
|
|
; Registers used s0.
|
|
;
|
|
onechar_to_value: ADD s0, C6 ;reject character codes above '9' (39 hex)
|
|
RETURN C ;carry flag is set
|
|
SUB s0, F6 ;reject character codes below '0' (30 hex)
|
|
RETURN ;carry is set if value not in range
|
|
;
|
|
;
|
|
; Determine the numerical value of a two character decimal string held in
|
|
; scratch pad memory such the result is in the range 0 to 99 (00 to 63 hex).
|
|
;
|
|
; The string must be stored in two consecutive memory locations and the
|
|
; location of the first (tens) character supplied in the s1 register.
|
|
; The result is provided in register s2. Strings not using characters in the
|
|
; range '0' to '9' are signified by the return with the CARRY flag set.
|
|
;
|
|
; Registers used s0, s1 and s2.
|
|
;
|
|
twochar_to_value: FETCH s0, (s1) ;read 'tens' character
|
|
CALL onechar_to_value ;convert to numerical value
|
|
RETURN C ;bad character - CARRY set
|
|
LOAD s2, s0
|
|
SL0 s2 ;multiply 'tens' value by 10 (0A hex)
|
|
SL0 s2
|
|
ADD s2, s0
|
|
SL0 s2
|
|
ADD s1, 01 ;read 'units' character
|
|
FETCH s0, (s1)
|
|
CALL onechar_to_value ;convert to numerical value
|
|
RETURN C ;bad character - CARRY set
|
|
ADD s2, s0 ;add units to result and clear CARRY flag
|
|
RETURN
|
|
;
|
|
;
|
|
; Convert hexadecimal value provided in register s0 into ASCII characters
|
|
;
|
|
; The value provided must can be any value in the range 00 to FF and will be converted into
|
|
; two ASCII characters.
|
|
; The upper nibble will be represented by an ASCII character returned in register s2.
|
|
; The lower nibble will be represented by an ASCII character returned in register s1.
|
|
;
|
|
; The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex
|
|
; added to the actual decimal value. The ASCII representations of 'A' to 'F' are 41 to 46
|
|
; hexadecimal requiring a further addition of 07 to the 30 already added.
|
|
;
|
|
; Registers used s0, s1 and s2.
|
|
;
|
|
hex_byte_to_ASCII: LOAD s1, s0 ;remember value supplied
|
|
SR0 s0 ;isolate upper nibble
|
|
SR0 s0
|
|
SR0 s0
|
|
SR0 s0
|
|
CALL hex_to_ASCII ;convert
|
|
LOAD s2, s0 ;upper nibble value in s2
|
|
LOAD s0, s1 ;restore complete value
|
|
AND s0, 0F ;isolate lower nibble
|
|
CALL hex_to_ASCII ;convert
|
|
LOAD s1, s0 ;lower nibble value in s1
|
|
RETURN
|
|
;
|
|
; Convert hexadecimal value provided in register s0 into ASCII character
|
|
;
|
|
;Register used s0
|
|
;
|
|
hex_to_ASCII: SUB s0, 0A ;test if value is in range 0 to 9
|
|
JUMP C, number_char
|
|
ADD s0, 07 ;ASCII char A to F in range 41 to 46
|
|
number_char: ADD s0, 3A ;ASCII char 0 to 9 in range 30 to 40
|
|
RETURN
|
|
;
|
|
;
|
|
; Send the two character HEX value of the register contents 's0' to the UART
|
|
;
|
|
; Registers used s0, s1, s2
|
|
;
|
|
send_hex_byte: CALL hex_byte_to_ASCII
|
|
LOAD UART_data, s2
|
|
CALL send_to_UART
|
|
LOAD UART_data, s1
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
; Send the six character HEX value of the register contents [s9,s8,s7] to the UART
|
|
;
|
|
; Registers used s0, s1, s2
|
|
;
|
|
send_hex_3bytes: LOAD s0, s9
|
|
CALL send_hex_byte
|
|
LOAD s0, s8
|
|
CALL send_hex_byte
|
|
LOAD s0, s7
|
|
CALL send_hex_byte
|
|
RETURN
|
|
;
|
|
;
|
|
; Convert the HEX ASCII characters contained in 's3' and 's2' into
|
|
; an equivalent hexadecimal value in register 's0'.
|
|
; The upper nibble is represented by an ASCII character in register s3.
|
|
; The lower nibble is represented by an ASCII character in register s2.
|
|
;
|
|
; Input characters must be in the range 00 to FF hexadecimal or the CARRY flag
|
|
; will be set on return.
|
|
;
|
|
; Registers used s0, s2 and s3.
|
|
;
|
|
ASCII_byte_to_hex: LOAD s0, s3 ;Take upper nibble
|
|
CALL ASCII_to_hex ;convert to value
|
|
RETURN C ;reject if out of range
|
|
LOAD s3, s0 ;remember value
|
|
SL0 s3 ;multiply value by 16 to put in upper nibble
|
|
SL0 s3
|
|
SL0 s3
|
|
SL0 s3
|
|
LOAD s0, s2 ;Take lower nibble
|
|
CALL ASCII_to_hex ;convert to value
|
|
RETURN C ;reject if out of range
|
|
OR s0, s3 ;merge in the upper nibble with CARRY reset
|
|
RETURN
|
|
;
|
|
;
|
|
; Routine to convert ASCII data in 's0' to an equivalent HEX value.
|
|
;
|
|
; If character is not valid for hex, then CARRY is set on return.
|
|
;
|
|
; Register used s0
|
|
;
|
|
ASCII_to_hex: ADD s0, B9 ;test for above ASCII code 46 ('F')
|
|
RETURN C
|
|
SUB s0, E9 ;normalise 0 to 9 with A-F in 11 to 16 hex
|
|
RETURN C ;reject below ASCII code 30 ('0')
|
|
SUB s0, 11 ;isolate A-F down to 00 to 05 hex
|
|
JUMP NC, ASCII_letter
|
|
ADD s0, 07 ;test for above ASCII code 46 ('F')
|
|
RETURN C
|
|
SUB s0, F6 ;convert to range 00 to 09
|
|
RETURN
|
|
ASCII_letter: ADD s0, 0A ;convert to range 0A to 0F
|
|
RETURN
|
|
;
|
|
;
|
|
; Read one character from UART and echo.
|
|
; Convert to upper case and return.
|
|
;
|
|
;
|
|
read_upper_case: CALL read_from_UART ;read command character from UART
|
|
CALL send_to_UART ;echo character
|
|
LOAD s0, UART_data ;convert to upper case
|
|
CALL upper_case
|
|
RETURN
|
|
;
|
|
;
|
|
; Read two hex characters from UART and convert to single byte data
|
|
;
|
|
obtain_8bits: CALL read_upper_case ;obtain one byte from UART
|
|
LOAD s3, s0
|
|
CALL read_upper_case
|
|
LOAD s2, s0
|
|
CALL ASCII_byte_to_hex
|
|
RETURN
|
|
;
|
|
;**************************************************************************************
|
|
; Text messages
|
|
;**************************************************************************************
|
|
;
|
|
;
|
|
; Send Carriage Return to the UART
|
|
;
|
|
send_CR: LOAD UART_data, character_CR
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
; Send a space to the UART
|
|
;
|
|
send_space: LOAD UART_data, character_space
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send a minus sign to the UART
|
|
;
|
|
send_minus: LOAD UART_data, character_minus
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'PicoBlaze DS2432 Communicator v1.00' string to the UART
|
|
;
|
|
send_welcome: CALL send_CR
|
|
CALL send_CR
|
|
LOAD UART_data, character_P
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_i
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_c
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_o
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_B
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_l
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_z
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
CALL send_space
|
|
LOAD UART_data, character_D
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_S
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_2
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_4
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_3
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_2
|
|
CALL send_to_UART
|
|
CALL send_space
|
|
LOAD UART_data, character_C
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_o
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_m
|
|
CALL send_to_UART
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_u
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_n
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_i
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_c
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_t
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_o
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_r
|
|
CALL send_to_UART
|
|
CALL send_space
|
|
LOAD UART_data, character_v
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_1
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_fullstop
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_0
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_0
|
|
CALL send_to_UART
|
|
CALL send_CR
|
|
CALL send_CR
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
; Send reset menu to the UART
|
|
;
|
|
send_reset_menu: CALL send_CR
|
|
CALL send_CR
|
|
CALL send_HHelp
|
|
LOAD UART_data, character_1
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Master_Reset
|
|
CALL send_CR
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;
|
|
; Send ROM menu to the UART
|
|
;
|
|
send_ROM_menu: CALL send_CR
|
|
CALL send_CR
|
|
CALL send_HHelp
|
|
LOAD UART_data, character_1
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Master_Reset
|
|
CALL send_CR
|
|
LOAD UART_data, character_2
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Read
|
|
CALL send_space
|
|
CALL send_ROM
|
|
CALL send_space
|
|
CALL send_Command
|
|
CALL send_CR
|
|
LOAD UART_data, character_3
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Skip
|
|
CALL send_space
|
|
CALL send_ROM
|
|
CALL send_space
|
|
CALL send_Command
|
|
CALL send_CR
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
; Send DS2432 menu to the UART
|
|
;
|
|
send_DS2432_menu: CALL send_CR
|
|
CALL send_CR
|
|
CALL send_HHelp
|
|
LOAD UART_data, character_1
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Master_Reset
|
|
CALL send_CR
|
|
LOAD UART_data, character_2
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Read
|
|
CALL send_space
|
|
CALL send_Memory
|
|
CALL send_space
|
|
CALL send_Command
|
|
CALL send_CR
|
|
LOAD UART_data, character_3
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Write
|
|
CALL send_space
|
|
CALL send_Scratchpad
|
|
CALL send_space
|
|
CALL send_Memory
|
|
CALL send_space
|
|
CALL send_Command
|
|
CALL send_CR
|
|
LOAD UART_data, character_4
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Read
|
|
CALL send_space
|
|
CALL send_Scratchpad
|
|
CALL send_space
|
|
CALL send_Memory
|
|
CALL send_space
|
|
CALL send_Command
|
|
CALL send_CR
|
|
LOAD UART_data, character_5
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Write
|
|
CALL send_space
|
|
CALL send_Byte
|
|
CALL send_CR
|
|
LOAD UART_data, character_6
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
CALL send_Read
|
|
CALL send_space
|
|
CALL send_Byte
|
|
CALL send_CR
|
|
RETURN
|
|
;
|
|
;
|
|
;
|
|
; Send carriage return, 'OK' and carriage return to the UART
|
|
;
|
|
send_OK: CALL send_CR
|
|
LOAD UART_data, character_O
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_K
|
|
CALL send_to_UART
|
|
CALL send_CR
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'H-Help'menu to the UART
|
|
;
|
|
send_HHelp: CALL send_CR
|
|
LOAD UART_data, character_H
|
|
CALL send_to_UART
|
|
CALL send_minus
|
|
LOAD UART_data, character_H
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_l
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_p
|
|
CALL send_to_UART
|
|
CALL send_CR
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'ROM' to the UART
|
|
;
|
|
send_ROM: LOAD UART_data, character_R
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_O
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_M
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Memory' to the UART
|
|
;
|
|
send_Memory: LOAD UART_data, character_M
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_m
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_o
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_r
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_y
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Scratchpad' to the UART
|
|
;
|
|
send_Scratchpad: LOAD UART_data, character_S
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_c
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_r
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_t
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_c
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_h
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_p
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_d
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Master Reset' to the UART
|
|
;
|
|
send_Master_Reset: LOAD UART_data, character_M
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_s
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_t
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_r
|
|
CALL send_to_UART
|
|
CALL send_space
|
|
LOAD UART_data, character_R
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_s
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_t
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Byte' to the UART
|
|
;
|
|
send_Byte: LOAD UART_data, character_B
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_y
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_t
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Skip' to the UART
|
|
;
|
|
send_Skip: LOAD UART_data, character_S
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_k
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_i
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_p
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Read' to the UART
|
|
;
|
|
send_Read: LOAD UART_data, character_R
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_d
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Write' to the UART
|
|
;
|
|
send_Write: LOAD UART_data, character_W
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_r
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_i
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_t
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Pass' to the UART
|
|
;
|
|
send_Pass: LOAD UART_data, character_P
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_s
|
|
CALL send_to_UART
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Fail' to the UART
|
|
;
|
|
send_Fail: LOAD UART_data, character_F
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_i
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_l
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'Command' to the UART
|
|
;
|
|
send_Command: LOAD UART_data, character_C
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_o
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_m
|
|
CALL send_to_UART
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_n
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_d
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'address=' to the UART
|
|
;
|
|
send_address: CALL send_CR
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_d
|
|
CALL send_to_UART
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_r
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_s
|
|
CALL send_to_UART
|
|
CALL send_to_UART
|
|
send_equals: LOAD UART_data, character_equals
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'data' to the UART
|
|
;
|
|
send_data: CALL send_CR
|
|
LOAD UART_data, character_d
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_t
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
RETURN
|
|
;
|
|
;
|
|
; Send 'E/S=' to the UART
|
|
;
|
|
send_ES: CALL send_CR
|
|
LOAD UART_data, character_E
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_divide
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_S
|
|
CALL send_to_UART
|
|
JUMP send_equals
|
|
;
|
|
;
|
|
; Send 'code=' to the UART
|
|
;
|
|
send_code: LOAD UART_data, character_c
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_o
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_d
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
JUMP send_equals
|
|
;
|
|
;
|
|
; Send 'serial=' to the UART
|
|
;
|
|
send_serial: LOAD UART_data, character_s
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_e
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_r
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_i
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_a
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_l
|
|
CALL send_to_UART
|
|
JUMP send_equals
|
|
;
|
|
;
|
|
; Send 'CRC=' to the UART
|
|
;
|
|
send_CRC: LOAD UART_data, character_C
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_R
|
|
CALL send_to_UART
|
|
LOAD UART_data, character_C
|
|
JUMP send_equals
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Interrupt Service Routine (ISR)
|
|
;**************************************************************************************
|
|
;
|
|
; Interrupts are not used in this design. This is a place keeper only.
|
|
;
|
|
ADDRESS 3FE
|
|
ISR: RETURNI ENABLE
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Interrupt Vector
|
|
;**************************************************************************************
|
|
;
|
|
ADDRESS 3FF
|
|
JUMP ISR
|
|
;
|
|
;
|