Skip to content

Commit e2bfe57

Browse files
author
AnyKeyShik
committed
Init commit
0 parents  commit e2bfe57

File tree

3 files changed

+371
-0
lines changed

3 files changed

+371
-0
lines changed

README.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# I2C driver for EEPROM on ESP32
2+
3+
Simple driver for work with EEPROM on ESP32 according to the I2C protocol
4+
5+
## Constants
6+
* I2C_MASTER_SCL_IO
7+
8+
GPIO for SCL
9+
10+
11+
* I2C_MASTER_SDA_IO
12+
13+
GPIO for SDA
14+
15+
16+
* I2C_MASTER_NUM
17+
18+
I2C port
19+
20+
21+
* I2C_MASTER_TX_BUF_DISABLE
22+
23+
TX buffer disable(0)/enable(1)
24+
25+
26+
* I2C_MASTER_RX_BUF_DISABLE
27+
28+
RX buffer disable(0)/enable(1)
29+
30+
31+
* I2C_MASTER_FREQ_HZ
32+
33+
Clock frequency
34+
35+
36+
* PULLUP_SCL_GPIO
37+
38+
Enable pull-up on SCL GPIO
39+
40+
41+
* PULLUP_SDA_GPIO
42+
43+
Enable pull-up on SDA GPIO
44+
45+
46+
* ACK_CHECK_EN
47+
48+
Check ACK from EEPROM
49+
50+
51+
* ACK_CHECK_DIS
52+
53+
Don't check ACK from EEPROM
54+
55+
56+
* ACK_VAL
57+
58+
ACK value
59+
60+
61+
* NACK_VAL
62+
63+
NACK value
64+
65+
66+
* EEPROM_WRITE_ADDR
67+
68+
Write bit for EEPROM
69+
70+
71+
* EEPROM_READ_ADDR
72+
73+
Read bit for EEPROM
74+
75+
76+
* EEPROM_PAGE_SIZE
77+
78+
Page size of EEPROM
79+
80+
81+
## Provided functions
82+
* esp_err_t init_i2c_master()
83+
84+
I2C master initialization with PULLUP_`X`_GPIO pull-up on GPIOs I2C_MASTER_SDA_IO and I2C_MASTER_SCL_IO with I2C_MASTER_FREQ_HZ frequency on I2C_MODE_MASTER
85+
86+
Return ESP_OK or error
87+
88+
89+
* esp_err_t eeprom_write_byte(uint8_t deviceaddress, uint16_t eeaddress, uint8_t byte)
90+
91+
Write one byte to EEPROM
92+
93+
* deviceaddress - EEPROM address
94+
* eeaddress - address on EEPROM where byte will be write
95+
* byte - byte for write
96+
97+
Write schema in I2C:
98+
___________________________________________________________________________________________________________
99+
| start | slave_addr + wr_bit + ack | high_byte_aadr + ack | low_byte_addr + ack | data_byte + ack | stop |
100+
|-------|---------------------------|----------------------|---------------------|-----------------|------|
101+
102+
Return ESP_OK or error
103+
104+
105+
* esp_err_t eeprom_write(uint8_t deviceaddress, uint16_t eeaddress, uint8_t *data, size_t size)
106+
107+
Write a few bytes to EEPROM
108+
109+
* deviceaddress - EEPROM address
110+
* eeaddress - address on EEPROM where bytes will be write
111+
* data - bytes for write
112+
* size - size of data
113+
114+
Write schema in I2C:
115+
_______________________________________________________________________________________________________________________________________
116+
| start | slave_addr + wr_bit + ack | high_byte_aadr + ack | low_byte_addr + ack | data_byte_0 + ack | ... | data_byte_x + ack | stop |
117+
|-------|---------------------------|----------------------|---------------------|------------------|-----|--------------------|------|
118+
119+
Return ESP_OK or error
120+
121+
122+
* esp_err_t eeprom_read_byte(uint8_t deviceaddress, uint16_t eeaddress, uint8_t *byte)
123+
124+
Read random byte from EEPROM
125+
126+
* deviceaddress - EEPROM address
127+
* eeaddress - EEPROM address from which the byte will be read
128+
* byte - var into which byte will be read
129+
130+
Read schema in I2C:
131+
__________________________________________________________________________________________________________________________________________________
132+
| start | slave_addr + wr_bit + ack | high_byte_addr + ack | low_byte_addr + ack | start | slave_addr + rd_bit + ack | read 1 byte + nack | stop |
133+
|-------|---------------------------|----------------------|---------------------|-------|---------------------------|--------------------|------|
134+
135+
Return ESP_OK or error
136+
137+
138+
* esp_err_t eeprom_read(uint8_t deviceaddress, uint16_t eeaddress, uint8_t *data, size_t size)
139+
140+
Read byte sequential from EEPROM
141+
142+
* deviceaddress - EEPROM address
143+
* eeaddress - EEPROM address from which the bytes will be read
144+
* data - var into which bytes will be read
145+
146+
Read schema in I2C:
147+
148+
____________________________________________________________________________________________________________________________________________________________________________
149+
| start | slave_addr + wr_bit + ack | high_byte_addr + ack | low_byte_addr + ack | start | slave_addr + rd_bit + ack | read byte_1 + ack | ... | read byte_x + nack | stop |
150+
|-------|---------------------------|----------------------|---------------------|-------|---------------------------|-------------------|-----|--------------------|------|
151+
152+
Return ESP_OK or error

eeprom.c

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#include "eeprom.h"
2+
3+
/**
4+
* @brief I2C master initialization
5+
*/
6+
esp_err_t init_i2c_master() {
7+
int i2c_master_port = I2C_MASTER_NUM;
8+
esp_err_t ret;
9+
10+
i2c_config_t config;
11+
config.mode = I2C_MODE_MASTER;
12+
config.sda_io_num = I2C_MASTER_SDA_IO;
13+
config.scl_io_num = I2C_MASTER_SCL_IO;
14+
config.sda_pullup_en = PULLUP_SDA_GPIO;
15+
config.scl_pullup_en = PULLUP_SCL_GPIO;
16+
config.master.clk_speed = I2C_MASTER_FREQ_HZ;
17+
18+
ret = i2c_param_config(i2c_master_port, &config);
19+
if(ret != ESP_OK) {
20+
return ret;
21+
}
22+
23+
ret = i2c_driver_install(i2c_master_port, config.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
24+
25+
return ret;
26+
}
27+
28+
/**
29+
* @brief Write one byte to EEPROM.
30+
*
31+
* ___________________________________________________________________________________________________________
32+
* | start | slave_addr + wr_bit + ack | high_byte_aadr + ack | low_byte_addr + ack | data_byte + ack | stop |
33+
* |-------|---------------------------|----------------------|---------------------|-----------------|------|
34+
*
35+
*/
36+
esp_err_t eeprom_write_byte(uint8_t deviceaddress, uint16_t eeaddress, uint8_t byte) {
37+
esp_err_t ret;
38+
39+
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
40+
i2c_master_start(cmd);
41+
i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_WRITE_ADDR, ACK_CHECK_EN);
42+
i2c_master_write_byte(cmd, eeaddress >> 8, ACK_CHECK_EN);
43+
i2c_master_write_byte(cmd, eeaddress & 0xFF, ACK_CHECK_EN);
44+
i2c_master_write_byte(cmd, byte, ACK_CHECK_EN);
45+
i2c_master_stop(cmd);
46+
47+
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
48+
i2c_cmd_link_delete(cmd);
49+
50+
return ret;
51+
}
52+
53+
/**
54+
* @brief Write a few bytes to EEPROM.
55+
*
56+
* _______________________________________________________________________________________________________________________________________
57+
* | start | slave_addr + wr_bit + ack | high_byte_aadr + ack | low_byte_addr + ack | data_byte0 + ack | ... | data_byte127 + ack | stop |
58+
* |-------|---------------------------|----------------------|---------------------|------------------|-----|--------------------|------|
59+
*
60+
*/
61+
esp_err_t eeprom_write(uint8_t deviceaddress, uint16_t eeaddress, uint8_t *data, size_t size) {
62+
esp_err_t ret = ESP_OK;
63+
64+
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
65+
i2c_master_start(cmd);
66+
i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_WRITE_ADDR, ACK_CHECK_EN);
67+
i2c_master_write_byte(cmd, eeaddress >> 8, ACK_CHECK_EN);
68+
i2c_master_write_byte(cmd, eeaddress & 0xFF, ACK_CHECK_EN);
69+
70+
int bytes_remaining = size;
71+
int current_address = eeaddress;
72+
int first_write_size = ( (EEPROM_PAGE_SIZE - 1) - eeaddress % (EEPROM_PAGE_SIZE - 1) ) + 1;
73+
74+
if (eeaddress % (EEPROM_PAGE_SIZE-1) == 0 && eeaddress != 0) {
75+
first_write_size = 1;
76+
}
77+
78+
if (bytes_remaining <= first_write_size) {
79+
i2c_master_write(cmd, data, bytes_remaining, 1);
80+
}
81+
else {
82+
i2c_master_write(cmd, data, first_write_size, 1);
83+
bytes_remaining -= first_write_size;
84+
current_address += first_write_size;
85+
i2c_master_stop(cmd);
86+
87+
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000/portTICK_PERIOD_MS);
88+
i2c_cmd_link_delete(cmd);
89+
90+
if (ret != ESP_OK) {
91+
return ret;
92+
}
93+
94+
while (bytes_remaining > 0) {
95+
cmd = i2c_cmd_link_create();
96+
97+
// 2ms delay period to allow EEPROM to write the page buffer to memory.
98+
vTaskDelay(20 / portTICK_PERIOD_MS);
99+
100+
i2c_master_start(cmd);
101+
i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_WRITE_ADDR, ACK_CHECK_EN);
102+
i2c_master_write_byte(cmd, current_address >> 8, ACK_CHECK_EN);
103+
i2c_master_write_byte(cmd, current_address & 0xFF, ACK_CHECK_EN);
104+
105+
if (bytes_remaining <= EEPROM_PAGE_SIZE) {
106+
i2c_master_write(cmd, data + (size - bytes_remaining), bytes_remaining, ACK_CHECK_EN);
107+
bytes_remaining = 0;
108+
}
109+
else {
110+
i2c_master_write(cmd, data + (size - bytes_remaining), EEPROM_PAGE_SIZE, ACK_CHECK_EN);
111+
bytes_remaining -= EEPROM_PAGE_SIZE;
112+
current_address += EEPROM_PAGE_SIZE;
113+
}
114+
i2c_master_stop(cmd);
115+
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
116+
i2c_cmd_link_delete(cmd);
117+
118+
if (ret != ESP_OK) {
119+
return ret;
120+
}
121+
}
122+
}
123+
124+
return ret;
125+
}
126+
127+
/**
128+
* @brief Read random byte from EEPROM
129+
*
130+
* __________________________________________________________________________________________________________________________________________________
131+
* | start | slave_addr + wr_bit + ack | high_byte_addr + ack | low_byte_addr + ack | start | slave_addr + rd_bit + ack | read 1 byte + nack | stop |
132+
* |-------|---------------------------|----------------------|---------------------|-------|---------------------------|--------------------|------|
133+
*
134+
*/
135+
esp_err_t eeprom_read_byte(uint8_t deviceaddress, uint16_t eeaddress, uint8_t *byte) {
136+
esp_err_t ret;
137+
138+
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
139+
i2c_master_start(cmd);
140+
i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_WRITE_ADDR, ACK_CHECK_EN);
141+
i2c_master_write_byte(cmd, eeaddress << 8, ACK_CHECK_EN);
142+
i2c_master_write_byte(cmd, eeaddress & 0xFF, ACK_CHECK_EN);
143+
144+
i2c_master_start(cmd);
145+
i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_READ_ADDR, ACK_CHECK_EN);
146+
147+
i2c_master_read_byte(cmd, byte, NACK_VAL);
148+
i2c_master_stop(cmd);
149+
150+
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000/portTICK_PERIOD_MS);
151+
i2c_cmd_link_delete(cmd);
152+
153+
return ret;
154+
}
155+
156+
/**
157+
* @brief Read byte sequential from EEPROM
158+
*
159+
* ____________________________________________________________________________________________________________________________________________________________________________
160+
* | start | slave_addr + wr_bit + ack | high_byte_addr + ack | low_byte_addr + ack | start | slave_addr + rd_bit + ack | read byte_1 + ack | ... | read byte_x + nack | stop |
161+
* |-------|---------------------------|----------------------|---------------------|-------|---------------------------|-------------------|-----|--------------------|------|
162+
*
163+
*/
164+
esp_err_t eeprom_read(uint8_t deviceaddress, uint16_t eeaddress, uint8_t *data, size_t size) {
165+
esp_err_t ret;
166+
167+
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
168+
i2c_master_start(cmd);
169+
i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_WRITE_ADDR, ACK_CHECK_EN);
170+
i2c_master_write_byte(cmd, eeaddress << 8, ACK_CHECK_EN);
171+
i2c_master_write_byte(cmd, eeaddress & 0xFF, ACK_CHECK_EN);
172+
173+
i2c_master_start(cmd);
174+
i2c_master_write_byte(cmd, (deviceaddress << 1) | EEPROM_READ_ADDR, ACK_CHECK_EN);
175+
176+
if (size > 1) {
177+
i2c_master_read(cmd, data, size - 1, ACK_VAL);
178+
}
179+
180+
i2c_master_read_byte(cmd, data + size - 1, NACK_VAL);
181+
i2c_master_stop(cmd);
182+
183+
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
184+
i2c_cmd_link_delete(cmd);
185+
186+
return ret;
187+
}

