forked from RAKWireless/RAKwireless_Storage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RAK_EEPROM_I2C.cpp
167 lines (145 loc) · 4.55 KB
/
RAK_EEPROM_I2C.cpp
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/**
* @file RAK_EEPROM_I2C.cpp
* @author Bernd Giesecke (bernd.giesecke@rakwireless.com)
* @brief Driver to access EEPROM modules over I2C
* @version 0.1
* @date 2021-11-06
*
* @copyright Copyright (c) 2021
*
* @remark This library is based on the [Adafruit FRAM I2C](https://github.com/adafruit/Adafruit_FRAM_I2C), but cleaned up from the BUS_IO overhead to make it leaner.
*/
#include <math.h>
#include <stdlib.h>
#include "RAK_EEPROM_I2C.h"
/*========================================================================*/
/* CONSTRUCTORS */
/*========================================================================*/
/**************************************************************************/
/*!
Constructor
*/
/**************************************************************************/
RAK_EEPROM_I2C::RAK_EEPROM_I2C(void) {}
/*========================================================================*/
/* PUBLIC FUNCTIONS */
/*========================================================================*/
/*!
* @brief Sets up the hardware and initializes I2C
* @param addr
* The I2C address to be used.
* @param theWire
* The Wire object to be used for I2C connections.
* @return True if initialization was successful, otherwise false.
*/
bool RAK_EEPROM_I2C::begin(uint8_t addr, TwoWire *theWire)
{
i2c_dev = theWire;
_addr = addr;
i2c_dev->begin();
// A basic scanner, see if it ACK's
i2c_dev->beginTransmission(_addr);
if (i2c_dev->endTransmission() == 0)
{
return true;
}
return false;
}
/**************************************************************************/
/*!
@brief Writes a byte at the specific EEPROM address
@param[in] addr
The 16-bit address to write to in EEPROM memory
@param[in] value
The 8-bit value to write at addr
@returns True on I2C command success, false on timeout or I2C failure
*/
/**************************************************************************/
bool RAK_EEPROM_I2C::write(uint16_t addr, uint8_t value)
{
i2c_dev->beginTransmission(addr);
i2c_dev->write(addr >> 8);
i2c_dev->write(addr & 0xFF);
i2c_dev->write(value);
i2c_dev->endTransmission();
// Wait until it acks!
uint8_t timeout = 100;
while (timeout--)
{
i2c_dev->beginTransmission(addr);
if (i2c_dev->endTransmission() == 0)
{
return true;
}
delay(1);
}
// timed out :(
return false;
}
/**************************************************************************/
/*!
@brief Reads an 8 bit value from the specified EEPROM address
@param addr
The 16-bit address to read from in EEPROM memory
@returns The 8-bit value retrieved at addr
*/
/**************************************************************************/
uint8_t RAK_EEPROM_I2C::read(uint16_t addr)
{
i2c_dev->beginTransmission(addr);
i2c_dev->write(addr >> 8);
i2c_dev->write(addr & 0xFF);
i2c_dev->endTransmission();
size_t recv = i2c_dev->requestFrom(addr, (uint8_t)1);
if (recv != 1)
{
return 0;
}
return i2c_dev->read();
}
/**************************************************************************/
/*!
@brief Writes multiple bytes at the specific EEPROM address
@param[in] addr
The 16-bit address to write to in EEPROM memory
@param[in] buffer Pointer to buffer of bytes to write
@param num How many bytes to write!
@returns True on I2C command success, false on timeout or I2C failure
*/
/**************************************************************************/
bool RAK_EEPROM_I2C::write(uint16_t addr, uint8_t *buffer, uint16_t num)
{
while (num--)
{
if (!write(addr++, buffer[0]))
{
return false;
}
buffer++;
}
return true;
}
/**************************************************************************/
/*!
@brief Reads multiple bytes from the specified EEPROM address
@param addr
The 16-bit address to read from in EEPROM memory
@param buffer Pointer to buffer of bytes that will be filled!
@param num How many bytes to write!
@returns The 8-bit value retrieved at addr
*/
/**************************************************************************/
bool RAK_EEPROM_I2C::read(uint16_t addr, uint8_t *buffer, uint16_t num)
{
for (uint16_t i = 0; i < num; i++)
{
uint8_t buff[2] = {(uint8_t)(addr >> 8), (uint8_t)addr};
if (!write(_addr, buff, 2))
return false;
if (!read(_addr, buff, 1))
return false;
buffer[i] = buff[0];
addr++;
}
return true;
}