The programming steps for the I2C controller are listed in Table: I2C Reset through Table: I2C Self-Test.
Task |
Register |
Register Field |
Bits |
Notes |
---|---|---|---|---|
Read control register |
Control, 0x00 |
All |
15:0 |
Read operation |
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 |
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. |
Task |
Register |
Register Field |
Bits |
Notes |
---|---|---|---|---|
Write byte into data register |
Data, 0x0C |
DATA |
7:0 |
Write data |
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 |
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 |
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 |
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 |
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 |
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 |
Else program with required transfer size |
Transfer_Size, 0x14 |
Transfer_Size |
7:0 |
Required |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Task |
Register |
Register Field |
Bits |
Notes |
---|---|---|---|---|
Enable interrupts |
IER, 0x24 |
TX_OVF, TO, NACK, DATA, COMP |
6, 3, 2, 1, and 0 |
4Fh |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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) |
Task |
Control Register Field |
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 |
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 |
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.
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 |