Browse Source

Add graceful fail to i2c clock driver

patch
b1ackmai1er 5 years ago
parent
commit
9b9f9ded08
  1. 29
      Source/Apps/rtchb.asm
  2. 32
      Source/HBIOS/ds7rtc.asm
  3. 221
      Source/HBIOS/pcf8584.asm

29
Source/Apps/rtchb.asm

@ -1,27 +1,40 @@
;==================================================================================================
; GENERIC HBIOS DATE AND TIME
;==================================================================================================
;
.ECHO "rtchb\n"
;
; HBIOS FORMAT = YYMMDDHHMMSS
;
.ORG 100H
;
LD (HBC_STK),SP ; SETUP A
LD SP,HBC_LOC ; LOCAL STACK
;
LD B,$20 ; READ CLOCK DATA INTO BUFFER
LD HL,HBC_BUF ; DISPLAY TIME AND DATE FROM BUFFER
RST 08
;
OR A ; EXIT IF NO
JR NZ,HBC_ERR ; DRIVER OR HARDWARE
;
#IF (0)
PUSH AF
LD A,6
LD DE,HBC_BUF ; DISLAY DATA READ
; CALL PRTHEXBUF
CALL NEWLINE
POP AF
#ENDIF
;
CALL HBC_DISP
RET
HBC_BUF .FILL 6,0
CALL HBC_DISP
;
HBC_EXIT:
LD SP,(HBC_STK) ; RESTORE STACK AND
RET ; RETURN TO CP/M
;
HBC_BUF .FILL 6,0 ; DATE AND TIME STORAGE
HBC_STK .DW 2 ; SAVE STACK
;
;-----------------------------------------------------------------------------
; DISPLAY CLOCK INFORMATION FROM DATA STORED IN BUFFER
@ -80,7 +93,7 @@ HBC_PRTERR:
CALL PRTSTR
CALL NEWLINE
POP HL
RET
JP HBC_EXIT
;
HBC_FAIL .DB "ERROR$"
;
@ -96,9 +109,9 @@ CR .EQU 0DH ;CARRIAGE-RETURN
; OUTPUT TEXT AT HL
;
PRTSTR: LD A,(HL)
OR A
CP '$'
RET Z
CALL PRINP
CALL COUT
INC HL
JR PRTSTR
;
@ -215,4 +228,6 @@ BDO: PUSH HL
POP HL
RET
;
.FILL 128,$FF
HBC_LOC:
.END

32
Source/HBIOS/ds7rtc.asm

@ -18,18 +18,6 @@ DS7_WRITE .EQU (DS7_DS1307 | DS7_W) ; WRITE
;
DS7_CTL .EQU (DS7_OUT | DS7_SQWE | DS7_RATE)
;
; GENERIC CP/M STUFF
;
BS .EQU 8 ; BACKSPACE
TAB .EQU 9 ; TABULATOR
LF .EQU 0AH ; LINE-FEED
CR .EQU 0DH ; CARRIAGE-RETURN
CLIARGS .EQU $81
RESTART .EQU $0000 ; CP/M restart vector
BDOS .EQU $0005 ; BDOS invocation vector
FCB .EQU $5C ; Location of default FCB
;
;-----------------------------------------------------------------------------
; DS1307 INITIALIZATION
;
@ -45,6 +33,10 @@ FCB .EQU $5C ; Location of default FCB
DS7RTC_INIT:
PRTS("DS1307: $") ; ANNOUNCE DRIVER
;
LD A,(PCF_FAIL_FLAG) ; CHECK IF THE
OR A ; I2C DRIVER
JR NZ,RTC_INIT_FAIL ; INITIALIZED
CALL DS7_RDC ; READ CLOCK DATA
LD HL,DS7_BUF ; IF NOT RUNNING OR
BIT 7,(HL) ; INVALID, RESTART
@ -66,6 +58,16 @@ DS7_CSET:
XOR A ; SIGNAL SUCCESS
RET
;
RTC_INIT_FAIL: ; EXIT
CALL PRTSTRD ; WITH
.DB "NO I2C DRIVER$" ; ERROR
PUSH AF ; MESSAGE
RTC_INIT_ERR: ; EXIT
POP AF ; WITH
LD A,ERR_NOHW ; ERROR
OR A ; STATUS
RET
;
;-----------------------------------------------------------------------------
; DS1307 HBIOS DISPATCHER
;
@ -73,6 +75,12 @@ DS7_CSET:
; B: FUNCTION (IN)
;
DS7_DISPATCH:
PUSH AF ; CHECK IF WE
LD A,(PCF_FAIL_FLAG) ; HAVE HARDWARE
OR A ; AND ASSOCIATED
JR NZ,RTC_INIT_ERR ; DRIVER
POP AF
;
LD A, B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z, DS7_GETTIM ; GET TIME

