;====================================================================== ; POINTS include common.inc ;====================================================================== ; VARIABLES, HARDWARE, ETC ; ; Timer 3 pointmsg pointslave cducharging ; ; S Idle Off undefined undefined undefined ; S Firing Counting up 100PPPPP undefined undefined ; M Idle Off 00000000 0000 0000 0x00 ; M Firing Counting up 100PPPPP 0000 0000 0x00 ; M Telling Off 100PPPPP 00SS Sss0 0x00 ; M Told Off 100PPPPP 0000 0000 0x00 ; M Charging Off 00000000 0000 0000 >0 ; ; notes: firing see ie, slave*2 Counts down ; timeout detect.asm in ticks ; ; cducharging only counts if the cdu is enabled ; (according to CDU Enable LAT bit) cdu_timeout equ 300 ; ms cdu_inittimeout equ 750 ; ms ptix2latbit equ 0x300 ; has to be a multiple of 0x100 ptix2latbit_section udata ptix2latbit res maxpoints * 2 ; as produced by outpin_local_init udata_acs pointslave res 1 pointmsg res 1 cducharging res 1 udata 0x340 slave2ptinfo res maxpics slave2ptinfo_anypoints equ 0 ;====================================================================== ; LOCAL POINTS ; on slave, or master's own ;---------------------------------------------------------------------- ; LOCAL POINTS - ACTUALLY DOING near_local_do code ;---------------------------------------- point_local_do @ ; On slave, called during i2c receive, ie High ISR ; On master, called during serial receive, ie Low ISR ; W fire point msg undefined bt_f_if1 T3CON, TMR3ON bra point_clash mov_wf pointmsg ; pointmsg = SS zz zz pp pp pp pp pp intrlh_fsr0_save ; point_set_pin uses FSR0, see below call point_set_pin intrlh_fsr0_restore clr_f TMR3L ; also copies TMR3H into actual timer register bs_f T3CON, TMR3ON return ;---------- point_clash panic morse_PB points_section code ;---------------------------------------- points_local_intrl @ bt_f_if0 PIR2, TMR3IF return ; OK, it's us, and we're done changing a point: bt_f_if0 T3CON, TMR3ON bra point_spurious_intr rcall point_set_pin intrh_mask bc_f T3CON, TMR3ON bc_f PIR2, TMR3IF intrh_unmask mov_lw b'00100000' call message_for_master intrl_handled_nostack ;---------- point_spurious_intr panic morse_PI ;---------- point_set_pin ; Toggles the pin. The effect is: ; If we were idle, sets it H (to fire) unless pt0 in which case L ; If we were firing, sets it L (to stop) unless pt0 in which case H ; ; Called in various contexts, including both High and Low ISR. ; ; pointmsg point to start or stop firing preserved ; W,STATUS any undefined ; FSR0 any undefined ; all other any not interfered with ; mov_lw ptix2latbit >> 8 mov_wf FSR0H ; FSR0H -> table rl_fw pointmsg ; W = point addr, Z iff pt0 mov_wf FSR0L ; FSR0 -> &bit [Z still iff pt0] mov_fw POSTDEC0 ; W = bit, FSR0 -> &LAT* bra_z point_nonexistent mov_ff INDF0, FSR0L ; W = bit, FSR0L -> LAT* set_f FSR0H ; FSR0 -> LAT*, W = bit (still) xor_wff INDF0 ; pin = !pin return ;---------- point_nonexistent panic morse_PU ;---------------------------------------------------------------------- ; LOCAL POINTS - INITIALISATION ;---------------------------------------- points_local_init @ ; Initialises tables for points ; Clears TRIS* bits for all points and sets each pin to `not triggering' rcall point_timer_init outputs_local_init picno2ptmap, maxpoints, ptix2latbit, bkptix2portnumbitnum return ;---------- point_timer_init bt_f_if1 idloc1,idloc1_master bra point_timer_init_if_master ; slave: mov_lw (1< 1 0100 TTT O TTTTTTT ; ie 1010 0SSS ; OssT tttt tst_f_ifnz pointmsg bra command_point_busy tst_f_ifnz cducharging bra command_point_cduempty swap_fw POSTINC0 ; W = 0SSS 1010 and_lw 0x70 ; W = 0SSS 0000 rr_w ; W = 00SS S000 mov_wf pointslave ; pointslave = 00SS S000 mov_fw INDF0 ; W = OssT tttt N = O bra_n command_point_badmsg ; OK: ; W = 0ssT tttt and_lw 0x1f ; W = 000T tttt bs_w 7 ; W = 100T tttt mov_wf pointmsg ; pointmsg = 100T tttt swap_fw INDF0 ; W = tttt 0ssT and_lw 0x06 ; W = 0000 0ss0 ior_wff pointslave ; pointslave = 00SS Sss0 rr_fw pointslave ; W = 000S SSss bra_nz command_point_ifslave mov_fw pointmsg goto point_local_do command_point_badmsg panic morse_PX command_point_busy panic morse_PB command_point_cduempty panic morse_PC ;---------- command_point_ifslave mov_lfsr slave2ptinfo, 0 add_wff FSR0L bt_f_if1 INDF0, slave2ptinfo_anypoints goto i2c_needwrite ; oops: panic morse_PS ;---------- points_needwrite @ rr_fw pointslave ; W = 000S SSss bt_f_if1 STATUS, Z ; nothing ? return ; we need to write something: pop goto i2c_needwrite ;---------- points_getwritebyte @ rr_fw pointslave xor_wfw cwslave bt_f_if0 STATUS, Z ; right slave ? return ; yes: clr_f pointslave ; we're writing now, excellent mov_fw pointmsg goto i2c_getwritebyte_yes ;====================================================================== ; CDU ;-------------------- cdu_init @ clr_f pointslave clr_f pointmsg ;... ;----- cdu_off @ mov_lw (cdu_inittimeout * 1000) / tickdiv_us + 1 mov_wf cducharging cdu_panichook @ pin_l p0_cdu_enable return ;----- cdu_discharged mov_lw (cdu_timeout * 1000) / tickdiv_us + 1 mov_wf cducharging return ;-------------------- cdu_on @ pin_h p0_cdu_enable return ;-------------------- cdu_tickdiv @ pinlat_ifl p0_cdu_enable return tst_f_ifnz cducharging dec_f_ifnz cducharging ; so, decrement only if it was nonzero return ; return if we either didn't decrement, ; or didn't reach zero ; cducharging is already zero, from above mov_lw b'00101000' ; CHARGED goto serial_addbyte near_gots code ;-------------------- got_pointed @ tst_f_ifnz cducharging return ; presumably we just turned off bt_f_if0 pointmsg, 7 bra pointed_butnot_firing clr_f pointmsg call cdu_discharged mov_lw b'00100000' ; POINTED goto serial_addbyte pointed_butnot_firing panic morse_PA ;====================================================================== include final.inc