Skip to content

Commit

Permalink
Merge pull request #8432 from device111/development
Browse files Browse the repository at this point in the history
Support for VEML6075 and initial Support for VEML7700
  • Loading branch information
arendst authored May 22, 2020
2 parents 2b54311 + 8813616 commit 2b798ff
Show file tree
Hide file tree
Showing 35 changed files with 2,336 additions and 4 deletions.
4 changes: 3 additions & 1 deletion I2CDEVICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ Index | Define | Driver | Device | Address(es) | Description
45 | USE_HDC1080 | xsns_65 | HDC1080 | 0x40 | Temperature and Humidity sensor
46 | USE_IAQ | xsns_66 | IAQ | 0x5a | Air quality sensor
47 | USE_DISPLAY_SEVENSEG| xdsp_11 | HT16K33 | 0x70 - 0x77 | Seven segment LED
48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor
48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor
49 | USE_VEML6075 | xsns_68 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor
50 | USE_VEML7700 | xsns_69 | VEML7700 | 0x10 | Ambient light intensity sensor
23 changes: 23 additions & 0 deletions lib/Adafruit_BusIO/.travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
language: c
sudo: false
cache:
directories:
- ~/arduino_ide
- ~/.arduino15/packages/
git:
depth: false
quiet: true
env:
global:
- PRETTYNAME="Adafruit BusIO Library"

before_install:
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)

script:
- build_main_platforms

# Generate and deploy documentation
after_success:
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)
258 changes: 258 additions & 0 deletions lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
#include <Adafruit_BusIO_Register.h>

/*!
* @brief Create a register we access over an I2C Device (which defines the bus and address)
* @param i2cdevice The I2CDevice to use for underlying I2C access
* @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits
* @param width The width of the register data itself, defaults to 1 byte
* @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST
* @param address_width The width of the register address itself, defaults to 1 byte
*/
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr,
uint8_t width, uint8_t bitorder, uint8_t address_width) {
_i2cdevice = i2cdevice;
_spidevice = NULL;
_addrwidth = address_width;
_address = reg_addr;
_bitorder = bitorder;
_width = width;
}

/*!
* @brief Create a register we access over an SPI Device (which defines the bus and CS pin)
* @param spidevice The SPIDevice to use for underlying I2C access
* @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits
* @param type The method we use to read/write data to SPI (which is not as well defined as I2C)
* @param width The width of the register data itself, defaults to 1 byte
* @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST
* @param address_width The width of the register address itself, defaults to 1 byte
*/
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr,
Adafruit_BusIO_SPIRegType type,
uint8_t width, uint8_t bitorder, uint8_t address_width) {
_spidevice = spidevice;
_spiregtype = type;
_i2cdevice = NULL;
_addrwidth = address_width;
_address = reg_addr;
_bitorder = bitorder;
_width = width;
}

/*!
* @brief Create a register we access over an I2C or SPI Device. This is a handy function because we
* can pass in NULL for the unused interface, allowing libraries to mass-define all the registers
* @param i2cdevice The I2CDevice to use for underlying I2C access, if NULL we use SPI
* @param spidevice The SPIDevice to use for underlying I2C access, if NULL we use I2C
* @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits
* @param type The method we use to read/write data to SPI (which is not as well defined as I2C)
* @param width The width of the register data itself, defaults to 1 byte
* @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST
* @param address_width The width of the register address itself, defaults to 1 byte
*/
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, Adafruit_SPIDevice *spidevice,
Adafruit_BusIO_SPIRegType type, uint16_t reg_addr,
uint8_t width, uint8_t bitorder, uint8_t address_width) {
_spidevice = spidevice;
_i2cdevice = i2cdevice;
_spiregtype = type;
_addrwidth = address_width;
_address = reg_addr;
_bitorder = bitorder;
_width = width;
}


/*!
* @brief Write a buffer of data to the register location
* @param buffer Pointer to data to write
* @param len Number of bytes to write
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
*/
bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {

uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)};

if (_i2cdevice) {
return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth);
}
if (_spidevice) {
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
addrbuffer[0] &= ~0x80;
}
return _spidevice->write( buffer, len, addrbuffer, _addrwidth);
}
return false;
}

/*!
* @brief Write up to 4 bytes of data to the register location
* @param value Data to write
* @param numbytes How many bytes from 'value' to write
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
*/
bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) {
if (numbytes == 0) {
numbytes = _width;
}
if (numbytes > 4) {
return false;
}

for (int i=0; i<numbytes; i++) {
if (_bitorder == LSBFIRST) {
_buffer[i] = value & 0xFF;
} else {
_buffer[numbytes-i-1] = value & 0xFF;
}
value >>= 8;
}
return write(_buffer, numbytes);
}

/*!
* @brief Read data from the register location. This does not do any error checking!
* @return Returns 0xFFFFFFFF on failure, value otherwise
*/
uint32_t Adafruit_BusIO_Register::read(void) {
if (! read(_buffer, _width)) {
return -1;
}

uint32_t value = 0;

for (int i=0; i < _width; i++) {
value <<= 8;
if (_bitorder == LSBFIRST) {
value |= _buffer[_width-i-1];
} else {
value |= _buffer[i];
}
}

return value;
}


