Greetings,
I'm attempting to make an aquarium light with some neopixels but part of the code refuses to work and it's got me stumped.
What it does: Uses a PIC16F88 to drive a strip of 21 neopixels. There are 7 settings, the first 4 are plain white decreasing in brightness, the other 3 are shimmer effects which are achieved by scrolling colours copied from the data memory. This is the part which doesnt work. Everything else works as expected but the 3 later settings do nothing (just appear to be a copies of setting 4)
It uses the TMR2 interrupt and polls for a button press on RA0 to change the setting. This works. The neopixel code works (since it displays the solid white values). For some reason its either not copying the data memory contents to the 'screen memory' (pointed at by FSR) or its not calling the display function (f1_main) from the interrupt. I cant find anything wrong with the code there so maybe another set of eyes might spot something. Here is the code (uses my own assembler but shouldnt be too different from mainstream ones):
; =======================================
; Aquarium Light v0.1
; (c) 2018 Peter Hanratty
; =======================================
include f:\picprog\lib\pic16f88_reg.inc
; ---------------------------------------
equ func_count 7
equ pix_numlights 21
equ pix_numbytes 63
; ---------------------------------------
equ screen_addr 20h
equ pix_g 70h
equ pix_r 71h
equ pix_b 72h
equ pix_bits 73h
equ pix_bytes 74h
equ func_current 75h
equ func_select 76h
equ temp_s 77h
equ temp_d 78h
equ temp_c 79h
equ temp_b 7ah
; ---------------------------------------
; Reset and interrupt vectors
org 000h
goto init
; ---------------------------------------
org 004h
clrf status ; Bank 0
call f1_main
movf porta, w
movwf temp_b
btfss temp_b, 0
call changefunc
movf temp_b, w
xorlw 01h
movwf func_select
bcf pir1, 1
retfie
; =======================================
init:
; (dont) Set oscillator (HS, 16 MHz)
movlw 20h
movwf status ; Bank 1
clrf osccon
; Init PORTA (digital input)
clrf ansel
movlw ffh
movwf trisa
; Init PORTB (input, rb0=output)
movlw feh
movwf trisb
clrf status ; Bank 0
clrf portb
; Enable Interrupt
movlw c0h ; GIE, PEIE
movwf intcon
bsf status, 5 ; Bank 1
bsf pie1, 1 ; TMR2IE
; Set up TMR2
bcf pr2, 7 ; PR2 = 7fh
clrf status ; Bank 0
movlw 09h ; Pre:4, Post:16, Off
movwf t2con
; Init first function
clrf func_current
incf func_current, f
clrf func_select
call f1_init
; Start TMR2
bsf t2con, 2
goto main
; =======================================
changefunc:
btfsc func_select, 0
return
incf func_current, f
btfss func_current, 3
goto f1_init
movlw 1
movwf func_current
goto f1_init
; =======================================
fillstrip:
movlw screen_addr
movwf fsr
movlw pix_numlights
movwf pix_bytes
fillmem:
movf pix_g, w
movwf indf
incf fsr, f
movf pix_r, w
movwf indf
incf fsr, f
movf pix_b, w
movwf indf
incf fsr, f
decfsz pix_bytes, f
goto fillmem
return
; =======================================
colshuffle: ; shuffle pixels along
movlw 3
sublw pix_numbytes
movwf temp_c
addlw screen_addr
movwf temp_s
addlw 3
movwf temp_d
decf temp_s, f
decf temp_d, f
movf temp_d, w
movwf fsr
movf indf, w
movwf pix_b
decf fsr, f
movf indf, w
movwf pix_r
decf fsr, f
movf indf, w
movwf pix_g
colshuffle_loop:
movf temp_s, w
movwf fsr
movf indf, w
movwf temp_b
movf temp_d, w
movwf fsr
movf temp_b, w
movwf indf
decf temp_s, f
decf temp_d, f
decfsz temp_c, f
goto colshuffle_loop
movlw screen_addr
movwf fsr
movf pix_g, w
movwf indf
incf fsr, f
movf pix_r, w
movwf indf
incf fsr, f
movf pix_b, w
movwf indf
return
; =======================================
showpixels: ; Shift out pixel information
; Cycles: 19 per pixel + 35
movlw screen_addr
movwf fsr
movlw pix_numbytes
movwf pix_bytes
showbyte:
movlw 8
movwf pix_bits
movf indf, w
movwf temp_s
showbit:
btfsc temp_s, 7
goto highbit
nop
bsf portb, 0
bcf portb, 0
goto nextbit
highbit:
bsf portb, 0
nop
nop
bcf portb, 0
nextbit:
rlf temp_s, f
decfsz pix_bits, f
goto showbit
incf fsr, f
decfsz pix_bytes, f
goto showbyte
;movlw 10
;movwf temp_s
;pixwait: ; Delay for screen update
;decfsz temp_s, f
;goto pixwait
return
; =======================================
f1_init:
movf func_current, w
movwf temp_s
movlw ffh
decfsz temp_s, f
goto f2_init
goto f1_4_init
; ---------------------------------------
f2_init:
movlw c0h
decfsz temp_s, f
goto f3_init
goto f1_4_init
; ---------------------------------------
f3_init:
movlw 80h
decfsz temp_s, f
goto f4_init
goto f1_4_init
; ---------------------------------------
f4_init:
movlw 40h
decfsz temp_s, f
goto f5_init
goto f1_4_init
; ---------------------------------------
f5_init:
clrw
decfsz temp_s, f
goto f6_init
goto f5_7_init
; ---------------------------------------
f6_init:
addlw pix_numbytes
decfsz temp_s, f
goto f7_init
goto f5_7_init
; ---------------------------------------
f7_init:
addlw pix_numbytes
goto f5_7_init
; ---------------------------------------
f1_4_init:
movwf pix_g
movwf pix_r
movwf pix_b
call fillstrip
call showpixels
return
; ---------------------------------------
f5_7_init:
bsf status, 6 ; Bank 2
movwf eeadr
movlw screen_addr
movwf fsr
movlw pix_numbytes
movwf temp_c
f5_7_copy:
bsf status, 5 ; Bank 3
bcf eecon1, 7 ; Point to data memory
bsf eecon1, 0 ; Data memory read
bcf status, 5 ; Bank 2
movf eedata, w
movwf indf
incf eeadr, f
incf fsr, f
decfsz temp_c, f
goto f5_7_copy
clrf status ; Bank 0
return
; =======================================
f1_main:
movlw 5
subwf func_current, w
btfsc status, 0
return ; f1-4 = static light (do nothing)
f5_7_main:
call showpixels
call colshuffle
return
; =======================================
main:
nop
goto main
; =======================================