;*************************************************************************** ; FILE: medusa.asm * ; CONTENTS: Medusa * ; COPYRIGHT: MadLab Ltd. 2025 * ; AUTHOR: James Hutchby * ; UPDATED: 16/02/25 * ;*************************************************************************** ; mux could limit number of leds on at a time to 4 say processor 12F1840 include "p12f1840.inc" ifdef __DEBUG __config _CONFIG1, _FOSC_INTOSC&_WDTE_OFF&_PWRTE_OFF&_MCLRE_ON&_CP_OFF&_CPD_OFF&_BOREN_OFF&_CLKOUTEN_OFF&_IESO_OFF&_FCMEN_ON&h'3fff' __config _CONFIG2, _WRT_OFF&_PLLEN_OFF&_STVREN_ON&_BORV_19&_LVP_OFF&h'3fff' else __config _CONFIG1, _FOSC_INTOSC&_WDTE_ON&_PWRTE_ON&_MCLRE_OFF&_CP_OFF&_CPD_OFF&_BOREN_OFF&_CLKOUTEN_OFF&_IESO_OFF&_FCMEN_ON&h'3fff' __config _CONFIG2, _WRT_ALL&_PLLEN_OFF&_STVREN_ON&_BORV_19&_LVP_OFF&h'3fff' endif ; __idlocs h'' errorlevel -207,-302,-305,-311 ;*************************************************************************** ; * ; Specification * ; * ;*************************************************************************** ; power-up self-test - LED noodles lit in turn ; patterns displayed at random ;*************************************************************************** ; * ; Port assignments * ; * ;*************************************************************************** PORTA_IO equ b'111111' ; PORTA status BUTTON equ 3 ; pushbutton LED_MASK equ b'110011' ; charlieplexed LEDs MUX1 equ 5 ; R1 MUX2 equ 4 ; R2 MUX3 equ 1 ; R3 MUX4 equ 0 ; R4 LED1_TRIS equ PORTA_IO^(1<>2)<<2 while i > d'128' call delay128 ; [128] i -= d'128' endw while i > d'64' call delay64 ; [64] i -= d'64' endw if i >= d'16' variable n = (i-d'16')/d'8' call delay16-n ; [8+8n+8] i -= (n*d'8')+d'16' endif while i >= d'4' nop ; [4] i -= d'4' endw endif endm ;--------------------------------------------------------------------------- ; multiplexes the LEDs, fed with the wait in 1/100s in the w reg ;--------------------------------------------------------------------------- routine mux_leds led macro TRIS_,LAT_,duty_ local mux0 ; tstf duty_ ; bz mux0 movlb 2 ; [4] movlw ~LED_MASK ; [4] andwf LATA ; [4] movlb 1 ; [4] movlf TRIS_,TRISA ; [8] movlb 2 ; [4] movfw duty_ ; [4] subwf phase,w ; [4] movlw LAT_ ; [4] skpc ; [4/8] iorwf LATA ; [4/0] movlb 0 ; [4] ITERS equ d'100' delay CLOCK/(d'100'*NUM_LEDS*ITERS)-d'56' mux0 clrwdt ; [4] endm movwf work mux1 movlf ITERS,work1 mux2 led LED1_TRIS,LED1_LAT,duty1 led LED2_TRIS,LED2_LAT,duty2 led LED3_TRIS,LED3_LAT,duty3 led LED4_TRIS,LED4_LAT,duty4 led LED5_TRIS,LED5_LAT,duty5 led LED6_TRIS,LED6_LAT,duty6 led LED7_TRIS,LED7_LAT,duty7 led LED8_TRIS,LED8_LAT,duty8 led LED9_TRIS,LED9_LAT,duty9 led LED10_TRIS,LED10_LAT,duty10 led LED11_TRIS,LED11_LAT,duty11 led LED12_TRIS,LED12_LAT,duty12 incf phase decfsz work1 goto mux2 decfsz work goto mux1 movlb 2 movlw ~LED_MASK andwf LATA movlb 0 return ;--------------------------------------------------------------------------- ; waits, fed with the wait in 1/100s in the w reg ;--------------------------------------------------------------------------- routine wait movwf loop wait1 movlf CLOCK/(d'100'*d'16'*d'256'),work wait2 clrf work1 wait3 clrwdt ; [4] decfsz work1 ; [4] goto wait3 ; [8] decfsz work goto wait2 decfsz loop goto wait1 return ;--------------------------------------------------------------------------- ; generates a pseudo random number ;--------------------------------------------------------------------------- routine get_random movfw rand_l iorwf rand_h,w bnz getr1 movfw TMR0 ; seed generator movwf rand_l xorlw h'ff' movwf rand_h getr1 rlf rand_h,w ; calculate next in sequence xorwf rand_h,w movwf work1 ; msb <= Q15 ^ Q14 swapf rand_l,w btfsc rand_h,4 xorlw h'80' ; msb <= Q12 ^ Q3 xorwf work1 rlf work1 rlf rand_l rlf rand_h ; << 1 + (Q15 ^ Q14 ^ Q12 ^ Q3) movfw rand_l return ;--------------------------------------------------------------------------- ; initialises the hardware ;--------------------------------------------------------------------------- routine init_hardware movlb 0 ; bank 0 movlp 0 ; page 0 movlb 2 ; initialise port clrf LATA movlb 1 movlf PORTA_IO,TRISA movlb 0 movlb 1 ; weak pull-ups enabled movlf b'00001000',OPTION_REG movlb 0 movlb 4 movlf 1<