added i2c controller functions, added IDE interface functions, fiexd IDE schematics

This commit is contained in:
Dennis Gunia
2023-01-16 19:30:31 +01:00
parent 265342e7f7
commit 96c4dca4d5
34 changed files with 18931 additions and 3700 deletions

View File

@@ -0,0 +1,327 @@
.include "extern_symbols.s" ;include monitor symbols.
org 0xB000
CS_PIO_BD .EQU 0xF5
CS_PIO_BC .EQU 0xF7
CS_PIO_AD .EQU 0xF4
CS_PIO_AC .EQU 0xF6
CS_I2C_S1 .EQU 0xF3
CS_I2C_SX .EQU 0xF2
IIC_RTC equ 11010000b
IIC_INIT:
LD A,0xCF
OUT (CS_PIO_AC), A
LD A,11110101b
OUT (CS_PIO_AC), A
LD A,00000000b ; Reset PCF8584 minimum 30 clock cycles
OUT (CS_PIO_AD), A
LD BC,0x1000
CALL PAUSE_LOOP
LD A,0000010b
OUT (CS_PIO_AD), A
NOP
NOP
NOP
LD A, 0x80 ;S1 -> Select S0, PIN disabled, ESO = 0, Interrupt disabled, STA, STA, ACK = 0
OUT (CS_I2C_S1),A
CALL SlowAccess
CALL SlowAccess
LD A,0x55 ;S0 -> Loads byte 55H into register S0'; effective own address becomes AAH
OUT (CS_I2C_SX),A
CALL SlowAccess
LD A, 0xA0 ;S1 -> Loads byte A0H into register S1, i.e. next byte will be loaded into the clock control register S2.
OUT (CS_I2C_S1),A
CALL SlowAccess
LD A,0x00 ;Load 18H into S2 register (clock control - 8 MHz, 90 KHz)
OUT (CS_I2C_SX),A
CALL SlowAccess
LD A,0xC1 ;S1 -> loads byte C1H into register S1; register enable
;serial interface, set I 2C-bus into idle mode;
;SDA and SCL are HIGH. The next write or read
;operation will be to/from data transfer register
;S0 if A0 = LOW.;
OUT (CS_I2C_S1),A
CALL SlowAccess
;CALL force_stop
JP PROMPT_BEGIN
LD BC,$0100
CALL PAUSE_LOOP
; Send test message to RTC
LD DE, 0xC000 ; Set I2C Buffer Location
LD A,0x00
LD (DE),A
;call regdump
LD B, IIC_RTC ; Set I2C Address
LD A, 1 ; Set I2C Buffer length
call i2c_send
LD DE, 0xC010
LD B, IIC_RTC
LD A, 7
call i2c_read
JP PROMPT_BEGIN
;CLK_ENABLE:
; LD DE, 0xC000 ; Set I2C Buffer Location
; LD A,0x00
; LD (0xC000),A
; LD (0xC001),A
; ;call regdump
;
; LD B, IIC_RTC ; Set I2C Address
; LD A, 2 ; Set I2C Buffer length
; call i2c_send
; JP PROMPT_BEGIN
;------------------------------------------------------------------------------
; i2c_send
;
; Sends data over the i2c bus
; A contains BYTE COUNTER
; B contains ADDRESS
; DE contains location of Data Buffer
;------------------------------------------------------------------------------
i2c_send:
; CALL PRINTINLINE;
; defb "SEND A",10,13,0
PUSH BC
PUSH AF
CALL i2c_bus_rdy
; CALL PRINTINLINE
; defb "SEND START",10,13,0
LD A,B ;Load 'slave address' into S0 register:
OUT (CS_I2C_SX),A
CALL SlowAccess
LD A, 0xC5 ;Load C5H into S1. 'C5H' = PCF8584 generates
;the 'START' condition and clocks out the slave
;address and the clock pulse for slave acknowledgement.
OUT (CS_I2C_S1),A
POP AF
LD C,A
INC C
i2c_send_1: ; LOOP 1 : Wait for bus ready
IN A,(CS_I2C_S1) ; Read byte from S1 register
BIT 7,A ; Is bus free? (S1 ~BB=1?)
JR NZ,i2c_send_1 ; No - loop
BIT 4,A ; slave acknowledged? (LRB = 0?)
JR NZ, i2c_send_stop ; if not, cancel transmission
LD A,(DE) ; Load next byte from buffer
INC DE
DEC C
JR Z, i2c_send_stop ; if counter = 0, exit loop
OUT (CS_I2C_SX),A ; Send byte
JR i2c_send_1 ; if counter > 0, loop again
i2c_send_stop:
LD A, 0xC3 ;STOP
OUT (CS_I2C_S1),A
CALL SlowAccess
POP BC
RET
;------------------------------------------------------------------------------
; i2c_read
;
; Sends data over the i2c bus
; A contains BYTE COUNTER
; B contains ADDRESS
; DE contains location of Data Buffer
;------------------------------------------------------------------------------
i2c_read:
PUSH DE
PUSH BC
PUSH AF
LD A,B ;Load 'slave address' into S0 register:
OR 0x01 ;Set RW Bit for read operation
OUT (CS_I2C_SX),A
CALL SlowAccess
CALL i2c_bus_rdy ; Is bus ready
LD A, 0xC5 ;Load C5H into S1. 'C5H' = PCF8584 generates
;the 'START' condition and clocks out the slave
;address and the clock pulse for slave acknowledgement.
OUT (CS_I2C_S1),A
;Setup counter
POP AF
LD C,A ; Load BYTE COUNTER into C
INC C ; Offset C by 1
i2c_read_1: ;Wait for PIN = 0
IN A,(CS_I2C_S1) ; Read byte from S1 register
BIT 7,A ; S1 PIN=1?
JR NZ,i2c_read_1 ; No - loop
BIT 3,A ; S1 LRB=0? slave ACK?
JR NZ, i2c_read_error ; No ACK -> an error has occured
DEC C
LD A, C
DEC A ;If n = m 1?
JR Z, i2c_read_last
IN A,(CS_I2C_SX)
LD (DE),A
INC DE
JR i2c_read_1
i2c_read_last: ;read last byte
LD A, 0x40
OUT (CS_I2C_S1),A
CALL SlowAccess
IN A,(CS_I2C_SX) ;receives the final data byte. Neg. ACK is also sent.
LD (DE),A
INC DE
i2c_read_last_1:
IN A,(CS_I2C_S1) ; Read byte from S1 register
BIT 7,A ; S1 PIN=1?
JR NZ,i2c_read_last_1 ; No - loop
i2c_read_error:
NOP
i2c_read_stop:
LD A, 0xC3
OUT (CS_I2C_S1),A
CALL SlowAccess
IN A,(CS_I2C_SX) ;transfers the final data byte from the
;data buffer to accumulator.
CALL SlowAccess
LD (DE),A
POP BC
POP DE
RET
i2c_stop_force:
;------------------------------------------------------------------------------
; i2c_rdy
;
; Waits until the PCF8584 signals a byte transmission/reception is complete.
;------------------------------------------------------------------------------
i2c_rdy:
PUSH AF
i2c_rlp:
IN A,(CS_I2C_S1) ; Read byte from S1 register
BIT 7,A ; Is Tx/Rx complete? (S1 PIN=0?)
call print_a_hex
JR NZ,i2c_rlp ; No - loop
i2crlpex:
POP AF
RET
;------------------------------------------------------------------------------
; i2c_bus_rdy
;
; Waits until the I2C bus is free before RETurning
;------------------------------------------------------------------------------
i2c_bus_rdy:
PUSH AF
i2c_blp:
IN A,(CS_I2C_S1) ; Read byte from S1 register
PUSH AF
call print_a_hex
POP AF
BIT 0,A ; Is bus free? (S1 ~BB=1?)
JR Z,i2c_blp ; No - loop
i2cblpex:
POP AF
RET
;------------------------------------------------------------------------------
; PAUSE_LOOP
;
; Timer function
;
; 16-bit (BC) decrement counter, performing 4xNEG loop until BC
; reaches zero.
;
; 61 T-states in loop = 15.25uS per loop @ 4 MHz - near enough
; a second delay for 65,535 iterations.
;
; Set iteration count in BC before calling this function.
; Destroys: BC
;------------------------------------------------------------------------------
PAUSE_LOOP:
PUSH AF ; 11 T-states
pau_lp:
;NEG ; 8 T-states
;NEG ; 8 T-states
;NEG ; 8 T-states
;NEG ; 8 T-states
PUSH BC ; 11 T-states
POP BC ; 10 T-states
PUSH BC ; 11 T-states
POP BC ; 10 T-states
DEC BC ; 6 T-states
LD A,C ; 9 T-states
OR B ; 4 T-states
JP NZ,pau_lp ; 10 T-states
POP AF ; 10 T-states
RET ; Pause complete, RETurn
;------------------------------------------------------------------------------
; PRINTINLINE
;
; String output function
;
; Prints in-line data (bytes immediately following the PRINTINLINE call)
; until a string terminator is encountered (0 - null char).
;------------------------------------------------------------------------------
PRINTINLINE:
EX (SP),HL ; PUSH HL and put RET ADDress into HL
PUSH AF
PUSH BC
nxtILC:
LD A,(HL)
CP 0
JR Z,endPrint
CALL print_char
INC HL
JR nxtILC
endPrint:
INC HL ; Get past "null" terminator
POP BC
POP AF
EX (SP),HL ; PUSH new RET ADDress on stack and restore HL
RET
SlowAccess:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;.include "regdump.s"
force_stop:
IN A,(CS_I2C_S1)
BIT 0, A
RET NZ
LD A, 11000011b
OUT (CS_I2C_S1),A
NOP
NOP
JR force_stop