R32V2020 I2C Interface

From Land Boards Wiki
Jump to navigation Jump to search

I2C Interface

R32V2020 - I2C Software Interface

  • The I2C core provides register addresses that the CPU can read or written to:
    • x5800 - I2C Address/register - Address 0 -> DATA (write/read) or SLAVE ADDRESS (write)
    • x5801 - I2C Control register - Address 1 -> Command/Status Register (write/read)

Data Buffer (write/read)

    • bit 7-0 = Stores I2C read/write data, or
      • bit 7-1 = Holds the first seven address bits of the I2C slave device
      • bit 0 = I2C 1:read/0:write bit

Command Register (write)

    • bit 7-2 = Reserved
    • bit 1-0 =
      • 00: IDLE
      • 01: START
      • 10: nSTART
      • 11: STOP

Status Register (read)

    • bit 7-2 = Reserved
    • bit 1 = ERROR (I2C transaction error)
    • bit 0 = BUSY (I2C bus busy)

Sample Code

Write to I2C Data/Address Register

;
; write_I2C_Data_Address_Reg
;

write_I2C_Data_Address_Reg:
	push	PAR
	lix		PAR,0x5800	; I2C Address/register
	spl		r8			; Write control register
	bsr		i2c_ack
;	lix		r8,20
;	bsr		delay_uS
	pull	PAR
	pull	PC

Read the I2C data into r8 register

;
; read_I2C_Data_Reg - Read I2C data into r8
;

read_I2C_Data_Reg:
	push	PAR
	lix		PAR,0x5800	; I2C Data Address
	lix		r8,0x54
	spl		r8
	bsr		i2c_ack
	lix		PAR,0x5800	; I2C Data Address
	lpl		r8
	pull	PAR
	pull	PC
	

Write to I2C Control Register

;
; write_I2C_Ctrl_Reg
; Command Register (write):
;	bit 7-2	= Reserved
;	bit 1-0	= 
;		00: IDLE
;		01: START
;		10: nSTART
;		11: STOP
;

write_I2C_Ctrl_Reg:
	push	PAR
	lix		PAR,0x5801	; I2C Control register
	spl		r8			; Write control register
	pull	PAR
	pull	PC

Wait for transfer to complete

;
; i2c_ack - wait for transfer to complete
; Status Register (read):
;	bit 7-2	= Reserved
;	bit 1 	= ERROR 	(I2C transaction error)
;	bit 0 	= BUSY 	(I2C bus busy)
;

i2c_ack:
	push	PAR
	lix		PAR,0x5801	; Control register
i2c_ack_loop:
	lpl		r8
	and		r8,r8,r1	; busy bit is least significant bit
	be1		i2c_ack_loop
	pull	PAR
	pull	PC

Sample Application - MCP23008

main:
	bsr		initDir_I2CIO8
loopMain:
	;lix		r8,0x50
	bsr		readI2CDat_MCP23008
	sr1		r8,r8
	sr1		r8,r8
	sr1		r8,r8
	sr1		r8,r8
	bsr		writeI2CAdrDat_MCP23008
	lix		r8,10
	bsr		delay_mS
	bra		loopMain
	
loopForever:
	bra		loopForever
	
;
; initDir_I2CIO8 - Set IO Dir
;

initDir_I2CIO8:
	push	r8
	; Write 0x22 to IOCON register (not sequential operations)
	lix		r8,0x01		; I2C_Ctrl = START
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0x40		; I2C write command at slave address = 0x20
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x00		; I2C_Ctrl = IDLE
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0x05		; MCP23008 IOCON
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x03		; I2C_Ctrl = STOP
	bsr		write_I2C_Ctrl_Reg	
	lix		r8,0x22		; SEQOP = Disabled, INTPOL = Active-high
	bsr		write_I2C_Data_Address_Reg
	; Write 0xF0 to Direction Control register
	lix		r8,0x01		; I2C_Ctrl = START
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0x40		; I2C write command at slave address = 0x20
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x00		; I2C_Ctrl = IDLE
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0x00		; MCP23008 IODIR
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x03		; I2C_Ctrl = STOP
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0xF0		; Input and output bits
	bsr		write_I2C_Data_Address_Reg
	pull	r8
	pull	PC

; writeI2CAdrDat_MCP23008 - Write address to the I2C bus
; Address 0x5800 -> DATA (write/read) or SLAVE ADDRESS (write)  
; Address 0x5801 -> Command/Status Register (write/read)
; r8 is the value to write

writeI2CAdrDat_MCP23008:
	push	r8
	lix		r8,0x01		; I2C_Ctrl = START
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0x40		; I2C write command at slave address = 0x20
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x00		; I2C_Ctrl = IDLE
	bsr		write_I2C_Ctrl_Reg	
	lix		r8,0x0A		; MCP23008 OLAT
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x03		; I2C_Ctrl = STOP
	bsr		write_I2C_Ctrl_Reg	
	pull	r8			; Data to write is in r8
	bsr		write_I2C_Data_Address_Reg
	pull	PC
	
; readI2CDat_MCP23008 - Read data from the I2C bus
; Address 0x5800 -> DATA (write/read) or SLAVE ADDRESS (write)  
; Address 0x5801 -> Command/Status Register (write/read)
; r8 is the value to write

readI2CDat_MCP23008:
	; write the GPIO address register
	lix		r8,0x01		; I2C_Ctrl = START
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0x40		; I2C write command at slave address = 0x20
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x03		; I2C_Ctrl = STOP
	bsr		write_I2C_Ctrl_Reg	
	lix		r8,0x09		; MCP23008 - GPIO register address
	bsr		write_I2C_Data_Address_Reg
	; Read the GPIO line value
	lix		r8,0x01		; I2C_Ctrl = START
	bsr		write_I2C_Ctrl_Reg
	lix		r8,0x41		; I2C read command at slave address = 0x20
	bsr		write_I2C_Data_Address_Reg
	lix		r8,0x00		; I2C_Ctrl = IDLE
	bsr		write_I2C_Ctrl_Reg	
	bsr		read_I2C_Data_Reg
	push	r8
	lix		r8,0x03		; I2C_Ctrl = STOP
	bsr		write_I2C_Ctrl_Reg	
	pull	r8
	pull	PC