;====================================================================== ; 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 200 ; ms cdu_inittimeout equ 750 ; ms ptix2latbit equ 0x300 ; has to be a multiple of 0x100 ptix2latbit_section udata ptix2latbit res maxpoints * 2 ; LAT* and bit ; for unused point, 0x00 and 0x00 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 intrh_fsr0_save ; point_set_pin uses FSR0, see below call point_set_pin intrh_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 ; We do this in two stages. ; Firstly, we scan the bitmap for this pic, setting ; ptix2latbit to 0xff,0x00 for used points and 0x00,0x00 ; to unused ones. ; Secondly, we scan the bkptix2portnumbitnum, adjusting ; ptix2latbit to have actually correct data. ; Doing it like this avoids having to constantly recompute ; individual TBLPTR*'s. mov_lfsr ptix2latbit-1, 0 ; FSR0 -> this bit and LAT* ; points just at last thing we've filled in load_perpic_tblptr picno2ptmap, maxpoints/8 mov_lw maxpoints/8 mov_wf t ; t = byte counter ;... points_init_byte_loop mov_lw 8 ; W = bit counter tblrd_postinc_fixup ; TABLAT = bitmap data being processed ;... points_init_bit_loop clr_f PREINC0 ; FSR0 -> LAT*[current] := 0 rrc_f TABLAT bt_f_if1 STATUS,C set_f INDF0 ; FSR0 -still-> LAT*[current] := 0xff clr_f PREINC0 ; FSR0 -> bit[current] := 0 dec_w_ifnz bra points_init_bit_loop dec_f_ifnz t bra points_init_byte_loop ;... end of loop: ; We've scanned for points used on this board; ; now find the actual pins. mov_lw bkptix2portnumbitnum & 0xff bt_f_if1 idloc1,idloc1_boarddet add_lw maxpoints mov_wf TBLPTRL mov_lw bkptix2portnumbitnum >> 8 mov_wf TBLPTRH ; TBLPTR* -> point port/bit data set_f FSR2H ; FSR2 -> some SFR, will point to LAT/TRIS mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7 mov_lfsr ptix2latbit-1, 0 ; FSR0 -> last bit (and previous LAT*) mov_lw maxpoints mov_wf t ; t = loop counter ;... points_init_portbit_loop tblrd_postinc_fixup ; TABLAT = portnum4 || bitnum4 bt_f_if0 PREINC0,7 ; zero?, FSR0 -> LAT*[this] bra points_init_portbit_endif_used ;... points_init_portbit_if_used mov_fw TABLAT bra_n point_initing_bad_point ior_lw 0xf8 ; W -> bit value for bit mov_wf FSR1L ; FSR1 -> bit value for bit swap_fw TABLAT ; W = bitnum4 || portnum4 and_lw 0x0f ; W = portnum4 add_lw LATA & 0xff ; W = LAT* mov_wf POSTINC0 ; LAT*[this] := LAT, FSR0 -> bit[this] mov_wf FSR2L ; FSR2 -> LAT* mov_fw INDF1 ; W = bit mov_wf POSTDEC0 ; bit[this] = bit, FSR0 -> LAT*[this] com_w ; W = ~bit and_wff INDF2 ; LAT* &= ~bit, ie pin set to L (still Z) pin_vh pall_pt0reverse ; but pt0 pin is backwards, set to H ; (still Z, unless we've done this already) mov_lw TRISA-LATA add_wff FSR2L ; FSR2 -> TRIS* com_fw INDF1 ; W = ~bit and_wff INDF2 ; TRIS* &= ~bit, ie pin set to not Z set_f FSR1L ; FSR1 -> bitnum2bit+7, again points_init_portbit_endif_used ; so now we move on to the next one mov_fw POSTINC0 ; FSR0 -> bit[this] dec_f_ifnz t bra points_init_portbit_loop return ;---------- point_initing_bad_point panic morse_PF ;---------- 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: ;... ;---------- point_needwrite_yes 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 @ cdu_panichook @ pin_l p0_cdu_enable mov_lw (cdu_inittimeout * 1000) / tickdiv_us + 1 mov_wf cducharging 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 bra pointed_already_charging 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 pointed_already_charging panic morse_PQ ;====================================================================== include final.inc