Browse Source

I2C updates

patch
b1ackmai1er 5 years ago
parent
commit
4d208094e7
  1. 3
      Source/Apps/I2C/Build.cmd
  2. 193
      Source/Apps/I2C/I2CSCAN.ASM
  3. 238
      Source/Apps/I2C/RTCds7.asm
  4. 132
      Source/Apps/I2C/i2ccpm.inc
  5. 517
      Source/Apps/I2C/i2clcd.asm
  6. 107
      Source/HBIOS/ds7rtc.asm
  7. 25
      Source/HBIOS/pcf8584.asm

3
Source/Apps/I2C/Build.cmd

@ -7,8 +7,9 @@ set TASMTABS=%TOOLS%\tasm32
tasm -t180 -g3 -fFF i2cscan.asm i2cscan.com i2cscan.lst
tasm -t180 -g3 -fFF rtcds7.asm rtcds7.com rtcds7.lst
tasm -t180 -g3 -fFF i2clcd.asm i2clcd.com i2clcd.lst
if errorlevel 1 goto :eof
copy /Y i2cscan*.com ..\..\..\Binary\Apps\
copy /Y i2c*.com ..\..\..\Binary\Apps\
copy /Y rtcds7*.com ..\..\..\Binary\Apps\

193
Source/Apps/I2C/I2CSCAN.ASM

