Using Vivado 2018.3 .

I2C EEPROM operation

I have xx24C64 on my board:

  • 8 KB (64 Kb) space
  • Address range 0~0x1FFF
  • Device address 7’b101_0011, 0x53 (on my board, A2=0, A1=A0=1)

Datasheet: CAT24C64 - 64 Kb I2C CMOS Serial EEPROM (onsemi.com)

Byte Write

Selective Read

Vivado Block Design

Except for the AXI_IIC IP, other settings are the same as the block design in Microblaze2.1 JTAG-UART | QY’s Notes.

I2C Polled-mode

From xiic documentation, iic: Main Page:

This driver does not provide a polled mode of operation primarily because polled mode which is non-blocking is difficult with the amount of interaction with the hardware that is necessary.

So, at first, I thought interrupt was necessary… Until I find this example: xiic_low_level_eeprom_example.c

Since I only wanted to configure an I2C slave device, polled-mode with blocking is fine. Basically, I just need XIic_Recv() and XIic_Send().

And the job was done. I guess I won’t be using microblaze in a while…

Resource

Sample Code

Run result: write 0x67, read 0x67, pass.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xiic_l.h"
#include "sleep.h"

#define IIC_BASE_ADDRESS	XPAR_IIC_0_BASEADDR

#define EEPROM_ADDRESS  0x53

int eepromWriteByte(u32 IicBaseAddress,
				u8 deviceAddress,
				int romAddr,
				u8 dataByte);

u8 eepromReadByte(u32 IicBaseAddress,
				u8 deviceAddress,
				int romAddr);

int main()
{

	u8 byteSend;
	u8 byteRecv;
	int eepromAddr;

    init_platform();

    eepromAddr = 0x0123;
    byteSend = 0x67;
    eepromWriteByte(IIC_BASE_ADDRESS, EEPROM_ADDRESS,
    		eepromAddr, byteSend);

    usleep(6000); // delay >5ms
    // wait for eeprom internal write cycle

    byteRecv = eepromReadByte(IIC_BASE_ADDRESS, EEPROM_ADDRESS, eepromAddr);

    xil_printf("Received: 0x%X\n\r", byteRecv);
    if( byteRecv == byteSend)
    	xil_printf("EEPROM byte wirte and read OK.\n\r");

    cleanup_platform();
    return 0;
}


int eepromWriteByte(u32 IicBaseAddress,
				u8 deviceAddress,
				int romAddr,
				u8 dataByte)
{
	int bitCount;
	u8 writeBuffer[3];

	writeBuffer[0] = (u8)(romAddr >> 8); //higher 8 bits
	writeBuffer[1] = (u8)(romAddr & 0x00FF); //lower 8 bits
	writeBuffer[2] = dataByte;

	bitCount = XIic_Send(IicBaseAddress, deviceAddress,
			writeBuffer, 3, XIIC_STOP);
	return bitCount;
}

u8 eepromReadByte(u32 IicBaseAddress,
				u8 deviceAddress,
				int romAddr)
{

	u8 recvData;
	int bitCount;
	u8 writeBuffer[2];

	writeBuffer[0] = (u8)(romAddr >> 8); //higher 8 bits
	writeBuffer[1] = (u8)(romAddr & 0x00FF); //lower 8 bits

	bitCount = XIic_Send(IicBaseAddress, deviceAddress,
			writeBuffer, 3, XIIC_REPEATED_START);

	bitCount = XIic_Recv(IicBaseAddress, deviceAddress,
				&recvData, 1, XIIC_STOP);

	return recvData;
}