221
Source/HBIOS/pcf8584.asm

@ -6,9 +6,9 @@ PCF_BASE .EQU 0F0H
PCF_ID .EQU 0AAH
CPU_CLK .EQU 12
PCF_RS0 .EQU PCF_BASE
PCF_RS1 .EQU PCF_RS0+1
PCF_OWN .EQU (PCF_ID >> 1) ; PCF'S ADDRESS IN SLAVE MODE
PCF_RS0 .EQU PCF_BASE
PCF_RS1 .EQU PCF_RS0+1
PCF_OWN .EQU (PCF_ID >> 1) ; PCF'S ADDRESS IN SLAVE MODE
;
;T4LC512D .EQU 10100000B ; DEVICE IDENTIFIER
;T4LC512A1 .EQU 00000000B ; DEVICE ADDRESS
@ -37,10 +37,10 @@ PCF_STA .EQU 00000100B
PCF_STO .EQU 00000010B
PCF_ACK .EQU 00000001B
;
PCF_START_ .EQU (PCF_PIN | PCF_ES0 | PCF_STA | PCF_ACK)
PCF_STOP_ .EQU (PCF_PIN | PCF_ES0 | PCF_STO | PCF_ACK)
PCF_REPSTART_ .EQU ( PCF_ES0 | PCF_STA | PCF_ACK)
PCF_IDLE_ .EQU (PCF_PIN | PCF_ES0 | PCF_ACK)
PCF_START_ .EQU (PCF_PIN | PCF_ES0 | PCF_STA | PCF_ACK)
PCF_STOP_ .EQU (PCF_PIN | PCF_ES0 | PCF_STO | PCF_ACK)
PCF_REPSTART_ .EQU ( PCF_ES0 | PCF_STA | PCF_ACK)
PCF_IDLE_ .EQU (PCF_PIN | PCF_ES0 | PCF_ACK)
;
; STATUS REGISTER BITS
;
@ -52,7 +52,7 @@ PCF_AD0 .EQU 00001000B
PCF_LRB .EQU 00001000B
PCF_AAS .EQU 00000100B
PCF_LAB .EQU 00000010B
PCF_BB .EQU 00000001B
PCF_BB .EQU 00000001B
;
; CLOCK CHIP FREQUENCIES
;
@ -109,6 +109,7 @@ PCF8584_INIT:
PRTS("I2C: IO=0x$")
LD A, PCF_BASE
CALL PRTHEXBYTE
CALL PC_SPACE
CALL PCF_INIT
CALL NEWLINE
RET
@ -122,81 +123,91 @@ PCF8584_INIT:
;
;-----------------------------------------------------------------------------
PCF_START:
LD A,PCF_START_
OUT (PCF_RS1),A
LD A,PCF_START_
OUT (PCF_RS1),A
RET
;
;-----------------------------------------------------------------------------
PCF_REPSTART:
LD A,PCF_REPSTART_
OUT (PCF_RS1),A
LD A,PCF_REPSTART_
OUT (PCF_RS1),A
RET
;
;-----------------------------------------------------------------------------
PCF_STOP:
LD A,PCF_STOP_
OUT (PCF_RS1),A
RET
OUT (PCF_RS1),A
RET
;
;-----------------------------------------------------------------------------
;
PCF_INIT:
LD A,PCF_PIN ; S1=80H: S0 SELECTED, SERIAL
OUT (PCF_RS1),A ; INTERFACE OFF
NOP
IN A,(PCF_RS1) ; CHECK TO SEE S1 NOW USED AS R/W
AND 07FH ; CTRL. PCF8584 DOES THAT WHEN ESO
JP NZ,PCF_INIERR ; IS ZERO
;
LD A,PCF_OWN ; LOAD OWN ADDRESS IN S0,
OUT (PCF_RS0),A ; EFFECTIVE ADDRESS IS (OWN <<1)
NOP
IN A,(PCF_RS0) ; CHECK IT IS REALLY WRITTEN
CP PCF_OWN
JP NZ,PCF_SETERR
;
LD A,+(PCF_PIN | PCF_ES1) ; S1=0A0H
OUT (PCF_RS1),A ; NEXT BYTE IN S2
NOP
IN A,(PCF_RS1)
AND 07FH
CP PCF_ES1
JP NZ,PCF_REGERR
;
LD A,PCF_CLK ; LOAD CLOCK REGISTER S2
OUT (PCF_RS0),A
NOP
IN A,(PCF_RS0) ; CHECK IT'S REALLY WRITTEN, ONLY
AND 1FH ; THE LOWER 5 BITS MATTER
CP PCF_CLK
JP NZ,PCF_CLKERR
;
LD A,PCF_IDLE_
OUT (PCF_RS1),A
NOP
IN A,(PCF_RS1)
CP +(PCF_PIN | PCF_BB)
JP NZ,PCF_IDLERR
;
RET
LD A,PCF_PIN ; S1=80H: S0 SELECTED, SERIAL
OUT (PCF_RS1),A ; INTERFACE OFF
NOP
IN A,(PCF_RS1) ; CHECK TO SEE S1 NOW USED AS R/W
AND 07FH ; CTRL. PCF8584 DOES THAT WHEN ESO
JR NZ,PCF_FAIL ; IS ZERO
;
LD A,PCF_OWN ; LOAD OWN ADDRESS IN S0,
OUT (PCF_RS0),A ; EFFECTIVE ADDRESS IS (OWN <<1)
NOP
IN A,(PCF_RS0) ; CHECK IT IS REALLY WRITTEN
CP PCF_OWN
JP NZ,PCF_SETERR
;
LD A,+(PCF_PIN | PCF_ES1) ; S1=0A0H
OUT (PCF_RS1),A ; NEXT BYTE IN S2
NOP
IN A,(PCF_RS1)
AND 07FH
CP PCF_ES1
JP NZ,PCF_REGERR
;
LD A,PCF_CLK ; LOAD CLOCK REGISTER S2
OUT (PCF_RS0),A
NOP
IN A,(PCF_RS0) ; CHECK IT'S REALLY WRITTEN, ONLY
AND 1FH ; THE LOWER 5 BITS MATTER
CP PCF_CLK
JP NZ,PCF_CLKERR
;
LD A,PCF_IDLE_
OUT (PCF_RS1),A
NOP
IN A,(PCF_RS1)
CP +(PCF_PIN | PCF_BB)
JP NZ,PCF_IDLERR
;
XOR A
RET
;
PCF_FAIL:
CALL PCF_INIERR
LD A,ERR_NOHW
LD (PCF_FAIL_FLAG),A
RET
;
PCF_FAIL_FLAG:
.DB 0
;
;-----------------------------------------------------------------------------
PCF_HANDLE_LAB:
;
LD A,PCF_PIN
OUT (PCF_RS1),A
LD A,PCF_ES0
OUT (PCF_RS1),A
LD A,PCF_PIN
OUT (PCF_RS1),A
LD A,PCF_ES0
OUT (PCF_RS1),A
;
LD HL,PCF_LABDLY
LD HL,PCF_LABDLY
PCF_LABLP:
LD A,H
OR L
DEC HL
JR NZ,PCF_LABLP
LD A,H
OR L
DEC HL
JR NZ,PCF_LABLP
;
IN A,(PCF_RS1)
RET
IN A,(PCF_RS1)
RET
;
;-----------------------------------------------------------------------------
;
@ -207,10 +218,10 @@ PCF_LABLP:
;
PCF_WAIT_FOR_PIN:
PUSH HL
LD HL,PCF_PINTO ; SET TIMEOUT VALUE
LD HL,PCF_PINTO ; SET TIMEOUT VALUE
PCF_WFP0:
IN A,(PCF_RS1) ; GET BUS
IN A,(PCF_RS1) ; GET BUS
LD (PCF_STATUS),A ; STATUS
LD B,A
@ -220,8 +231,8 @@ PCF_WFP0:
JR Z,PCF_WFP1 ; YES WE HAVE, GO ACTION IT
LD A,B ;
AND PCF_PIN ; IS TRANSMISSION COMPLETE?
JR NZ,PCF_WFP0 ; KEEP ASKING IF NOT OR
AND PCF_PIN ; IS TRANSMISSION COMPLETE?
JR NZ,PCF_WFP0 ; KEEP ASKING IF NOT OR
POP HL ; YES COMPLETE (PIN=0) RETURN WITH ZERO
RET
PCF_WFP1:
@ -234,7 +245,7 @@ PCF_WFP1:
XOR A ; RETURN NZ, A=01H
INC A
PCF_WFP2:
POP HL ; RET NZ, A=FF IF TIMEOUT
POP HL ; RET NZ, A=FF IF TIMEOUT
RET
;
PCF_STATUS .DB 00H
@ -250,18 +261,18 @@ PCF_WAIT_FOR_ACK:
LD HL,PCF_ACKTO
;
PCF_WFA0:
IN A,(PCF_RS1) ; READ PIN
LD (PCF_STATUS),A ; STATUS
LD B,A
;
DEC HL ; SEE IF WE HAVE TIMED
LD A,H ; OUT WAITING FOR PIN
OR L ; EXIT IF
JR Z,PCF_WFA1 ; WE HAVE
;
LD A,B ; OTHERWISE KEEP LOOPING
AND PCF_PIN ; UNTIL WE GET PIN
JR NZ,PCF_WFA0 ; OR TIMEOUT
IN A,(PCF_RS1) ; READ PIN
LD (PCF_STATUS),A ; STATUS
LD B,A
;
DEC HL ; SEE IF WE HAVE TIMED
LD A,H ; OUT WAITING FOR PIN
OR L ; EXIT IF
JR Z,PCF_WFA1 ; WE HAVE
;
LD A,B ; OTHERWISE KEEP LOOPING
AND PCF_PIN ; UNTIL WE GET PIN
JR NZ,PCF_WFA0 ; OR TIMEOUT
;
LD A,B ; WE GOT PIN SO NOW
AND PCF_LRB ; CHECK WE HAVE
@ -375,16 +386,16 @@ PCF_READI2C:
; AFTER RESET THE BUS BUSY BIT WILL BE SET TO 1 I.E. NOT BUSY
;
PCF_WAIT_FOR_BB:
LD HL,PCF_BBTO
LD HL,PCF_BBTO
PCF_WFBB0:
IN A,(PCF_RS1)
AND PCF_BB
RET Z ; BUS IS FREE RETURN ZERO
DEC HL
LD A,H
OR L
JR NZ,PCF_WFBB0 ; REPEAT IF NOT TIMED OUT
CPL ; RET NZ IF TIMEOUT
IN A,(PCF_RS1)
AND PCF_BB
RET Z ; BUS IS FREE RETURN ZERO
DEC HL
LD A,H
OR L
JR NZ,PCF_WFBB0 ; REPEAT IF NOT TIMED OUT
CPL ; RET NZ IF TIMEOUT
RET
;
;-----------------------------------------------------------------------------
@ -397,32 +408,32 @@ PCF_RDERR:
;
PCF_INIERR:
PUSH HL
LD HL,PCF_NOPCF
LD HL,PCF_NOPCF
JR PCF_PRTERR
;
PCF_SETERR:
PUSH HL
LD HL,PCF_WRTFAIL
LD HL,PCF_WRTFAIL
JR PCF_PRTERR
;
PCF_REGERR:
PUSH HL
LD HL,PCF_REGFAIL
LD HL,PCF_REGFAIL
JR PCF_PRTERR
;
PCF_CLKERR:
PUSH HL
LD HL,PCF_CLKFAIL
LD HL,PCF_CLKFAIL
JR PCF_PRTERR
;
PCF_IDLERR:
PUSH HL
LD HL,PCF_IDLFAIL
LD HL,PCF_IDLFAIL
JR PCF_PRTERR
;
PCF_ACKERR:
PUSH HL
LD HL,PCF_ACKFAIL
LD HL,PCF_ACKFAIL
JR PCF_PRTERR
;
PCF_RDBERR:
@ -452,7 +463,7 @@ PCF_BBERR:
;
PCF_PRTERR:
CALL PRTSTR
CALL NEWLINE
; CALL NEWLINE
POP HL
RET
;
@ -462,8 +473,8 @@ PCF_PRTERR:
#IF (1)
PCF_DBG:
PUSH AF
PUSH DE
PUSH HL
PUSH DE
PUSH HL
LD A,'['
CALL COUT
LD HL,PCF_DBGF
@ -473,19 +484,19 @@ PCF_DBG:
CALL COUT
LD A,']'
CALL COUT
POP HL
POP DE
POP AF
POP HL
POP DE
POP AF
RET
PCF_DBGF:
.DB 0 ; DEBUG STAGE COUNTER
#ENDIF
;
PCF_NOPCF .DB "NO DEVICE FOUND$"
PCF_WRTFAIL .DB "SETTING DEVICE ID FAILED$"
PCF_REGFAIL .DB "CLOCK REGISTER SELECT ERROR$"
PCF_CLKFAIL .DB "CLOCK SET FAIL$"
PCF_IDLFAIL .DB "BUS IDLE FAILED$"
PCF_WRTFAIL .DB "SETTING DEVICE ID FAILED$"
PCF_REGFAIL .DB "CLOCK REGISTER SELECT ERROR$"
PCF_CLKFAIL .DB "CLOCK SET FAIL$"
PCF_IDLFAIL .DB "BUS IDLE FAILED$"
PCF_ACKFAIL .DB "FAILED TO RECEIVE ACKNOWLEDGE$"
PCF_RDFAIL .DB "READ FAILED$"
PCF_RDBFAIL .DB "READBYTES FAILED$"

Loading…
Cancel
Save