@ -1,24 +1,48 @@
.ECHO "I2CSCAN"/N
; I2C BUS SCANNER
;
_io .equ 0A0h
_sda .equ 0
_scl .equ 1
_idle .equ 00000011B
.ECHO "i2cscan\n"
;
;-----------------------------------------------------------------------------
; I2C BUS SCANNER
; MARCO MACCAFERRI, HTTPS://WWW.MACCASOFT.COM
; HBIOS VERSION BY PHIL SUMMERS (B1ACKMAILER) DIFFICULTLEVELHIGH@GMAIL.COM
;
PCF .EQU 1
P8X180 .EQU 0
SC126 .EQU 0
SC137 .EQU 0
;
#IF (PCF)
I2C_BASE .EQU 0F0H
PCF_ID .EQU 0AAH
CPU_CLK .EQU 12
;
PCF_RS0 .EQU I2C_BASE
PCF_RS1 .EQU PCF_RS0+1
PCF_OWN .EQU (PCF_ID >> 1) ; PCF'S ADDRESS IN SLAVE MODE
#ENDIF
;
#IF (P8X180)
I2C_BASE .EQU 0A0h
_sda .EQU 0
_scl .EQU 1
_idle .EQU 00000011B
#ENDIF
;
#IF (SC126)
I2C_BASE .EQU 0Ch
_sda .EQU 7
_scl .EQU 0
_idle .EQU 10001101B
#ENDIF
;
#IF (SC137)
I2C_BASE .EQU 20h
_sda .EQU 7
_scl .EQU 0
_idle .EQU 10000001B
#ENDIF
;
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
.org 100h
ld sp,stack
@ -31,8 +55,6 @@ PCF_OWN .EQU (PCF_ID >> 1) ; PCF'S ADDRESS IN SLAVE MODE
call _cout
call _cout
; display x axis header 00-0F
xor a
@ -131,7 +153,16 @@ lp5f: ld a,(addr) ; next address
jp 0
signon: .db "I2C Bus Scanner"
.db 13, 10, 13, 10, 0, "$"
#IF (PCF)
.DB " - PCF8584"
#ENDIF
#IF (SC126)
.DB " - SC126"
#ENDIF
#IF (SC137)
.DB " - SC137"
#ENDIF
.db 13, 10, 13, 10, 0, "$"8
_strout:
st1: ld a,(hl) ; display
@ -188,26 +219,27 @@ _cout: ; character
ret
;-----------------------------------------------------------------------------
#IF (PCF)
_i2c_start:
PCF_START:
LD A,PCF_START_
OUT (PCF_RS1),A
RET
;
#ELSE
;_i2c_start:
ld a,_idle ; issue
out (_io),a ; start
out (I2C_BASE),a ; start
; command
res _sda,a
out (_io),a
out (I2C_BASE),a
nop
nop
res _scl,a
out (_io),a
out (I2C_BASE),a
ld (oprval),a
ret
#ENDIF
;
;-----------------------------------------------------------------------------
;
@ -244,47 +276,8 @@ PCF_ACKTO .EQU 65000
PCF_BBTO .EQU 65000
PCF_LABDLY .EQU 65000
;
;-----------------------------------------------------------------------------
;
; RETURN A=00/Z IF SUCCESSFULL
; RETURN A=FF/NZ IF TIMEOUT
; RETURN A=01/NZ IF LOST ARBITRATION
; PCF_STATUS HOLDS LAST PCF STATUS
;
PCF_WAIT_FOR_PIN:
PUSH HL
LD HL,PCF_PINTO ; SET TIMEOUT VALUE
PCF_WFP0:
IN A,(PCF_RS1) ; GET BUS
LD (PCF_STATUS),A ; STATUS
LD B,A
DEC HL ; HAVE WE
LD A,H ; TIMED OUT
OR L
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
POP HL ; YES COMPLETE (PIN=0) RETURN WITH ZERO
RET
PCF_WFP1:
LD A,B ; DID WE LOSE ARBITRATION?
AND PCF_LAB ; IF A=0 THEN NO
CPL
JR NZ,PCF_WFP2 ; NO
CALL PCF_HANDLE_LAB ; YES GO HANDLE IT
LD (PCF_STATUS),A
XOR A ; RETURN NZ, A=01H
INC A
PCF_WFP2:
POP HL ; RET NZ, A=FF IF TIMEOUT
RET
;
PCF_STATUS .DB 00H
;
;--------------------------------------------------------------------------------
;
; RETURN NZ/FF IF TIMEOUT ERROR
@ -343,24 +336,6 @@ PCF_WFBB0:
RET
;
;-----------------------------------------------------------------------------
PCF_HANDLE_LAB:
;
LD A,PCF_PIN
OUT (PCF_RS1),A
LD A,PCF_ES0
OUT (PCF_RS1),A
;
LD HL,PCF_LABDLY
PCF_LABLP:
LD A,H
OR L
DEC HL
JR NZ,PCF_LABLP
;
IN A,(PCF_RS1)
RET
;
;-----------------------------------------------------------------------------
; DISPLAY ERROR MESSAGES
;
PCF_RDERR:
@ -429,7 +404,6 @@ PCF_PRTERR:
POP HL
RET
;
;
PCF_NOPCF .DB "NO DEVICE FOUND$"
PCF_WRTFAIL .DB "SETTING DEVICE ID FAILED$"
PCF_REGFAIL .DB "CLOCK REGISTER SELECT ERROR$"
@ -444,28 +418,29 @@ PCF_PINFAIL .DB "PIN FAIL$"
PCF_BBFAIL .DB "BUS BUSY$"
;
;-----------------------------------------------------------------------------
#IF (PCF)
_i2c_stop:
PCF_STOP:
LD A,PCF_STOP_ ; issue
OUT (PCF_RS1),A ; stop
RET ; command
#ELSE
;_i2c_stop:
ld a,(oprval)
res _scl,a
res _sda,a
out (_io),a
out (I2C_BASE),a
set _scl,a
out (_io),a
out (I2C_BASE),a
nop
nop
set _sda,a
out (_io),a
out (I2C_BASE),a
ld (oprval),a
ret
;
_i2c_write: ; write
ld a,(oprval) ; to i2c
; bus
@ -474,38 +449,37 @@ i2c1: res _sda,a
rl c
jr nc,i2c2
set _sda,a
i2c2: out (_io),a
i2c2: out (I2C_BASE),a
set _scl,a
out (_io),a
; COND SC126=0
; ld d,a
;i2c3: in a,(_io)
; bit _scl,a
; jr z,i2c3
; ld a,d
; ENDC
out (I2C_BASE),a
#IF (SC126=0)
ld d,a
i2c3: in a,(I2C_BASE)
bit _scl,a
jr z,i2c3
ld a,d
#ENDIF
res _scl,a
out (_io),a
out (I2C_BASE),a
djnz i2c1
set _sda,a
out (_io),a
out (I2C_BASE),a
set _scl,a
out (_io),a
out (I2C_BASE),a
ld d,a
i2c4: in a,(_io)
; COND SC126=0
; bit _scl,a
; jr z,4b
; ENDC
i2c4: in a,(I2C_BASE)
#IF (SC126=0)
bit _scl,a
jr z,4b
#ENDIF
ld c,a
ld a,d
res _scl,a
out (_io),a
out (I2C_BASE),a
ld (oprval),a
xor a
@ -514,8 +488,7 @@ i2c4: in a,(_io)
inc a
ret
#ENDIF
oprval: .db 0
x: .db 0
y: .db 0

238
Source/Apps/I2C/RTCds7.asm

