implement ads1015 driver (#2458)

* first approximation of ads1015

* fix ads

* misc

* comment

Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
Matthew Kennedy 2021-03-14 16:02:42 -07:00 committed by GitHub
parent ef65c01a40
commit 9d7436c062
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 2 deletions

View File

@ -0,0 +1,65 @@
#include "ads1015.h"
#include "efilib.h"
constexpr uint8_t addr = 0x48;
#define ADS1015_CONV (0)
#define ADS1015_CONFIG (1)
#define ADS1015_LO_THRESH (2)
#define ADS1015_HI_THRESH (3)
bool Ads1015::init(brain_pin_e scl, brain_pin_e sda) {
m_i2c.init(scl, sda);
// ADS1015 has no ID register - so we read the Lo_thresh instead
uint16_t loThresh = readReg(ADS1015_LO_THRESH);
if (loThresh != 0x8000) {
return false;
}
m_hasInit = true;
return true;
}
void Ads1015::readChannels(float (&result)[4]) {
for (size_t i = 0; i < 4; i++) {
result[i] = readChannel(i);
}
}
float Ads1015::readChannel(uint8_t ch) {
// set the channel
// set to +-6.144v full scale, fastest sampling, manual conversion start
writeReg(ADS1015_CONFIG, 0xC1E0 | ch << 12);
// Wait for conversion to complete
// Bit is cleared while conversion is ongoing, set when done
while ((readReg(ADS1015_CONFIG) & 0x8000) == 0) ;
// Read the result
int16_t result = readReg(ADS1015_CONV);
// Result is 12 bits left aligned, so right align the result
result = result >> 4;
// 2048 counts = positive 6.144 volts
constexpr float ratio = 6.144f / 2048;
return result * ratio;
}
void Ads1015::writeReg(uint8_t reg, uint16_t data) {
uint8_t packet[3];
packet[0] = reg;
packet[1] = data >> 8;
packet[2] = data & 0xFF;
m_i2c.write(addr, packet, 3);
}
uint16_t Ads1015::readReg(uint8_t reg) {
uint16_t res;
m_i2c.write(addr, &reg, 1);
m_i2c.read(addr, reinterpret_cast<uint8_t*>(&res), 2);
return SWAP_UINT16(res);
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "i2c_bb.h"
class Ads1015 {
public:
bool init(brain_pin_e scl, brain_pin_e sda);
void readChannels(float (&result)[4]);
private:
float readChannel(uint8_t ch);
void writeReg(uint8_t reg, uint16_t data);
uint16_t readReg(uint8_t reg);
bool m_hasInit = false;
BitbangI2c m_i2c;
};

View File

@ -31,6 +31,7 @@ HW_LAYER_EMS_CPP = $(HW_LAYER_EGT_CPP) \
$(PROJECT_DIR)/hw_layer/lcd/lcd_HD44780.cpp \
$(PROJECT_DIR)/hw_layer/adc/adc_inputs.cpp \
$(PROJECT_DIR)/hw_layer/adc/adc_subscription.cpp \
$(PROJECT_DIR)/hw_layer/adc/ads1015.cpp \
$(PROJECT_DIR)/hw_layer/sensors/hip9011.cpp \
$(PROJECT_DIR)/hw_layer/sensors/hip9011_logic.cpp \
$(PROJECT_DIR)/hw_layer/mc33816.cpp \

View File

@ -188,8 +188,11 @@ void BitbangI2c::writeRead(uint8_t addr, const uint8_t* writeData, size_t writeS
for (size_t i = 0; i < writeSize; i++) {
writeByte(writeData[i]);
}
// Send a repeated start bit to indicate transition to read
read(addr, readData, readSize);
}
void BitbangI2c::read(uint8_t addr, uint8_t* readData, size_t readSize) {
start();
// Address + read

View File

@ -23,6 +23,8 @@ public:
// Write a sequence of bytes to the specified device
void write(uint8_t addr, const uint8_t* data, size_t size);
// Read a sequence of bytes from the device
void read(uint8_t addr, uint8_t* data, size_t size);
// Write some bytes then read some bytes back after a repeated start bit
void writeRead(uint8_t addr, const uint8_t* writeData, size_t writeSize, uint8_t* readData, size_t readSize);