diff --git a/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.cpp index 57016e9937..42bbce7c96 100644 --- a/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.cpp @@ -18,11 +18,11 @@ using namespace mbed; #define I2CEE_TIMEOUT 10000 - + I2CEEBlockDevice::I2CEEBlockDevice( - PinName sda, PinName scl, uint8_t addr, - bd_size_t size, bd_size_t block, int freq) + PinName sda, PinName scl, uint8_t addr, + bd_size_t size, bd_size_t block, int freq) : _i2c_addr(addr), _size(size), _block(block) { _i2c = new (_i2c_buffer) I2C(sda, scl); @@ -30,15 +30,15 @@ I2CEEBlockDevice::I2CEEBlockDevice( } I2CEEBlockDevice::I2CEEBlockDevice( - I2C * i2c_obj, uint8_t addr, - bd_size_t size, bd_size_t block) + I2C *i2c_obj, uint8_t addr, + bd_size_t size, bd_size_t block) : _i2c_addr(addr), _size(size), _block(block) { _i2c = i2c_obj; } I2CEEBlockDevice::~I2CEEBlockDevice() { - if (_i2c == (I2C*)_i2c_buffer) { + if (_i2c == (I2C *)_i2c_buffer) { _i2c->~I2C(); } } @@ -59,50 +59,55 @@ int I2CEEBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) MBED_ASSERT(is_valid_read(addr, size)); _i2c->start(); + if (!_i2c->write(_i2c_addr | 0) || - !_i2c->write((char)(addr >> 8)) || - !_i2c->write((char)(addr & 0xff))) { + !_i2c->write((char)(addr >> 8)) || + !_i2c->write((char)(addr & 0xff))) { return BD_ERROR_DEVICE_ERROR; } + _i2c->stop(); - if (_i2c->read(_i2c_addr, static_cast(buffer), size) < 0) { + if (_i2c->read(_i2c_addr, static_cast(buffer), size) < 0) { return BD_ERROR_DEVICE_ERROR; } return 0; } - + int I2CEEBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size) { // Check the addr and size fit onto the chip. MBED_ASSERT(is_valid_program(addr, size)); - + // While we have some more data to write. while (size > 0) { uint32_t off = addr % _block; uint32_t chunk = (off + size < _block) ? size : (_block - off); _i2c->start(); + if (!_i2c->write(_i2c_addr | 0) || - !_i2c->write((char)(addr >> 8)) || - !_i2c->write((char)(addr & 0xff))) { + !_i2c->write((char)(addr >> 8)) || + !_i2c->write((char)(addr & 0xff))) { return BD_ERROR_DEVICE_ERROR; } for (unsigned i = 0; i < chunk; i++) { - _i2c->write(static_cast(buffer)[i]); + _i2c->write(static_cast(buffer)[i]); } + _i2c->stop(); int err = _sync(); + if (err) { return err; } addr += chunk; size -= chunk; - buffer = static_cast(buffer) + chunk; + buffer = static_cast(buffer) + chunk; } return 0; @@ -129,7 +134,7 @@ int I2CEEBlockDevice::_sync() return BD_ERROR_DEVICE_ERROR; } - + bd_size_t I2CEEBlockDevice::get_read_size() const { return 1; diff --git a/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.h b/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.h index a86631e130..4cc94ce209 100644 --- a/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.h +++ b/components/storage/blockdevice/COMPONENT_I2CEE/I2CEEBlockDevice.h @@ -15,10 +15,10 @@ */ #ifndef MBED_I2CEEPROM_BLOCK_DEVICE_H #define MBED_I2CEEPROM_BLOCK_DEVICE_H - + #include "BlockDevice.h" #include "I2C.h" - + /** BlockDevice for I2C based flash device such as * Microchip's 24LC or ATMEL's AT24C ranges * @@ -26,36 +26,37 @@ * // Here's an example using a 24LC256 on a GR PEACH * #include "mbed.h" * #include "I2CEEBlockDevice.h" - * + * * // Create EEPROM device on I2C bus with 32kbytes of memory * I2CEEBlockDevice i2cee(D14, D15, 0xa0, 32*1024); - * + * * int main() { * printf("i2cee test\n"); - * + * * // Initialize the device and print the memory layout * i2cee.init(); * printf("i2cee size: %llu\n", i2cee.size()); * printf("i2cee read size: %llu\n", i2cee.get_read_size()); * printf("i2cee program size: %llu\n", i2cee.get_program_size()); * printf("i2cee erase size: %llu\n", i2cee.get_erase_size()); - * + * * // Write "Hello World!" to the first block * char *buffer = (char*)malloc(i2cee.get_erase_size()); * sprintf(buffer, "Hello World!\n"); * i2cee.erase(0, i2cee.get_erase_size()); * i2cee.program(buffer, 0, i2cee.get_erase_size()); - * + * * // Read back what was stored * i2cee.read(buffer, 0, i2cee.get_erase_size()); * printf("%s", buffer); - * + * * // Deinitialize the device * i2cee.deinit(); * } * @endcode */ -class I2CEEBlockDevice : public BlockDevice { +class I2CEEBlockDevice : public BlockDevice +{ public: /** Constructor to create an I2CEEBlockDevice on I2C pins * @@ -67,21 +68,21 @@ public: * @param freq The frequency of the I2C bus, defaults to 400K. */ I2CEEBlockDevice( - PinName sda, PinName scl, uint8_t address, - bd_size_t size, bd_size_t block=32, - int bus_speed=400000); + PinName sda, PinName scl, uint8_t address, + bd_size_t size, bd_size_t block = 32, + int bus_speed = 400000); - /** 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. - */ + /** 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. + */ I2CEEBlockDevice( - mbed::I2C * i2c_obj, uint8_t address, - bd_size_t size, bd_size_t block=32); + mbed::I2C *i2c_obj, uint8_t address, + bd_size_t size, bd_size_t block = 32); /** Destructor of I2CEEBlockDevice */ @@ -161,9 +162,9 @@ public: * @return A string representation of the BlockDevice class type. */ virtual const char *get_type() const; - + private: - mbed::I2C * _i2c; + mbed::I2C *_i2c; uint32_t _i2c_buffer[sizeof(mbed::I2C) / sizeof(uint32_t)]; uint8_t _i2c_addr; uint32_t _size; @@ -171,6 +172,6 @@ private: int _sync(); }; - + #endif /* MBED_SD_BLOCK_DEVICE_H */ diff --git a/components/storage/blockdevice/COMPONENT_I2CEE/TESTS/block_device/i2cee/main.cpp b/components/storage/blockdevice/COMPONENT_I2CEE/TESTS/block_device/i2cee/main.cpp index 846b523519..dd167d1c5d 100644 --- a/components/storage/blockdevice/COMPONENT_I2CEE/TESTS/block_device/i2cee/main.cpp +++ b/components/storage/blockdevice/COMPONENT_I2CEE/TESTS/block_device/i2cee/main.cpp @@ -27,20 +27,23 @@ const struct { }; -void test_read_write() { +void test_read_write() +{ I2CEEBlockDevice bd(TEST_PINS, TEST_ADDR, - TEST_SIZE, TEST_BLOCK_SIZE, TEST_FREQ); + TEST_SIZE, TEST_BLOCK_SIZE, TEST_FREQ); int err = bd.init(); TEST_ASSERT_EQUAL(0, err); - for (unsigned a = 0; a < sizeof(ATTRS)/sizeof(ATTRS[0]); a++) { + for (unsigned a = 0; a < sizeof(ATTRS) / sizeof(ATTRS[0]); a++) { static const char *prefixes[] = {"", "k", "M", "G"}; + for (int i = 3; i >= 0; i--) { bd_size_t size = (bd.*ATTRS[a].method)(); - if (size >= (1ULL << 10*i)) { + + if (size >= (1ULL << 10 * i)) { printf("%s: %llu%sbytes (%llubytes)\n", - ATTRS[a].name, size >> 10*i, prefixes[i], size); + ATTRS[a].name, size >> 10 * i, prefixes[i], size); break; } } @@ -50,11 +53,11 @@ void test_read_write() { uint8_t *write_block = new uint8_t[block_size]; uint8_t *read_block = new uint8_t[block_size]; uint8_t *error_mask = new uint8_t[TEST_ERROR_MASK]; - unsigned addrwidth = ceil(log(float(bd.size()-1)) / log(float(16)))+1; + unsigned addrwidth = ceil(log(float(bd.size() - 1)) / log(float(16))) + 1; for (int b = 0; b < TEST_BLOCK_COUNT; b++) { // Find a random block - bd_addr_t block = (rand()*block_size) % bd.size(); + bd_addr_t block = (rand() * block_size) % bd.size(); // Use next random number as temporary seed to keep // the address progressing in the pseudorandom sequence @@ -62,6 +65,7 @@ void test_read_write() { // Fill with random sequence srand(seed); + for (bd_size_t i = 0; i < block_size; i++) { write_block[i] = 0xff & rand(); } @@ -76,59 +80,70 @@ void test_read_write() { TEST_ASSERT_EQUAL(0, err); printf("write %0*llx:%llu ", addrwidth, block, block_size); + for (int i = 0; i < block_size && i < 16; i++) { printf("%02x", write_block[i]); } + if (block_size > 16) { printf("...\n"); } + printf("\n"); err = bd.read(read_block, block, block_size); TEST_ASSERT_EQUAL(0, err); printf("read %0*llx:%llu ", addrwidth, block, block_size); + for (int i = 0; i < block_size && i < 16; i++) { printf("%02x", read_block[i]); } + if (block_size > 16) { printf("..."); } + printf("\n"); // Find error mask for debugging memset(error_mask, 0, TEST_ERROR_MASK); - bd_size_t error_scale = block_size / (TEST_ERROR_MASK*8); + bd_size_t error_scale = block_size / (TEST_ERROR_MASK * 8); srand(seed); - for (bd_size_t i = 0; i < TEST_ERROR_MASK*8; i++) { + + for (bd_size_t i = 0; i < TEST_ERROR_MASK * 8; i++) { for (bd_size_t j = 0; j < error_scale; j++) { - if ((0xff & rand()) != read_block[i*error_scale + j]) { - error_mask[i/8] |= 1 << (i%8); + if ((0xff & rand()) != read_block[i * error_scale + j]) { + error_mask[i / 8] |= 1 << (i % 8); } } } printf("error %0*llx:%llu ", addrwidth, block, block_size); + for (int i = 0; i < TEST_ERROR_MASK; i++) { printf("%02x", error_mask[i]); } + printf("\n"); // Check that the data was unmodified srand(seed); + for (bd_size_t i = 0; i < block_size; i++) { TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); } } - + err = bd.deinit(); TEST_ASSERT_EQUAL(0, err); } // Test setup -utest::v1::status_t test_setup(const size_t number_of_cases) { +utest::v1::status_t test_setup(const size_t number_of_cases) +{ GREENTEA_SETUP(30, "default_auto"); return verbose_test_setup_handler(number_of_cases); } @@ -139,6 +154,7 @@ Case cases[] = { Specification specification(test_setup, cases); -int main() { +int main() +{ return !Harness::run(specification); }