@ -2,115 +2,11 @@
; PCF8584 I2C Clock Driver
;==================================================================================================
;
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
REGS0 .EQU PCF_BASE
REGS1 .EQU REGS0+1
;
;T4LC512D .EQU 10100000B ; DEVICE IDENTIFIER
;T4LC512A1 .EQU 00000000B ; DEVICE ADDRESS
;T4LC512A2 .EQU 00001110B ; DEVICE ADDRESS
;T4LC512A3 .EQU 00000010B ; DEVICE ADDRESS
;T4LC512W .EQU 00000000B ; DEVICE WRITE
;T4LC512R .EQU 00000001B ; DEVICE READ
;
;I2CDEV1W .EQU (T4LC512D+T4LC512A1+T4LC512W)
;I2CDEV1R .EQU (T4LC512D+T4LC512A1+T4LC512R)
;
;I2CDEV2W .EQU (T4LC512D+T4LC512A2+T4LC512W)
;I2CDEV2R .EQU (T4LC512D+T4LC512A2+T4LC512R)
;
;I2CDEV3W .EQU (T4LC512D+T4LC512A3+T4LC512W)
;I2CDEV3R .EQU (T4LC512D+T4LC512A3+T4LC512R)
;
; CONTROL REGISTER BITS
;
PCF_PIN .EQU 10000000B
PCF_ES0 .EQU 01000000B
PCF_ES1 .EQU 00100000B
PCF_ES2 .EQU 00010000B
PCF_EN1 .EQU 00001000B
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)
;
; STATUS REGISTER BITS
;
;PCF_PIN .EQU 10000000B
PCF_INI .EQU 01000000B ; 1 if not initialized
PCF_STS .EQU 00100000B
PCF_BER .EQU 00010000B
PCF_AD0 .EQU 00001000B
PCF_LRB .EQU 00001000B
PCF_AAS .EQU 00000100B
PCF_LAB .EQU 00000010B
PCF_BB .EQU 00000001B
;
; CLOCK CHIP FREQUENCIES
;
PCF_CLK3 .EQU 000H
PCF_CLK443 .EQU 010H
PCF_CLK6 .EQU 014H
PCF_CLK8 .EQU 018H
PCF_CLK12 .EQU 01cH
;
; TRANSMISSION FREQUENCIES
;
PCF_TRNS90 .EQU 000H ; 90 kHz */
PCF_TRNS45 .EQU 001H ; 45 kHz */
PCF_TRNS11 .EQU 002H ; 11 kHz */
PCF_TRNS15 .EQU 003H ; 1.5 kHz */
;
; TIMEOUT AND DELAY VALUES (ARBITRARY)
;
PCF_PINTO .EQU 65000
PCF_ACKTO .EQU 65000
PCF_BBTO .EQU 65000
PCF_LABDLY .EQU 65000
;
; DATA PORT REGISTERS
;
#IF (CPU_CLK = 443)
PCF_CLK .EQU PCF_CLK443
#ELSE
#IF (CPU_CLK = 8)
PCF_CLK .EQU PCF_CLK8
#ELSE
#IF (CPU_CLK = 12)
PCF_CLK .EQU PCF_CLK12
#ELSE ***ERROR
#ENDIF
#ENDIF
#ENDIF
;
DS7_OUT .EQU 10000000B ; SELECT SQUARE WAVE FUNCTION
DS7_SQWE .EQU 00010000B ; ENABLE SQUARE WAVE OUTPUT
DS7_RATE .EQU 00000000B ; SET 1HZ OUPUT
;
DS7_DS1307 .EQU 11010000B ; DEVICE IDENTIFIER
DS7_W .EQU 00000000B ; DEVICE WRITE
DS7_R .EQU 00000001B ; DEVICE READ
.ECHO "rtcds7\n"
;
DS7_READ .EQU (DS7_DS1307 | DS7_R) ; READ
DS7_WRITE .EQU (DS7_DS1307 | DS7_W) ; WRITE
#INCLUDE "pcfi2c.inc"
;
DS7_CTL .EQU (DS7_OUT | DS7_SQWE | DS7_RATE)
;
CLIARGS .EQU $81
RESTART .EQU $0000 ; CP/M restart vector
BDOS .EQU $0005 ; BDOS invocation vector
FCB .EQU $5C ; Location of default FCB
;
.ORG 100H
;
@ -654,132 +550,6 @@ PCF_BBFAIL .DB "BUS BUSY$"
;
;-----------------------------------------------------------------------------
;
;BDOS .EQU 5 ;ENTRY BDOS
BS .EQU 8 ;BACKSPACE
TAB .EQU 9 ;TABULATOR
LF .EQU 0AH ;LINE-FEED
CR .EQU 0DH ;CARRIAGE-RETURN
;
; OUTPUT TEXT AT HL
;
PRTSTR: LD A,(HL)
CP '$'
RET Z
CALL PRINP
INC HL
JR PRTSTR
;
;Output WORD
;***********
;
;PARAMETER: Entry WORD IN HL
;*********
;
OUTW: LD A,H
CALL OUTB
LD A,L
CALL OUTB
RET
;
;Output BYTE
;***********
;
;PARAMETER: Entry BYTE IN A
;*********
;
OUTB: PUSH AF
RRCA
RRCA
RRCA
RRCA
AND 0FH
CALL HBTHE ;Change Half-BYTE
POP AF
AND 0FH
CALL HBTHE
RET
;
;Output HALF-BYTE
;****************
;
;PARAMETER: Entry Half-BYTE IN A (BIT 0 - 3)
;*********
;
HBTHE: CP 0AH
JR C,HBTHE1
ADD A,7 ;Character to Letter
HBTHE1: ADD A,30H
LD E,A
CALL PCHAR
RET
;
;
;Output on Screen
;****************
;
PRBS: LD E,BS
CALL PCHAR
RET
;
;Output CR+LF on Screen
;**********************
;
NEWLINE:
CRLF: LD E,CR
CALL PCHAR
LD E,LF
CALL PCHAR
RET
;
;Output ASCII-Character
;**********************
;
COUT:
PRINP: PUSH AF
PUSH DE
LD E,A
CALL PCHAR
POP DE
POP AF
RET
;
;CALL BDOS with Register Save
;****************************
;
INCHA: LD C,1 ;INPUT CHARACTER TO A
JR BDO
PCHAR: LD C,2 ;PRINT CHARACTER IN E
JR BDO
PSTRIN: LD C,9 ;PRINT STRING
JR BDO
INBUFF: LD C,10 ;READ CONSOLE-BUFFER
JR BDO
CSTS: LD C,11 ;CONSOLE-STATUS
JR BDO
OPEN: LD C,15 ;OPEN FILE
JR BDO
CLOSE: LD C,16 ;CLOSE FILE
JR BDO
DELETE: LD C,19 ;DELETE FILE
JR BDO
READS: LD C,20 ;READ SEEK
JR BDO
WRITES: LD C,21 ;WRITE SEEK
JR BDO
MAKE: LD C,22 ;MAKE FILE
JR BDO
SETDMA: LD C,26 ;SET DMA-ADDRESS
BDO: PUSH HL
PUSH DE
PUSH BC
PUSH IX
PUSH IY
CALL BDOS
POP IY
POP IX
POP BC
POP DE
POP HL
RET
#INCLUDE "i2ccpm.inc"
;
.END

