📄 serial.asm
字号:
;==============================================================
; Knoll Uart to I2C converter
; Original Version: 1.0
; Original Release Date:
;==============================================================
; Version Description:
; Version 1.01P - TDA's are working, Channels 1-3 and Inputs 1-3 can be selected
; Version 1.02P - Added 6K7 support, tested channels 1-7 out of amps 1-6
; Version 1.03P - Changed command structure to (xxx!nnn)
; Version 1.04P - Vol and Input Sel Functional
; Veriosn 1.05P - First debugged version sent to Knoll, all zones tested.
; Version 1.06P - Chnaged to 18F2420, fixed bugs in A/D POR
; Version 1.07P - added Bass and Treble commands
; Version 1.08P - added read volume command
; Version 1.09P = fixed bug in "all" commands by resetting all TDA's before any
; command is sent to them.
;Version 1.10P = Added basic keypad responses and ack
;Version 1.11P = Added full command set from keypads.
;Version 1.00 - first production version with all debugging.
;Version 1.01 - fixed bug in bass/treble translate from keypad
;Version 1.02 - more fixes
;Version 1.03 - amp now saves bass/treble settings, can auto-calibrate with keypad
;Version 1.04 - implemented talk routine, fixed all up/down volumes
;Version 2.00 - changed timing, removed ack
;Version 2.01 - added "all off" (aof) command through serial
;Version 2.02 - 5/2/7 buglist
; started reflecting UART commands out through com wire. Volume does not!
; changed trigger output - any channel on, port B7 goes high.
; removed external osc.
; RESET TDA on ACK ERROR! Allows transparent recovert from keypress....
; Other changes in keypad firmware
;Version 2.03 - Changed send2TDA timing, added wait states
;Version 2.04 - Fixed bug in "all" from keypad, reset of TDA's new implemented.
;Version 2.05 - Fixed bug in resetting TDA's - was sending wrong volume and not
; clearing "b_tdaonly" when completed.
;Version 3.00 - Added Balance feature, clean up "nops" for crossing PCH alignment
;Version 3.01 - Fixed bug from balance feature in "all" function
;Version 3.02 - Working at Leviton Labs, implemented party mode, all v jump to speed volume
;Version 3.04 - Changed for version control
;Version 3.05 - fixed minor bugs, all vol down ch 4, p mode ch 5, added comma between commands
;
;==============================================================
;Used for developing the Sensor Controller Serial Routines
;for I2C router
;==============================================================
; File INCLUDES
; Include the Standard Microchip Include Files
; by Processor Type
;==============================================================
;Set the processor variables
list p=18F2420
include "p18F2420.inc"
include "myconfig.inc" ;adapted for config bits
include "system_var.inc"
include "RAM.inc"
;Program Configuration Register 1H
; __CONFIG _CONFIG1H, _XT_OSC_1H
; __CONFIG _CONFIG2L, _BOR_ON_2L & _BORV_42_2L & _PWRT_ON_2L
; __CONFIG _CONFIG2H, _WDT_OFF_2H
;==============================================================
;This is the start of the actual running code ....
;==============================================================
ORG 0 ;Power on reset address
nop ;nop for ICD
bra START ;jump to program start
;==============================================================
;Here is the interrupt vector
;==============================================================
ORG 0x008 ;Interrupt service routines (no priority)
INT?1
btfss PIR1,RCIF ;check for an interrupt flag from the UART
goto INT?2 ;skip if none
movf RCREG,W ;pull into W, auto clears flag
movwf RECBUFF ;Save copy in RECBUFF
bsf FLAG1,b_IPENDING ;set service request flag
goto INTDONE
INT?2
INTDONE
retfie FAST ;Return from interrupt(s)
;===========================================================
;Start of Program
;===========================================================
START
call BOOT
;******************************************************************
;Main code loop. Check for serial commands, execute, and loop back
;wait.
;******************************************************************
MAIN
btfsc FLAG1,b_IPENDING ;check for a serial command interrupt
goto GETCHAR
btfsc FLAG1,b_pending ;state machine
call states
;test loop for I2C to keypads
; bcf TRISA,2
; bcf TRISA,3
;testloop
; btg SDA1 ;PORTA,3 - RC7 on keypad
; movlw 0x0f
; call LONG_DELAY
; btg SCK1 ;PORTA,2 - RB1/INT1 on keypad
; movlw 0x0f
; call LONG_DELAY
; bra testloop
btfss SDA1 ;look for SDA to drop
call I2C_get
;look for paging input....
btfss PAGE_IN
call paged
;look for trigger.....
movf CHANNELS,f
bz MAIN_1
bsf PORTB,7
bra MAIN
MAIN_1
bcf PORTB,7
bra MAIN
;*********************************************************
;*********************************************************
;STATE MACHINE
;*********************************************************
;*********************************************************
states
movf PCL,w ;false read to update PCU,PCH
movf current_state,w
addwf PCL,F ;jump to next state!
bra state0 ;current_state = "0", first char decode
bra state1 ;current_state = "2", ACK test to keypads
bra statev ;current_state = "4", char is a v
bra statevr ;currnet_state = "6", char is vr - version)
bra statevr? ;current_state = "8", char is vr? - send version after ")"
bra statevl ;current_state = "10", char is vl (volume)
bra statevlx ;12
bra a_statevlxx ;14
bra a_statevlxx_end ;16
bra a_state3 ;current_state = "18", system reset
bra a_staterx_end ;current_state = "20", look for ) on reset
; bra state4 ;current_state = "8", set keypad zone
; bra state5 ;current_state = "10",internal TDA ack test
bra a_state6 ;current_state = "22",turn on individual amps
bra a_state_on ;24 - turn on a,ps
bra a_state_off ;26 - turn off amps
bra a_statem ;28 - look for mute
bra a_statem_end ;30
bra a_stateu ;32
bra a_stateu_end ;34
bra a_state8 ;36 current_state = "36", send command to TDA's
;Do NOT USE STATE 8 for INPUT SELECT! for 6K7!!!!!!!
bra a_state9 ;38 - setup looking for "l" after s (sl)
bra a_state_sl ;40
bra a_state_slx ;42
bra a_state_sl_end ;44 input has been decoded and sent to the 16F627A,
;you MUST still use STATE 8
bra statebx ;46 - bass value
bra statebx_end ;48 - end bass
bra statetx ;50 - treble value
bra statetx_end ;52 - treble end
bra a_statevl?_end ;54 - request volume
bra stateax ;56
bra state_am ;58
bra state_au ;60
bra state_av ;62
bra state_as ;64
bra state_amu ;66
bra state_aum ;68
bra state_avlx ;70
bra state_aslx ;72
bra state_avlxx ;74
bra state_avlxx_end ;76
bra state_asl_end ;78
bra state_ao ;80 - all off
bra state_aof ;82 - all off
;have to extend addressing...........
a_statevl?_end
goto statevl?_end
a_state_slx
goto state_slx
a_state_sl_end
goto state_sl_end
a_state6
goto state6
a_state_on
goto state_on
a_state_off
goto state_off
a_statem
goto statem
a_statem_end
goto statem_end
a_stateu
goto stateu
a_stateu_end
goto stateu_end
a_state8
goto state8
a_state9
goto state9
a_state_sl
goto state_sl
a_staterx_end
goto staterx_end
a_state3
goto state3
a_statevlxx
goto statevlxx
a_statevlxx_end
goto statevlxx_end
;*********************************************************
; STATE0, main entry point
;*********************************************************
;state 0 will decode command character, and also inital decimal (amp select).
;Following states can just look in var current_channel to view amp.
;entry command char ( is decoded by get_char, but ending ) must be manually
;decoded and b_tilda cleared at end of states.
state0
bcf FLAG1,b_pending
movlw "k"
cpfseq RECBUFF
bra s0_1
goto state1 ;I2C ACK test - SINGLE KEYPAD ON ANY ZONE (0-16) ONLY!
s0_1
movlw "v"
cpfseq RECBUFF
bra s0_2
goto statev ;Char is v, could be version or volume
s0_2
movlw "r"
cpfseq RECBUFF
bra s0_3
goto state3 ;System Reset
s0_3
movlw "c" ;dummy placement - there is no "c"
cpfseq RECBUFF
bra s0_4
goto state4 ;set zone - SINGLE KEYPAD ONLY!
s0_4
movlw "i"
cpfseq RECBUFF
bra s0_5
goto state5 ;internal ack test - look for TDA's
s0_5
movlw "o"
cpfseq RECBUFF
bra s0_6
goto state6 ;on or off, need to further decode
s0_6
movlw "e"
cpfseq RECBUFF
bra s0_7
; goto state7 ;disabled
s0_7
movlw "1"
cpfseq RECBUFF
bra s0_8
movlw 0x01
movwf current_channel
return
s0_8
movlw "2"
cpfseq RECBUFF
bra s0_9
movlw 0x02
movwf current_channel
return
s0_9
movlw "3"
cpfseq RECBUFF
bra s0_10
movlw 0x03
movwf current_channel
return
s0_10
movlw "4"
cpfseq RECBUFF
bra s0_11
movlw 0x4
movwf current_channel
return
s0_11
movlw "5"
cpfseq RECBUFF
bra s0_12
movlw 0x05
movwf current_channel
return
s0_12
movlw "6"
cpfseq RECBUFF
bra s0_13
movlw 0x06
movwf current_channel
return
s0_13
movlw "s"
cpfseq RECBUFF
bra s0_14
goto state9
s0_14
movlw "m"
cpfseq RECBUFF
bra s0_15
goto statem ;mute
s0_15
movlw "u"
cpfseq RECBUFF
bra s0_16
goto stateu ;unmute
s0_16
movlw "b"
cpfseq RECBUFF
bra s0_17
goto stateb ;bass or balance....
s0_17
movlw "t"
cpfseq RECBUFF
bra s0_18
goto statet ;treble
s0_18
movlw "a"
cpfseq RECBUFF
bra s0_19
goto statea
s0_19
command_error
call String_ERROR2 ;unrecognized command
bcf FLAG3,b_TILDA ;get ready for next command
bcf FLAG1,b_pending
clrf current_state
return
state1
clrf zones ;clear zones register
bcf FLAG3,b_ACKERROR ;start with ack error clear
movlw zone1_add ;load address of zone1
call checkzone ;check for keypad
btfsc FLAG3,b_ACKERROR ;check for ack error
bra s1_0 ;if ack error, skip response
call String_ZONE1 ;if no error, send zone
bsf zones,zone1 ;set bit for zone1 here
s1_0
bcf FLAG3,b_ACKERROR ;do same for zones 2,3,4
movlw zone2_add
call checkzone
btfsc FLAG3,b_ACKERROR
bra s1_1
call String_ZONE2
bsf zones,zone2
s1_1
bcf FLAG3,b_ACKERROR
movlw zone3_add
call checkzone
btfsc FLAG3,b_ACKERROR
bra s1_2
call String_ZONE3
bsf zones,zone3
s1_2
bcf FLAG3,b_ACKERROR
movlw zone4_add
call checkzone
btfsc FLAG3,b_ACKERROR
bra s1_3
call String_ZONE4
bsf zones,zone4
s1_3
movf zones,w
bz S1_4
return
S1_4
call String_ERROR3 ;if no zones ack'd, then error code
return
checkzone
movwf I2CBUF ;start with address 0 in I2C buff
bcf SDA1 ;drop SDA, (send START) condition
call WAIT_STATE ;give slaves time to respond
bcf SCK1 ;drop SCK so we can change SDA
;without getting a stop condition
call SEND_I2C ;call send I2C routine
bcf SDA1 ;make sure SDA is low (send STOP)
call WAIT_STATE
bsf SCK1 ;raise SCK
call WAIT_STATE
bsf SDA1 ;raise SDA
btfss FLAG3,b_ACKERROR ;if no error, skip jmp
bsf zones,zone1
return
call String_ERROR3 ;no keypad detected
bcf FLAG2,b_TILDA
return
;--------------------------------------------------------------------------------------------------------------
statea
;--------------------------------------------------------------------------------------------------------------
;we have a a, so is all command. We have no zone number!
;now decipher command!
bcf FLAG1,b_pending
movlw d'56'
movwf current_state
return
;-----------
; ax - what is x?
stateax
bcf FLAG1,b_pending
movlw "m"
cpfseq RECBUFF
bra ax_0
bra am
ax_0
movlw "u"
cpfseq RECBUFF
bra ax_1
bra au
ax_1
movlw "v"
cpfseq RECBUFF
bra ax_2
bra av
ax_2
movlw "s"
cpfseq RECBUFF
bra ax_3
bra as
ax_3
movlw "o"
cpfseq RECBUFF
bra ax_4
bra ao
ax_4
goto command_error
as
movlw d'64'
movwf current_state
return
am
movlw d'58'
movwf current_state
return
au
movlw d'60'
movwf current_state
return
av
movlw d'62'
movwf current_state
return
ao movlw d'80'
movwf current_state
return
;-----------------------
state_am
bcf FLAG1,b_pending
movlw "u"
cpfseq RECBUFF
goto command_error
movlw d'66'
movwf current_state
return
state_au
bcf FLAG1,b_pending
movlw "m"
cpfseq RECBUFF
goto command_error
movlw d'68'
movwf current_state
return
state_av
bcf FLAG1,b_pending
movlw "l"
cpfseq RECBUFF
goto command_error
movlw d'70'
movwf current_state
return
state_as
bcf FLAG1,b_pending
movlw "l"
cpfseq RECBUFF
goto command_error
movlw d'72'
movwf current_state
return
state_ao
bcf FLAG1,b_pending
movlw "f"
cpfseq RECBUFF
goto command_error
movlw d'82'
movwf current_state
return
;--------------------------
state_amu
bcf FLAG1,b_pending
movlw ")"
cpfseq RECBUFF
goto command_error
;now send mute on
bsf FLAG2,b_tdaonly
movlw 0x06
movwf current_subadd
movlw 0x00
movwf current_data
movlw 1
movwf current_channel
call send2TDA ;ch 1
incf current_channel,f
call wait_4
call send2TDA ;ch 2
incf current_channel,f
call wait_4
call send2TDA ;ch 3
incf current_channel,f
call wait_4
call send2TDA ;ch 4
incf current_channel,f
call wait_4
call send2TDA ;ch 5
incf current_channel,f
call wait_4
call send2TDA ;ch 6
;don't forget to clear the state....
bcf FLAG2,b_tdaonly
clrf current_state
bcf FLAG3,b_TILDA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -