Thundersoft / Mbed OS BH1790GLC_for_TTMxx
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 "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.h"          //prototypes
00029 #define I2C_WRITE 0
00030 #define I2C_READ  1
00031 
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[data_len+1];
00092 
00093     cmd[0] = reg;
00094     for (int i = 0; i < data_len; i++) {
00095         cmd[i+1] = data[i];
00096     }
00097     error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), cmd, data_len+1, true);
00098     return error;
00099 }
00100 
00101 /** Write register with two separate writes.
00102  * First write register address and then continue with data. Send stop only after second write.
00103  */
00104 bool RegisterWriter::write_register_separate(uint8_t sad, uint8_t reg, uint8_t* data, uint8_t data_len) {
00105     bool error;
00106 
00107     error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), (char*)&reg, (int)1, true);
00108     error = error || i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), (char*)data, (int)data_len, false);
00109 
00110     return error;
00111 }
00112 
00113 bool RegisterWriter::write_register(uint8_t sad, uint8_t reg, uint8_t data) {
00114     char data_to_send[2];
00115     bool error;
00116 
00117     data_to_send[0] = reg;
00118     data_to_send[1] = data;
00119     error = i2c_bus.write( (int)((sad << 1) | I2C_WRITE ), &data_to_send[0], 2);
00120 
00121     return error;
00122 }
00123 
00124 /* @return error true/false */
00125 bool RegisterWriter::change_bits(uint8_t sad, uint8_t reg, uint8_t mask, uint8_t bits){
00126     uint8_t value, error;
00127     
00128     error = read_register(sad, reg, &value, 1);
00129     if( !error ){
00130         value = value & ~mask;
00131         value = value | (bits & mask);
00132         return write_register(sad, reg, value);
00133         }
00134     else{
00135         //DEBUG_printf("Read before change_bits() failed.");
00136         return true;
00137         }
00138 }
00139 
00140 void RegisterWriter::set_hs_mode_for_one_command(){
00141     #define MCODE (1<<3)
00142     char temp;
00143     //Fullspeed mode -> highspeed mode for one command.
00144     i2c_bus.write( (int)(MCODE), (char*)&temp, (int)0, true ); //Trick to write just mcode+make nack.
00145     }
00146 
00147 
00148 #endif
00149 
00150 
00151