include/eeprom.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
3+
#include <stdio.h>
4+
#include "driver/i2c.h"
5+
6+
// Definitions for i2c
7+
#define I2C_MASTER_SCL_IO 18 // GPIO for SCL
8+
#define I2C_MASTER_SDA_IO 19 // GPIO for SDA
9+
#define I2C_MASTER_NUM I2C_NUM_1 // I2C port
10+
#define I2C_MASTER_TX_BUF_DISABLE 0 // I2C master doesn't need buffer
11+
#define I2C_MASTER_RX_BUF_DISABLE 0 // I2C master doesn't need buffer
12+
#define I2C_MASTER_FREQ_HZ 100000 // I2C master clock frequency
13+
#define PULLUP_SCL_GPIO GPIO_PULLUP_ENABLE // Enable pull-up on SCL GPIO
14+
#define PULLUP_SDA_GPIO GPIO_PULLUP_ENABLE // Enable pull-up on SDA GPIO
15+
16+
#define ACK_CHECK_EN 0x1 // I2C master will check ack from EEPROM
17+
#define ACK_CHECK_DIS 0x0 // I2C master will not check ack from EEPROM
18+
#define ACK_VAL 0x0 // I2C ack value
19+
#define NACK_VAL 0x1 // I2C nack value
20+
21+
#define EEPROM_WRITE_ADDR 0x00 // Write bit for EEPROM
22+
#define EEPROM_READ_ADDR 0x01 // Read bit for EEPROM
23+
24+
#define EEPROM_PAGE_SIZE 32 // Page size of EEPROM
25+
26+
esp_err_t init_i2c_master();
27+
28+
esp_err_t eeprom_write_byte(uint8_t, uint16_t, uint8_t);
29+
esp_err_t eeprom_write(uint8_t, uint16_t, uint8_t*, size_t);
30+
31+
esp_err_t eeprom_read_byte(uint8_t, uint16_t, uint8_t *);
32+
esp_err_t eeprom_read(uint8_t, uint16_t, uint8_t *, size_t);

0 commit comments

Comments
 (0)