Class for making communication easier from code to i2c connected Rohm/Kionix sensors. Maybe could be used later also for abstracting Arduino/mbed os. Code ported from 'C'-library rohm-sensor-hal.

Dependents:   kionix-kx123-hello rohm-bh1790glc-hello simple-sensor-client rohm-SensorShield-example

Fork of rohm-sensor-hal by Rohm

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RegisterWriter.cpp Source File

RegisterWriter.cpp

00001 /*
00002 The MIT License (MIT)
00003 Copyright (c) 2017 Rohm Semiconductor
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a
00006 copy of this software and associated documentation files (the
00007 "Software"), to deal in the Software without restriction, including
00008 without limitation the rights to use, copy, modify, merge, publish,
00009 distribute, sublicense, and/or sell copies of the Software, and to
00010 permit persons to whom the Software is furnished to do so, subject to
00011 the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included
00014 in all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00017 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00018 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00019 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00020 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00021 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00022 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023 */
00024 
00025 #include "../RegisterWriter/rohm_hal2.h"           //types, USE_MBED_HARDWARE_I2C, DEBUG_print*, I2C.h, I2C_SDA, I2C_SCL
00026 
00027 #ifdef USE_MBED_HARDWARE_I2C
00028 #include "../RegisterWriter/RegisterWriter.h"          //prototypes
00029 #define I2C_WRITE 0
00030 #define I2C_READ  1
00031 #define MAX_DATA_LENGTH 6
00032 
00033 RegisterWriter::RegisterWriter(I2C &i2c_obj) : i2c_bus(i2c_obj) {
00034     self_created_i2c = false;
00035     write_single = true;
00036 }
00037 
00038 RegisterWriter::RegisterWriter(PinName sda, PinName scl) : i2c_bus(sda, scl) {
00039     self_created_i2c = true;
00040     write_single = true;
00041 }
00042 
00043 RegisterWriter::~RegisterWriter(){
00044     if (self_created_i2c == true){
00045         delete &i2c_bus;
00046         }
00047 }
00048 
00049 /* i2c common functions */
00050 uint8_t RegisterWriter::read_register(uint8_t sad, uint8_t reg, uint8_t* buf, uint8_t buf_len) {
00051     int error;
00052 
00053     i2c_bus.write( (int)((sad << 1) | I2C_WRITE), (char*)&reg, (int)1 );
00054     error = i2c_bus.read( (int)((sad << 1) | I2C_READ), (char*)buf, (int)buf_len);
00055     return( error );
00056 }
00057 
00058 uint8_t RegisterWriter::read_fifo_register(uint8_t sad, uint8_t reg, uint8_t* buf, uint8_t buf_len) {
00059     uint8_t received_bytes;
00060     int read_ok;
00061 
00062     i2c_bus.write( (int)((sad << 1) | I2C_WRITE), (char*)&reg, (int)1, true );
00063     read_ok = i2c_bus.read( (int)((sad << 1) | I2C_READ), (char*)buf, (int)buf_len);
00064 
00065     if( read_ok == 0 ){     //0 == success(ack)
00066         received_bytes = buf_len;
00067         }
00068     else{                   //non0 == fail (nack)
00069         received_bytes = 0;
00070         }
00071     return( received_bytes );
00072 }
00073 
00074 uint8_t RegisterWriter::hs_read_register(uint8_t sad, uint8_t reg, uint8_t* buf, uint8_t buf_len) {
00075     set_hs_mode_for_one_command();
00076     //Next read command as usual, but in highspeed
00077     return read_fifo_register(sad, reg, buf, buf_len);
00078 }
00079 
00080 /** Write data to register. */
00081 bool RegisterWriter::write_register(uint8_t sad, uint8_t reg, uint8_t* data, uint8_t data_len) {
00082     if (write_single)
00083         return write_register_single(sad, reg, data, data_len);
00084     return write_register_separate(sad, reg, data, data_len);
00085 }
00086 
00087 /** Write register with single write. */
00088 bool RegisterWriter::write_register_single(uint8_t sad, uint8_t reg, uint8_t* data, uint8_t data_len) {
00089     bool error;
00090 
00091     char cmd[MAX_DATA_LENGTH+1];  // assume max value of data_len is 6
00092     if (data_len>MAX_DATA_LENGTH) {
00093         return false;
00094     }
00095 
00096     cmd[0] = reg;
00097     for (int i = 0; i < data_len; i++) {
00098         cmd[i+1] = data[i];
00099     }
00100     error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), cmd, data_len+1, true);
00101     return error;
00102 }
00103 
00104 /** Write register with two separate writes.
00105  * First write register address and then continue with data. Send stop only after second write.
00106  */
00107 bool RegisterWriter::write_register_separate(uint8_t sad, uint8_t reg, uint8_t* data, uint8_t data_len) {
00108     bool error;
00109 
00110     error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), (char*)&reg, (int)1, true);
00111     error = error || i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), (char*)data, (int)data_len, false);
00112 
00113     return error;
00114 }
00115 
00116 bool RegisterWriter::write_register(uint8_t sad, uint8_t reg, uint8_t data) {
00117     char data_to_send[2];
00118     bool error;
00119 
00120     data_to_send[0] = reg;
00121     data_to_send[1] = data;
00122     error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), &data_to_send[0], 2);
00123 
00124     return error;
00125 }
00126 
00127 /* @return error true/false */
00128 bool RegisterWriter::change_bits(uint8_t sad, uint8_t reg, uint8_t mask, uint8_t bits){
00129     uint8_t value, error;
00130     
00131     error = read_register(sad, reg, &value, 1);
00132     if( !error ){
00133         value = value & ~mask;
00134         value = value | (bits & mask);
00135         return write_register(sad, reg, value);
00136         }
00137     else{
00138         //DEBUG_printf("Read before change_bits() failed.");
00139         return true;
00140         }
00141 }
00142 
00143 void RegisterWriter::set_hs_mode_for_one_command(){
00144     #define MCODE (1<<3)
00145     char temp;
00146     //Fullspeed mode -> highspeed mode for one command.
00147     i2c_bus.write( (int)(MCODE), (char*)&temp, (int)0, true ); //Trick to write just mcode+make nack.
00148     }
00149 
00150 
00151 #endif
00152 
00153