arduino/bmp280-test/i2c.h
2018-11-03 20:21:33 +00:00

174 lines
5.0 KiB
C++

#ifndef WirePlus_h
#define WirePlus_h
#include "Wire.h"
#include <Arduino.h> // for uint8_t data type
/** ######### usefull defines ################################################################# */
#define getmax(a,b) ((a)>(b)?(a):(b)) // TODO: implement as static const
#define BITMASK(a) (1<<a)
#define BIT(a) (1<<a)
#ifndef TRUE
#define TRUE (1==1)
#define FALSE (1==2)
#endif
#ifndef HIGH
#define LOW (0)
#define HIGH (1)
#endif
/// are they really usefull?
#define UBLB(a,b) ( ( (a) << 8) | (b) )
#define UBLB19(a,b) ( ( (a) << 16 ) | (b) )
#define UBLB32(a,b,c,d) ((( ((a)<<24) | ((b)<<16) ) | ((c)<<8)) | (d) )
/**< A way to get around Questions with shifting
uint8_t value = 250;
Serial.println(value); // --> 250
Serial.println(int8_t(value)); // --> -6
Serial.println(int8_t(value)<<8); // --> -1536 = -6*256
Serial.println(uint8_t(value)); // --> 250
Serial.println(uint8_t(value)<<8); // --> -1536 = -6*256 !!!!!!!!!!!!!!!!!!!!!!
Serial.println(uint16_t(value<<8)); // --> 64000
*/
class WirePlus
{
public:
WirePlus();
uint8_t probe (const uint8_t);
uint8_t probeAddress(const uint8_t);
void write (const uint8_t, const uint8_t, const uint8_t *, const uint8_t);
void writeByte (const uint8_t, const uint8_t, const uint8_t);
void writeCMD (const uint8_t, const uint8_t);
uint8_t readByte (const uint8_t, const uint8_t);
void read (const uint8_t, const uint8_t, uint8_t *, const uint8_t);
void setRegister (const uint8_t, const uint8_t, const uint8_t, const uint8_t);
uint8_t getRegister (const uint8_t, const uint8_t, const uint8_t);
private:
WirePlus(const WirePlus&); // declaration only for copy constructor
WirePlus& operator=(const WirePlus&); // declaration only for copy assignment --> make it uncopyable
};
/** ######### Implementation ################################################################# */
WirePlus::WirePlus()
{
Wire.begin(); // I2C as Master
// bitSet(PORTC, 4); // deactivate internal pull-ups for twi
// bitSet(PORTC, 5); // as per note from atmega8 manual pg167
// switch to 400KHz I2C - eheheh
TWBR = ((F_CPU / 400000L) - 16) / 2; // see twi_init in Wire/utility/twi.c
};
/** ######### Public Methods ################################################################# */
uint8_t WirePlus::probe(const uint8_t address)
{
Wire.beginTransmission(address);
if (Wire.endTransmission(true)==0) return 1; // found something
else return 0; // no response
};
uint8_t WirePlus::probeAddress(const uint8_t address)
{
return probe(address);
};
void WirePlus::write(const uint8_t address, const uint8_t register_address, const uint8_t write_value[], const uint8_t length=1)
{
if (!length) return;
Wire.beginTransmission(address);
Wire.write(register_address);
uint8_t counter;
counter = 0;
while (counter < length)
{
Wire.write(write_value[counter]);
counter++;
}
Wire.endTransmission(true);
};
void WirePlus::writeByte(const uint8_t address, const uint8_t register_address, const uint8_t write_value)
{
Wire.beginTransmission(address);
Wire.write(register_address);
Wire.write(write_value);
Wire.endTransmission(true);
};
void WirePlus::writeCMD(const uint8_t address, const uint8_t cmd)
{
Wire.beginTransmission(address);
Wire.write(cmd);
Wire.endTransmission();
};
void WirePlus::read(const uint8_t address, const uint8_t registeraddress, uint8_t buff[], const uint8_t length=1)
{
Wire.beginTransmission(address); // Adress + WRITE (0)
Wire.write(registeraddress);
Wire.endTransmission(false); // No Stop Condition, for repeated Talk
if (!length) return;
Wire.requestFrom(address, length); // Address + READ (1)
uint8_t _i;
_i=0;
while(Wire.available())
{
buff[_i] = Wire.read();
_i++;
}
Wire.endTransmission(true); // Stop Condition
};
uint8_t WirePlus::readByte(const uint8_t address, const uint8_t register_address)
{
uint8_t _readvalue;
read(address, register_address, &_readvalue, 1);
return _readvalue;
};
void WirePlus::setRegister(const uint8_t address, const uint8_t registeraddress, const uint8_t mask, const uint8_t writevalue)
{
uint8_t _setting;
read(address, registeraddress, &_setting, 1 );
_setting &= ~mask;
_setting |= (writevalue&mask);
writeByte(address, registeraddress, _setting);
};
uint8_t WirePlus::getRegister(const uint8_t address, const uint8_t registeraddress, const uint8_t mask)
{
uint8_t _setting;
read(address, registeraddress, &_setting, (uint8_t)1 );
return (_setting & mask);
};
extern WirePlus i2c;
/** ######### Preinstantiate Object ################################################################# */
WirePlus i2c;
//#include "i2c.cpp" // TODO: ugly BUGFIX to get Scripts without i2c down in filesize (i2c.cpp is loaded w/o request)
#endif