Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
I2CEEBlockDevice.cpp
00001 /* Simple access class for I2C EEPROM chips like Microchip 24LC 00002 * Copyright (c) 2015 Robin Hourahane 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "I2CEEBlockDevice.h" 00017 00018 #define I2CEE_TIMEOUT 10000 00019 00020 00021 I2CEEBlockDevice::I2CEEBlockDevice( 00022 PinName sda, PinName scl, uint8_t addr, 00023 bd_size_t size, bd_size_t block, int freq) 00024 : _i2c(sda, scl), _i2c_addr(addr), _size(size), _block(block) 00025 { 00026 _i2c.frequency(freq); 00027 } 00028 00029 int I2CEEBlockDevice::init() 00030 { 00031 return _sync(); 00032 } 00033 00034 int I2CEEBlockDevice::deinit() 00035 { 00036 return 0; 00037 } 00038 00039 int I2CEEBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) 00040 { 00041 // Check the address and size fit onto the chip. 00042 MBED_ASSERT(is_valid_read(addr, size)); 00043 00044 _i2c.start(); 00045 if (!_i2c.write(_i2c_addr | 0) || 00046 !_i2c.write((char)(addr >> 8)) || 00047 !_i2c.write((char)(addr & 0xff))) { 00048 return BD_ERROR_DEVICE_ERROR; 00049 } 00050 _i2c.stop(); 00051 00052 if (_i2c.read(_i2c_addr, static_cast<char*>(buffer), size) < 0) { 00053 return BD_ERROR_DEVICE_ERROR; 00054 } 00055 00056 return 0; 00057 } 00058 00059 int I2CEEBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size) 00060 { 00061 // Check the addr and size fit onto the chip. 00062 MBED_ASSERT(is_valid_program(addr, size)); 00063 00064 // While we have some more data to write. 00065 while (size > 0) { 00066 uint32_t off = addr % _block; 00067 uint32_t chunk = (off + size < _block) ? size : (_block - off); 00068 00069 _i2c.start(); 00070 if (!_i2c.write(_i2c_addr | 0) || 00071 !_i2c.write((char)(addr >> 8)) || 00072 !_i2c.write((char)(addr & 0xff))) { 00073 return BD_ERROR_DEVICE_ERROR; 00074 } 00075 00076 for (unsigned i = 0; i < chunk; i++) { 00077 _i2c.write(static_cast<const char*>(buffer)[i]); 00078 } 00079 _i2c.stop(); 00080 00081 int err = _sync(); 00082 if (err) { 00083 return err; 00084 } 00085 00086 addr += chunk; 00087 size -= chunk; 00088 buffer = static_cast<const char*>(buffer) + chunk; 00089 } 00090 00091 return 0; 00092 } 00093 00094 int I2CEEBlockDevice::erase(bd_addr_t addr, bd_size_t size) 00095 { 00096 // No erase needed 00097 return 0; 00098 } 00099 00100 int I2CEEBlockDevice::_sync() 00101 { 00102 // The chip doesn't ACK while writing to the actual EEPROM 00103 // so loop trying to do a zero byte write until it is ACKed 00104 // by the chip. 00105 for (int i = 0; i < I2CEE_TIMEOUT; i++) { 00106 if (_i2c.write(_i2c_addr | 0, 0, 0) < 1) { 00107 return 0; 00108 } 00109 00110 wait_ms(1); 00111 } 00112 00113 return BD_ERROR_DEVICE_ERROR; 00114 } 00115 00116 bd_size_t I2CEEBlockDevice::get_read_size() const 00117 { 00118 return 1; 00119 } 00120 00121 bd_size_t I2CEEBlockDevice::get_program_size() const 00122 { 00123 return 1; 00124 } 00125 00126 bd_size_t I2CEEBlockDevice::get_erase_size() const 00127 { 00128 return 1; 00129 } 00130 00131 bd_size_t I2CEEBlockDevice::size() const 00132 { 00133 return _size; 00134 }
Generated on Tue Jul 12 2022 20:17:22 by
1.7.2