mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-28 07:02:55 +08:00
573 lines
32 KiB
Plaintext
573 lines
32 KiB
Plaintext
; KCPSM3 Program - LED control with Pulse Width Modulation (PWM).
|
|
;
|
|
; Design provided for use with the design 'low_cost_design_authentication_for_spartan_3e.vhd'
|
|
; and the Spartan-3E Starter Kit. This design provides the token 'real' application to be
|
|
; protected by design authentication.
|
|
;
|
|
; Ken Chapman - Xilinx Ltd
|
|
;
|
|
; Version v1.00 - 9th November 2006
|
|
;
|
|
; This code automatically sequences the LEDs on the board using PWM to change intensity.
|
|
; It also checks for correct design authentication and will perform a different sequence if
|
|
; the design is not authorised.
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; NOTICE:
|
|
;
|
|
; Copyright Xilinx, Inc. 2006. This code may be contain portions patented by other
|
|
; third parties. By providing this core as one possible implementation of a standard,
|
|
; Xilinx is making no representation that the provided implementation of this standard
|
|
; is free from any claims of infringement by any third party. Xilinx expressly
|
|
; disclaims any warranty with respect to the adequacy of the implementation, including
|
|
; but not limited to any warranty or representation that the implementation is free
|
|
; from claims of any third party. Furthermore, Xilinx is providing this core as a
|
|
; courtesy to you and suggests that you contact all third parties to obtain the
|
|
; necessary rights to use this implementation.
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Port definitions
|
|
;**************************************************************************************
|
|
;
|
|
;
|
|
;
|
|
CONSTANT LED_port, 80 ;8 simple LEDs
|
|
CONSTANT LED0, 01 ; LD0 - bit0
|
|
CONSTANT LED1, 02 ; LD1 - bit1
|
|
CONSTANT LED2, 04 ; LD2 - bit2
|
|
CONSTANT LED3, 08 ; LD3 - bit3
|
|
CONSTANT LED4, 10 ; LD4 - bit4
|
|
CONSTANT LED5, 20 ; LD5 - bit5
|
|
CONSTANT LED6, 40 ; LD6 - bit6
|
|
CONSTANT LED7, 80 ; LD7 - bit7
|
|
;
|
|
CONSTANT LED_read_port, 00 ;read back of current LED drive values
|
|
;
|
|
;
|
|
CONSTANT security_request_port, 40 ;Port to stimulate security KCPSM3 processor
|
|
CONSTANT security_interrupt, 01 ; interrupt - bit0
|
|
;
|
|
;
|
|
;A FIFO buffer links the security KCPSM3 processor to the application KCPSM3 processor.
|
|
; This application processor controls and reads the FIFO.
|
|
; The security processor writes to the FIFO.
|
|
;
|
|
CONSTANT link_fifo_control_port, 20 ;FIFO control
|
|
CONSTANT link_fifo_reset, 01 ; reset - bit0
|
|
;
|
|
CONSTANT link_FIFO_status_port, 01 ;FIFO status input
|
|
CONSTANT link_FIFO_data_present, 01 ; half full - bit0
|
|
CONSTANT link_FIFO_half_full, 02 ; full - bit1
|
|
CONSTANT link_FIFO_full, 04 ; data present - bit2
|
|
;
|
|
CONSTANT link_FIFO_read_port, 02 ;read FIFO data
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Special Register usage
|
|
;**************************************************************************************
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
;Scratch Pad Memory Locations
|
|
;**************************************************************************************
|
|
;
|
|
CONSTANT PWM_duty_counter, 00 ;Duty Counter 0 to 255 within 1KHz period (1ms)
|
|
CONSTANT PWM_channel0, 01 ;PWM settings for each channel
|
|
CONSTANT PWM_channel1, 02 ; Channels 0 to 7 = LEDs 0 to 7
|
|
CONSTANT PWM_channel2, 03
|
|
CONSTANT PWM_channel3, 04
|
|
CONSTANT PWM_channel4, 05
|
|
CONSTANT PWM_channel5, 06
|
|
CONSTANT PWM_channel6, 07
|
|
CONSTANT PWM_channel7, 08
|
|
CONSTANT ISR_preserve_s0, 0D ;preserve register contents during Interrupt Service Routine
|
|
CONSTANT ISR_preserve_s1, 0E
|
|
CONSTANT ISR_preserve_s2, 0F
|
|
;
|
|
;
|
|
CONSTANT LED0_sequence, 10 ;LED sequence values
|
|
CONSTANT LED1_sequence, 11
|
|
CONSTANT LED2_sequence, 12
|
|
CONSTANT LED3_sequence, 13
|
|
CONSTANT LED4_sequence, 14
|
|
CONSTANT LED5_sequence, 15
|
|
CONSTANT LED6_sequence, 16
|
|
CONSTANT LED7_sequence, 17
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
;Useful data constants
|
|
;**************************************************************************************
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
;Initialise the system
|
|
;**************************************************************************************
|
|
;
|
|
; All PWM channels initialise to off (zero).
|
|
; Simple I/O outputs will remain off at all times.
|
|
;
|
|
cold_start: LOAD s0, 00
|
|
LOAD s1, PWM_channel0
|
|
clear_loop: STORE s0, (s1)
|
|
COMPARE s1, PWM_channel7
|
|
JUMP Z, enable_int
|
|
ADD s1, 01
|
|
JUMP clear_loop
|
|
;
|
|
enable_int: ENABLE INTERRUPT ;interrupts used to set PWM frequency
|
|
;
|
|
;
|
|
; Initialise LED pattern sequence
|
|
;
|
|
LOAD s0, 01 ;trigger to start wave pattern
|
|
STORE s0, LED0_sequence
|
|
LOAD s0, 00
|
|
STORE s0, LED1_sequence
|
|
STORE s0, LED2_sequence
|
|
STORE s0, LED3_sequence
|
|
STORE s0, LED4_sequence
|
|
STORE s0, LED5_sequence
|
|
STORE s0, LED6_sequence
|
|
STORE s0, LED7_sequence
|
|
;
|
|
;
|
|
; Reset authentication check counter
|
|
;
|
|
LOAD sF, 00
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Main program
|
|
;**************************************************************************************
|
|
;
|
|
; Provides a pattern of interest on the LEDs :-)
|
|
;
|
|
; Each LED increases intensity in 8 steps and then decreases intensity in 8 steps until it is off.
|
|
; The middle LEDs (LD2 to LD5) each start to turn on when either neighbour is turned half on and increasing
|
|
; to provide the effect of a passing a 'wave' of light passing from side to side. The pair of LEDs at each
|
|
; (LD0, Ld1 and LD6, LD7) are required to reflect the 'wave' so that the pattern continues.
|
|
;
|
|
; I'm sure this code cold be written in more elegant way, but I leave that as an exercise to you :-)
|
|
;
|
|
;
|
|
; Using a simple software counter (implemented by register sF) the design occasionally requests an
|
|
; authorisation message from the authentication processor. If it receives a PASS message it continues
|
|
; normally but if it receives a FAIL message the LED pattern is changed.
|
|
;
|
|
;
|
|
;
|
|
warm_start: ADD sF, 01 ;authentication check timer
|
|
JUMP C, authentication_check ;Check made approximately every 8 seconds.
|
|
;
|
|
normal_LED_sequence: LOAD s2, 03 ;simple delay loop (delay will be increased by ISR processing)
|
|
delay_s2_loop: LOAD s1, FF
|
|
delay_s1_loop: LOAD s0, FF
|
|
delay_s0_loop: SUB s0, 01
|
|
JUMP NC, delay_s0_loop
|
|
SUB s1, 01
|
|
JUMP NC, delay_s1_loop
|
|
SUB s2, 01
|
|
JUMP NC, delay_s2_loop
|
|
;
|
|
;Pattern generation
|
|
;
|
|
FETCH s0, LED0_sequence ;read sequence for LED0
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED0_start
|
|
SUB s0, 20 ;Count longer to ensure end stops then reset count if maximum
|
|
JUMP Z, update_LED0
|
|
ADD s0, 20
|
|
inc_LED0: ADD s0, 01 ;increment counter
|
|
JUMP update_LED0
|
|
test_LED0_start: FETCH s1, LED1_sequence ;start LED0 if LED1 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED0
|
|
update_LED0: STORE s0, LED0_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel0
|
|
;
|
|
FETCH s1, LED0_sequence ; refresh LED1 if LED0 = 11 (0B hex) to reflect wave
|
|
COMPARE s1, 0B
|
|
JUMP NZ, normal_LED1
|
|
LOAD s0, 04
|
|
JUMP update_LED1
|
|
normal_LED1: FETCH s0, LED1_sequence ;read sequence for LED1
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED1_start
|
|
SUB s0, 10 ;reset count if maximum
|
|
JUMP Z, update_LED1
|
|
ADD s0, 10
|
|
inc_LED1: ADD s0, 01 ;increment counter
|
|
JUMP update_LED1
|
|
test_LED1_start: FETCH s1, LED0_sequence ;start LED1 if LED0 = 11 (0B hex) to reflect wave
|
|
COMPARE s1, 0B
|
|
JUMP Z, inc_LED1
|
|
FETCH s1, LED2_sequence ;start LED1 if LED2 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED1
|
|
update_LED1: STORE s0, LED1_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel1
|
|
;
|
|
FETCH s0, LED2_sequence ;read sequence for LED2
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED2_start
|
|
SUB s0, 10 ;reset count if maximum
|
|
JUMP Z, update_LED2
|
|
ADD s0, 10
|
|
inc_LED2: ADD s0, 01 ;increment counter
|
|
JUMP update_LED2
|
|
test_LED2_start: FETCH s1, LED1_sequence ;start LED2 if LED1 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED2
|
|
FETCH s1, LED3_sequence ;start LED2 if LED3 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED2
|
|
update_LED2: STORE s0, LED2_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel2
|
|
;
|
|
;
|
|
FETCH s0, LED3_sequence ;read sequence for LED3
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED3_start
|
|
SUB s0, 10 ;reset count if maximum
|
|
JUMP Z, update_LED3
|
|
ADD s0, 10
|
|
inc_LED3: ADD s0, 01 ;increment counter
|
|
JUMP update_LED3
|
|
test_LED3_start: FETCH s1, LED2_sequence ;start LED3 if LED2 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED3
|
|
FETCH s1, LED4_sequence ;start LED3 if LED4 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED3
|
|
update_LED3: STORE s0, LED3_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel3
|
|
;
|
|
FETCH s0, LED4_sequence ;read sequence for LED4
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED4_start
|
|
SUB s0, 10 ;reset count if maximum
|
|
JUMP Z, update_LED4
|
|
ADD s0, 10
|
|
inc_LED4: ADD s0, 01 ;increment counter
|
|
JUMP update_LED4
|
|
test_LED4_start: FETCH s1, LED3_sequence ;start LED4 if LED3 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED4
|
|
FETCH s1, LED5_sequence ;start LED4 if LED5 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED4
|
|
update_LED4: STORE s0, LED4_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel4
|
|
;
|
|
FETCH s0, LED5_sequence ;read sequence for LED5
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED5_start
|
|
SUB s0, 10 ;reset count if maximum
|
|
JUMP Z, update_LED5
|
|
ADD s0, 10
|
|
inc_LED5: ADD s0, 01 ;increment counter
|
|
JUMP update_LED5
|
|
test_LED5_start: FETCH s1, LED4_sequence ;start LED5 if LED4 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED5
|
|
FETCH s1, LED6_sequence ;start LED5 if LED6 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED5
|
|
update_LED5: STORE s0, LED5_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel5
|
|
;
|
|
FETCH s1, LED7_sequence ; refresh LED6 if LED7 = 11 (0B hex) to reflect wave
|
|
COMPARE s1, 0B
|
|
JUMP NZ, normal_LED6
|
|
LOAD s0, 04
|
|
JUMP update_LED6
|
|
normal_LED6: FETCH s0, LED6_sequence ;read sequence for LED6
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED6_start
|
|
SUB s0, 10 ;reset count if maximum
|
|
JUMP Z, update_LED6
|
|
ADD s0, 10
|
|
inc_LED6: ADD s0, 01 ;increment counter
|
|
JUMP update_LED6
|
|
test_LED6_start: FETCH s1, LED5_sequence ;start LED6 if LED5 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED6
|
|
update_LED6: STORE s0, LED6_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel6
|
|
;
|
|
FETCH s0, LED7_sequence ;read sequence for LED7
|
|
COMPARE s0, 00
|
|
JUMP Z, test_LED7_start
|
|
SUB s0, 20 ;Count longer to ensure end stops then reset count if maximum
|
|
JUMP Z, update_LED7
|
|
ADD s0, 20
|
|
inc_LED7: ADD s0, 01 ;increment counter
|
|
JUMP update_LED7
|
|
test_LED7_start: FETCH s1, LED6_sequence ;start LED7 if LED6 = 4
|
|
COMPARE s1, 04
|
|
JUMP Z, inc_LED7
|
|
update_LED7: STORE s0, LED7_sequence
|
|
CALL LED_to_duty
|
|
STORE s1, PWM_channel7
|
|
JUMP warm_start
|
|
;
|
|
;
|
|
; Convert LED sequence number into PWM intensity figure
|
|
;
|
|
; LEDs duty cycle values are 0,1,2,4,8,16,32 and 64 because they appear to give what
|
|
; appears to be a fairly liner change in intensity and provides a simple way to set
|
|
; the duty value.
|
|
;
|
|
; Provide sequence value in register s0 and intensity will be
|
|
; returned in register s1.
|
|
;
|
|
; s0 s1
|
|
; 00 00
|
|
; 01 01
|
|
; 02 02
|
|
; 03 04
|
|
; 04 08
|
|
; 05 10
|
|
; 06 20
|
|
; 07 40
|
|
; 08 80
|
|
; 09 40
|
|
; 0A 20
|
|
; 0B 10
|
|
; 0C 08
|
|
; 0D 04
|
|
; 0E 02
|
|
; 0F 01
|
|
; 10 00 and zero for all larger values of s0
|
|
;
|
|
LED_to_duty: LOAD s1, 00
|
|
COMPARE s0, 00 ;test for zero
|
|
RETURN Z
|
|
LOAD s1, 01 ;inject '1'
|
|
go_up_loop: SUB s0, 01
|
|
RETURN Z
|
|
SL0 s1 ;multiply by 2
|
|
JUMP C, go_down
|
|
JUMP go_up_loop
|
|
go_down: LOAD s1, 40
|
|
go_down_loop: SUB s0, 01
|
|
RETURN Z
|
|
SR0 s1 ;divide by 2
|
|
JUMP go_down_loop
|
|
;
|
|
;
|
|
;
|
|
;**************************************************************************************
|
|
; Authentication Check and fail procedure
|
|
;**************************************************************************************
|
|
;
|
|
; 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
|
|
;
|
|
;
|