132
Source/Apps/I2C/i2ccpm.inc

@ -0,0 +1,132 @@
;==================================================================================================
; GENERIC CP/M ROUTINES
;==================================================================================================
;
BDOS .EQU 5 ;ENTRY BDOS
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
FCB .EQU $5C ; Location of default FCB
;
; OUTPUT TEXT AT HL
;
PRTSTR: LD A,(HL)
CP '$'
RET Z
CALL COUT
INC HL
JR PRTSTR
;
;Output WORD
;***********
;
;PARAMETER: Entry WORD IN HL
;*********
;
OUTW: LD A,H
CALL OUTB
LD A,L
CALL OUTB
RET
;
;Output BYTE
;***********
;
;PARAMETER: Entry BYTE IN A
;*********
;
OUTB: PUSH AF
RRCA
RRCA
RRCA
RRCA
AND 0FH
CALL HBTHE ;Change Half-BYTE
POP AF
AND 0FH
CALL HBTHE
RET
;
;Output HALF-BYTE
;****************
;
;PARAMETER: Entry Half-BYTE IN A (BIT 0 - 3)
;*********
;
HBTHE: CP 0AH
JR C,HBTHE1
ADD A,7 ;Character to Letter
HBTHE1: ADD A,30H
LD E,A
CALL PCHAR
RET
;
;
;Output on Screen
;****************
;
PRBS: LD E,BS
CALL PCHAR
RET
;
;Output CR+LF on Screen
;**********************
;
NEWLINE:
LD E,CR
CALL PCHAR
LD E,LF
CALL PCHAR
RET
;
;Output ASCII-Character
;**********************
;
COUT: PUSH AF
LD E,A
CALL PCHAR
POP AF
RET
;
;CALL BDOS with Register Save
;****************************
;
INCHA: LD C,1 ;INPUT CHARACTER TO A
JR BDO
PCHAR: LD C,2 ;PRINT CHARACTER IN E
JR BDO
PSTRIN: LD C,9 ;PRINT STRING
JR BDO
INBUFF: LD C,10 ;READ CONSOLE-BUFFER
JR BDO
CSTS: LD C,11 ;CONSOLE-STATUS
JR BDO
OPEN: LD C,15 ;OPEN FILE
JR BDO
CLOSE: LD C,16 ;CLOSE FILE
JR BDO
DELETE: LD C,19 ;DELETE FILE
JR BDO
READS: LD C,20 ;READ SEEK
JR BDO
WRITES: LD C,21 ;WRITE SEEK
JR BDO
MAKE: LD C,22 ;MAKE FILE
JR BDO
SETDMA: LD C,26 ;SET DMA-ADDRESS
BDO: PUSH HL
PUSH DE
PUSH BC
PUSH IX
PUSH IY
CALL BDOS
POP IY
POP IX
POP BC
POP DE
POP HL
RET

517
Source/Apps/I2C/i2clcd.asm

