I2C Controller Programming Steps

Zynq UltraScale+ Device Technical Reference Manual (UG1085)

Document ID
UG1085
Release Date
2023-12-21
Revision
2.4 English

The programming steps for the I2C controller are listed in Table: I2C Reset through Table: I2C Self-Test.

Table 22-3:      I2C Reset

Task

Register

Register Field

Bits

Notes

Abort start

Save interrupt mask register

IMR, 0x20

All

9:0

Read operation

Disable interrupts

IDR, 0x28

All

9:0

Write 2FFh

Reset configuration and clear FIFOs

Control, 0x00

All

15:0

Write 40h

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits detected as set.

Restore interrupt state

IER, 0x24

All

9:0

0x2FF and ~IMR

Abort end

Reset configuration

Control, 0x00

All

15:0

Write 0h

Reset time out

Time_Out, 0x1C

All

7:0

Write FFh

Disable all interrupts

IDR, 0x28

All

9:0

Write 2FFh

Table 22-4:      I2C Get Options

Task

Register

Register Field

Bits

Notes

Read control register

Control, 0x00

All

15:0

Read operation

Table 22-5:      I2C Check Bus is Busy

Task

Register

Register Field

Bits

Notes

Read bus active state

Status, 0x04

BA

8

Read operation

If set bus is busy, else bus is free

Table 22-6:      I2C Transmit FIFO Fill

Task

Register

Register Field

Bits

Notes

Read transfer size register

Transfer_Size, 0x14

Transfer_Size

7:0

Read operation

Calculate available bytes = FIFO DEPTH(16) – Transfer_Size

Fill data register with the data until available bytes count is reached. Refer to I2C Send Byte.

Table 22-7:      I2C Send Byte

Task

Register

Register Field

Bits

Notes

Write byte into data register

Data, 0x0C

DATA

7:0

Write data

Table 22-8:      I2C Reset Hardware

Task

Register

Register Field

Bits

Notes

Disable all interrupts

IDR, 0x28

All

9:0

2FFh

Clear interrupt status

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits detected as set.

Clear hold, master enable, and acknowledge bits

Read control register

Control, 0x00

All

15:0

Read operation

Clear bits

Control, 0x00

CLR_FIFO, HOLD, ACK_EN, MS

6, 4, 3, and 1

(~(0x0015) | 0x0040) (hex)

Reset time out

Time_Out, 0x1C

All

7:0

FFh

Clear transfer size register

Transfer_Size, 0x14

Transfer_Size

7:0

Write 00h

Clear status register

Read status register

ISR, 0x04

All

8:0

Read operation

Write back status register

ISR, 0x04

All

8:0

Read value

Reset configuration register

Control, 0x00

All

15:0

Write 0000h

Table 22-9:      I2C Setup Master

Task

Register

Register Field

Bits

Notes

Read control register

Control, 0x00

All

15:0

Read operation

If [HOLD] is set = 1, then check if bus is busy (refer to I2C Check Bus is Busy); if bus is busy return

Setup master

Control, 0x00

CLR_FIFO, HOLD, ACK_EN, NEA, MS

6, 4, 3, 2, and 1

5Eh

For receiver role

Enable master receiver

Control, 0x00

RW

0

1

For transmitter role

Enable master transmitter

Control, 0x00

RW

0

0

Disable all interrupts

IDR, 0x28

All

9:0

2FFh

Table 22-10:      I2C Master Send

Task

Register

Register Field

Bits

Notes

Set repeated start if data is more than FIFO depth

Set hold bit

Control, 0x00

HOLD

4

1

Setup master for transmitter role (refer to I2C Setup Master)

Transmit FIFO full (refer to I2C Transmit FIFO Fill)

Program transfer address

Address, 0x08

ADD

9:0

Address

Enable interrupts

IER, 0x24

ARB_LOST, NACK, COMP

9, 2, and 0

205h

Table 22-11:      I2C Master Receive

Task

Register

Register Field

Bits

Notes

Set repeated start if data is more than FIFO depth

Set hold bit

Control, 0x00

HOLD

4

1

Setup master for receiver role (refer to I2C Setup Master)

Program transfer address

Address, 0x08

ADD

9:0

Write address

Setup transfer size

Transfer_Size, 0x14

Transfer_Size

7:0

Required transfer size

Enable interrupts

IER, 0x24

ARB_LOST, RX_OVF, NACK, COMP

9, 5, 2, 1 and 0

227h

Table 22-12:      I2C Master Send Polled

Task

Register

Register Field

Bits

Notes

Set repeated start if data is more than FIFO DEPTH

Set hold bit

Control, 0x00

HOLD

4

1

Setup master for transmitter role (refer to I2C Setup Master)

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits detected as set.

Transmit first FIFO full of data (refer to I2C Transmit FIFO Fill)

Program transfer address

Address, 0x08

ADD

9:0

Address

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Perform the following steps as long as no errors are reported by hardware from the status register read and total bytes are sent.

Read status register

Status, 0x04

All

8:0

Read operation

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Transmit first FIFO full of data (refer to I2C Transmit FIFO Fill)

Check for transfer completion

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

If any error reported by hardware transfer failed

Clear hold bit if not repeated start operation

Control, 0x00

HOLD

4

0

Table 22-13:      I2C Master Receive Polled

Task

Register

Register Field

Bits

Notes

Set repeated start if data is more than FIFO DEPTH

Set hold bit

Control, 0x00

HOLD

4

1

Setup master for receiver role (refer to I2C Setup Master)

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clears bits detected as set

Transfer address

Address, 0x08

ADD

9:0

Address

Program transfer size

Transfer_Size, 0x14

Transfer_Size

7:0

Required
transfer size

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Start loop 1: perform the following steps as long as receiving bytes and no errors from hardware reported

Read status register

Status, 0x04

All

8:0

Read operation

Start loop 2: perform the following steps as long as RXDV bit is non zero in SR

Clear repeat start if receive byte count is less than 14

Control, 0x00

HOLD

4

0

Receive byte

Data, 0x0C

DATA

7:0

Read operation

Read status register

Status, 0x04

All

8:0

Read operation

End loop 2

If receive byte count is >0 and bytes still need to be received

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clears bits detected as set

If receive byte count > maximum transfer size, then program transfer size

Transfer_Size, 0x14

Transfer_Size

7:0

Maximum
transfer size

Else program with required transfer size

Transfer_Size, 0x14

Transfer_Size

7:0

Required
transfer size

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

End loop 1

Clear hold bit if not repeated start operation

Control, 0x00

HOLD

4

0

If any error reported by hardware transfer failed else transfer success

Table 22-14:      I2C Enable Slave Monitor

Task

Register

Register Field

Bits

Notes

Clear transfer size register

Transfer_Size, 0x14

Transfer_Size

7:0

0

Enable slave monitor mode

Control, 0x00

MS | NEA
| CLR_FIFO | SLVMON

15:0

0066h

Enable slave monitor interrupt

IER, 0x24

SLV_RDY

4

1

Initialize slave monitor register

Slave_Mon_Pause, 0x18

Pause

3:0

Fh

Program transfer address

Address, 0x08

ADD

9:0

Address

Table 22-15:      I2C Disable Slave Monitor

Task

Register

Register Field

Bits

Notes

Disable slave monitor mode

Control, 0x00

SLVMON

5

0

Disable slave monitor interrupt

IER, 0x24

SLV_RDY

4

0

Table 22-16:      I2C Master Send Data

Task

Register

Register Field

Bits

Notes

Transmit first FIFO full of data (refer to I2C Transmit FIFO Fill)

Set repeated start bit if requested

Control, 0x00

HOLD

4

1

Table 22-17:      I2C Master Interrupt Handler

Task

Register

Register Field

Bits

Notes

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits detected as set

Get the enabled interrupts

IMR, 0x20

All

9:0

Read operation

ISR & IMR

Check if hold bit is set (isHold)

Control, 0x00

HOLD

4

Read operation

If send operation && (ISR & [COMP])

Send data (refer to I2C Master Send Data)

If receive operation && (ISR & [COMP]) || (ISR & [DATA)

Perform the following operations until receive data valid mask is set (loop-1 started)

Read status register

Status, 0x04

All

8:0

Read operation

Clear hold bit if not needed

Control, 0x00

HOLD

4

0

Receive byte

Data, 0x0C

DATA

7:0

Read operation

Loop-1 ended

If receive byte count is >0 and bytes still need to be received

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits detected as set

If receive byte count > maximum transfer size then setup transfer size

Transfer_Size, 0x14

Transfer_Size

7:0

Maximum transfer size

Else program with required transfer size

Transfer_Size, 0x14

Transfer_Size

7:0

Required transfer size

Enable interrupts

IER, 0x24

ARB_LOST, RX_OVF, NACK, DATA, COMP

9, 5, 2, 1, and 0

227h

Clear hold bit if all interrupts attended

Control, 0x00

HOLD

4

0

Clear hold bit if slave ready interrupt is triggered

Control, 0x00

HOLD

4

0

Clear hold bit if any other interrupts occurred. (event errors)

Control, 0x00

HOLD

4

0

Table 22-18:      I2C Setup Slave

Task

Register

Register Field

Bits

Notes

Clear ack_en, nea, FIFO, and set master in slave mode

Control, 0x00

CLR_FIFO, ACK_EN, NEA, MS

6, 3, 2, and 1

2Ch

Disable all interrupts

Intrpt_disable_reg0

All

9:0

2FFh

Transfer address

Address, 0x08

ADD

9:0

Address

Table 22-19:      I2C Slave Send

Task

Register

Register Field

Bits

Notes

Enable interrupts

IER, 0x24

TX_OVF, TO, NACK, DATA, COMP

6, 3, 2, 1, and 0

4Fh

Table 22-20:      I2C Slave Receive

Task

Register

Register Field

Bits

Notes

Enable interrupts

IER, 0x24

RX_UNF, RX_OVF, TO, NACK, DATA, COMP

7, 5, 3, 2, 1, and 0

AFh

Table 22-21:      I2C Slave Send Polled

Task

Register

Register Field

Bits

Notes

Use RXRW bit in status register to wait master to start a read

Read status register

Status, 0x04

All

8:0

Read operation

Check the RXRW bit is set by reading status register continuously. If master tries to send data, it is an error.

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits
detected as set

Send data as long as there is more data to send and there are no errors (refer to I2C Send Byte)

Read status register

Status, 0x04

All

8:0

Read operation

Wait for master to read the data out of the Tx FIFO; [SR] & [TXDV] != 0.. And there are no errors.

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

If master terminates the transfer before all data is sent, it is an error (interrupt status register and NACK)

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits
detected as set

Table 22-22:      I2C Slave Receive Polled

Task

Register

Register Field

Bits

Notes

Read status register

Status, 0x04

All

8:0

Read operation

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits
detected as set

Read status register

Status, 0x04

All

8:0

Read operation

Write back status register

Status, 0x04

All

8:0

Write status

Read status register

Status, 0x04

All

8:0

Read operation

Perform the following operations until all bytes received (Loop-1 started)

Perform the following operations as long as SR and RXDV = 0 (Loop-2 started)

Read status register

Status, 0x04

All

8:0

Read operation

If (status register and (DATA | COMP) != 0) && (status register and RXDV ==0) && receive byte count >0) then it is a failure.

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits
detected as set

