divert(-1) # SynDEx generic executive kernel, customization for CAN communications ifdef(`syndex.m4x_already_included',,`errprint( __file__:__line__: m4: syndex.m4x must be included before __file__! )m4exit(1)') ifelse(lang_,`PIC18F2680',, `error_(`lang_=PIC18F2680 expected, not lang_='lang_)m4exit(1)') ifdef( __file__`_already_included', `error_(`already included : '__file__)m4exit(1)', `define(__file__`_already_included')') define(`_pic18f2680_endian_',`LittleEndian') # ----------------------------------------------------------------------------- # C O N F I G U R A T I O N # ----------------------------------------------------------------------------- define(`CAN_IDMSB',0x55) # identifier for the communication sequence define(`CAN_BSIDLSB',0x7) # identifier (LSB) for the Backward-saver # ----------------------------------------------------------------------------- # C O M M U N I C A T I O N S E Q U E N C E # ----------------------------------------------------------------------------- # CAN_shared_(mediaName,procrNames) define(`CAN_shared_',`dnl define(`CAN_bpf_',8)dnl number of bytes transferred by frame indent_(+)dnl _(`')dnl -------------------------------------------------- CAN_init_state ---- define(`NOindent')dnl _(`CAN_init_state: ; count received sync-frames')dnl _(`lfsr FSR0,CANnsyn ; decr nysn')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.16')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.10')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.4')dnl _(`decf INDF0')dnl _(`return')dnl _(`')dnl ------------------------------------------------- CAN_send_shared ---- define(`NOindent')dnl _(`CAN_send_shared: ; called by every CAN_send_ communication step')dnl _(`lfsr FSR0,CANiptr ; save iptr')dnl _(`movf TOSL,0')dnl _(`movwf POSTINC0')dnl _(`movf TOSH,0')dnl _(`movwf POSTINC0')dnl _(`pop')dnl _(`;lfsr FSR0,CANnsyn')dnl _(`movf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl pushtag(`can')_(`bz 'tag_` ; if all synch-frames received, otherwise:')dnl _(`;lfsr FSR0,CANstat')dnl _(`movlw low CAN_send_waitingSynch_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_send_waitingSynch_state')dnl _(`movwf POSTINC0')dnl _(`return')dnl _(`')dnl ------------------------------------- CAN_send_waitingSynch_state ---- define(`NOindent')dnl _(`CAN_send_waitingSynch_state: ; waiting sync-frames before sending')dnl _(`lfsr FSR0,CANnsyn ; decr nysn')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.16')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.10')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.4')dnl _(`decf INDF0')dnl _(`lfsr FSR0,CANnsyn')dnl _(`movf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`bz $+4')dnl _(`return ; if still waiting, otherwise:')dnl define(`NOindent')_(tag_`:')poptag(`can')dnl _(`;lfsr FSR0,CANstat')dnl _(`movlw low CAN_sending_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_sending_state')dnl _(`movwf INDF0')dnl define(`NOindent')dnl ---------------------------------- CAN_sending_state ---- _(`CAN_sending_state: ; sending data frames')dnl _(`; copy 8 bytes in any cases, and update addr and size:')dnl _(`movff CANaddr,FSR0L')dnl _(`movff CANaddr+1,FSR0H')dnl _(`movlb .15')dnl _(`lfsr FSR1,TXB0D0')dnl _(`movlw .'CAN_bpf_)dnl _(`movwf TXB0DLC,1')dnl _(`movff POSTINC0,POSTINC1')dnl _(`decfsz WREG')dnl _(`bra $-.6')dnl _(`movff FSR0L,CANaddr')dnl _(`movff FSR0H,CANaddr+1')dnl _(`lfsr FSR0,CANsize')dnl _(`movlw .'CAN_bpf_)dnl _(`subwf POSTINC0')dnl _(`clrf WREG')dnl _(`subwfb POSTDEC0')dnl _(`movf POSTINC0,0')dnl _(`iorwf POSTDEC0,0')dnl _(`bz $+.4')dnl _(`bnn $+.18')dnl _(`movf INDF0,0 ; adjust TxDLC if last frame')dnl _(`addwf TXB0DLC,1,1')dnl _(`lfsr FSR0,CANstat')dnl _(`movlw low CAN_resume_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_resume_state')dnl _(`movwf INDF0')dnl _(`bsf TXB0CON,TXREQ,1 ; request Tx')dnl _(`return')dnl _(`')dnl ------------------------------------------------- CAN_recv_shared ---- define(`NOindent')dnl _(`CAN_recv_shared: ; called by every CAN_recv_ communication step')dnl _(`lfsr FSR0,CANiptr ; save iptr')dnl _(`movf TOSL,0')dnl _(`movwf POSTINC0')dnl _(`movf TOSH,0')dnl _(`movwf POSTINC0')dnl _(`pop')dnl _(`lfsr FSR0,CANstat')dnl _(`movlw low CAN_recv_waitingSynch_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_recv_waitingSynch_state')dnl _(`movwf INDF0')dnl _(`movlb .15')dnl _(`clrf TXB0DLC,1 ; request Tx of synch-frame (length=0)')dnl _(`bsf TXB0CON,TXREQ,1')dnl _(`return')dnl _(`')dnl ------------------------------------- CAN_recv_waitingSynch_state ---- define(`NOindent')dnl _(`CAN_recv_waitingSynch_state: ; waiting synch-frames before receiving')dnl _(`lfsr FSR0,CANnsyn ; decr nysn')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.16')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.10')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.4')dnl _(`decf INDF0')dnl _(`lfsr FSR0,CANnsyn')dnl _(`movf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`bz $+4')dnl _(`return ; if still waiting other synch-frames, otherwise:')dnl _(`;lfsr FSR0,CANstat')dnl _(`movlw low CAN_recving_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_recving_state')dnl _(`movwf INDF0')dnl _(`return')dnl _(`')dnl ----------------------------------------------- CAN_recving_state ---- define(`NOindent')dnl _(`CAN_recving_state: ; storing received frames')dnl _(`movff CANaddr,FSR0L')dnl _(`movff CANaddr+1,FSR0H')dnl _(`lfsr FSR1,RXB0D0')dnl _(`movf RXB0DLC,0')dnl _(`banksel CANsize ; update size')dnl _(`subwf CANsize,1,1')dnl _(`banksel CANsize+1')dnl _(`btfss STATUS,C')dnl _(`decf CANsize+1,1,1')dnl _(`movff POSTINC1,POSTINC0 ; copy bytes')dnl _(`decfsz WREG')dnl _(`bra $-.6')dnl _(`movf CANsize+1,0,1')dnl _(`banksel CANsize')dnl _(`iorwf CANsize,0,1')dnl _(`bz CAN_resume_state')dnl _(`movff FSR0L,CANaddr')dnl _(`movff FSR0H,CANaddr+1')dnl _(`return')dnl _(`')dnl --------------------------------------------------- CAN_recv_brev ---- _(`; byte-reverse bytes items after reception from BigEndian processor')dnl define(`NOindent')dnl _(`CAN_recv_brev2:')dnl _(`movff POSTINC0,FSR2L')dnl _(`movf POSTDEC0,0')dnl _(`movwf POSTINC0')dnl _(`movff FSR2L,POSTINC0')dnl _(`movf FSR0L,0')dnl _(`cpfseq FSR1L')dnl _(`bra CAN_recv_brev2')dnl _(`movf FSR0H,0')dnl _(`cpfseq FSR1H')dnl _(`bra CAN_recv_brev2')dnl _(`return')dnl define(`NOindent')dnl _(`CAN_recv_brev4:')dnl _(`movff POSTINC0,FSR2L')dnl _(`movff POSTINC0,FSR2H')dnl _(`movf POSTINC0')dnl _(`movf INDF0,0')dnl _(`movff FSR2L,POSTDEC0')dnl _(`movff INDF0,FSR2L')dnl _(`movff FSR2H,POSTDEC0')dnl _(`movff FSR2L,POSTDEC0')dnl _(`movwf POSTINC0')dnl _(`movf POSTINC0')dnl _(`movf POSTINC0')dnl _(`movf POSTINC0')dnl _(`movf FSR0L,0')dnl _(`cpfseq FSR1L')dnl _(`bra CAN_recv_brev4')dnl _(`movf FSR0H,0')dnl _(`cpfseq FSR1H')dnl _(`bra CAN_recv_brev4')dnl _(`return')dnl _(`')dnl ------------------------------------------------- CAN_sync_shared ---- define(`NOindent')dnl _(`CAN_sync_shared: ; called by every CAN_sync_ communication step')dnl _(`lfsr FSR0,CANiptr ; save iptr')dnl _(`movf TOSL,0')dnl _(`movwf POSTINC0')dnl _(`movf TOSH,0')dnl _(`movwf POSTINC0')dnl _(`pop')dnl _(`lfsr FSR0,CANstat')dnl _(`movlw low CAN_sync_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_sync_state')dnl _(`movwf INDF0')dnl _(`return')dnl _(`')dnl -------------------------------------------------- CAN_sync_state ---- define(`NOindent')dnl _(`CAN_sync_state: ; waiting for synch-frames')dnl _(`lfsr FSR0,CANnsyn ; decr nysn')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.16')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.10')dnl _(`decf INDF0')dnl _(`comf POSTINC0,0')dnl _(`bnz $+.4')dnl _(`decf INDF0')dnl _(`lfsr FSR0,CANnsyn')dnl _(`movf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`bz $+4')dnl _(`return ; if still waiting other synch-frames, otherwise:')dnl _(`;bra CAN_resume_state')dnl _(`')dnl ------------------------------------------------ CAN_resume_state ---- define(`NOindent')dnl _(`CAN_resume_state: ; restore message buffer initial state')dnl _(`lfsr FSR0,CANstat')dnl _(`movlw low CAN_init_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_init_state')dnl _(`movwf INDF0')dnl _(`lfsr FSR0,CANiptr+1 ; resume communication sequence')dnl _(`movf POSTDEC0,0')dnl _(`movwf PCLATH')dnl _(`movf INDF0,0')dnl _(`movwf PCL')dnl _(`')dnl ------------------------------------------- CAN interrupt handler ---- indent_(-)dnl divert(1)dnl switch to interrupt handler indent_(+)dnl define(`NOindent')dnl _(`CAN_it: ; CAN interrupt main handler')dnl alloc_(short,CANiptr,1)dnl address of pending instruction in communication seq. alloc_(int,CANnsyn,1)dnl number of synch-frames to wait for before data-frames alloc_(short,CANstat,1)dnl address of interrupt sub-handler for current state alloc_(short,CANaddr,1)dnl address of next byte to transfer alloc_(short,CANsize,1)dnl remaining number of bytes to transfer _(`btfss PIR3,2')dnl _(`bra $+.6')dnl _(`bcf PIR3,2')dnl _(`bra $+.12')dnl _(`btfss PIR3,0')dnl _(`bra CAN_it_end')dnl _(`btfsc RXB0CON,RXFUL ; release buffer')dnl _(`bcf RXB0CON,RXFUL')dnl _(`bcf PIR3,0')dnl _(`push ; sub-handler returns to CAN_it_end')dnl _(`movlw .20')dnl _(`addwf TOSL')dnl _(`clrf WREG')dnl _(`addwfc TOSH')dnl _(`lfsr FSR0,CANstat+1 ; jump to sub-handler for current state')dnl _(`movf POSTDEC0,0')dnl _(`movwf PCLATH')dnl _(`movf INDF0,0')dnl _(`movwf PCL')dnl define(`NOindent')_(`CAN_it_end:')dnl indent_(-)dnl divert(0)') # CAN_ini_(mediaName,procrNames) define(`CAN_ini_',`dnl _(`; CAN initialization')dnl _(`; Baudrate has been configured by the bootloader')dnl _(`movlb .15')dnl _(`bsf CANCON,7 ; request configuration mode')dnl _(`movlw 'CAN_IDMSB` ; set filter for buffer 0')dnl _(`movwf RXF0SIDH,1')dnl _(`clrf RXF0SIDL,1')dnl _(`setf RXM0SIDH,1 ; consider only the 8 MSbits of frame IDs')dnl _(`clrf RXM0SIDL,1')dnl _(`movlw 'CAN_IDMSB` ; setup transmit buffer')dnl _(`movwf TXB0SIDH,1')dnl _(`movlw 0x'eval(lindex(processorName_,shift($@))<<5,16,2))dnl _(`movwf TXB0SIDL,1')dnl _(`clrf CANCON ; reenter normal mode')dnl _(`; initialize the interrupt handler context')dnl _(`lfsr FSR0,CANnsyn')dnl _(`clrf POSTINC0 ; nsyn=0')dnl _(`clrf POSTINC0')dnl _(`clrf POSTINC0')dnl _(`clrf POSTINC0')dnl _(`;lfsr FSR0,CANstat')dnl _(`movlw low CAN_init_state ; stat=CAN_init_state')dnl _(`movwf POSTINC0')dnl _(`movlw high CAN_init_state')dnl _(`movwf INDF0')dnl _(`bsf PIE3,TXB0IE ; enable CAN transmit buffer 0 interrupt')dnl _(`bsf PIE3,RXB0IE ; enable CAN receive buffer 0 interrupt')') # CAN_end_(mediaName,procrNames) define(`CAN_end_',`dnl _(`; freeze CAN')') # CAN_send_(1bufferName,2senderType,3senderName {,receiverNames}) define(`CAN_send_',`dnl _(`lfsr FSR0,CANaddr')dnl _(`movlw low $1')dnl _(`movwf POSTINC0')dnl _(`movlw high $1')dnl _(`movwf POSTINC0')dnl _(`;lfsr FSR0,CANsize')dnl pushdef(`size_',eval($1_size_*type_($1)_size_))dnl _(`movlw .'eval(size_&255))dnl _(`movwf POSTINC0')dnl _(`movlw .'eval(size_>>8&255))dnl _(`movwf POSTINC0')dnl popdef(`size_')dnl pushdef(`nsyn_',eval($#-3))dnl _(`lfsr FSR0,CANnsyn')dnl _(`movlw .'eval(nsyn_&255)` ; add nsyn to synch-frames to be received')dnl _(`addwf POSTINC0')dnl _(`movlw .'eval(nsyn_>>8&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>16&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>24&255))dnl _(`addwfc POSTINC0')dnl popdef(`nsyn_')dnl _(`call CAN_send_shared')') # CAN_recv_(1bufferName,2senderType,3senderName {,receiverNames}) define(`CAN_recv_',`dnl _(`lfsr FSR0,CANaddr')dnl _(`movlw low $1')dnl _(`movwf POSTINC0')dnl _(`movlw high $1')dnl _(`movwf POSTINC0')dnl _(`;lfsr FSR0,CANsize')dnl pushdef(`size_',eval($1_size_*type_($1)_size_))dnl _(`movlw .'eval(size_&255))dnl _(`movwf POSTINC0')dnl _(`movlw .'eval(size_>>8&255))dnl _(`movwf POSTINC0')dnl popdef(`size_')dnl pushdef(`nsyn_',eval($#-3))dnl _(`lfsr FSR0,CANnsyn')dnl _(`movlw .'eval(nsyn_&255)` ; add nsyn to synch-frames to be received')dnl _(`addwf POSTINC0')dnl _(`movlw .'eval(nsyn_>>8&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>16&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>24&255))dnl _(`addwfc POSTINC0')dnl popdef(`nsyn_')dnl _(`call CAN_recv_shared')dnl ifelse(_$2_endian_,`BigEndian',`dnl if different endianness: ifelse(type_($1)_size_,1,,`dnl if byte order has to be reversed: _(`lfsr FSR0,$1')dnl _(`lfsr FSR1,$1+.'eval(type_($1)_size_))dnl _(`call CAN_recv_brev'type_($1)_size_)')')') # CAN_sync_(1bufferType,2bufferSize,3senderName {,receiverNames}) define(`CAN_sync_',`dnl pushdef(`nsyn_',eval($#-4+($2*$1_size_+CAN_bpf_-1)/CAN_bpf_))dnl _(`lfsr FSR0,CANnsyn ; add nsyn to synch-frames to be received')dnl _(`movlw .'eval(nsyn_&255))dnl _(`addwf POSTINC0')dnl _(`movlw .'eval(nsyn_>>8&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>16&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>24&255))dnl _(`addwfc POSTINC0')dnl popdef(`nsyn_')dnl _(`call CAN_sync_shared')') # ----------------------------------------------------------------------------- # F O R W A R D - L O A D E R # ----------------------------------------------------------------------------- # CAN_loadDnto_(srceMedia {,procrName}) define(`CAN_loadDnto_',`CAN_loadFrom_') # CAN_loadFrom_(procrName {,destMedia}) define(`CAN_loadFrom_',`dnl _(`clrf TXB0D0,1 ; send controlFlowFrame to request no more executive')dnl _(`movlw 1')dnl _(`movwf TXB0DLC,1 ; dataByte0=0')dnl _(`bsf TXB0CON,TXREQ,1 ; request Tx')dnl _(`bra WaitPrefixFrame')dnl define(`NOindent')_(`WaitFrame:')dnl _(`btfss RXB0CON,RXFUL ; wait till a frame is received')dnl _(`bra $-2')dnl _(`bcf RXB0CON,RXFUL')dnl _(`clrf PIR3')dnl _(`return')dnl define(`NOindent')_(`WaitFlowControlFrame:')dnl _(`rcall WaitFrame ; wait flow control frame: dataByte0=nbDataFrames')dnl _(`movff RXB0D0,TABLAT')dnl define(`NOindent')_(`WaitFullDataFrame:')dnl _(`rcall WaitFrame ; wait full dataFrame with 8 data bytes')dnl _(`movlw .8 ; executiveLength-=8')dnl _(`subwf PRODL')dnl _(`clrf WREG')dnl _(`subwfb PRODH')dnl _(`decfsz TABLAT ; until --nbDataFrames==0')dnl _(`bra WaitFullDataFrame')dnl _(`movf PRODL,0')dnl _(`iorwf PRODH,0 ; until executiveLength==0')dnl _(`bnz WaitFlowControlFrame')dnl define(`NOindent')_(`WaitControlFlowFrame:')dnl _(`rcall WaitFrame ; wait request for (no) more executive')dnl define(`NOindent')_(`WaitPrefixFrame:')dnl _(`; wait prefix frame: 0-3=ProcId 4-7=executiveLength')dnl _(`rcall WaitFrame')dnl _(`movff RXB0D6,PRODH ; executiveLength')dnl _(`movf RXB0D7,0')dnl _(`movwf PRODL')dnl _(`iorwf PRODH,0 ; null executiveLength marks download end')dnl _(`bnz WaitFlowControlFrame')') # ----------------------------------------------------------------------------- # B A C K W A R D - S A V E R # ----------------------------------------------------------------------------- define(`backwardSaver_',`ifdef(`BackwardSaver_once_',,`dnl define(`BackwardSaver_once_')dnl basicEndthread_(mediaName_)dnl will be called back by Chrono_end_ define(`NOindent')_(`SaverRecvFrame: ; wait till a frame is received')dnl _(`btfss RXB0CON,RXFUL')dnl _(`bra $-2')dnl _(`bcf RXB0CON,RXFUL')dnl _(`clrf PIR3')dnl _(`return')dnl define(`NOindent')_(`SaverSendDataFrame: ; FSR1=dataFrame')dnl _(`lfsr FSR0,TXB0D0')dnl _(`movlw .6')dnl _(`movff POSTINC1,POSTINC0')dnl _(`decfsz WREG')dnl _(`bra $-.6')dnl define(`NOindent')_(`SaverSendFrame:')dnl _(`bsf TXB0CON,TXREQ,1 ; resquest Tx')dnl _(`btfsc TXB0CON,TXREQ,1 ; wait for frame sent')dnl _(`bra $-.2')dnl _(`return')dnl define(`NOindent')_(`SaverSyncFrame:')dnl _(`rcall SaverRecvFrame ; wait flow control frame')dnl _(`movf RXB0D0,0 ; null label indicates end of upload')dnl _(`iorwf RXB0D1,0')dnl _(`bnz SaverSyncFrame')dnl _(`return')dnl define(`NOindent')_(`SaverWaitFlowControlFrame:')dnl _(`rcall SaverSyncFrame')dnl define(`NOindent')_(`SaverWaitPrefixFrame:')dnl _(`rcall SaverRecvFrame ; frame from ascendant CANstation')dnl _(`movf RXB0D0,0')dnl _(`iorwf RXB0D1,0')dnl _(`iorwf RXB0D2,0')dnl _(`iorwf RXB0D3,0')dnl _(`btfsc STATUS,Z')dnl _(`return ; end of upload, otherwise:')dnl _(`movlw .'eval(processorId_&255)` ; until ProcID match')dnl _(`cpfseq RXB0D0')dnl _(`bra SaverWaitFlowControlFrame')dnl _(`movlw .'eval(processorId_>>8&255))dnl _(`cpfseq RXB0D1')dnl _(`bra SaverWaitFlowControlFrame')dnl _(`movlw .'eval(processorId_>>16&255))dnl _(`cpfseq RXB0D2')dnl _(`bra SaverWaitFlowControlFrame')dnl _(`movlw .'eval(processorId_>>24&255))dnl _(`cpfseq RXB0D3')dnl _(`bra SaverWaitFlowControlFrame')dnl define(`NOindent')_(`SaverDescendantTime:')dnl _(`lfsr FSR0,TXB0D0 ; frame to ascendant CANstation')dnl _(`setf POSTINC0')dnl _(`setf POSTINC0')dnl _(`bcf INTCON,GIE')dnl _(`movff TMR0L,POSTINC0')dnl _(`movff TMR0H,POSTINC0')dnl _(`movff Chrono_msb,POSTINC0')dnl _(`movff Chrono_msb+1,POSTINC0')dnl _(`bsf INTCON,GIE')dnl _(`rcall SaverSendFrame')dnl _(`rcall SaverRecvFrame ; frame from ascendant CANstation')dnl _(`lfsr FSR0,TXB0D2 ; frame to ascendant CANstation')dnl _(`bcf INTCON,GIE')dnl _(`movff TMR0L,POSTINC0')dnl _(`movff TMR0H,POSTINC0')dnl _(`movff Chrono_msb,POSTINC0')dnl _(`movff Chrono_msb+1,POSTINC0')dnl _(`bsf INTCON,GIE')dnl _(`rcall SaverSendFrame')dnl _(`rcall SaverSendChronos')dnl _(`bra SaverWaitPrefixFrame')dnl define(`NOindent')_(`SaverGetTime:')dnl _(`rcall SaverRecvFrame ; frame from descendant CANstation')dnl _(`lfsr FSR0,TXB0D0 ; frame to descendant CANstation')dnl _(`setf POSTINC0')dnl _(`setf POSTINC0')dnl _(`bcf INTCON,GIE')dnl _(`movff TMR0L,POSTINC0')dnl _(`movff TMR0H,POSTINC0')dnl _(`movff Chrono_msb,POSTINC0')dnl _(`movff Chrono_msb+1,POSTINC0')dnl _(`bsf INTCON,GIE')dnl _(`rcall SaverSendFrame')dnl _(`rcall SaverRecvFrame ; frame from descendant CANstation')dnl _(`bra SaverSyncFrame')dnl define(`NOindent')_(`SaverSendChronos:')dnl _(`movlw low Chrono_base')dnl _(`movwf FSR1L')dnl _(`movlw high Chrono_base')dnl _(`movwf FSR1H')dnl define(`NOindent')_(`SaverSendNextChrono:')dnl _(`call SaverSendDataFrame')dnl _(`movf POSTINC1,0 ; label=0 if upload complete')dnl _(`iorwf POSTDEC1,0')dnl _(`bz SaverSectionEnd')dnl _(`movlw low(Chrono_base+.'decr(Chrono_base_size_)`) ; upload complete')dnl _(`cpfseq FSR1L')dnl _(`bra SaverSendNextChrono')dnl _(`movlw high(Chrono_base+.'decr(Chrono_base_size_)`)')dnl _(`cpfseq FSR1H')dnl _(`bra SaverSendNextChrono')dnl define(`NOindent')_(`SaverSectionEnd:')dnl _(`clrf TXB0D0,1 ; null label indicates end of section')dnl _(`clrf TXB0D1,1')dnl _(`bra SaverSendFrame')dnl define(`NOindent')_(`BackwardSaver:')')') # CAN_saveFrom_(srceMedia {,procrName}) define(`CAN_saveFrom_',`ifdef(`Chronos_once_',`dnl backwardSaver_()dnl _(`bcf INTCON,GIE')dnl _(`lfsr FSR0,CANnsyn')dnl pushdef(`nsyn_',decr($#))dnl _(`movlw .'eval(nsyn_&255)` ; add nsyn to synch-frames to be received')dnl _(`addwf POSTINC0')dnl _(`movlw .'eval(nsyn_>>8&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>16&255))dnl _(`addwfc POSTINC0')dnl _(`movlw .'eval(nsyn_>>24&255))dnl _(`addwfc POSTINC0')dnl popdef(`nsyn_')dnl _(`bsf INTCON,GIE')dnl _(`lfsr FSR0,CANnsyn ; synchronize with descendant CANstations')dnl _(`bcf INTCON,GIE')dnl _(`movf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`iorwf POSTINC0,0')dnl _(`bsf INTCON,GIE')dnl _(`bnz $-.16')dnl _(`movlw 0x24 ; disable all external interrupts')dnl _(`andwf INTCON')dnl _(`movlw 0xc0')dnl _(`andwf INTCON3')dnl _(`banksel Chrono_freeze')dnl _(`bsf Chrono_freeze,0,1')dnl _(`bsf INTCON,GIE')dnl _(`; upload chronos buffer')dnl _(`movlb .15')dnl _(`movlw 'CAN_BSIDLSB`<<.5 ; backward-saver')dnl _(`movwf TXB0SIDL,1')dnl _(`movlw .6 ; always 6 data bytes ')dnl _(`movwf TXB0DLC,1')dnl _(`movlw .'eval(processorId_&255)` ; 'processorName_` procID')dnl _(`movwf TXB0D0,1')dnl _(`movlw .'eval(processorId_>>8&255))dnl _(`movwf TXB0D1,1')dnl _(`movlw .'eval(processorId_>>16&255))dnl _(`movwf TXB0D2,1')dnl _(`movlw .'eval(processorId_>>24&255))dnl _(`movwf TXB0D3,1')dnl _(`call SaverSendFrame')dnl _(`call SaverSendChronos')dnl CAN_descendants_(shift($@))dnl _(`clrf TXB0D2,1 ; upload process is complete')dnl _(`clrf TXB0D3,1')dnl _(`call SaverSectionEnd')')') define(`CAN_descendants_',`ifelse($1,,,`dnl _(`movlw .'eval($1_ID&255)` ; $1 procID')dnl _(`movwf TXB0D0,1')dnl _(`movlw .'eval($1_ID>>8&255))dnl _(`movwf TXB0D1,1')dnl _(`movlw .'eval($1_ID>>16&255))dnl _(`movwf TXB0D2,1')dnl _(`movlw .'eval($1_ID>>24&255))dnl _(`movwf TXB0D3,1')dnl _(`call SaverSendFrame')dnl _(`call SaverGetTime')dnl CAN_descendants_(shift($@))')') # CAN_saveUpto_(procrName {,destMedia}) define(`CAN_saveUpto_',`ifdef(`Chronos_once_',`dnl backwardSaver_()dnl _(`movlw 0x24 ; disable all external interrupts')dnl _(`andwf INTCON')dnl _(`movlw 0xc0')dnl _(`andwf INTCON3')dnl _(`banksel Chrono_freeze')dnl _(`bsf Chrono_freeze,0,1')dnl _(`bsf INTCON,GIE')dnl _(`movlb .15')dnl _(`clrf TXB0DLC,1')dnl _(`bsf TXB0CON,TXREQ,1 ; request Tx')dnl _(`call SaverRecvFrame')dnl _(`movf RXB0DLC,1,1')dnl _(`bz $-.6')dnl _(`movlw .6 ; always 6 data bytes ')dnl _(`movwf TXB0DLC,1')dnl _(`call SaverWaitPrefixFrame+.2')')') divert`'dnl ----------------- end of file -----------------------------