@ -0,0 +1,517 @@
;==================================================================================================
; PCF8584 HD44780 I2C LCD UTILITY
;
; SOME GENERAL INFORMATION ON LCDS CAN BE SEEN HERE : FOCUSLCDS.COM/PRODUCT-CATEGORY/CHARACTER-LCD/
;
;==================================================================================================
;
.ECHO "i2clcd\n"
;
#INCLUDE "pcfi2c.inc"
;
; LCD COMMANDS
;
LCDFSET .EQU 00100000B ; 20H
LCD4BIT .EQU 00000000B ; 00H
LCD2LIN .EQU 00001000B ; 08H
LCDDON .EQU 00000100B ; 04H
LCDDMOV .EQU 00001000B ; 07H
LCDSGRA .EQU 01000000B ; 04H
LCDSDRA .EQU 10000000B ; 80H
LCDEMS .EQU 00000100B ; 04H
LCDELFT .EQU 00000010B ; 03H
;
LCDPINE .EQU 00000100B ; PIN 2
LCDPIND .EQU 00000001B ; PIN O
;
;
; STANDARD FORMATS - 8X1, 8X2, 16X1, 16X2, 16X4, 20X1, 20X2, 20X4, 24X2, 40X1, 40X2, 40X4
;
TIMEOUT .EQU 255
.ORG 100H
;INIT: CALL PCF_INIT
;
LD A,0
LD (DEBUGF),A
;
CALL LCDINIT ; SETUP THE LCD THROUGH THE PCF8574
LD HL,LCDDATA ; DISPLAY TEXT AT HL
PUSH HL
CALL LCDSTR
POP HL
CALL STOP ; CLOSE I2C CONNECTION
;
RET
;-----------------------------------------------------------------------------
;
LCDLITE .DB 00001000B
;
LCDINIT:
; CALL DEBUG
;
LD A,I2CLCDW ; SET SLAVE ADDRESS
OUT (REGS0),A
;
LD A,0C5H ; GENERATE START CONDITION
OUT (REGS1),A ; AND ISSUE THE SLAVE ADDRESS
CALL CHKPIN
;
; CALL DEBUG
;
LD HL,LCDINIT1
LD B,2
CALL WLN
;
CALL DELAY
;
LD HL,LCDINIT2
LD B,2
CALL WLN
;
CALL DELAY
;
; NOW WE ARE IN 4 BIT MODE
;
LD A,+(LCDFSET | LCD4BIT | LCD2LIN)
CALL LCDCMD
LD A,+(LCDDON | LCDDMOV)
CALL LCDCMD
LD A,+(LCDEMS | LCDELFT)
CALL LCDCMD
LD A,LCDSDRA
CALL LCDCMD
;
RET
;
;-----------------------------------------------------------------------------
;
WLN: LD A,(HL)
OUT (REGS0),A ; PUT DATA ON BUS
CALL CHKPIN
INC HL
DJNZ WLN
RET
;
;-----------------------------------------------------------------------------
; DISPLAY STRING AT HL, TERMINATED BY 0
;
LCDSTR: POP BC ; GET THE POINTER OF
POP HL ; THE TEXT TO DISPLAY
PUSH HL ; OFF THE STACK AND
PUSH BC ; PUT IT IN HL.
;
LCDST0: LD A,(HL) ; GET NEXT CHARACTER TO
OR A ; DISPLAY BUT RETURN
RET Z ; WHEN TERMINATOR REACHED
PUSH HL
;
CALL LCDATA ; OUTPUT TO LCD
POP HL
; RET C ; POINT TO NEXT
INC HL ; AND REPEAT
JR LCDST0
;
;-----------------------------------------------------------------------------
; SEND BYTE IN A TO LCD IN 4-BIT MODE
;
LCDATA: PUSH DE
LD D,A
LD A,(LCDLITE)
OR +(LCDPINE | LCDPIND)
JP LCDSND
LCDCMD: PUSH DE
LD D,A
LD A,(LCDLITE)
OR LCDPINE
LCDSND: LD E,A
LD A,D
PUSH BC
LD C,11110000B
AND C
OR E
LD (LCDBUF),A
AND ~LCDPINE
LD (LCDBUF+1),A
LD A,D
RLC A
RLC A
RLC A
RLC A
AND C
OR E
LD (LCDBUF+2),A
AND ~LCDPINE
LD (LCDBUF+3),A
;
LD HL,LCDBUF ; OUTPUT 1 BYTE WHICH
LD B,4 ; REQUIRES A FOUR
CALL WLN ; BYTE SEQUENCE
;
POP BC
POP DE
RET
;
LCDDATA:
.DB "TEST HOW BIG IS THIS LINE DOES IT WRAP",0
;
LCDINIT1:
.DB 00110100B
.DB 00011000B
;
LCDINIT2:
.DB 00100100B
.DB 00100000B
;
LCDBUF:
.DB 0, 0, 0, 0 ; BUFFER TO HOLD 4 BYTE SEQUENCE
; FLASH DEVICE READ
;
DEVMADR .EQU 0
READR: LD B,255
DLY1: DJNZ DLY1
;
LD A,D ; SET SLAVE ADDRESS
OUT (REGS0),A
;
LD A,0C5H ; GENERATE START CONDITION
OUT (REGS1),A ; AND ISSUE THE SLAVE ADDRESS
CALL CHKPIN
;
LD A,+(DEVMADR/256)
OUT (REGS0),A ; PUT ADDRESS MSB ON BUS
CALL CHKPIN
;
LD A,+(DEVMADR&$00FF)
OUT (REGS0),A ; PUT ADDRESS LSB ON BUS
CALL CHKPIN
;
LD A,045H ; START
OUT (REGS1),A
;
LD A,E ; ISSUE CONTROL BYTE + READ
OUT (REGS0),A
;
CALL READI2C ; DUMMY READ
JR NZ,ERREXT
;
READLP1:CALL READI2C
; JR Z,ERREXT
CP 1AH
PUSH AF
CALL COUT
POP AF
JR NZ,READLP1
;
LD A,PCF_ES0
OUT (REGS1),A
CALL CHKPIN
IN A,(REGS0)
CALL READI2C
CALL STOP
;
CALL NEWLINE
;
RET
;
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
RESET: LD A,0C2H ; STOP
OUT (REGS1),A
LD B,255
DLY2: DJNZ DLY2
LD A,0C1H
OUT (REGS1),A
RET
RDSTAT: LD BC,-1
STATLP: IN A,(REGS1)
AND 1
RET Z
LD A,B
OR C
DEC BC
JR NZ,STATLP
LD A,'T'
JP ERREXTT
;
ERREXT: LD A,'Q'
JR ERR
ERREXTT: POP HL
ERR: CALL COUT
CALL STOP
CALL RESET
RET
;
STOP: LD A,0C3H
OUT (REGS1),A
RET
;
DELAY: PUSH HL
LD HL,-1
DLOOP: LD A,H
OR L
DEC HL
JR NZ,DLOOP
POP HL
RET
;
CHKPIN: IN A,(REGS1) ; POLL FOR
BIT 7,A ; TRANSMISSION
JP NZ,CHKPIN ; TO FINISH
; IN A,(REGS1) ; CHECK FOR
BIT 3,A ; SLAVE
RET Z ; ACKNOWLEDGMENT
LD A,'A'
JP ERREXTT
;
; READ ONE BYTE FROM I2C
; RETURNS DATA IN A
; Z flag set is acknowledge received (correct operation)
;
READI2C:
IN A,(REGS1) ; READ S1 REGISTER
BIT 7,A ; CHECK PIN STATUS
JP NZ,READI2C
BIT 3,A ; CHECK LRB=0
RET NZ
IN A,(REGS0) ; GET DATA
RET
;
DEBUG: PUSH AF
PUSH DE
LD A,'['
CALL COUT
LD HL,DEBUGF
LD A,(HL)
INC (HL)
CALL HBTHE
LD A,']'
CALL COUT
POP DE
POP AF
RET
DEBUGF: .DB 00H
;
;-----------------------------------------------------------------------------
;
; LINUX DRIVER BASED CODE
;
; I2C_INB = IN A,(REGS0)
; I2C_OUTB = LD A,* | OUT (REGS0),A
; SET_PCF = LD A,* | OUT (REGS1),A
; GET_PCF = IN A,(REGS1)
;
;-----------------------------------------------------------------------------
I2C_START:
LD A,PCF_START_
OUT (REGS1),A
RET
;
;-----------------------------------------------------------------------------
I2C_REPSTART:
LD A,PCF_START_
OUT (REGS1),A
RET
;
;-----------------------------------------------------------------------------
I2C_STOP:
LD A,PCF_STOP_
OUT (REGS1),A
RET
;
;-----------------------------------------------------------------------------
HANDLE_LAB:
LABDLY .EQU 0F000H
LD A,PCF_PIN
OUT (REGS1),A
LD A,PCF_ES0
OUT (REGS1),A
;
LD HL,LABDLY
LABLP LD A,H
OR L
DEC HL
JR NZ,LABLP
;
IN A,(REGS1)
RET
;
;-----------------------------------------------------------------------------
WAIT_FOR_BB:
;
BBTIMO .EQU 255
;
LD HL,BBTIMO
BBNOTO IN A,(REGS1)
AND PCF_BB
RET Z
DEC HL
LD A,H
OR A
JR NZ,BBNOTO
CPL ; RET NZ IF TIMEOUT
BBNOTB RET ; RET Z IF BUS IS BUSY
;
;-----------------------------------------------------------------------------
WAIT_FOR_PIN:
;
; RETURN A=00/Z IF SUCCESSFULL
; RETURN A=FF/NZ IF TIMEOUT
; RETURN A=01/NZ IF LOST ARBITRATION
;
PINTIMO .EQU 16000
;
LD HL,PINTIMO
PINNOTO IN A,(REGS1)
LD (STATUS),A
LD B,A
AND PCF_PIN
RET Z
DEC HL
LD A,H
OR A
JR NZ,PINNOTO
CPL ; RET NZ IF TIMEOUT
PINNOTB RET ; RET Z IF BUS IS BUSY
;
LD B,A
AND PCF_LAB
CALL HANDLE_LAB
LD (STATUS),A
XOR A
INC A
RET
;
STATUS .DB 00H
;
;-----------------------------------------------------------------------------
PCF_INIT:
LD A,PCF_PIN ; S1=80H: S0 SELECTED, SERIAL
OUT (REGS1),A ; INTERFACE OFF
NOP
IN A,(REGS1) ; CHECK TO SEE S1 NOW USED AS R/W
AND 07FH ; CTRL. PCF8584 DOES THAT WHEN ESO
JR NZ,INIERR ; IS ZERO
;
LD A,PCF_OWN ; LOAD OWN ADDRESS IN S0,
OUT (REGS0),A ; EFFECTIVE ADDRESS IS (OWN <<1)
NOP
IN A,(REGS0) ; CHECK IT IS REALLY WRITTEN
CP PCF_OWN
JR NZ,SETERR
;
LD A,+(PCF_PIN | PCF_ES1) ; S1=0A0H
OUT (REGS1),A ; NEXT BYTE IN S2
NOP
IN A,(REGS1)
AND 07FH
CP PCF_ES1
JR NZ,REGERR
;
LD A,PCF_CLK ; LOAD CLOCK REGISTER S2
OUT (REGS0),A
NOP
IN A,(REGS0) ; CHECK IT'S REALLY WRITTEN, ONLY
AND 1FH ; THE LOWER 5 BITS MATTER
CP PCF_CLK
JR NZ,CLKERR
;
LD A,PCF_IDLE_
OUT (REGS1),A
NOP
IN A,(REGS1)
CP +(PCF_PIN | PCF_BB)
JR NZ,IDLERR
RET
;
;-----------------------------------------------------------------------------
PCF_SENDBYTES: ; HL POINTS TO DATA, BC = COUNT, A = 0 LAST A=1 NOT LAST
;
LD (LASTB),A
;
SB0: LD A,(HL)
OUT (REGS0),A
CALL WAIT_FOR_PIN
JR Z,SB1
CP 01H ; EXIT IF ARBITRATION ERROR
RET Z
CALL I2C_STOP ; MUST BE TIMEOUT
LD A,055H ; ERROR
RET
SB1: LD A,(STATUS)
AND PCF_LRB
JR NZ,SB2
LD A,055H
;
SB2: LD A,B
OR C
INC HL
JR NZ,SB0 ; CHECK IF FINISHED
;
SBGOOD: LD A,(LASTB)
OR A
JR NZ,DB3
CALL I2C_STOP
RET
DB3: CALL I2C_REPSTART
RET
;
LASTB .DB 00H
;
; I2C_INB = IN A,(REGS0)
; I2C_OUTB = LD A,* | OUT (REGS0),A
; SET_PCF = LD A,* | OUT (REGS1),A
; GET_PCF = IN A,(REGS1)
;
;-----------------------------------------------------------------------------
INIERR LD HL,NOPCF
CALL PRTSTR
RET
;
SETERR LD HL,WRTFAIL
CALL PRTSTR
RET
REGERR LD HL,REGFAIL
CALL PRTSTR
RET
;
CLKERR LD HL,CLKFAIL
CALL PRTSTR
RET
;
IDLERR LD HL,IDLFAIL
CALL PRTSTR
RET
;
NOPCF .DB "NO DEVICE FOUND",CR,LF,"$"
WRTFAIL .DB "SETTING DEVICE ID FAILED",CR,LF,"$"
REGFAIL .DB "CLOCK REGISTER SELECT ERROR",CR,LF,"$"
CLKFAIL .DB "CLOCK SET FAIL",CR,LF,"$"
IDLFAIL .DB "BUS IDLE FAILED",CR,LF,"$"
;
#INCLUDE "i2ccpm.inc"
;
BUFFER: .DS 256
;
.END

