📄 led_ctrl.psm
字号:
;
; The authentication check is performed by issuing and interrupt to the authentication
; processor and then observing the simple text string that it returns via the link FIFO
; buffer.
;
; PASS - Design is authorised to work.
; FAIL - Design is not authorised and should stop working normally.
;
;
;ASCII character values that are used in messages
;
CONSTANT character_A, 41
CONSTANT character_F, 46
CONSTANT character_I, 49
CONSTANT character_L, 4C
CONSTANT character_P, 50
CONSTANT character_S, 53
;
;
authentication_check: LOAD s0, link_fifo_reset ;clear link FIFO to ensure no unexpected characters
OUTPUT s0, link_fifo_control_port
LOAD s0, 00
OUTPUT s0, link_fifo_control_port
;
LOAD s0, security_interrupt ;generate interrupt to authentication processor
OUTPUT s0, security_request_port
LOAD s0, 00
OUTPUT s0, security_request_port
;
CALL read_link_FIFO ;read each character and compare
COMPARE s0, character_P
JUMP NZ, fail_confirm
CALL read_link_FIFO
COMPARE s0, character_A
JUMP NZ, fail_confirm
CALL read_link_FIFO
COMPARE s0, character_S
JUMP NZ, fail_confirm
CALL read_link_FIFO
COMPARE s0, character_S
JUMP NZ, fail_confirm
JUMP normal_LED_sequence ;Continue normal operation for PASS message
;
;
; To confirm that the authentication is really a FAIL message
; another request is made to the authentication processor and tested.
;
fail_confirm: LOAD s0, FF ;short delay to ensure authentication processor is ready
request_delay: SUB s0, 01 ; to respond to new interrupt request
JUMP NZ, request_delay
;
LOAD s0, link_fifo_reset ;clear link FIFO to ensure no unexpected characters
OUTPUT s0, link_fifo_control_port
LOAD s0, 00
OUTPUT s0, link_fifo_control_port
;
LOAD s0, security_interrupt ;generate interrupt to authentication processor
OUTPUT s0, security_request_port
LOAD s0, 00
OUTPUT s0, security_request_port
;
CALL read_link_FIFO ;read each character and compare
COMPARE s0, character_F
JUMP NZ, normal_LED_sequence
CALL read_link_FIFO
COMPARE s0, character_A
JUMP NZ, normal_LED_sequence
CALL read_link_FIFO
COMPARE s0, character_I
JUMP NZ, normal_LED_sequence
CALL read_link_FIFO
COMPARE s0, character_L
JUMP NZ, normal_LED_sequence
;
;
; When the design fails to authenticate the LEDs will appear to
; turn on and then slowly fade to off using PWM.
;
failed_LED_sequence: LOAD s0, FF ;maximum intensity on all LEDs
LOAD s4, 00 ;reset fade rate control
all_LED_fade: LOAD s1, PWM_channel0
all_LED_fade_loop: STORE s0, (s1)
COMPARE s1, PWM_channel7
JUMP Z, decay_LEDs
ADD s1, 01
JUMP all_LED_fade_loop
decay_LEDs: LOAD s1, s4 ;software delay starts quickly and slows down because LEDs are non-linear.
wait_s1: LOAD s2, 18
wait_s2: LOAD s3, FF
wait_s3: SUB s3, 01
JUMP NZ, wait_s3
SUB s2, 01
JUMP NZ, wait_s2
SUB s1, 01
JUMP NZ, wait_s1
COMPARE s0, 00 ;test for fully off
JUMP Z, stop_completely
SUB s0, 01 ;fade LEDs
ADD s4, 01 ;slow fade rate as intensity decreases
JUMP all_LED_fade
;
stop_completely: JUMP stop_completely
;
;**************************************************************************************
; Read Byte from Link FIFO
;**************************************************************************************
;
; The routine first tests the FIFO buffer to see if data is present.
; If the FIFO is empty, the routine waits until there is a character to read.
; the read value is returned in register s0.
;
;
read_link_FIFO: INPUT s0, link_FIFO_status_port ;test FIFO buffer
TEST s0, link_FIFO_data_present ;wait if empty
JUMP Z, read_link_FIFO
INPUT s0, link_FIFO_read_port ;read data from FIFO
RETURN
;
;
;**************************************************************************************
; Interrupt Service Routine (ISR)
;**************************************************************************************
;
; Interrupts occur at 3.92us intervals and are used to generate the PWM pulses generated
; at a PRF of 1KHz. The 3.92us interrupt rate corresponds with a resolution of 256 steps
; over the 1ms associated with the 1KHz PRF.
;
; The ISR is self contained and all registers used are preserved. Scratch pad memory
; locations are used to determine the desired duty factor for each of 8 channels.
;
; Note that an interrupt is generated every 196 clock cycles. This means that there is
; only time to execute 98 instructions between each interrupt. This ISR is 35 instructions
; long. A further 3 instructions are also consumed by the interrupt process
; (abandoned instruction, virtual CALL to 3FF and the interrupt vector JUMP) and hence
; PicoBlaze has approximately 63% of its time available for other tasks in the main program.
;
; Although a loop would normal be employed in software to process each of 8 channels,
; the implementation of a loop would increase the number of instructions which needed to
; be executed significantly reduce the time available for the main program to operate.
; Consequently the code is written out in a linear fashion which consumes more program
; space but which executes faster.
;
ISR: STORE s0, ISR_preserve_s0 ;preserve registers to be used
STORE s1, ISR_preserve_s1
STORE s2, ISR_preserve_s2
;Determine the number of steps currently through the 1ms PWM cycle
FETCH s1, PWM_duty_counter ;read 8-bit counter of steps
ADD s1, 01 ;increment counter (will roll over to zero)
STORE s1, PWM_duty_counter ;update count value in memory for next interrupt.
;Read duty factor for each channel and compare it with the duty counter and set or
;reset a bit in register s2 accordingly.
FETCH s0, PWM_channel7 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel6 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel5 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel4 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel3 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel2 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel1 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel0 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
OUTPUT s2, LED_port ;drive LEDs
FETCH s0, ISR_preserve_s0 ;restore register values
FETCH s1, ISR_preserve_s1
FETCH s2, ISR_preserve_s2
RETURNI ENABLE
;
;
;**************************************************************************************
; Interrupt Vector
;**************************************************************************************
;
ADDRESS 3FF
JUMP ISR
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -