Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions MS5607Driver/Inc/MS5607Driver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/** ********************************************************************************
* @file MS5607Driver.hpp
* @author Noah
* @date Nov 16, 2024
* @brief This driver gets pressure and temperature readings from the MS5607 barometers.
******************************************************************************** */
#ifndef SOARDRIVERS_MS5607DRIVER_INC_MS5607DRIVER_HPP_
#define SOARDRIVERS_MS5607DRIVER_INC_MS5607DRIVER_HPP_
/************************************ * INCLUDES ************************************/
#include "SystemDefines.hpp"
#include "cmsis_os.h"
/************************************ * MACROS AND DEFINES ************************************/
constexpr int TEMP_LOW = 2000;
constexpr int TEMP_VERY_LOW = -1500;
constexpr int CMD_SIZE = 1;
constexpr int CMD_TIMEOUT = 150;
/************************************ * TYPEDEFS ************************************/
struct MS5607_DATA_t{
int16_t temp;
uint32_t pressure;
};
/************************************ * CLASS DEFINITIONS ************************************/
/**
* @brief the driver for MS5607 barometers
* see datasheet here: https://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Data+Sheet%7FMS5607-02BA03%7FB%7Fpdf%7FEnglish%7FENG_DS_MS5607-02BA03_B.pdf%7FCAT-BLPS0035
*/
class MS5607_Driver{
public:
MS5607_Driver(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_):
hspi(hspi_), cs_gpio(cs_gpio_), cs_pin(cs_pin_){}

MS5607_DATA_t getSample();
private:

//constants
GPIO_TypeDef* cs_gpio;
uint16_t cs_pin;
SPI_HandleTypeDef* hspi;

uint16_t readCalibrationCoefficients(uint8_t PROM_READ_CMD);
uint32_t getTemperatureReading();
uint32_t getPressureReading();
void resetBarometer();
};

/************************************ * FUNCTION DECLARATIONS ************************************/
#endif /* EXAMPLE_TASK_HPP_ */
239 changes: 239 additions & 0 deletions MS5607Driver/MS5607Driver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/** ********************************************************************************
* @file MS5607Driver.cpp
* @author Noah
* @date Nov 16, 2024
* @brief This driver gets pressure and temperature readings from the MS5607 barometers.
******************************************************************************** */
/************************************ * INCLUDES ************************************/
#include "MS5607Driver.hpp"
/************************************ * PRIVATE MACROS AND DEFINES ************************************/
/************************************ * VARIABLES ************************************/
// Barometer Commands (should not be modified, non-const due to HAL and C++ strictness)
static uint8_t ADC_D1_512_CONV_CMD = 0x42;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason these are static? Can they not be constexpr?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HAL freaks out if they are const, although they should not be changed.

static uint8_t ADC_D2_512_CONV_CMD = 0x52;
static uint8_t ADC_READ_CMD = 0x00;
static uint8_t PROM_READ_SENS_CMD = 0xA2;
static uint8_t PROM_READ_OFF_CMD = 0xA4;
static uint8_t PROM_READ_TCS_CMD = 0xA6;
static uint8_t PROM_READ_TCO_CMD = 0xA8;
static uint8_t PROM_READ_TREF_CMD = 0xAA;
static uint8_t PROM_READ_TEMPSENS_CMD = 0xAC;
static uint8_t READ_BYTE_CMD = 0x00;
static uint8_t RESET_CMD = 0x1E;
/************************************ * FUNCTION DECLARATIONS ************************************/
/************************************ * FUNCTION DEFINITIONS ************************************/

/**
* @brief gets a single sample of barometer data
* @returns a barometer data structure consisting of a 'temp' and 'pressure' variable
*/
MS5607_DATA_t MS5607_Driver::getSample(){
/**
* Variable Descriptions from MS5607-02BA03 Data Sheet:
*
* C1 (SENSt1) - Pressure sensitivity
* C2 (OFFt1) - Pressure offset
* C3 (TCS) - Temperature coefficient of pressure sensitivity
* C4 (TCO) - Temperature coefficient of pressure offset
* C5 (Tref) - Reference temperature
* C6 (TEMPSENS) - Temperature coefficient of the temperature
*
* D1 - Digital pressure value
* D2 - Digital temperature value
*
* dT - Difference between actual and reference temperature
* dT = D2 - Tref = D2 - (C5 * 2^8)
* TEMP - Actual temperature (-40...85�C with 0.01�C resolution)
* TEMP = 20�C + (dT * TEMPSENS) = 2000 + (dT * C6)/2^23
* OFF - Offset at actual temperature
* OFF = OFFt1 + (TCO * dT) = (C2 * 2^17) + (C4 * dT)/2^6
* SENS - Sensitivity at actual temperature
* SENS = SENSt1 + (TCS * dT) = (C1 * 2^16) + (C3 * dT)/2^7
* P - Temperature compensated pressure (10...1200mbar with 0.01mbar resolution)
* P = (D1 * SENS) - OFF = ((D1 * SENS)/2^21 - OFF)/2^15
*/

// Variables
uint32_t pressureReading = 0; // Stores a 24 bit value
uint32_t temperatureReading = 0; // Stores a 24 bit value
MS5611_DATA_t data;

// Reset the barometer
resetBarometer();

// Read PROM for calibration coefficients
uint16_t c1Sens = ReadCalibrationCoefficients(PROM_READ_SENS_CMD);
uint16_t c2Off = ReadCalibrationCoefficients(PROM_READ_OFF_CMD);
uint16_t c3Tcs = ReadCalibrationCoefficients(PROM_READ_TCS_CMD);
uint16_t c4Tco = ReadCalibrationCoefficients(PROM_READ_TCO_CMD);
uint16_t c5Tref = ReadCalibrationCoefficients(PROM_READ_TREF_CMD);
uint16_t c6Tempsens = ReadCalibrationCoefficients(PROM_READ_TEMPSENS_CMD);

/**
* Repeatedly read digital pressure and temperature.
* Convert these values into their calibrated counterparts.
* Finally, update the data globally if the mutex is available.
*/
/* Read Digital Pressure (D1) ----------------------------------------*/
pressureReading = getPressureReading();

/* Read Digital Temperature (D2) -------------------------------------*/
temperatureReading = getTemperatureReading();

/* Calculate First-Order Temperature and Parameters ------------------*/

// Calibration coefficients need to be type cast to int64_t to avoid overflow during intermediate calculations
int32_t dT = temperatureReading - ((int32_t)c5Tref << 8);
int32_t temp = 2000 + ((dT * (int64_t)c6Tempsens) >> 23); // Divide this value by 100 to get degrees Celsius
int64_t off = ((int64_t)c2Off << 17) + ((dT * (int64_t)c4Tco) >> 6);
int64_t sens = ((int64_t)c1Sens << 16) + ((dT * (int64_t)c3Tcs) >> 7);

/* Calculate Second-Order Temperature and Pressure -------------------*/

if (temp < TEMP_LOW) // If the temperature is below 20C
{
int32_t t2 = ((int64_t)dT * dT) >> 31;
int64_t off2 = 61 * (((int64_t)(temp - 2000) * (temp - 2000)) >> 4);
int64_t sens2 = 2 * ((int64_t)(temp - 2000) * (temp - 2000));

if (temp < TEMP_VERY_LOW) // If the temperature is below -15�C
{
off2 = off2 + (15 * ((int64_t)(temp + 1500) * (temp + 1500)));
sens2 = sens2 + (8 * ((int64_t)(temp + 1500) * (temp + 1500)));
}

temp = temp - t2;
off = off - off2;
sens = sens - sens2;
}

int32_t p = (((pressureReading * sens) >> 21) - off) >> 15; // Divide this value by 100 to get millibars

/* Store Data --------------------------------------------------------*/
data.pressure = p;
data.temperature = temp;

return data;

// All equations provided by MS5607-02BA03 data sheet

// PRESSURE AND TEMPERATURE VALUES ARE STORED AT 100x VALUE TO MAINTAIN
// 2 DECIMAL POINTS OF PRECISION AS AN INTEGER!
// E.x. The value 1234 should be interpreted as 12.34
}

/**
* @brief This function reads and returns a 16-bit coefficient from the barometer.
* @param PROM_READ_CMD The command to send in order to read the desired
* coefficient. See the data sheet for the commands.
* @return The read coefficient.
*/
uint16_t MS5607_Driver::readCalibrationCoefficients(uint8_t PROM_READ_CMD)
{
uint8_t dataInBuffer;

HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET);

HAL_SPI_Transmit(hspi, &PROM_READ_CMD, CMD_SIZE, CMD_TIMEOUT);

// Read the first byte (bits 15-8)
HAL_SPI_TransmitReceive(hspi, &READ_BYTE_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
uint16_t coefficient = dataInBuffer << 8;

// Read the second byte (bits 7-0)
HAL_SPI_TransmitReceive(hspi, &READ_BYTE_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
coefficient += dataInBuffer;

HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_SET);

return coefficient;
}

/**
* @brief This function resets the barometer prior to sampling
*/
void MS5607_Driver::resetBarometer()
{
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(hspi, &RESET_CMD, CMD_SIZE, CMD_TIMEOUT);
osDelay(4); // 2.8ms reload after Reset command
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_SET);
}

/**
* @brief This function reads and returns a 32-bit pressure reading from the barometer (without converting it to a workable format).
* @return The read pressure
*/
uint32_t MS5607_Driver::getPressureReading()
{
uint32_t pressureReading = 0; // Stores a 24 bit value
uint8_t dataInBuffer;

// Tell the barometer to convert the pressure to a digital value with an over-sampling ratio of 512
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(hspi, &ADC_D1_512_CONV_CMD, CMD_SIZE, CMD_TIMEOUT);
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_SET);

osDelay(2); // 1.17ms max conversion time for an over-sampling ratio of 512

HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET);

HAL_SPI_Transmit(hspi, &ADC_READ_CMD, CMD_SIZE, CMD_TIMEOUT);

// Read the first byte (bits 23-16)
HAL_SPI_TransmitReceive(hspi, &READ_BYTE_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
pressureReading = dataInBuffer << 16;

// Read the second byte (bits 15-8)
HAL_SPI_TransmitReceive(hspi, &READ_BYTE_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
pressureReading += dataInBuffer << 8;

// Read the third byte (bits 7-0)
HAL_SPI_TransmitReceive(hspi, &READ_BYTE_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
pressureReading += dataInBuffer;

HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_SET);

return pressureReading;
}

/**
* @brief This function reads and returns a 32-bit temperature reading from the barometer (without converting it to a workable format).
* @return The read temperature
*/
uint32_t MS5607_Driver::getTemperatureReading()
{
uint32_t temperatureReading = 0; // Stores a 24 bit value
uint8_t dataInBuffer;

// Tell the barometer to convert the temperature to a digital value with an over-sampling ratio of 512
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(hspi, &ADC_D2_512_CONV_CMD, CMD_SIZE, CMD_TIMEOUT);
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_SET);

osDelay(2); // 1.17ms max conversion time for an over-sampling ratio of 512

HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET);

HAL_SPI_Transmit(hspi, &ADC_READ_CMD, CMD_SIZE, CMD_TIMEOUT);

// Read the first byte (bits 23-16)
HAL_SPI_TransmitReceive(hspi, &ADC_READ_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
temperatureReading = dataInBuffer << 16;

// Read the second byte (bits 15-8)
HAL_SPI_TransmitReceive(hspi, &ADC_READ_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
temperatureReading += dataInBuffer << 8;

// Read the third byte (bits 7-0)
HAL_SPI_TransmitReceive(hspi, &ADC_READ_CMD, &dataInBuffer, CMD_SIZE, CMD_TIMEOUT);
temperatureReading += dataInBuffer;

HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_SET);

return temperatureReading;

}



1 change: 1 addition & 0 deletions MS5607Driver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This driver gets pressure and temperature readings from the MS5607 barometers.
48 changes: 48 additions & 0 deletions MS5611Driver/Inc/MS5611Driver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/** ********************************************************************************
* @file MS5611Driver.hpp
* @author Noah
* @date Nov 9, 2024
* @brief This driver gets pressure and temperature readings from the MS5611 barometers.
******************************************************************************** */
#ifndef SOARDRIVERS_MS5611DRIVER_INC_MS5611DRIVER_HPP_
#define SOARDRIVERS_MS5611DRIVER_INC_MS5611DRIVER_HPP_
/************************************ * INCLUDES ************************************/
#include "SystemDefines.hpp"
#include "cmsis_os.h"
/************************************ * MACROS AND DEFINES ************************************/
constexpr int TEMP_LOW = 2000;
constexpr int TEMP_VERY_LOW = -1500;
constexpr int CMD_SIZE = 1;
constexpr int CMD_TIMEOUT = 150;
/************************************ * TYPEDEFS ************************************/
struct MS5611_DATA_t{
int16_t temp;
uint32_t pressure;
};
/************************************ * CLASS DEFINITIONS ************************************/
/**
* @brief the driver for MS5611 barometers
* see datasheet here: https://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Data+Sheet%7FMS5611-01BA03%7FB3%7Fpdf%7FEnglish%7FENG_DS_MS5611-01BA03_B3.pdf%7FCAT-BLPS0036
*/
class MS5611_Driver{
public:
MS5611_Driver(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_):
hspi(hspi_), cs_gpio(cs_gpio_), cs_pin(cs_pin_){}

MS5611_DATA_t getSample();

private:
// constants
GPIO_TypeDef* cs_gpio;
uint16_t cs_pin;
SPI_HandleTypeDef* hspi;

// helper functions
uint16_t readCalibrationCoefficients(uint8_t PROM_READ_CMD);
uint32_t getTemperatureReading();
uint32_t getPressureReading();
void resetBarometer();
};

/************************************ * FUNCTION DECLARATIONS ************************************/
#endif /* EXAMPLE_TASK_HPP_ */
Loading