107
Source/HBIOS/ds7rtc.asm

@ -18,6 +18,18 @@ 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
;
@ -88,7 +100,7 @@ DS7_DISPATCH:
;-----------------------------------------------------------------------------
; DS1307 GET TIME
;
; HL POINT TO A BUFFER TO STORE THE CURRENT TIME AND DATE IN.
; HL POINTS TO A BUFFER TO STORE THE CURRENT TIME AND DATE IN.
; THE TIME AND DATE INFORMATION MUST BE TRANSLATED TO THE
; HBIOS FORMAT AND COPIED FROM THE HBIOS DRIVER BANK TO
; CALLER INVOKED BANK.
@ -143,10 +155,103 @@ DS7_GT0:LD A,(HL)
;-----------------------------------------------------------------------------
; DS1307 SET TIME
;
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERROR
; HL: DATE/TIME BUFFER (IN)
;
; HBIOS FORMAT = YYMMDDHHMMSS
; DS1307 FORMAT = SSMMHH..DDMMYY..
;
DS7_SETTIM:
; CALL PCF_DBG ; [0]
LD A, (HB_INVBNK) ; COPY FROM CURRENT USER BANK
LD (HB_SRCBNK), A ; SET IT
LD A, BID_BIOS ; COPY TO BIOS BANK
LD (HB_DSTBNK), A ; SET IT
LD DE, DS7_BUF ; DESTINATION ADDRESS
LD BC,6 ; LENGTH IS 6 BYTES
#IF (INTMODE == 1)
DI
#ENDIF
CALL HB_BNKCPY ; Copy the clock data
#IF (INTMODE == 1)
EI
#ENDIF
;
; CALL PCF_DBG ; [1]
CALL PCF_WAIT_FOR_BB
JP NZ,PCF_BBERR
;
LD A,DS7_WRITE ; SET SLAVE ADDRESS
OUT (PCF_RS0),A
;
CALL PCF_START ; GENERATE START CONDITION
CALL PCF_WAIT_FOR_PIN; AND ISSUE THE SLAVE ADDRESS
CALL NZ,PCF_PINERR
;
LD A,00H ; REGISTER 00
OUT (PCF_RS0),A ; PUT ADDRESS ON BUS
CALL PCF_WAIT_FOR_PIN
CALL NZ,PCF_PINERR
;
LD DE,5
CALL DS7_SET3 ; STARTING AT REGISTER 0
;
CALL PCF_STOP
CALL PCF_WAIT_FOR_BB
JP NZ,PCF_BBERR
; CALL PCF_DBG ; [2]
;
LD A,DS7_WRITE ; SET SLAVE ADDRESS
OUT (PCF_RS0),A
;
CALL PCF_START ; GENERATE START CONDITION
CALL PCF_WAIT_FOR_PIN; AND ISSUE THE SLAVE ADDRESS
CALL NZ,PCF_PINERR
; CALL PCF_DBG ; [3]
;
LD A,04H ; REGISTER 04
OUT (PCF_RS0),A ; PUT ADDRESS ON BUS
CALL PCF_WAIT_FOR_PIN
CALL NZ,PCF_PINERR
;
LD DE,2
CALL DS7_SET3
; CALL PCF_DBG ; [4]
;
CALL PCF_STOP
XOR A
RET
;
DS7_SET3:
LD B,3
LD HL,DS7_BUF
ADD HL,DE
DS7_SC1:PUSH BC
LD A,(HL)
; CALL PRTHEXBYTE
OUT (PCF_RS0),A ; PUT DATA ON BUS
CALL PCF_WAIT_FOR_ACK
CALL NZ,PCF_ACKERR
POP BC
DEC HL
DJNZ DS7_SC1
RET
;
; HBIOS FORMAT = YYMMDDHHMMSS
; 991122083100
; DS1307 FORMAT = SSMMHH..DDMMYY..
; 003108..221199
;
;-----------------------------------------------------------------------------
; FUNCTIONS THAT ARE NOT AVAILABLE OR IMPLEMENTED
;

