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

Revision:
13:3d4508874121
Parent:
12:bc2446aabbfe
Child:
14:f33e0914ea36
--- a/source/RegisterWriter.cpp	Thu Oct 06 10:33:05 2016 +0000
+++ b/source/RegisterWriter.cpp	Fri Jun 16 11:54:33 2017 +0000
@@ -1,17 +1,27 @@
-/*   Copyright 2016 Rohm Semiconductor
+/*
+The MIT License (MIT)
+Copyright (c) 2017 Rohm Semiconductor
 
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
 
-       http://www.apache.org/licenses/LICENSE-2.0
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
 
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
+
 #include "../RegisterWriter/rohm_hal2.h"           //types, USE_MBED_HARDWARE_I2C, DEBUG_print*, I2C.h, I2C_SDA, I2C_SCL
 
 #ifdef USE_MBED_HARDWARE_I2C
@@ -22,10 +32,12 @@
 
 RegisterWriter::RegisterWriter(I2C &i2c_obj) : i2c_bus(i2c_obj) {
     self_created_i2c = false;
+    write_single = true;
 }
 
 RegisterWriter::RegisterWriter(PinName sda, PinName scl) : i2c_bus(sda, scl) {
     self_created_i2c = true;
+    write_single = true;
 }
 
 RegisterWriter::~RegisterWriter(){
@@ -36,19 +48,11 @@
 
 /* i2c common functions */
 uint8_t RegisterWriter::read_register(uint8_t sad, uint8_t reg, uint8_t* buf, uint8_t buf_len) {
-    uint8_t received_bytes;
-    int read_ok;
+    int error;
 
     i2c_bus.write( (int)((sad << 1) | I2C_WRITE), (char*)&reg, (int)1 );
-    read_ok = i2c_bus.read( (int)((sad << 1) | I2C_READ), (char*)buf, (int)buf_len);
-
-    if( read_ok == 0 ){     //0 == success(ack)
-        received_bytes = buf_len;
-        }
-    else{                   //non0 == fail (nack)
-        received_bytes = 0;
-        }
-    return( received_bytes );
+    error = i2c_bus.read( (int)((sad << 1) | I2C_READ), (char*)buf, (int)buf_len);
+    return( error );
 }
 
 uint8_t RegisterWriter::read_fifo_register(uint8_t sad, uint8_t reg, uint8_t* buf, uint8_t buf_len) {
@@ -73,10 +77,36 @@
     return read_fifo_register(sad, reg, buf, buf_len);
 }
 
+/** Write data to register. */
 bool RegisterWriter::write_register(uint8_t sad, uint8_t reg, uint8_t* data, uint8_t data_len) {
+    if (write_single)
+        return write_register_single(sad, reg, data, data_len);
+    return write_register_separate(sad, reg, data, data_len);
+}
+
+/** Write register with single write. */
+bool RegisterWriter::write_register_single(uint8_t sad, uint8_t reg, uint8_t* data, uint8_t data_len) {
     bool error;
+
+    char cmd[data_len+1];
+
+    cmd[0] = reg;
+    for (int i = 0; i < data_len; i++) {
+        cmd[i+1] = data[i];
+    }
+    error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), cmd, data_len+1, true);
+    return error;
+}
+
+/** Write register with two separate writes.
+ * First write register address and then continue with data. Send stop only after second write.
+ */
+bool RegisterWriter::write_register_separate(uint8_t sad, uint8_t reg, uint8_t* data, uint8_t data_len) {
+    bool error;
+
     error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), (char*)&reg, (int)1, true);
     error = error || i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), (char*)data, (int)data_len, false);
+
     return error;
 }
 
@@ -91,11 +121,12 @@
     return error;
 }
 
+/* @return error true/false */
 bool RegisterWriter::change_bits(uint8_t sad, uint8_t reg, uint8_t mask, uint8_t bits){
-    uint8_t value, read_bytes;
-    bool error;
-    read_bytes = read_register(sad, reg, &value, 1);
-    if( read_bytes != 0 ){
+    uint8_t value, error;
+    
+    error = read_register(sad, reg, &value, 1);
+    if( !error ){
         value = value & ~mask;
         value = value | (bits & mask);
         return write_register(sad, reg, value);