diff --git a/Source/Apps/I2C/Build.cmd b/Source/Apps/I2C/Build.cmd index 4ddbf8b2..60b6a312 100644 --- a/Source/Apps/I2C/Build.cmd +++ b/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\ diff --git a/Source/Apps/I2C/I2CSCAN.ASM b/Source/Apps/I2C/I2CSCAN.ASM index ff8bc356..5b594ef5 100644 --- a/Source/Apps/I2C/I2CSCAN.ASM +++ b/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 diff --git a/Source/Apps/I2C/RTCds7.asm b/Source/Apps/I2C/RTCds7.asm index c99d7123..045a1cd0 100644 --- a/Source/Apps/I2C/RTCds7.asm +++ b/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 diff --git a/Source/Apps/I2C/i2ccpm.inc b/Source/Apps/I2C/i2ccpm.inc new file mode 100644 index 00000000..ee469e5d --- /dev/null +++ b/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 diff --git a/Source/Apps/I2C/i2clcd.asm b/Source/Apps/I2C/i2clcd.asm new file mode 100644 index 00000000..548895b2 --- /dev/null +++ b/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 diff --git a/Source/HBIOS/ds7rtc.asm b/Source/HBIOS/ds7rtc.asm index ab105c9b..31a259df 100644 --- a/Source/HBIOS/ds7rtc.asm +++ b/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 ; diff --git a/Source/HBIOS/pcf8584.asm b/Source/HBIOS/pcf8584.asm index e53a4adb..5f4c8330 100644 --- a/Source/HBIOS/pcf8584.asm +++ b/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 ;