******************************** * PROGRAM FOR TESTING * THE PCF8584 I2C INTERFACE * CONNECTED TO A DS1307 RTC * TIME CAN BE SET AND READ * FROM THE DS1307 * BY: DANIEL TUFVESSON 2015 ******************************** RETURN EQU $C000 RETURN TO PROMPT OUTCHAR EQU $C003 OUTPUT CHAR ON CONSOLE INCHAR EQU $C006 INPUT CHAR FROM CONSOLE AND ECHO PDATA EQU $C009 PRINT TEXT STRING @ X ENDED BY $04 OUT2HS EQU $C012 PRINT 2 HEX CHARS @ X INBYTE EQU $C01B INPUT 1 BYTE TO A. CARRY SET = OK BADDR EQU $C01E INPUT ADDRESS TO X. CARRY SET = OK PCRLF EQU $C021 PRINT CRLF OUTS EQU $C024 PRINT SPACE CONSVEC EQU $7FE5 CONSOLE STATUS VECTOR CONOVEC EQU $7FE8 CONSOLE OUTPUT VECTOR CONIVEC EQU $7FEB CONSOLE INPUT VECTOR PAGEREG EQU $0002 I/O PAGE SELECT REGISTER * * PCF8584 REGISTERS * P8584 EQU $8050 P8584SX EQU P8584+0 P8584S1 EQU P8584+1 * * I2C DEVICES * RTCADDR EQU $68 * * PROGRAM BEGIN HERE * ORG $0100 JMP START TXSTART FCC '(S)ET OR (G)ET TIME?' FCB $04 TXSEC FCB $0A,$0D FCC 'SECONDS [00-59]' FCB $0A,$0D,$04 TXMIN FCB $0A,$0D FCC 'MINUTES [00-59]' FCB $0A,$0D,$04 TXHOU FCB $0A,$0D FCC 'HOURS [00-23]' FCB $0A,$0D,$04 TXDAY FCB $0A,$0D FCC 'DAY OF WEEK [01-07, MON=01 SUN=07]' FCB $0A,$0D,$04 TXDAT FCB $0A,$0D FCC 'DATE [01-31]' FCB $0A,$0D,$04 TXMON FCB $0A,$0D FCC 'MONTH [01-12]' FCB $0A,$0D,$04 TXYEA FCB $0A,$0D FCC 'YEAR [0000-9999]' FCB $0A,$0D,$04 TXCOR FCB $0A,$0D FCC 'CORRECT? [CR=YES]' FCB $0A,$0D,$04 TXABO FCB $0A,$0D FCC 'ABORTED' FCB $0A,$0D,$04 TXSET FCB $0A,$0D FCC 'TIME SET' FCB $0A,$0D,$04 TXDAYS FCC 'MON' FCB $04 FCC 'TUE' FCB $04 FCC 'WED' FCB $04 FCC 'THU' FCB $04 FCC 'FRI' FCB $04 FCC 'SAT' FCB $04 FCC 'SUN' FCB $04 BUFF RMB 10 START LDX #TXSTART JSR PDATA JSR CONIVEC ANDA #$DF CMPA #'G BEQ LOOP CMPA #'S BEQ *+5 JMP RETURN JSR RTCSET JSR PCRLF LOOP JSR RTCGET LDAA BUFF CMPA BUFF+9 BEQ LOOP STAA BUFF+9 LDAA #$0D JSR OUTCHAR JSR OUTS LDAA BUFF+3 CALC DAY NAME DECA LDAB #4 MUL LDX #TXDAYS ABX JSR PDATA DAY JSR OUTS LDX #BUFF+8 JSR OUT2HS CENTURY DEX DEX DEX LDAA #$08 JSR OUTCHAR JSR OUT2HS YEAR DEX DEX LDAA #$08 JSR OUTCHAR LDAA #'- JSR OUTCHAR JSR OUT2HS MONTH DEX DEX LDAA #$08 JSR OUTCHAR LDAA #'- JSR OUTCHAR JSR OUT2HS DATE DEX DEX DEX JSR OUT2HS HOURS DEX DEX LDAA #$08 JSR OUTCHAR LDAA #': JSR OUTCHAR JSR OUT2HS MINUTES DEX DEX LDAA #$08 JSR OUTCHAR LDAA #': JSR OUTCHAR JSR OUT2HS SECONDS JSR CONSVEC TSTA BEQ LOOP JSR CONIVEC JMP RETURN * * RTC GET TIME * RTCGET LDAA #$00 STAA PAGEREG JSR I2CINIT INIT PCF8584 LDAB #RTCADDR JSR I2CWRIT START WRITE CLRA STAA BUFF LDX #BUFF CLRB BYTES TO SEND JSR I2CTX SEND ADDRESS LDAB #RTCADDR JSR I2CREAD START READ LDAB #8 READ 9 BYTES LDX #BUFF JSR I2CRX READ BYTES JSR I2CSTOP STOP TRANSMISSION RTS * * RTC SET TIME * RTCSET LDX #TXYEA READ YEAR JSR PDATA JSR BADDR XGDX STAA BUFF+8 STAB BUFF+6 LDX #TXMON READ MONTH JSR PDATA JSR INBYTE ANDA #%00011111 STAA BUFF+5 LDX #TXDAT READ DATE JSR PDATA JSR INBYTE ANDA #%00111111 STAA BUFF+4 LDX #TXDAY READ DAY OF WEEK JSR PDATA JSR INBYTE ANDA #%00000111 STAA BUFF+3 LDX #TXHOU READ HOURS JSR PDATA JSR INBYTE ANDA #%00111111 STAA BUFF+2 LDX #TXMIN READ MINUTES JSR PDATA JSR INBYTE ANDA #%01111111 STAA BUFF+1 LDX #TXSEC READ SECONDS JSR PDATA JSR INBYTE ANDA #%01111111 STAA BUFF CLR BUFF+7 CONFIG REG LDX #TXCOR ENTRY CORRECT? JSR PDATA JSR CONIVEC CMPA #$0D BEQ RTCSETW LDX #TXABO ABORT JSR PDATA BRA RTCSETE * WRITE DATA TO RTC RTCSETW LDAA #$00 STAA PAGEREG JSR I2CINIT INIT PCF8584 LDAB #RTCADDR JSR I2CWRIT START WRITE CLR BUFF+9 LDX #BUFF+9 CLRB JSR I2CTX SEND ADDRESS LDX #BUFF LDAB #8 WRITE 9 BYTES JSR I2CTX JSR I2CSTOP RTCSETE RTS * * INIT PCF8584 * I2CINIT LDAA #$80 PIN - SX = OWN ADDRESS STAA P8584S1 LDAA #$55 OWN ADDRESS STAA P8584SX LDAA #$A0 PIN+ES1 - SX = CLOCK REGISTER STAA P8584S1 LDAA #$00 3MHz, 90kHz STAA P8584SX LDAA #$C1 PIN+ESO+ACK STAA P8584S1 JSR I2CBUSY RTS * * WAIT FOR PCF8584 READY * I2CBUSY LDAA P8584S1 ANDA #$01 CHECK BUSY BIT BEQ I2CBUSY RTS * * I2C READ START * B = SLAVE ADDRESS ($00-$7F) * I2CREAD LDAA P8584S1 BPL I2CREA1 BUS OPERATION IS CURRENTLY ACTIVE (PIN SET)? * START NEW BUS OPERATION JSR I2CBUSY ASLB ORAB #%00000001 SET READ BIT STAB P8584SX SET SLAVE ADDRESS LDAA #$C5 PIN+ESO+STA+ACK - "START" STAA P8584S1 BRA I2CREAW WAIT FOR COMMAND TO COMPLETE * RESTART BUS OPERATION I2CREA1 LDAA #$45 ESO+STA+ACK - "START" WITHOUT PREVIOUS "STOP" STAA P8584S1 ASLB ORAB #%00000001 SET READ BIT STAB P8584SX SET SLAVE ADDRESS I2CREAW LDAA P8584S1 BMI I2CREAW PIN SET? DATA SENT? ANDA #$08 MASK OUT LRB BNE I2CREAE ERROR - SLAVE DID NOT ACK LDAA P8584SX DUMMY READ TO CLEAR DATA REG FROM SLAVE ADDRESS SEC RTS I2CREAE CLC RTS * * I2C WRITE START * B = SLAVE ADDRESS ($00-$7F) * I2CWRIT JSR I2CBUSY ASLB ANDB #%11111110 SET WRITE BIT STAB P8584SX SET SLAVE ADDRESS LDAA #$C5 PIN+ESO+STA+ACK - "START" STAA P8584S1 I2CWRIW LDAA P8584S1 BMI I2CWRIW PIN SET? DATA SENT? ANDA #$08 MASK OUT LRB BNE I2CWRIE ERROR - SLAVE DID NOT ACK SEC RTS I2CWRIE CLC RTS * * I2C STOP * I2CSTOP LDAA P8584S1 BMI I2CSTOP PIN SET? DATA SENT? LDAA #$C3 PIN+ES0+STO+ACK - "STOP" STAA P8584S1 RTS * * I2C RX * B = NUMBER OF BYTES TO READ * X = DATA BUFFER * I2CRX LDAA P8584S1 BMI I2CRX PIN SET? DATA RECEIVED? ANDA #$08 MASK OUT LRB BNE I2CRXER ERROR - SLAVE DID NOT ACK TSTB CHECK IF THIS IS THE FINAL BYTE BNE I2CRX1 LDAA #$40 ESO - SEND "NACK" FOR FINAL BYTE STAA P8584S1 I2CRX1 LDAA P8584SX READ DATA FROM BUS STAA ,X INX DECB CMPB #$FF BNE I2CRX MORE BYTES TO READ? SEC RTS I2CRXER CLC RTS * * I2C TX * B = NUMBER OF BYTES TO SEND * X = DATA BUFFER * I2CTX LDAA ,X INX STAA P8584SX SEND DATA TO BUS I2CTXW LDAA P8584S1 BMI I2CTXW PIN SET? DATA SENT? ANDA #$08 MASK OUT LRB BNE I2CTXER ERROR - SLAVE DID NOT ACK DECB CMPB #$FF BNE I2CTX MORE BYTES TO WRITE? SEC RTS I2CTXER CLC RTS