Loop-2 ended

Perform the following operations until status register and RXDV!= 0 and receive byte count!=0 (Loop-3 started)

Receive byte

Data, 0x0C

DATA

7:0

Read operation

Read status register

Status, 0x04

All

8:0

Read operation

Loop-3 ended

Loop-1 ended

Table 22-23:      I2C Receive Data

Task

Register

Register Field

Bits

Notes

Read status register

Status, 0x04

All

8:0

Read operation

Until (status register and RXDV) && receive byte count !=0 (Loop -1 started)

Receive byte

Data, 0x0C

DATA

7:0

Read operation

Read status register

Status, 0x04

All

8:0

Read operation

Loop-1 ended

Table 22-24:      I2C Slave Interrupt Handler

Task

Register

Register Field

Bits

Notes

Read interrupt status register

ISR, 0x10

All

9:0

Read operation

Write the status back to clear the interrupts so no events are missed while processing this interrupt

Write back interrupt status register

ISR, 0x10

All

9:0

Clear bits detected as set

Get the enabled interrupts (imr)

IMR, 0x20

All

9:0

Read operation

Use the mask register AND with the interrupt status register so disabled interrupts are not processed (~(imr) and IntrStatusReg).

Data interrupt (If interrupt status register and data)

This means master wants to do more data transfers.

Also check for completion of transfer, signal upper layer if done

For sending transmit FIFO fill (refer to I2C Transmit FIFO Fill)

Else receive slave data (refer to I2C Slave Receive data)

Table 22-25:      I2C Set and Clear Options

Task

Control Register Field
(offset 0x00)

Bits

Set Options

For 7-bit address option

NEA

2

1

For 10-bit address option

NEA

2

0

Slave monitor option

SLVMON

5

1

For repeated start option

HOLD

4

1

 

Clear Options

For 7-bit address option

NEA

2

0

For 10-bit address option

NEA

2

1

Slave monitor option

SLVMON

5

0

For repeated start option

HOLD

4

0

 

Table 22-26:      I2C Set SCLK

Task

Register

Register Field

Bits

Notes

Read transfer size register

Transfer_Size, 0x14

Transfer_Size

7:0

Read operation

If the Transfer_Size register is not = 0, then stop here. If the device is currently transferring data, the transfer must complete or be aborted before setting options.

Make sure clock option is with in range FSCL >0. Calculate values for divisor_a (best_divA) and divisor_b (best_divB)

Program the divisor values

Control, 0x00

divisor_a | divisor_b

15:8

Best_divA | best_divB

 

 

Table 22-27:      I2C Get CLK

Task

Register

Register Field

Bits

Notes

Read the divisor values (Div_a | Div_b)

Control, 0x00

divisor_a | divisor_b

15:8

Read operation

Calculate actual clock value = (input clock / (22U x (Div_a + 1U) x (Div_b + 1U)).

Note:   The actual frequency of SCL output is exactly 22 times slower than the frequency of clock_enable. The frequency of clock_enable signal is defined by the frequency of pclk input and the values of divisor_a and divisor_b.

Table 22-28:      I2C Self-Test

Task

Register

Register Field

Bits

Notes

All the I2C registers should be in their default state.

Read control register (CR)

Control, 0x00

All

15:0

Read operation

Read interrupt mask register (imr)

IMR, 0x20

All

9:0

Read operation

If (CR != 0) OR if (imr != 0x2FF) stop here.

Perform reset (refer to I2C Reset Hardware)

Write test value (0x05) into slave monitor register

Slave_Mon_Pause, 0x18

Pause

3:0

5h

Read back slave monitor register

Slave_Mon_Pause, 0x18

Pause

3:0

Read operation

Verify the value with written value. If not same test failed. Else passed.

Reset slave monitor register

Slave_Mon_Pause, 0x18

Pause

3:0

0h