;############# THE INTERRUPTS ################################## ;interrupt uses FS2, without saving this. ;( using interrupt as counter, - frequency ) ;if we plan max. 40 cycles for every interrupt, ;we have up to 650 cycles place for program, or ;additionally step_work in interrupt, when ;transfering all 1/7200 second a byte ;so for three boards, we have 7200 / 21 = 342 ;times per second to update a target-position ;by 3 boards in the program loop, or direct by interrupt. ;INT_AS_FRQ is a special flag, inticating, that the ;interrupt is used as frequency, so STEP_WORK is called ;before anything is doing with the interrupt. ;That makes sure, that the step_work is done by a ;frequency, which is stable, as the master sends ;bytes using a stable freq. ( The max. possible freq. ;to handling all is 7200. ) ;So using this, steps, will be handled every 1/7200 ;second, and updating target every 1/342 second, if ;master sending a byte every 1/7200 second. ;INT_HANDLES_CMD is also special, means, if the ;last byte of a sequence is received, and spi_cmd ;is set, the command is handled directly by the ;interrupt, otherwise it will be handled by the ;programloop INT_SPI BCF PIE1,SSPIE,AC ;disabling spi-int BTFSC drv_flags,INT_AS_FRQ,AC CALL STEP_WORK MOVF SSPBUF,W,AC ;read, and clear input-buffer MOVWF spi_tmp,AC ;store to temp TSTFSZ spi_ctr,AC ;if counter 0 ? GOTO ispiloop ;this is part of one of the following 6 bytes ;ok, this is the first byte in a sequence, or a single command ;first we looking, if it is for us ANDLW 0x07 ;clear for address MOVWF spi_tmpaddr,AC CPFSEQ spi_addr,AC ;compare with board addr GOTO istart_notforus istart_forus ;ok, we have the first command, and our board is meaned. MOVFF spi_tmp,spi_tmpcmd ;storing cmd for later using BTFSC spi_tmp,H'0005',AC ;test if bit 5 of command is 1 BCF run_flags,STEP_ON,AC ;if so, we clear STEP_ON BTFSC spi_tmp,H'0006',AC ;test if bit 6 of command is 1 MOVFF spi_addr,spiobuf0 ;if it is 1, we send our address as first returnbyte MOVFF spiobuf0,SSPBUF ;fill buffer with spival BTFSC spi_tmp,H'0007',AC ;test if bit 7 of command is 1 GOTO ispiall_forus ;if so, we receive complete sequence in one int MOVLW 0x06 ;set counter MOVWF spi_ctr,AC ;at least switch on the interrupt again BCF PIR1,SSPIF ;clear int-req flag BSF PIE1,SSPIE,AC ;enabling spi-int RETFIE 1 ;32 cycles till here ispiloop ;on of the following 6 bytes, address is stored in spi_tmpaddr ;spi_ctr is the bytecounter MOVF spi_tmpaddr,W,AC CPFSEQ spi_addr,AC ;compare with board addr GOTO ispiloop_notforus ispiloop_forus ;this is one of the following 6 bytes for us ;spi_ctr is the bytecounter ;store spiibuf with spi_tmp LFSR FSR2,spiibufend MOVF spi_ctr,W,AC SUBWF FSR2L,1,AC MOVFF spi_tmp,INDF2 ;store spi_tmp from spiobuf LFSR FSR2,spiobufend MOVF spi_ctr,W,AC SUBWF FSR2L,1,AC MOVFF INDF2,spi_tmp DCFSNZ spi_ctr,1,AC ;decrement counter GOTO ispiloop_lastbyte ;if counter 0, we handle last byte MOVFF spi_tmp,SSPBUF ;at least switch on the interrupt again BCF PIR1,SSPIF ;clear int-req flag BSF PIE1,SSPIE,AC ;enabling spi-int RETFIE 1 ;36 cycles till here ispiloop_lastbyte ;the last byte , now we can handle the cmd SETF SSPBUF,AC ;filling output only with 0xff MOVF spi_tmpcmd,W,AC ANDLW 0xF8 MOVWF spi_cmd,AC ;and now storing the command BTFSC drv_flags,INT_HANDLES_CMD,AC CALL CMD_WORK ;at least switch on the interrupt again BCF PIR1,SSPIF ;clear int-req flag BSF PIE1,SSPIE,AC ;enabling spi-int RETFIE 1 ;41 cycles till here istart_notforus ;first byte, but not for us SETF SSPBUF,AC ;not for us, so fill only with 0xff BTFSC spi_tmp,H'0007',AC ;test if bit 7 of command is 1 GOTO ispiall_notforus ;if so, we receive complete sequence in one int MOVLW 0x06 ;set counter MOVWF spi_ctr,AC ;at least switch on the interrupt again BCF PIR1,SSPIF ;clear int-req flag BSF PIE1,SSPIE,AC ;enabling spi-int RETFIE 1 ;26 cycles till here ispiloop_notforus ;this is one of the following 6 bytes not for us ;spi_ctr is the bytecounter, we only fill output with 0xff ;and decrement counter SETF SSPBUF,AC DECF spi_ctr,1,AC ;decrement counter ;at least switch on the interrupt again BCF PIR1,SSPIF ;clear int-req flag BSF PIE1,SSPIE,AC ;enabling spi-int RETFIE 1 ; 20 cycles till here ispiall_forus ;till here are 26 cycles used ;spi_tmp, and spi_tmpcmd contain command ;SSPBUF is filled with spiobuf0 previous ;(if bit 6 is set this is our address) ;so we have to wait for 6 addtional bytes ;and return 5 bytes ( spiobuf1 - 5) ;byte 1 ispi_fs_0 BTFSS SSPSTAT,BF,AC BRA ispi_fs_0 MOVF SSPBUF,W,AC MOVWF spiibuf0,AC MOVF spiobuf1,W,AC MOVWF SSPBUF,AC ;byte 2 ispi_fs_1 BTFSS SSPSTAT,BF,AC BRA ispi_fs_1 MOVF SSPBUF,W,AC MOVWF spiibuf1,AC MOVF spiobuf2,W,AC MOVWF SSPBUF,AC ;byte 3 ispi_fs_2 BTFSS SSPSTAT,BF,AC BRA ispi_fs_2 MOVF SSPBUF,W,AC MOVWF spiibuf2,AC MOVF spiobuf3,W,AC MOVWF SSPBUF,AC ;byte 4 ispi_fs_3 BTFSS SSPSTAT,BF,AC BRA ispi_fs_3 MOVF SSPBUF,W,AC MOVWF spiibuf3,AC MOVF spiobuf4,W,AC MOVWF SSPBUF,AC ;byte 5 ispi_fs_4 BTFSS SSPSTAT,BF,AC BRA ispi_fs_4 MOVF SSPBUF,W,AC MOVWF spiibuf4,AC MOVF spiobuf5,W,AC MOVWF SSPBUF,AC ;byte 6 ispi_fs_5 BTFSS SSPSTAT,BF,AC BRA ispi_fs_5 MOVF SSPBUF,W,AC MOVWF spiibuf5,AC ;the last has to be 0xff for next SETF SSPBUF,AC MOVF spi_tmpcmd,W,AC ANDLW 0xF8 MOVWF spi_cmd,AC ;and now storing the command BTFSC drv_flags,INT_HANDLES_CMD,AC CALL CMD_WORK ;at least switch on the interrupt again BCF PIR1,SSPIF ;clear int-req flag BSF PIE1,SSPIE,AC ;enabling spi-int ;ok, seqence for addressed driver is ready ;W,STATUS,BSR is automatically restored RETFIE 1 ispiall_notforus ;till here are 21 cycles used ;SSPBUF is filled with 0xff previous ;so we have to wait for 6 additional bytes, ;allways returning 0xff ;byte 1 ispi_nfs_0 BTFSS SSPSTAT,BF,AC BRA ispi_nfs_0 MOVF SSPBUF,W,AC SETF SSPBUF,AC ;byte 2 ispi_nfs_1 BTFSS SSPSTAT,BF,AC BRA ispi_nfs_1 MOVF SSPBUF,W,AC SETF SSPBUF,AC ;byte 3 ispi_nfs_2 BTFSS SSPSTAT,BF,AC BRA ispi_nfs_2 MOVF SSPBUF,W,AC SETF SSPBUF,AC ;byte 4 ispi_nfs_3 BTFSS SSPSTAT,BF,AC BRA ispi_nfs_3 MOVF SSPBUF,W,AC SETF SSPBUF,AC ;byte 5 ispi_nfs_4 BTFSS SSPSTAT,BF,AC BRA ispi_nfs_4 MOVF SSPBUF,W,AC SETF SSPBUF,AC ;byte 6 ispi_nfs_5 BTFSS SSPSTAT,BF,AC BRA ispi_nfs_5 MOVF SSPBUF,W,AC SETF SSPBUF,AC ;at least switch on the interrupt again BCF PIR1,SSPIF ;clear int-req flag BSF PIE1,SSPIE,AC ;enabling spi-int ;ok, seqence for non-addressed driver is ready ;W,STATUS,BSR is automatically restored RETFIE 1