25
Source/HBIOS/pcf8584.asm

@ -79,7 +79,7 @@ PCF_LABDLY .EQU 65000
; DATA PORT REGISTERS
;
#IF (CPU_CLK = 443)
PCF_CLK .EQU PCF_CLK443
PCF_CLK .EQU PCF_CLK4433
#ELSE
#IF (CPU_CLK = 8)
PCF_CLK .EQU PCF_CLK8
@ -91,6 +91,19 @@ PCF_CLK .EQU PCF_CLK12
#ENDIF
#ENDIF
;
; THE PCF8584 TARGETS A TOP I2C CLOCK SPEED OF 90KHZ AND SUPPORTS DIVIDERS FOR
; 3, 4.43, 6, 8 AND 12MHZ TO ACHEIVE THIS.
;
; +--------------------------------------------------------------------------------------------+
; | div/clk | 2MHz | 4MHz | 6MHz | 7.38Mhz | 10MHz | 12MHz | 16MHz | 18.432Mhz | 20MHz |
; +----------------------------------------------------------------------------------+---------+
; | 3MHz | 60Khz | 120Khz | | | | | | | |
; | 4.43MHz | | 81Khz | | | | | | | |
; | 6MHz | | | 90Khz | 110Khz | | | | | |
; | 8MHz | | | | 83Khz | 112Khz | | | | |
; | 12MHz | | | | | | 90Khz | 120Khz | 138Khz | 150Khz |
; +----------------------------------------------------------------------------------+---------+
;
PCF8584_INIT:
CALL NEWLINE ; Formatting
PRTS("I2C: IO=0x$")
@ -104,7 +117,7 @@ PCF8584_INIT:
;
; I2C_INB = IN A,(PCF_RS0)
; I2C_OUTB = LD A,* | OUT (PCF_RS0),A
; SET_PCF = LD A,* | OUT (PCF_RS1),A
; SET_PCF -= LD A,* | OUT (PCF_RS1),A
; GET_PCF = IN A,(PCF_RS1)
;
;-----------------------------------------------------------------------------
@ -446,14 +459,14 @@ PCF_PRTERR:
;-----------------------------------------------------------------------------
; DEBUG HELPER
;
#IF (0)
DS7_DBG:
#IF (1)
PCF_DBG:
PUSH AF
PUSH DE
PUSH HL
LD A,'['
CALL COUT
LD HL,DS7_DBGF
LD HL,PCF_DBGF
LD A,(HL)
ADD A,'0'
INC (HL)
@ -464,7 +477,7 @@ DS7_DBG:
POP DE
POP AF
RET
DS7_DBGF:
PCF_DBGF:
.DB 0 ; DEBUG STAGE COUNTER
#ENDIF
;

Loading…
Cancel
Save