mirror of https://github.com/ARMmbed/mbed-os.git
Add Eight-Bit-Adressing mode to I2CEEBlockDevice.
When dealing with EEPROMs without a 16 bit adressing, the current implementation does not work, as it writes a 16 bit address to the chip. This may cause undefined behaviour. This change adds a new constructor argument to enable this new eight-bit mode. It defaults to false to not break existing code. This constructor argument should actually never be necessary to manually set, except when dealing with cheap devices.pull/12446/head
parent
3d038e55ee
commit
cd34860bd0
|
@ -22,8 +22,10 @@ using namespace mbed;
|
|||
|
||||
I2CEEBlockDevice::I2CEEBlockDevice(
|
||||
PinName sda, PinName scl, uint8_t addr,
|
||||
bd_size_t size, bd_size_t block, int freq)
|
||||
: _i2c_addr(addr), _size(size), _block(block)
|
||||
bd_size_t size, bd_size_t block, int freq,
|
||||
bool address_is_eight_bit)
|
||||
: _i2c_addr(addr), _size(size), _block(block),
|
||||
_address_is_eight_bit(address_is_eight_bit)
|
||||
{
|
||||
_i2c = new (_i2c_buffer) I2C(sda, scl);
|
||||
_i2c->frequency(freq);
|
||||
|
@ -31,8 +33,10 @@ I2CEEBlockDevice::I2CEEBlockDevice(
|
|||
|
||||
I2CEEBlockDevice::I2CEEBlockDevice(
|
||||
I2C *i2c_obj, uint8_t addr,
|
||||
bd_size_t size, bd_size_t block)
|
||||
: _i2c_addr(addr), _size(size), _block(block)
|
||||
bd_size_t size, bd_size_t block,
|
||||
bool address_is_eight_bit)
|
||||
: _i2c_addr(addr), _size(size), _block(block),
|
||||
_address_is_eight_bit(address_is_eight_bit)
|
||||
{
|
||||
_i2c = i2c_obj;
|
||||
}
|
||||
|
@ -60,9 +64,15 @@ int I2CEEBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
|
|||
|
||||
_i2c->start();
|
||||
|
||||
if (!_i2c->write(_i2c_addr | 0) ||
|
||||
!_i2c->write((char)(addr >> 8)) ||
|
||||
!_i2c->write((char)(addr & 0xff))) {
|
||||
if (!_i2c->write(_i2c_addr | 0)) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (!_address_is_eight_bit && !_i2c->write((char)(addr >> 8))) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (!_i2c->write((char)(addr & 0xff))) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
|
@ -92,9 +102,15 @@ int I2CEEBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
|
|||
|
||||
_i2c->start();
|
||||
|
||||
if (!_i2c->write(_i2c_addr | 0) ||
|
||||
!_i2c->write((char)(addr >> 8)) ||
|
||||
!_i2c->write((char)(addr & 0xff))) {
|
||||
if (!_i2c->write(_i2c_addr | 0)) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (!_address_is_eight_bit && !_i2c->write((char)(addr >> 8))) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (!_i2c->write((char)(addr & 0xff))) {
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,29 +59,37 @@ class I2CEEBlockDevice : public BlockDevice {
|
|||
public:
|
||||
/** Constructor to create an I2CEEBlockDevice on I2C pins
|
||||
*
|
||||
* @param sda The pin name for the sda line of the I2C bus.
|
||||
* @param scl The pin name for the scl line of the I2C bus.
|
||||
* @param addr The 8bit I2C address of the chip, common range 0xa0 - 0xae.
|
||||
* @param size The size of the device in bytes
|
||||
* @param block The page size of the device in bytes, defaults to 32bytes
|
||||
* @param freq The frequency of the I2C bus, defaults to 400K.
|
||||
* @param sda The pin name for the sda line of the I2C bus.
|
||||
* @param scl The pin name for the scl line of the I2C bus.
|
||||
* @param addr The 8bit I2C address of the chip, common range 0xa0 - 0xae.
|
||||
* @param size The size of the device in bytes
|
||||
* @param block The page size of the device in bytes, defaults to 32bytes
|
||||
* @param freq The frequency of the I2C bus, defaults to 400K.
|
||||
* @param address_is_eight_bit Specifies whether the EEPROM device is using eight bit
|
||||
* addresses instead of 16 bit addresses. This should not be needed
|
||||
* unless dealing with very cheap devices.
|
||||
*/
|
||||
I2CEEBlockDevice(
|
||||
PinName sda, PinName scl, uint8_t address,
|
||||
bd_size_t size, bd_size_t block = 32,
|
||||
int bus_speed = 400000);
|
||||
int bus_speed = 400000,
|
||||
bool address_is_eight_bit = false);
|
||||
|
||||
/** Constructor to create an I2CEEBlockDevice on I2C pins
|
||||
*
|
||||
* @param i2c The I2C instance pointer
|
||||
* @param addr The 8bit I2C address of the chip, common range 0xa0 - 0xae.
|
||||
* @param size The size of the device in bytes
|
||||
* @param block The page size of the device in bytes, defaults to 32bytes
|
||||
* @param freq The frequency of the I2C bus, defaults to 400K.
|
||||
*/
|
||||
*
|
||||
* @param i2c The I2C instance pointer
|
||||
* @param addr The 8bit I2C address of the chip, common range 0xa0 - 0xae.
|
||||
* @param size The size of the device in bytes
|
||||
* @param block The page size of the device in bytes, defaults to 32bytes
|
||||
* @param freq The frequency of the I2C bus, defaults to 400K.
|
||||
* @param address_is_eight_bit Specifies whether the EEPROM device is using eight bit
|
||||
* addresses instead of 16 bit addresses. This should not be needed
|
||||
* unless dealing with very cheap devices.
|
||||
*/
|
||||
I2CEEBlockDevice(
|
||||
mbed::I2C *i2c_obj, uint8_t address,
|
||||
bd_size_t size, bd_size_t block = 32);
|
||||
bd_size_t size, bd_size_t block = 32,
|
||||
bool address_is_eight_bit = false);
|
||||
|
||||
/** Destructor of I2CEEBlockDevice
|
||||
*/
|
||||
|
@ -169,6 +177,8 @@ private:
|
|||
uint32_t _size;
|
||||
uint32_t _block;
|
||||
|
||||
bool _address_is_eight_bit;
|
||||
|
||||
int _sync();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue