Finish writing the driver; Still needs testing and debugging

This commit is contained in:
Theodor Teslia 2023-02-27 16:42:33 +01:00
parent 21e4d4a4e2
commit 71b9753860
4 changed files with 156 additions and 3 deletions

View File

@ -1,5 +1,11 @@
# Driver for the MS5607 pressure sensor # Driver for the MS5607 pressure sensor
# Usage
1. The driver has two main methods: ```int32_t getPressure()``` and ```int32_t getTemperature()```
2. The constructor takes an SpiDevice pointer and an instance from the OsrLevel enum
3. The OsrLevel enum stores the possible values for the OSR (how fine the sensor measures or sth.)
4. When calling ```getPressure()```, the temperature gets requested from the sensor as well -> May be too slow
## TODO ## TODO
1. Understand the Datasheet (RIP) 1. Debug
2. Write the fucking driver 2. Check whether more accurate temp measurements are necessary

View File

@ -2,6 +2,8 @@
#define STA_SENSORS_MS5607_HPP #define STA_SENSORS_MS5607_HPP
#include<sta/spi/device.hpp> #include<sta/spi/device.hpp>
#include<sta/endian.hpp>
#include<sta/stm32/delay.hpp>
namespace sta { namespace sta {
class MS5607 { class MS5607 {
@ -14,19 +16,40 @@ namespace sta {
_4096 = 4 _4096 = 4
}; };
MS5607(SpiDevice* device, OsrLevel osr);
int32_t getPressure();
int32_t getTemperature();
void changeOsrLevel(OsrLevel newOsr) { this->osr_ = newOsr; }
private: private:
SpiDevice* device_; SpiDevice* device_;
OsrLevel osr_;
uint16_t sens, off, tcs, tco, t_ref, tempsens; uint16_t sens, off, tcs, tco, t_ref, tempsens;
enum Operations { enum Operations {
RESET = 0x1E, RESET = 0x1E,
READ_PROM = 0xA0, READ_PROM = 0xA2,
D1_CONVERSION = 0x40, D1_CONVERSION = 0x40,
D2_CONVERSION = 0x50, D2_CONVERSION = 0x50,
ADC_RESULT = 0x00 ADC_RESULT = 0x00
}; };
uint32_t readPressure();
uint32_t readTemp();
int32_t calculatePressure(uint32_t d1, int32_t dT);
int32_t calculateTemperature(uint32_t d2);
void reset();
void readPROM();
// Take first bytes from buffer, swap them and store those in uint16_t
static uint16_t uint_8BufferTouint16_t(uint8_t* buffer);
const char RESET_DELAY = 2800; // in uS
const char ADC_DELAY = 8220; // in uS; not sure if thats correct since the datasheet doesn't say anything explicitly
}; };
} }

6
include/sta/config.hpp Normal file
View File

@ -0,0 +1,6 @@
// Needed for sta/endian.hpp
#define STA_MCU_LITTLE_ENDIAN
// Needed for sta/stm32/delay.hpp
#define STA_PLATFORM_STM32
#define STA_STM32_DELAY_US_TIM

View File

@ -0,0 +1,118 @@
#include "sta/MS5607.hpp"
namespace sta {
MS5607::MS5607(SpiDevice* device, OsrLevel level) {
this->device_ = device;
this->osr_ = level;
this->reset();
this->readPROM();
}
int32_t MS5607::getPressure() {
uint32_t d1 = readPressure();
// Since pressure is temp-dependant, temperature needs to be polled
// Could be too costly timewise, since 8ms is needed for the ADC
// May need future optimisation
uint32_t d2 = readTemp();
int32_t dT = d2 - (this->t_ref << 8);
return calculatePressure(d1, dT);
}
uint32_t MS5607::readPressure() {
this->device_->beginTransmission();
this->device_->transfer(MS5607::Operations::D1_CONVERSION + 2*this->osr_);
delayUs(MS5607::ADC_DELAY);
uint8_t d1Arr[3];
this->device_->receive(d1Arr, 3);
this->device_->endTransmission();
uint32_t res = 0;
res |= d1Arr[0] | d1Arr[1] << 8 | d1Arr[2] << 16;
return res;
}
int32_t MS5607::calculatePressure(uint32_t d1, int32_t dT) {
int64_t offset = (this->off << 17) + ((this->tco * dT) >> 6);
int64_t sensitivity = (this->sens << 16) + ((this->tcs * dT) >> 7);
int32_t pres = (((d1 * sensitivity) >> 21) - offset) >> 15;
return pres;
}
int32_t MS5607::getTemperature() {
uint32_t d2 = readTemp();
calculateTemperature(d2);
}
uint32_t MS5607::readTemp() {
this->device_->beginTransmission();
this->device_->transfer(MS5607::Operations::D2_CONVERSION + 2*this->osr_);
delayUs(MS5607::ADC_DELAY);
uint8_t d2Arr[3];
this->device_->receive(d2Arr, 3);
this->device_->endTransmission();
uint32_t res = 0;
res |= d2Arr[0] | d2Arr[1] << 8 | d2Arr[2] << 16;
}
int32_t MS5607::calculateTemperature(uint32_t d2) {
int32_t dT = d2 - (this->t_ref << 8);
int32_t temp = 2000 + ((dT * this->tempsens) >> 23);
// Further calculations for low (<20) and very low (<(-15)) could be possible
// But I don't know whether they are necessary
return temp;
}
void MS5607::reset() {
this->device_->beginTransmission();
this->device_->transfer(MS5607::Operations::RESET);
delayUs(MS5607::RESET_DELAY);
this->device_->endTransmission();
}
void MS5607::readPROM() {
this->device_->beginTransmission();
this->device_->transfer(Operations::READ_PROM);
uint8_t sensArr[2];
this->device_->receive(sensArr, 2);
this->sens = uint_8BufferTouint16_t(sensArr);
this->device_->transfer(Operations::READ_PROM+2);
uint8_t offArr[2];
this->device_->receive(offArr, 2);
this->off = uint_8BufferTouint16_t(offArr);
this->device_->transfer(Operations::READ_PROM+4);
uint8_t tcsArr[2];
this->device_->receive(tcsArr, 2);
this->sens = uint_8BufferTouint16_t(sensArr);
this->device_->transfer(Operations::READ_PROM+6);
uint8_t tcoArr[2];
this->device_->receive(tcoArr, 2);
this->tco = uint_8BufferTouint16_t(tcoArr);
this->device_->transfer(Operations::READ_PROM+8);
uint8_t t_refArr[2];
this->device_->receive(t_refArr, 2);
this->t_ref = uint_8BufferTouint16_t(t_refArr);
this->device_->transfer(Operations::READ_PROM+0xA);
uint8_t tempsensArr[2];
this->device_->receive(tempsensArr, 2);
this->tempsens = uint_8BufferTouint16_t(tempsensArr);
this->device_->endTransmission();
}
uint16_t MS5607::uint_8BufferTouint16_t(uint8_t* buffer) {
return buffer[0] | (buffer[1] << 8);
}
}