uclock.psm

来自「PacoBlaze is a from-scratch synthesizabl」· PSM 代码 · 共 1,009 行 · 第 1/4 页

PSM
1,009
字号
                        ;KCPSM3 Program - Real Time Clock with UART communication.
                        ;
                        ;Ken Chapman - Xilinx Ltd - October 2003
                        ;
                        ;
                        ;Port definitions
                        ;
                        constant UART_status_port, $00            ;UART status input
                        constant tx_half_full, $01                ;  Transmitter     half full - bit0
                        constant tx_full, $02                     ;    FIFO               full - bit1
                        constant rx_half_full, $04                ;  Receiver        half full - bit2
                        constant rx_full, $08                     ;    FIFO               full - bit3
                        constant rx_data_present, $10             ;               data present - bit4
                        ;
                        constant UART_read_port, $01              ;UART Rx data input
                        ;
                        constant UART_write_port, $01             ;UART Tx data output
                        ;
                        constant alarm_port, $00                  ;Alarm output
                        constant alarm_control, $01               ;     bit0
                        ;
                        ;Special Register usage
                        ;
                        register UART_data, $f                    ;used to pass data to and from the UART
                        ;
                        register store_pointer, $e                ;used to pass location of data in scratch pad memory
                        ;
                        ;Two registers to form a 16-bit counter used to count
                        ;interrupt pulses generated at 1us intervals.
                        ;
                        register int_counter_lsb, $d              ;lower 8-bits
                        register int_counter_msb, $c              ;upper 8-bits
                        ;
                        ;
                        ;Scratch Pad Memory Locations
                        ;
                        ;
                        constant us_time_stamp_lsb, $00           ;16-bit micro-second time stamp
                        constant us_time_stamp_msb, $01
                        ;
                        constant us_time_lsb, $02                 ;16-bit micro-second real time value
                        constant us_time_msb, $03
                        ;
                        constant ms_time_lsb, $04                 ;16-bit milli-second real time value
                        constant ms_time_msb, $05
                        ;
                        constant real_time_hours, $06             ;Current clock time
                        constant real_time_minutes, $07
                        constant real_time_seconds, $08
                        ;
                        constant alarm_time_hours, $09            ;Alarm time
                        constant alarm_time_minutes, $0A
                        constant alarm_time_seconds, $0B
                        ;
                        constant alarm_status, $0C                ;Alarm status
                        constant alarm_active, $01                ;    bit0 - Alarm is active
                        constant alarm_armed, $02                 ;    bit1 - Alarm is armed
                        ;
                        constant time_preserve0, $10              ;storage for protection of registers
                        constant time_preserve1, $11              ;used by the real time clock routine.
                        constant time_preserve2, $12
                        constant time_preserve3, $13
                        constant time_preserve4, $14
                        constant time_preserve5, $15
                        ;
                        ;UART character strings will be stored in scratch pad memory ending in carriage return.
                        ;A string can be up to 16 characters with the start location defined by this constant.
                        ;
                        constant string_start, $20
                        ;
                        ;
                        ;Initialise the system
                        ;
                        ;
            cold_start: load s0, $00                              ;clear all time values
                        store s0, us_time_stamp_lsb
                        store s0, us_time_stamp_msb
                        store s0, us_time_lsb
                        store s0, us_time_msb
                        store s0, ms_time_lsb
                        store s0, ms_time_msb
                        store s0, real_time_hours
                        store s0, real_time_minutes
                        store s0, real_time_seconds
                        store s0, alarm_time_hours
                        store s0, alarm_time_minutes
                        store s0, alarm_time_seconds
                        store s0, alarm_status                   ;clear and disable alarm
                        call alarm_drive                         ;turn off alarm control output port
                        load int_counter_lsb, $00                 ;clear 'us' interrupt counter
                        load int_counter_msb, $00
                        interrupt enable                         ;enable the 1us interrupts
                        ;
                        ;
                        ;Start of the main program loop.
                        ;
                        ;A prompt is transmitted to the UART transmitter and then
                        ;a command can be entered and interpreted.
                        ;
                        ;
          prompt_input: call send_prompt                         ;Prompt 'KCPSM3>'
                        call receive_string                      ;obtain input string and maintain the time
                        ;
                        ;
                        ;Parse the string and perform actions as required
                        ;
                        ;
                        ;
                        load s1, string_start
                        call fetch_char_from_memory
                        compare s0, character_CR                 ;carriage return does nothing
                        jump z, prompt_input
                        compare s0, character_T                  ;start of 'TIME' command?
                        jump z, test_for_TIME
                        compare s0, character_A                  ;start of 'ALARM' command?
                        jump z, test_for_ALARM
                        ;
                        ;trap other command starts here
                        ;
     bad_input_command: call send_Syntax_Error                   ;no valid command
                        jump z, prompt_input
                        ;
                        ;
         test_for_TIME: call fetch_char_from_memory
                        compare s0, character_I                  ;test for rest of 'TIME'
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_M
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_E
                        jump nz, bad_input_command
                        ;now have a valid TIME command to process
                        call fetch_char_from_memory
                        compare s0, character_CR                 ;carriage return means display time
                        jump nz, set_time_command
                        call transmit_time                       ;transmit time to UART
                        jump prompt_input
      set_time_command: compare s0, character_space
                        jump nz, bad_input_command
                        call test_time_string                    ;interpret 'hh:mm:ss' string
                        jump c, prompt_input                     ;test for invalid input
                        store s6, real_time_hours                ;set new time into clock
                        store s5, real_time_minutes
                        store s4, real_time_seconds
                        store s0, ms_time_lsb                    ;clear 'ms' counter (s0=00)
                        store s0, ms_time_msb
                        call transmit_time                       ;transmit new time to UART
                        jump prompt_input
                        ;
                        ;
        test_for_ALARM: call fetch_char_from_memory
                        compare s0, character_L                  ;test for rest of 'ALARM'
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_A
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_R
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_M
                        jump nz, bad_input_command
                        ;now have a valid ALARM command to process
                        call fetch_char_from_memory
                        compare s0, character_CR                 ;carriage return means display alarm time
                        jump nz, set_alarm_command
                        call transmit_alarm_time                 ;transmit time to UART
                        jump prompt_input
     set_alarm_command: compare s0, character_space              ;test for ON or OFF command
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_O
                        jump z, set_alarm_on_off
                        sub s1, $01                               ;move memory pointer back to first character of 'hh:mm:ss' string
                        call test_time_string                    ;interpret 'hh:mm:ss' string
                        jump c, prompt_input                     ;test for invalid input
                        store s6, alarm_time_hours               ;set new time into clock
                        store s5, alarm_time_minutes
                        store s4, alarm_time_seconds
                        call transmit_alarm_time                 ;transmit new alarm time and status
                        jump prompt_input
      set_alarm_on_off: call fetch_char_from_memory
                        compare s0, character_N                  ;test for 'ON'
                        jump nz, test_OFF
                        call fetch_char_from_memory
                        compare s0, character_CR
                        jump nz, bad_input_command
                        fetch s0, alarm_status                   ;turn alarm on
                        or s0, alarm_armed
                        store s0, alarm_status
                        call transmit_alarm_time                 ;transmit alarm time and status
                        jump prompt_input
              test_OFF: compare s0, character_F                  ;test for for 'OFF'
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_F
                        jump nz, bad_input_command
                        call fetch_char_from_memory
                        compare s0, character_CR
                        jump nz, bad_input_command
                        load s0, $00                              ;turn alarm off and stop an active alarm
                        store s0, alarm_status
                        call alarm_drive                         ;turn off alarm
                        call transmit_alarm_time                 ;transmit alarm time and status
                        jump prompt_input
                        ;
                        ;
                        ;
                        ;
                        ;Read an 'hh:mm:ss' time string and provide new values.
                        ;
                        ;The string must be provided in successive scratch pad memory locations
                        ;with the s1 register containing the location of the first character.
                        ;
                        ;A correct time specification will result in the return of new values
                        ;as follows:-
                        ;
                        ;       s6 = hours
                        ;       s5 = minutes
                        ;       s4 = seconds
                        ;
                        ;If the syntax is incorrect or values are not in the correct ranges an
                        ;'Invalid Time' message will be transmitted and the CARRY flag will be set
                        ;
                        ;Registers used s0, s1, s6, s5 and s4
                        ;
      test_time_string: call _2char_to_value                      ;obtain hours value
                        jump c, invalid_time                     ;test for non-decimal characters
                        load s6, s2                              ;remember hours
                        add s1, $01                               ;increment memory pointer past hours
                        call fetch_char_from_memory
                        compare s0, character_colon              ;test for colon
                        jump nz, invalid_time
                        call _2char_to_value                      ;obtain minutes value
                        jump c, invalid_time                     ;test for non-decimal characters
                        load s5, s2                              ;remember minutes
                        add s1, $01                               ;increment memory pointer past minutes
                        call fetch_char_from_memory
                        compare s0, character_colon              ;test for colon
                        jump nz, invalid_time
                        call _2char_to_value                      ;obtain seconds value
                        jump c, invalid_time                     ;test for non-decimal characters
                        load s4, s2                              ;remember minutes
                        add s1, $01                               ;increment memory pointer past seconds
                        call fetch_char_from_memory
                        compare s0, character_CR                 ;finish with carriage return
                        jump nz, invalid_time
                        ;Have values for hh:mm:ss but need to test if each is valid range.
                        compare s6, hours_in_a_day
                        jump nc, invalid_time
                        compare s5, minutes_in_an_hour
                        jump nc, invalid_time

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?