@@ -22,17 +22,21 @@ using namespace mbed;
2222
2323I2CEEBlockDevice::I2CEEBlockDevice (
2424 PinName sda, PinName scl, uint8_t addr,
25- bd_size_t size, bd_size_t block, int freq)
26- : _i2c_addr(addr), _size(size), _block(block)
25+ bd_size_t size, bd_size_t block, int freq,
26+ bool address_is_eight_bit)
27+ : _i2c_addr(addr), _size(size), _block(block),
28+ _address_is_eight_bit(address_is_eight_bit)
2729{
2830 _i2c = new (_i2c_buffer) I2C (sda, scl);
2931 _i2c->frequency (freq);
3032}
3133
3234I2CEEBlockDevice::I2CEEBlockDevice (
3335 I2C *i2c_obj, uint8_t addr,
34- bd_size_t size, bd_size_t block)
35- : _i2c_addr(addr), _size(size), _block(block)
36+ bd_size_t size, bd_size_t block,
37+ bool address_is_eight_bit)
38+ : _i2c_addr(addr), _size(size), _block(block),
39+ _address_is_eight_bit(address_is_eight_bit)
3640{
3741 _i2c = i2c_obj;
3842}
@@ -58,48 +62,61 @@ int I2CEEBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
5862 // Check the address and size fit onto the chip.
5963 MBED_ASSERT (is_valid_read (addr, size));
6064
65+ auto *pBuffer = static_cast <char *>(buffer);
66+
6167 _i2c->start ();
6268
63- if (!_i2c->write (_i2c_addr | 0 ) ||
64- !_i2c->write ((char )(addr >> 8 )) ||
65- !_i2c->write ((char )(addr & 0xff ))) {
69+ if (1 != _i2c->write (get_paged_device_address (addr))) {
6670 return BD_ERROR_DEVICE_ERROR;
6771 }
6872
69- _i2c->stop ();
73+ if (!_address_is_eight_bit && 1 != _i2c->write ((char )(addr >> 8u ))) {
74+ return BD_ERROR_DEVICE_ERROR;
75+ }
7076
71- auto err = _sync ();
72- if (err) {
73- return err;
77+ if (1 != _i2c->write ((char )(addr & 0xffu ))) {
78+ return BD_ERROR_DEVICE_ERROR;
7479 }
7580
76- if (0 != _i2c->read (_i2c_addr, static_cast <char *>(buffer), size)) {
81+ _i2c->stop ();
82+
83+ if (0 != _i2c->read (_i2c_addr, pBuffer, size)) {
7784 return BD_ERROR_DEVICE_ERROR;
7885 }
7986
80- return 0 ;
87+ return BD_ERROR_OK ;
8188}
8289
8390int I2CEEBlockDevice::program (const void *buffer, bd_addr_t addr, bd_size_t size)
8491{
8592 // Check the addr and size fit onto the chip.
8693 MBED_ASSERT (is_valid_program (addr, size));
8794
95+ const auto *pBuffer = static_cast <const char *>(buffer);
96+
8897 // While we have some more data to write.
8998 while (size > 0 ) {
9099 uint32_t off = addr % _block;
91100 uint32_t chunk = (off + size < _block) ? size : (_block - off);
92101
93102 _i2c->start ();
94103
95- if (!_i2c->write (_i2c_addr | 0 ) ||
96- !_i2c->write ((char )(addr >> 8 )) ||
97- !_i2c->write ((char )(addr & 0xff ))) {
104+ if (1 != _i2c->write (get_paged_device_address (addr))) {
105+ return BD_ERROR_DEVICE_ERROR;
106+ }
107+
108+ if (!_address_is_eight_bit && 1 != _i2c->write ((char )(addr >> 8u ))) {
109+ return BD_ERROR_DEVICE_ERROR;
110+ }
111+
112+ if (1 != _i2c->write ((char )(addr & 0xffu ))) {
98113 return BD_ERROR_DEVICE_ERROR;
99114 }
100115
101116 for (unsigned i = 0 ; i < chunk; i++) {
102- _i2c->write (static_cast <const char *>(buffer)[i]);
117+ if (1 != _i2c->write (pBuffer[i])) {
118+ return BD_ERROR_DEVICE_ERROR;
119+ }
103120 }
104121
105122 _i2c->stop ();
@@ -112,10 +129,10 @@ int I2CEEBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
112129
113130 addr += chunk;
114131 size -= chunk;
115- buffer = static_cast < const char *>(buffer) + chunk;
132+ pBuffer += chunk;
116133 }
117134
118- return 0 ;
135+ return BD_ERROR_OK ;
119136}
120137
121138int I2CEEBlockDevice::erase (bd_addr_t addr, bd_size_t size)
@@ -164,3 +181,15 @@ const char *I2CEEBlockDevice::get_type() const
164181{
165182 return " I2CEE" ;
166183}
184+
185+ uint8_t I2CEEBlockDevice::get_paged_device_address (bd_addr_t address)
186+ {
187+ if (!_address_is_eight_bit) {
188+ return _i2c_addr;
189+ } else {
190+ // Use the three least significant bits of the 2nd byte as the page
191+ // The page will be bits 2-4 of the user defined addresses.
192+ return _i2c_addr | ((address & 0x0700u ) >> 7u );
193+ }
194+ }
195+
0 commit comments