; fdec.asm - function decoder - a modified version of 25v6.asm ; 5 additional I/O ports for minidecoder ; acknowledge off (activate with CV42,7) ; Version: 2 Date: 03 March 2002 ; Copyright (C) 1999 Georg Ziegler ; EEPROM read/write routine from MICROCHIP PIC12CE519 documentation ; This program is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License as ; published by the Free Software Foundation; either version 2 of ; the License, or (at your option) any later version. ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; General Public License for more details. ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; Contact: ; Georg Ziegler ; Zwehrener Weg 23a ; 34121 Kassel ; g.zi@gmx.de ;-------------------------------------------------------------------- LIST P=12CE519, R=DEC INCLUDE __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_ON & _IntRC_OSC ;-------------------------------------------------------------------- ; 0AAA AAAA 01DL SSSS -> Lok Adress Direction Light & Speed ; 0AAA AAAA 100D DDDD -> Lok Function F1-F4 & FL ; 0AAA AAAA 1011 DDDD -> Lok Function F5-F8 ; 0000 0000 -> Broadcast Adress for all Lok Decoder ; 10AA AAAA 1AAA CDDD -> 9 Bit Accessory on/off F1-F8 ; 1011 1111 1000 CDDD -> Broadcast Command for all Accessory Decoder ; 11AA AAAA & AAAA AAAA -> long Adress ; 1111 1111 0000 0000 -> Idle Packet for all Decoder ;-------------------------------------------------------------------- #DEFINE DCCIN 3 ; DCC input pin (GPIO,3 only input) ;-------------------------------------------------------------------- CV8 EQU 0x0D ; Home Made Decoder CV7 EQU 0x02 ; Version No. ;-------------------------------------------------------------------- INDF EQU 0x00 ; Indirect Adressing tmr0 EQU 0x01 ; Timer PC EQU 0x02 ; Programm Counter STATUS EQU 0x03 ; Status Register FSR EQU 0x04 ; Special Funcion Register OSCCAL EQU 0x05 ; Calibration Register GPIO EQU 0x06 ; GP0-GP5 input/output ;-------------------- S31 EQU 0x07 ; CONFIG EQU 0x08 ; 0=DIR 1=CONSIST 2=STEPOK/NOCV 5=FS126 6=BITHI 7=FLAG GPIOOUT EQU 0x09 ; BT1 EQU 0x0A ; FSR auf 0x09 BT2 EQU 0x0B ; BT3 EQU 0x0C ; BT4 EQU 0x0D ; BT5 EQU 0x0E ; BT6 EQU 0x0F ; FSR auf 0x10 ;-------------------- SOLL EQU 0x10 ; speed to go ; EQU 0x11 ; ACC EQU 0x12 ; DEC EQU 0x13 ; ; EQU 0x14 ; TFLKOFF EQU 0x15 ; flickering firebox offtime FLAG EQU 0x16 ; F1F8OLD EQU 0x17 ; XOR EQU 0x18 ; NOADR EQU 0x19 ; no adress since ... PWM EQU 0x1A ; (Z1) F1F8SET EQU 0x1B ; IST EQU 0x1C ; actual speed PRE EQU 0x1D ; Preample 12 BIT LO EQU 0x1E ; low bit counter HI EQU 0x1F ; hi bit counter ;-------------------- CV1 EQU 0x30 ; Primary Adress CV17 EQU 0x31 ; Extended Adress Low Byte CV18 EQU 0x32 ; Extended Adress High Byte CV19 EQU 0x33 ; Consist Adress CV29 EQU 0x34 ; 0=DIR 1=14/28 2=PWRSRC 3=ADVACK 4=SPDTAB 5=LADRE 6= 7=ACCDEC MAPCV EQU 0x35 ; rom CV's copied to here CV33 EQU 0x36 ; front light -> GPIO (xx54x210) CV34 EQU 0x37 ; back light -> GPIO (xx54x210) CV35 EQU 0x38 ; F1 -> GPIO (xx54x210) CV36 EQU 0x39 ; F2 -> GPIO (xx54x210) CV37 EQU 0x3A ; F3 -> GPIO (xx54x210) CV38 EQU 0x3B ; F4 -> GPIO (xx54x210) CV39 EQU 0x3C ; F5 -> GPIO (xx54x210) CV40 EQU 0x3D ; F6 -> GPIO (xx54x210) CV41 EQU 0x3E ; F7 -> GPIO (xx54x210) CV42 EQU 0x3F ; F8 -> GPIO (xx54x210) ;--------------------- CARRY EQU 0 ZERO EQU 2 SEITE EQU 5 ;-------------------------------- #DEFINE DIR CONFIG,0 ; #DEFINE CONSIST CONFIG,1 ; #DEFINE STEPOK? CONFIG,2 ; #DEFINE NOCV CONFIG,2 ; is mapped with STEPOK? #DEFINE ROMCV CONFIG,3 ; is mapped with #DEFINE LASTLT CONFIG,3 ; #DEFINE FS126 CONFIG,5 ; #DEFINE BITHI CONFIG,6 ; #DEFINE FLAGS2 CONFIG,7 ; #DEFINE LASTDIR CONFIG,7 ; ;-------------------------------- #DEFINE LITOPEN FLAG,6 ; for lit open/close (copy from CV64) ;-------------------------------- #DEFINE DIRINV CV29,0 ; direction inverted (+light) #DEFINE FS28 CV29,1 ; 14/28 speed step #DEFINE LIINV CV29,2 ; light inverted (PWRSRC never used) #DEFINE STAB CV29,4 ; speedtab / CV2,CV5&CV6 #DEFINE LADRE CV29,5 ; long adress enable #DEFINE PROGBIT CV29,6 ; #DEFINE PROGBT1 CV29,7 ; ;-------------------------------- #DEFINE ACKBIT STATUS,6 ; never overwriten #DEFINE ACKON CV42,7 ; acknowledge on (for additional I/O ports must switch off) ;-------------------------------------------------------------------- ORG 0 ; Reset Vector ;-------------------------TEST------------------------------ ;#DEFINE TEST #IFDEF CALL TEST1 BSF FSR,5 BSF STATUS,SEITE MOVLW 10010000b ; 100LDDDD MOVWF BT2 MOVLW 0x2B ; BT2 MOVWF FSR ; to 2. byte CALL LIGHT BCF STATUS,SEITE GOTO TEST1 #ENDIF #IFDEF TEST MOVLW (1< 25? GOTO CALEX ;----------------- MOVLW 00001000b ; ADDWF OSCCAL,1 ; GOTO CALI ;----------------- ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ; ----------------------------------- CALEX MOVLW 11010111b ; no wakeup, no pullup, T0 int., hightolow, T0, 1:256 OPTION COMF XOR,0 ; inverted stored for reset conditions (all zero) XORWF F1F8SET,0 ; for brown out to start XORWF GPIOOUT,0 ; with same speed BTFSC STATUS,ZERO ; all Bytes ok? GOTO START ; ----------------------------------- CLEAR BCF ACKBIT ; 5. CLRF IST ; ----------------------------------- CLRF SOLL ; set all register to start condition CLRF S31 ; CLRF LO ; CLRF HI ; set PWM to 1 to force a jump CLRF PWM ; in STEP for stop condition INCF PWM ; ----------------------------------- CLRF F1F8SET ; set all register to start condition CLRF F1F8OLD ; BCF LASTLT BEGIN MOVLW 00111111b ; all Input TRIS GPIO ; tristate port GPIO ; EEPROM ............................................................ LOADREG MOVLW 0x30 ; MOVWF FSR ; Pointer for indirect Adressing CLRF EEADDR ; EEREAD BSF STATUS,SEITE ; set to 200H begin EEPROM CALL READ_RANDOM ; BCF STATUS,SEITE ; auf ROM seite 0 BTFSC STATUS,ZERO ; ERROR? GOTO EEREAD ; MOVF EEDATA,0 ; MOVWF INDF ; MOVLW 0x3F ; XORWF FSR,0 ; ANDLW 00111111b ; BTFSC STATUS,ZERO ; GOTO START ; START INCF FSR,1 ; INCF EEADDR ; GOTO EEREAD ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;.................................................................. SPDTAB MOVF S31,0 ;13 ADDWF PC ;14 RETLW 0 ;15-16 RETLW 0 ; RETLW 0 ; RETLW 0 ; RETLW 2 ; 1 RETLW 3 ; 2 RETLW 5 ; 3 RETLW 7 ; 4 RETLW 10 ; 5 RETLW 13 ; 6 RETLW 18 ; 7 RETLW 22 ; 8 RETLW 28 ; 9 RETLW 34 ; 10 RETLW 41 ; 11 RETLW 48 ; 12 RETLW 56 ; 13 RETLW 65 ; 14 RETLW 74 ; 15 RETLW 84 ; 16 RETLW 95 ; 17 RETLW 106 ; 18 RETLW 118 ; 19 RETLW 131 ; 20 RETLW 144 ; 21 RETLW 158 ; 22 RETLW 173 ; 23 RETLW 188 ; 24 RETLW 204 ; 25 RETLW 220 ; 26 RETLW 237 ; 27 RETLW 255 ; 28 ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;.................................................................... ;--------------------- multiply MULT1 * MULT2 = hi MULT1 low MULT2 -- MULTIP MOVLW 9 ; 1 MOVWF COUNT ; 2 CLRW ; 3 BCF STATUS,CARRY ; 4 MULTI MOVWF TEMP ; 1 RRF TEMP,0 ; 2 RRF MULT2,1 ; 3 BTFSC STATUS,CARRY ; 4 ADDWF MULT1,0 ; 5 DECFSZ COUNT,1 ; 6 GOTO MULTI ; 7-8 MOVWF MULT1 ; 9*8=72 76 RETLW 0 ; END MULTIP 77-78 ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS #IFNDEF TEST START CLRWDT ; 12 MOVLW 0xFF ; 13 MOVWF BT4 ; 14 MOVWF BT5 ; 15 MOVWF BT6 ; 16 MOVLW 0x09 ; Pointer for ind. Adressing 17 MOVWF FSR ; (BT1 - 1) 18 #ENDIF MOVLW 11 ; 19 MOVWF PRE ; PRE to 10 Bit for Preample 20 ;------------- INTEST CLRF HI ; 20 INTST BCF STEPOK? ; 21 NOP ; 22 CALL IN ; 23-24 BTFSC STEPOK? ; 4. GOTO STEPOK ; 5.-6 CALL STEP ; 6.-7. BTFSC GPIO,3 ; ########### input ########## 1 (25) BSF BITHI ; 2 GOTO $+1 ; 3-4 GOTO $+1 ; 5-6 STEPOK MOVLW 11111100b ; FF-03 7 MOVF HI,1 ; 8 BTFSC STATUS,ZERO ; 0? 9 GOTO LOWBIT ; low half of bit 10-11 ADDWF HI,0 ; BIT im Carry 11 DECFSZ PRE,1 ; Pre=0? 12 GOTO PRETEST ; 13-14 BTFSC STATUS,CARRY ; waiting for 0 14 GOTO BYTE ; Preample ok! 15-16 INCF PRE,1 ; 16 NOP ; 17 GOTO INTEST ; next Bit 18-19 PRETEST DECFSZ HI,0 ; HI=1? 15 BTFSC STATUS,CARRY ; 16 GOTO START19 ; no Preample! 17-18 GOTO INTEST ; 18-19 LOWBIT NOP ; 12 GOTO $+1 ; 13-14 BTFSC BITHI ; 15 INCF HI ; 16 BCF BITHI ; 17 INCFSZ LO,1 ; 18 GOTO INTST ; 19-20 GOTO BEGIN ; >10000uS 20-21 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IN BTFSS GPIO,3 ; ########### input ########## 1 (25) RETLW 0 ; 2.-3. INCF HI ; 3. CLRF LO ; 4. BSF STEPOK? ; 5. CALL STEP ; 6.-7. BTFSS GPIO,3 ; ########### input ########## 1 (25) RETLW 0 ; FF-03 2-3 INCF HI ; 3 NOP ; ----------------------------- 4 MOVF GPIOOUT,0 ; for brown out 5 XORWF F1F8SET,0 ; to start with 6 MOVWF XOR ; same speed 7 COMF XOR,1 ; ----------------------------- 8 BTFSC FS126 ; 9 GOTO FS126OV ; 10-11 ;.....................SPEEDTAB.......................................... CALL SPDTAB ; 11-12 MOVWF SOLL ; 17 BCF STATUS,CARRY ; 18 BTFSC FLAGS2 ; 19 RRF SOLL,1 ; 20 ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FS126BK BCF STEPOK? ; 21 INCFSZ HI,0 ; 22 GOTO IN ; 23-24 GOTO BEGIN ; >10000uS 24 FS126OV NOP ; 12 GOTO $+1 ; 13-14 GOTO $+1 ; 15-16 GOTO $+1 ; 17-18 GOTO FS126BK ; 19-20 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;..................................................................... STEP GOTO $+1 ; 8.-9. GOTO $+1 ; 10.-11. GOTO $+1 ; 12.-13. GOTO $+1 ; 14.-15. GOTO $+1 ; 16.-17. GOTO $+1 ; 18.-19. GOTO $+1 ; 20.-21. NOP ; 22. RETLW 0 ; 23.-24. ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LOWBIT1 MOVLW 0x10 ; ----------------------------- 12 SUBWF FSR,0 ; 13 ANDLW 00000111b ; more than 6 BYTE read 14 BTFSC STATUS,ZERO ; begin new! 15 GOTO START18 ; ----------------------------- 16-17 BTFSC BITHI ; 17 INCF HI ; 18 GOTO INTST1 ; 19-20 BYTE MOVLW 9 ; PRE to 8 Bit for 1.Byte 17 MOVWF PRE ; 18 INCF FSR,1 ; Pointer for ind. Adressing 19 INTEST1 CLRF HI ; 20 INTST1 BCF STEPOK? ; 21 BCF BITHI ; 22 CALL IN ; 23-24 BTFSC STEPOK? ; 4. GOTO STEPOK1 ; 5.-6 CALL STEP ; 6.-7. BTFSC GPIO,3 ; ########### input ########## 1 (25) BSF BITHI ; 2 NOP ; 3 NOP ; 4 NOP ; 5 NOP ; 6 STEPOK1 MOVLW 11111100b ; FF-03 7 MOVF HI,1 ; 8 BTFSC STATUS,ZERO ; 0? 9 GOTO LOWBIT1 ; low half of bit 10-11 ADDWF HI,0 ; BIT im Carry 11 DECFSZ PRE,1 ; Pre=0? 12 GOTO NEXT ; 13-14 BTFSC STATUS,CARRY ; 14 GOTO BYTE ; 9.Bit=0 15-16 ;------------- Letztes BIT=1 ------------- CLRF NOADR ; for IB with M* MOVF BT1,0 ; 17 XORWF BT2,0 ; 18 XORWF BT3,0 ; 19 XORWF BT4,0 ; 20 XORWF BT5,0 ; 21 XORWF BT6,0 ; 22 BTFSS STATUS,ZERO ; all Bytes ok? 23 GOTO START2. ; 24-1. COMF BT1,1 ; 9.Bit=1 (inverting BYTE) 1. COMF BT2,1 ; (inverting BYTE) 2. COMF BT3,1 ; (inverting BYTE) 3. COMF BT4,1 ; (inverting BYTE) 4. COMF BT5,1 ; (inverting BYTE) 5. CALL STEP ; 6.-7. DECF FSR,1 ; auf vorletztes Byte 1 MOVLW (1<0= 120 (120=CV1 121=CV2 ...) BTFSS STATUS,ZERO ; GOTO START ; BSF STATUS,SEITE ; GOTO PROG ; register mode (CV1-CV8) ;-------------------------------- SHORTA BTFSC STATUS,ZERO ; address = 0 9 GOTO BCAST ; 10-11 BTFSS LADRE ; long Adress enabled? 11 XORWF CV1,0 ; 12 BTFSC STATUS,ZERO ; 13 GOTO OVER ; 14-15 MOVF CV19,0 ; 15 ANDLW 01111111b ; 16 BCF CONSIST ; 17 BTFSS STATUS,ZERO ; 18 BSF CONSIST ; 19 XORWF BT1,0 ; consist? 20 BCBCK BTFSS STATUS,ZERO ; 21 GOTO CHKPROG ; 22-23 MOVLW 0x2B ; BT2 + FSR,5 23 MOVWF FSR ; to 2. byte 24 BSF STATUS,SEITE ; 25 GOTO DECOD ; 26-27 ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;-------------------------------- NEXT NOP ; 15 RLF INDF,1 ; 1.Byte zusammenbauen 16 DECFSZ HI,0 ; HI=1? 17 GOTO INTEST1 ; next bit 18-19 GOTO START21 ; 19-20 ;.................................................................... VMIDHI EQU 0x0A ; BT1 VMIDLO EQU 0x0B ; BT2 MULT1 EQU 0x0C ; BT3 MULT2 EQU 0x0D ; BT4 COUNT EQU 0x0E ; BT5 TEMP EQU 0x0F ; BT6 ;-------------------------------- CV2CV5 MOVLW 151 ; CV2=1 & CV5=255 MOVWF MULT1 ; MOVLW 4 ; 4-31 -> 0-27 SUBWF S31,0 ; MOVWF MULT2 ; ;------- CALL MULTIP ; 104-105 (1-86) ;------- RRF MULT1,1 ; 77 RRF MULT2,1 ; /4 78 RRF MULT1,1 ; 79 RRF MULT2,1 ; /8 80 RRF MULT1,1 ; 81 RRF MULT2,1 ; /16 82 RRF MULT1,1 ; 83 RRF MULT2,1 ; /32 84 ;------- BTFSC MULT1,0 ; > 255 ? GOTO BORROW ; MOVLW 1 ; ADDWF MULT2,0 ; BTFSC STATUS,CARRY ; BORROW MOVLW 255 ; BCF FSR,5 ; 1st page MOVWF SOLL ; GOTO START ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;-------------------------------------------------------------------- START1. NOP ; 1. START2. NOP ; 2. START3. NOP ; 3. START4. NOP ; 4. START5. NOP ; 5. START6. CALL STEP ; 6.-7. START1 NOP ; 1 START2 NOP ; 2 START3 NOP ; 3 START4 NOP ; 4 START5 NOP ; 5 START6 NOP ; 6 START7 NOP ; 7 START8 NOP ; 8 START9 NOP ; 9 START10 GOTO START ; 10-11 START11 NOP ; 11 START12 NOP ; 12 START13 NOP ; 13 START14 NOP ; 14 START15 NOP ; 15 START16 NOP ; 16 START17 NOP ; 17 START18 NOP ; 18 ;..................................................................... START19 INCF NOADR ; for IB with M* 19 START20 BTFSS NOADR,7 ; counts if no 20 START21 GOTO START23 ; DCC signal is 21 GOTO INIT ; readable 22 ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ START23 GOTO START1. ; 23-24 ;******************************************************************* ORG 0200h TITLE "PIC with EEPROM Data Memory Interface" LIST P=12CE519 SCL EQU 0x07 ; EEPROM Clock, SCL (I/O bit 7) SDA EQU 0x06 ; EEPROM Data, SDA (I/O bit 6) OK EQU 1 NO EQU 0 EE_OK EQU 7 ; Bit 7 in PC_OFFSET used as OK flag for EE PC_OFFSET EQU 0x35 ; PC offset register (low order 4 bits), ; value based on operating mode of EEPROM. ; Also, bit 7 used for EE_OK flag COUNTER EQU 0x08 ; Bit counter for serial transfer EEBYTE EQU 0x09 ; Byte sent to or received from ; EEPROM (control, address, or data) EEADDR EQU 0x0A ; EEPROM Address EEDATA EQU 0x0F ; EEPROM Data ;********************** Set up EEPROM control bytes ************************ READ_CURRENT MOVLW B'10000100' ; PC offset for read current addr. EE_OK bit7='1' MOVWF PC_OFFSET ; Load PC offset GOTO INIT_READ_CONTROL WRITE_BYTE MOVLW B'10000000' ; PC offset for write byte. EE_OK: bit7 = '1' GOTO INIT_WRITE_CONTROL READ_RANDOM MOVLW B'10000011' ; PC offset for read random. EE_OK: bit7 = '1' INIT_WRITE_CONTROL MOVWF PC_OFFSET ; Load PC offset register, value preset in W MOVLW B'10100000' ; Control byte with write bit, bit 0 = '0' START_BIT BCF GPIO,SDA ; Start bit, SDA and SCL preset to '1' ;******* Set up output data (control, address, or data) and counter ******** PREP_TRANSFER_BYTE MOVWF EEBYTE ; Byte to transfer to EEPROM already in W MOVLW 8 ; Counter to transfer 8 bits MOVWF COUNTER ;************ Clock out data (control, address, or data) byte ************ OUTPUT_BYTE BCF GPIO,SCL ; Set clock low during data set-up RLF EEBYTE,1 ; Rotate left, high order bit into carry bit BCF GPIO,SDA ; Set data low, if rotated carry bit is BTFSC STATUS,CARRY ;(SKPNC) a '1', then: BSF GPIO,SDA ; reset data pin to a one, otherwise leave low NOP BSF GPIO,SCL ; clock data into EEPROM DECFSZ COUNTER,1 ; Repeat until entire byte is sent GOTO OUTPUT_BYTE NOP ; Needed to meet Timing (Thigh=4000nS) ;************************** Acknowkedge Check ***************************** BCF GPIO,SCL ; Set SCL low, 0.5us < ack valid < 3us NOP ; Needed to meet Timing (Tlow= 4700nS) BSF GPIO,SDA NOP ; Necessary for SCL Tlow at low voltage, NOP ; Tlow=4700nS BSF GPIO,SCL ; Raise SCL, EEPROM acknowledge still valid BTFSC GPIO,SDA ; Check SDA for acknowledge (low) BCF PC_OFFSET,EE_OK ; If SDA not low (no ack), set error flag BCF GPIO,SCL ; Lower SCL, EEPROM release bus BTFSS PC_OFFSET,EE_OK ; If no error continue, else stop bit GOTO STOP_BIT ;***** Set up program counter offset, based on EEPROM operating mode ***** MOVF PC_OFFSET,0 ANDLW B'00001111' ADDWF PC GOTO INIT_ADDRESS ;PC offset=0, write control done, send address GOTO INIT_WRITE_DATA ;PC offset=1, write address done, send data GOTO STOP_BIT ;PC offset=2, write done, send stop bit GOTO INIT_ADDRESS ;PC offset=3, write control done, send address GOTO INIT_READ_CONTROL ;PC offset=4, send read control GOTO READ_BIT_COUNTER ;PC offset=5, set counter and read byte GOTO STOP_BIT ;PC offset=6, random read done, send stop ;********** Initalize EEPROM data (address, data, or control) bytes ****** INIT_ADDRESS INCF PC_OFFSET,1 ; Increment PC offset to 2 (write) or to 4 (read) MOVF EEADDR,W ; Put EEPROM address in W, ready to send to EEPROM GOTO PREP_TRANSFER_BYTE INIT_WRITE_DATA INCF PC_OFFSET,1 ; Increment PC offset to go to STOP_BIT next MOVF EEDATA,0 ; Put EEPROM data in W, ready to send to EEPROM GOTO PREP_TRANSFER_BYTE INIT_READ_CONTROL BSF GPIO,SCL ; Raise SCL BSF GPIO,SDA ; raise SDA INCF PC_OFFSET,1 ; Increment PC offset to go to READ_BIT_COUNTER next MOVLW B'10100001' ; Set up read control byte, ready to send to EEPROM GOTO START_BIT ; bit 0 = '1' for read operation ;************************** Read EEPROM data ***************************** READ_BIT_COUNTER BSF GPIO,SDA ; set data bit to 1 so we're not pulling bus down. NOP BSF GPIO,SCL MOVLW 8 ; Set counter so 8 bits will be read into EEDATA MOVWF COUNTER READ_BYTE BSF GPIO,SCL ; Raise SCL, SDA valid. SDA still input from ack SETC ; Assume bit to be read = 1 BTFSS GPIO,SDA ; Check if SDA = 1 BCF STATUS,CARRY ;(CLRC) if SDA not = 1 then clear carry bit RLF EEDATA,1 ; rotate carry bit (=SDA) into EEDATA; BCF GPIO,SCL ; Lower SCL bsf GPIO,SDA ; reset SDA DECFSZ COUNTER,1 ; Decrement counter GOTO READ_BYTE ; Read next bit if not finished reading byte BSF GPIO,SCL NOP BCF GPIO,SCL ;****************** Generate a STOP bit and RETURN *********************** STOP_BIT BCF GPIO,SDA ; SDA=0, on TRIS, to prepare for transition to '1' BSF GPIO,SCL ; SCL = 1 to prepare for STOP bit GOTO $+1 ; equivalent 4 NOPs neccessary for I2C spec Tsu:sto = 4.7us GOTO $+1 BSF GPIO,SDA ; Stop bit, SDA transition to '1' while SCL high BTFSS PC_OFFSET,EE_OK ; Check for error RETLW NO ; if error, send back NO RETLW OK ; if no error, send back OK ;************************ End EEPROM Subroutines ************************** ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; ; 0111 1RRR DDDD DDDD -> register mode ; ; 0111 10AA AAAA AAAA 111K DBBB ; Bit manipulation ; verify/write^ ;..................................................................... DECOD SWAPF INDF,0 ; 25 MOVWF BT6 ; 26 RRF BT6,0 ; 27 ANDLW 00000111b ; 28 ADDWF PC ; 29 GOTO DECCON ; 000 30-31 GOTO ADVAN ; 001 GOTO FORWARD ; 010 GOTO REVERSE ; 011 GOTO FTION ; 100 GOTO FTION1 ; 101 GOTO TELNEW ; 110 MOVF BT2,0 ;-------------------------------- XORLW 11111001b ; old acknowledge mode BTFSC STATUS,ZERO ; GOTO OLDACK ;-------------------------------- MOVF INDF,0 ; OTM mode -copy bytes MOVWF BT1 ; INCF FSR,1 ; MOVF INDF,0 ; CV to pogram MOVWF BT2 ; INCF FSR,1 ; DATA for cv MOVF INDF,0 ; INDF looks to data MOVWF BT3 ; GOTO PROGOTM ; 111 ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;..................................................................... BITMAN MOVWF FSR ; MOVLW 00000111b ; ANDWF BT3,0 ; CALL BITPOS ; BTFSS BT3,4 ; GOTO VBIT ; verify bit BTFSC BT3,3 ; IORWF INDF,1 ; set bit XORLW 0XFF ; BTFSS BT3,3 ; ANDWF INDF,1 ; clear bit MOVF FSR,0 ; EEADDR GOTO EEPROG ; write complete byte ;-------------------------------- VBIT ANDWF INDF,0 ; BTFSC STATUS,ZERO ; GOTO BITCLR ; BITSET BTFSC BT3,3 ; GOTO ACKNOW ; =1 GOTO HOPP ; BITCLR BTFSS BT3,3 ; GOTO ACKNOW ; =0 GOTO HOPP ; ;-------------------------------- BITPOS ADDWF PC ; RETLW 00000001b ; 0 RETLW 00000010b ; 1 RETLW 00000100b ; 2 RETLW 00001000b ; 3 RETLW 00010000b ; 4 RETLW 00100000b ; 5 RETLW 01000000b ; 6 RETLW 10000000b ; 7 ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;..................................................................... DECCON BTFSC INDF,4 ; 000>01LS0 MOVWF BT6 ; RRF BT6,0 ; xxD65432->10 ANDLW 00011111b ; xxx65432 MOVWF S31 ; xxx43210 BSF FS28 ; BSF FS126 ; RLF INDF,0 ; BCF FSR,5 ; MOVWF SOLL ; GOTO HOPP ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FTION2 ; TELNEW ; HOPP BCF PROGBIT ; BCF PROGBT1 ; BCF ACKBIT ; PROGEX BCF STATUS,SEITE ; BCF FSR,5 ; GOTO START ; ;******************************************************************** ORG 03FFh MOVLW 0x70 ; for OSCCAL END