/*!
* @brief Read a buffer of data from the register location
* @param buffer Pointer to data to read into
* @param len Number of bytes to read
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
*/
bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)};

if (_i2cdevice) {
return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
}
if (_spidevice) {
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
addrbuffer[0] |= 0x80;
}
return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
}
return false;
}

/*!
* @brief Read 2 bytes of data from the register location
* @param value Pointer to uint16_t variable to read into
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
*/
bool Adafruit_BusIO_Register::read(uint16_t *value) {
if (! read(_buffer, 2)) {
return false;
}

if (_bitorder == LSBFIRST) {
*value = _buffer[1];
*value <<= 8;
*value |= _buffer[0];
} else {
*value = _buffer[0];
*value <<= 8;
*value |= _buffer[1];
}
return true;
}

/*!
* @brief Read 1 byte of data from the register location
* @param value Pointer to uint8_t variable to read into
* @return True on successful write (only really useful for I2C as SPI is uncheckable)
*/
bool Adafruit_BusIO_Register::read(uint8_t *value) {
if (! read(_buffer, 1)) {
return false;
}

*value = _buffer[0];
return true;
}

/*!
* @brief Pretty printer for this register
* @param s The Stream to print to, defaults to &Serial
*/
void Adafruit_BusIO_Register::print(Stream *s) {
uint32_t val = read();
s->print("0x"); s->print(val, HEX);
}

/*!
* @brief Pretty printer for this register
* @param s The Stream to print to, defaults to &Serial
*/
void Adafruit_BusIO_Register::println(Stream *s) {
print(s);
s->println();
}


/*!
* @brief Create a slice of the register that we can address without touching other bits
* @param reg The Adafruit_BusIO_Register which defines the bus/register
* @param bits The number of bits wide we are slicing
* @param shift The number of bits that our bit-slice is shifted from LSB
*/
Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) {
_register = reg;
_bits = bits;
_shift = shift;
}

/*!
* @brief Read 4 bytes of data from the register
* @return data The 4 bytes to read
*/
uint32_t Adafruit_BusIO_RegisterBits::read(void) {
uint32_t val = _register->read();
val >>= _shift;
return val & ((1 << (_bits)) - 1);
}


/*!
* @brief Write 4 bytes of data to the register
* @param data The 4 bytes to write
*/
void Adafruit_BusIO_RegisterBits::write(uint32_t data) {
uint32_t val = _register->read();

// mask off the data before writing
uint32_t mask = (1 << (_bits)) - 1;
data &= mask;

mask <<= _shift;
val &= ~mask; // remove the current data at that spot
val |= data << _shift; // and add in the new data

_register->write(val, _register->width());
}

/*!
* @brief The width of the register data, helpful for doing calculations
* @returns The data width used when initializing the register
*/
uint8_t Adafruit_BusIO_Register::width(void) { return _width; }
69 changes: 69 additions & 0 deletions lib/Adafruit_BusIO/Adafruit_BusIO_Register.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <Adafruit_I2CDevice.h>
#include <Adafruit_SPIDevice.h>
#include <Arduino.h>


#ifndef Adafruit_BusIO_Register_h
#define Adafruit_BusIO_Register_h

typedef enum _Adafruit_BusIO_SPIRegType {
ADDRBIT8_HIGH_TOREAD = 0,
} Adafruit_BusIO_SPIRegType;

/*!
* @brief The class which defines a device register (a location to read/write data from)
*/
class Adafruit_BusIO_Register {
public:
Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr,
uint8_t width=1, uint8_t bitorder=LSBFIRST,
uint8_t address_width=1);
Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr,
Adafruit_BusIO_SPIRegType type,
uint8_t width=1, uint8_t bitorder=LSBFIRST,
uint8_t address_width=1);

Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
Adafruit_SPIDevice *spidevice,
Adafruit_BusIO_SPIRegType type,
uint16_t reg_addr,
uint8_t width=1, uint8_t bitorder=LSBFIRST,
uint8_t address_width=1);

bool read(uint8_t *buffer, uint8_t len);
bool read(uint8_t *value);
bool read(uint16_t *value);
uint32_t read(void);
bool write(uint8_t *buffer, uint8_t len);
bool write(uint32_t value, uint8_t numbytes=0);

uint8_t width(void);

void print(Stream *s=&Serial);
void println(Stream *s=&Serial);

private:
Adafruit_I2CDevice *_i2cdevice;
Adafruit_SPIDevice *_spidevice;
Adafruit_BusIO_SPIRegType _spiregtype;
uint16_t _address;
uint8_t _width, _addrwidth, _bitorder;
uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read
};


/*!
* @brief The class which defines a slice of bits from within a device register (a location to read/write data from)
*/
class Adafruit_BusIO_RegisterBits {
public:
Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift);
void write(uint32_t value);
uint32_t read(void);
private:
Adafruit_BusIO_Register *_register;
uint8_t _bits, _shift;
};


#endif //BusIO_Register_h
Loading

0 comments on commit 2b798ff

Please sign in to comment.