From 96647472a20a363c08a4517b8e11d90eade00b91 Mon Sep 17 00:00:00 2001 From: Noah Vickerson Date: Sat, 16 Nov 2024 13:21:29 -0700 Subject: [PATCH 1/4] initial implementation of barometer drivers --- MS5607Driver/Inc/MS5607Driver.hpp | 41 ++++++ MS5607Driver/MS5607Driver.cpp | 226 ++++++++++++++++++++++++++++++ MS5607Driver/README.md | 0 MS5611Driver/Inc/MS5611Driver.hpp | 41 ++++++ MS5611Driver/MS5611Driver.cpp | 226 ++++++++++++++++++++++++++++++ MS5611Driver/README.md | 1 + 6 files changed, 535 insertions(+) create mode 100644 MS5607Driver/Inc/MS5607Driver.hpp create mode 100644 MS5607Driver/MS5607Driver.cpp create mode 100644 MS5607Driver/README.md create mode 100644 MS5611Driver/Inc/MS5611Driver.hpp create mode 100644 MS5611Driver/MS5611Driver.cpp create mode 100644 MS5611Driver/README.md diff --git a/MS5607Driver/Inc/MS5607Driver.hpp b/MS5607Driver/Inc/MS5607Driver.hpp new file mode 100644 index 0000000..b9a3d44 --- /dev/null +++ b/MS5607Driver/Inc/MS5607Driver.hpp @@ -0,0 +1,41 @@ +/** ******************************************************************************** + * @file MS5607Driver.hpp + * @author Noah + * @date Nov 16, 2024 + * @brief + ******************************************************************************** */ +#ifndef SOARDRIVERS_MS5607DRIVER_INC_MS5607DRIVER_HPP_ +#define SOARDRIVERS_MS5607DRIVER_INC_MS5607DRIVER_HPP_ +/************************************ * INCLUDES ************************************/ +#include "SystemDefines.hpp" +#include "cmsis_os.h" +/************************************ * MACROS AND DEFINES ************************************/ +/************************************ * TYPEDEFS ************************************/ +typedef uint8_t MS5607_REGISTER_t; + +struct MS5607_DATA_t{ + int16_t temp; + uint32_t pressure; +}; +/************************************ * CLASS DEFINITIONS ************************************/ +class MS5607_Driver{ +public: + MS5607_Driver(); + void Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_); + + MS5607_DATA_t getSample(); +private: + // variables + bool initialized = false; + + //constants + GPIO_TypeDef* cs_gpio; + uint16_t cs_pin; + SPI_HandleTypeDef* hspi; + + bool SetRegister(MS5607_REGISTER_t reg, uint8_t val); + uint16_t ReadCalibrationCoefficients(uint8_t PROM_READ_CMD); +}; + +/************************************ * FUNCTION DECLARATIONS ************************************/ +#endif /* EXAMPLE_TASK_HPP_ */ diff --git a/MS5607Driver/MS5607Driver.cpp b/MS5607Driver/MS5607Driver.cpp new file mode 100644 index 0000000..5408c3b --- /dev/null +++ b/MS5607Driver/MS5607Driver.cpp @@ -0,0 +1,226 @@ +/** ******************************************************************************** + * @file MS5607Driver.cpp + * @author Noah + * @date Nov 16, 2024 + * @brief + ******************************************************************************** */ +/************************************ * INCLUDES ************************************/ +#include "MS5607Driver.hpp" +/************************************ * PRIVATE MACROS AND DEFINES ************************************/ +/************************************ * VARIABLES ************************************/ +constexpr int TEMP_LOW = 2000; +constexpr int TEMP_VERY_LOW = -1500; +constexpr int CMD_SIZE = 1; +constexpr int CMD_TIMEOUT = 150; + +// Barometer Commands (should not be modified, non-const due to HAL and C++ strictness) +static uint8_t ADC_D1_512_CONV_CMD = 0x42; +static uint8_t ADC_D2_512_CONV_CMD = 0x52; +static uint8_t ADC_READ_CMD = 0x00; +static uint8_t PROM_READ_SENS_CMD = 0xA2; // make sure these are the correct commands vv +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 ************************************/ +MS5611_Driver::MS5607_Driver(){ + +} + +void MS5607_Driver::Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_){ + if(!initialized){ + initialized = true; + + cs_gpio = cs_gpio_; + cs_pin = cs_pin_; + hspi = hspi_; + }else{ + SOAR_PRINT("Cannot initialize barometer driver twice"); + } +} + +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 + */ + assert(initialized); + + // Variables + uint32_t pressureReading = 0; // Stores a 24 bit value + uint32_t temperatureReading = 0; // Stores a 24 bit value + uint8_t dataInBuffer; + MS5611_DATA_t data; + + // Reset the barometer + 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); + + // 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) ----------------------------------------*/ + + // 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); + + /* Read Digital Temperature (D2) -------------------------------------*/ + + // 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); + + /* 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 20�C + { + 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) +{ + assert(initialized); + + 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; +} + + + + + diff --git a/MS5607Driver/README.md b/MS5607Driver/README.md new file mode 100644 index 0000000..e69de29 diff --git a/MS5611Driver/Inc/MS5611Driver.hpp b/MS5611Driver/Inc/MS5611Driver.hpp new file mode 100644 index 0000000..912e7bd --- /dev/null +++ b/MS5611Driver/Inc/MS5611Driver.hpp @@ -0,0 +1,41 @@ +/** ******************************************************************************** + * @file MS5611Driver.hpp + * @author Noah + * @date Nov 9, 2024 + * @brief + ******************************************************************************** */ +#ifndef SOARDRIVERS_MS5611DRIVER_INC_MS5611DRIVER_HPP_ +#define SOARDRIVERS_MS5611DRIVER_INC_MS5611DRIVER_HPP_ +/************************************ * INCLUDES ************************************/ +#include "SystemDefines.hpp" +#include "cmsis_os.h" +/************************************ * MACROS AND DEFINES ************************************/ +/************************************ * TYPEDEFS ************************************/ +typedef uint8_t MS5611_REGISTER_t; + +struct MS5611_DATA_t{ + int16_t temp; + uint32_t pressure; +}; +/************************************ * CLASS DEFINITIONS ************************************/ +class MS5611_Driver{ +public: + MS5611_Driver(); + void Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_); + + MS5611_DATA_t getSample(); +private: + // variables + bool initialized = false; + + //constants + GPIO_TypeDef* cs_gpio; + uint16_t cs_pin; + SPI_HandleTypeDef* hspi; + + bool SetRegister(MS5611_REGISTER_t reg, uint8_t val); + uint16_t ReadCalibrationCoefficients(uint8_t PROM_READ_CMD); +}; + +/************************************ * FUNCTION DECLARATIONS ************************************/ +#endif /* EXAMPLE_TASK_HPP_ */ diff --git a/MS5611Driver/MS5611Driver.cpp b/MS5611Driver/MS5611Driver.cpp new file mode 100644 index 0000000..e960fd2 --- /dev/null +++ b/MS5611Driver/MS5611Driver.cpp @@ -0,0 +1,226 @@ +/** ******************************************************************************** + * @file MS5611Driver.cpp + * @author root + * @date Nov 9, 2024 + * @brief + ******************************************************************************** */ +/************************************ * INCLUDES ************************************/ +#include "MS5611Driver.hpp" +/************************************ * PRIVATE MACROS AND DEFINES ************************************/ +/************************************ * VARIABLES ************************************/ +constexpr int TEMP_LOW = 2000; +constexpr int TEMP_VERY_LOW = -1500; +constexpr int CMD_SIZE = 1; +constexpr int CMD_TIMEOUT = 150; + +// Barometer Commands (should not be modified, non-const due to HAL and C++ strictness) +static uint8_t ADC_D1_512_CONV_CMD = 0x42; +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 ************************************/ +MS5611_Driver::MS5611_Driver(){ + +} + +void MS5611_Driver::Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_){ + if(!initialized){ + initialized = true; + + cs_gpio = cs_gpio_; + cs_pin = cs_pin_; + hspi = hspi_; + }else{ + SOAR_PRINT("Cannot initialize barometer driver twice"); + } +} + +MS5611_DATA_t MS5611_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 + */ + assert(initialized); + + // Variables + uint32_t pressureReading = 0; // Stores a 24 bit value + uint32_t temperatureReading = 0; // Stores a 24 bit value + uint8_t dataInBuffer; + MS5611_DATA_t data; + + // Reset the barometer + 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); + + // 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) ----------------------------------------*/ + + // 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); + + /* Read Digital Temperature (D2) -------------------------------------*/ + + // 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); + + /* 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 << 16) + ((dT * (int64_t)c4Tco) >> 7); + int64_t sens = ((int64_t)c1Sens << 15) + ((dT * (int64_t)c3Tcs) >> 8); + + /* Calculate Second-Order Temperature and Pressure -------------------*/ + + if (temp < TEMP_LOW) // If the temperature is below 20�C + { + int32_t t2 = ((int64_t)dT * dT) >> 31; + int64_t off2 = 5 * (((int64_t)(temp - 2000) * (temp - 2000)) >> 1); + int64_t sens2 = 5 * (((int64_t)(temp - 2000) * (temp - 2000)) >> 2); + + if (temp < TEMP_VERY_LOW) // If the temperature is below -15�C + { + off2 = off2 + (7 * ((int64_t)(temp + 1500) * (temp + 1500))); + sens2 = sens2 + ((11 * ((int64_t)(temp + 1500) * (temp + 1500)) >> 1)); + } + + 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 MS5611_Driver::ReadCalibrationCoefficients(uint8_t PROM_READ_CMD) +{ + assert(initialized); + + 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; +} + + + + + diff --git a/MS5611Driver/README.md b/MS5611Driver/README.md new file mode 100644 index 0000000..4260d84 --- /dev/null +++ b/MS5611Driver/README.md @@ -0,0 +1 @@ +see the readme for the MS607 driver \ No newline at end of file From 4c20720b7d4c74c4f6e82e4c50015b0ba98d52bc Mon Sep 17 00:00:00 2001 From: Noah Vickerson Date: Sat, 16 Nov 2024 13:37:59 -0700 Subject: [PATCH 2/4] moved init into constructor --- MS5607Driver/Inc/MS5607Driver.hpp | 12 +++++++----- MS5607Driver/MS5607Driver.cpp | 21 +++++---------------- MS5611Driver/Inc/MS5611Driver.hpp | 13 +++++++------ MS5611Driver/MS5611Driver.cpp | 23 +++++------------------ 4 files changed, 24 insertions(+), 45 deletions(-) diff --git a/MS5607Driver/Inc/MS5607Driver.hpp b/MS5607Driver/Inc/MS5607Driver.hpp index b9a3d44..0885dce 100644 --- a/MS5607Driver/Inc/MS5607Driver.hpp +++ b/MS5607Driver/Inc/MS5607Driver.hpp @@ -2,7 +2,7 @@ * @file MS5607Driver.hpp * @author Noah * @date Nov 16, 2024 - * @brief + * @brief This driver gets pressure and temperature readings from the MS5607 barometers. ******************************************************************************** */ #ifndef SOARDRIVERS_MS5607DRIVER_INC_MS5607DRIVER_HPP_ #define SOARDRIVERS_MS5607DRIVER_INC_MS5607DRIVER_HPP_ @@ -18,15 +18,17 @@ struct MS5607_DATA_t{ 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(); - void Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_); + 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: - // variables - bool initialized = false; //constants GPIO_TypeDef* cs_gpio; diff --git a/MS5607Driver/MS5607Driver.cpp b/MS5607Driver/MS5607Driver.cpp index 5408c3b..002a92b 100644 --- a/MS5607Driver/MS5607Driver.cpp +++ b/MS5607Driver/MS5607Driver.cpp @@ -2,7 +2,7 @@ * @file MS5607Driver.cpp * @author Noah * @date Nov 16, 2024 - * @brief + * @brief This driver gets pressure and temperature readings from the MS5607 barometers. ******************************************************************************** */ /************************************ * INCLUDES ************************************/ #include "MS5607Driver.hpp" @@ -27,22 +27,11 @@ static uint8_t READ_BYTE_CMD = 0x00; static uint8_t RESET_CMD = 0x1E; /************************************ * FUNCTION DECLARATIONS ************************************/ /************************************ * FUNCTION DEFINITIONS ************************************/ -MS5611_Driver::MS5607_Driver(){ - -} - -void MS5607_Driver::Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_){ - if(!initialized){ - initialized = true; - - cs_gpio = cs_gpio_; - cs_pin = cs_pin_; - hspi = hspi_; - }else{ - SOAR_PRINT("Cannot initialize barometer driver twice"); - } -} +/** + * @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: diff --git a/MS5611Driver/Inc/MS5611Driver.hpp b/MS5611Driver/Inc/MS5611Driver.hpp index 912e7bd..957cebb 100644 --- a/MS5611Driver/Inc/MS5611Driver.hpp +++ b/MS5611Driver/Inc/MS5611Driver.hpp @@ -2,7 +2,7 @@ * @file MS5611Driver.hpp * @author Noah * @date Nov 9, 2024 - * @brief + * @brief This driver gets pressure and temperature readings from the MS5611 barometers. ******************************************************************************** */ #ifndef SOARDRIVERS_MS5611DRIVER_INC_MS5611DRIVER_HPP_ #define SOARDRIVERS_MS5611DRIVER_INC_MS5611DRIVER_HPP_ @@ -18,16 +18,17 @@ struct MS5611_DATA_t{ 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(); - void Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_); + 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: - // variables - bool initialized = false; - //constants GPIO_TypeDef* cs_gpio; uint16_t cs_pin; diff --git a/MS5611Driver/MS5611Driver.cpp b/MS5611Driver/MS5611Driver.cpp index e960fd2..3deb77a 100644 --- a/MS5611Driver/MS5611Driver.cpp +++ b/MS5611Driver/MS5611Driver.cpp @@ -2,7 +2,7 @@ * @file MS5611Driver.cpp * @author root * @date Nov 9, 2024 - * @brief + * @brief This driver gets pressure and temperature readings from the MS5611 barometers. ******************************************************************************** */ /************************************ * INCLUDES ************************************/ #include "MS5611Driver.hpp" @@ -27,22 +27,11 @@ static uint8_t READ_BYTE_CMD = 0x00; static uint8_t RESET_CMD = 0x1E; /************************************ * FUNCTION DECLARATIONS ************************************/ /************************************ * FUNCTION DEFINITIONS ************************************/ -MS5611_Driver::MS5611_Driver(){ - -} - -void MS5611_Driver::Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_){ - if(!initialized){ - initialized = true; - - cs_gpio = cs_gpio_; - cs_pin = cs_pin_; - hspi = hspi_; - }else{ - SOAR_PRINT("Cannot initialize barometer driver twice"); - } -} +/** + * @brief gets a single sample of barometer data + * @returns a barometer data structure consisting of a 'temp' and 'pressure' variable + */ MS5611_DATA_t MS5611_Driver::getSample(){ /** * Variable Descriptions from MS5607-02BA03 Data Sheet: @@ -68,7 +57,6 @@ MS5611_DATA_t MS5611_Driver::getSample(){ * P - Temperature compensated pressure (10...1200mbar with 0.01mbar resolution) * P = (D1 * SENS) - OFF = ((D1 * SENS)/2^21 - OFF)/2^15 */ - assert(initialized); // Variables uint32_t pressureReading = 0; // Stores a 24 bit value @@ -199,7 +187,6 @@ MS5611_DATA_t MS5611_Driver::getSample(){ */ uint16_t MS5611_Driver::ReadCalibrationCoefficients(uint8_t PROM_READ_CMD) { - assert(initialized); uint8_t dataInBuffer; From 80d5420f2b78e00c737880274d04a902ee2fd452 Mon Sep 17 00:00:00 2001 From: Noah Vickerson Date: Mon, 18 Nov 2024 15:19:04 -0700 Subject: [PATCH 3/4] fixed a typo --- MS5607Driver/Inc/MS5607Driver.hpp | 2 -- MS5607Driver/MS5607Driver.cpp | 3 --- MS5607Driver/README.md | 1 + MS5611Driver/Inc/MS5611Driver.hpp | 6 +++--- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/MS5607Driver/Inc/MS5607Driver.hpp b/MS5607Driver/Inc/MS5607Driver.hpp index 0885dce..aad1367 100644 --- a/MS5607Driver/Inc/MS5607Driver.hpp +++ b/MS5607Driver/Inc/MS5607Driver.hpp @@ -11,8 +11,6 @@ #include "cmsis_os.h" /************************************ * MACROS AND DEFINES ************************************/ /************************************ * TYPEDEFS ************************************/ -typedef uint8_t MS5607_REGISTER_t; - struct MS5607_DATA_t{ int16_t temp; uint32_t pressure; diff --git a/MS5607Driver/MS5607Driver.cpp b/MS5607Driver/MS5607Driver.cpp index 002a92b..b3b1ab4 100644 --- a/MS5607Driver/MS5607Driver.cpp +++ b/MS5607Driver/MS5607Driver.cpp @@ -57,7 +57,6 @@ MS5607_DATA_t MS5607_Driver::getSample(){ * P - Temperature compensated pressure (10...1200mbar with 0.01mbar resolution) * P = (D1 * SENS) - OFF = ((D1 * SENS)/2^21 - OFF)/2^15 */ - assert(initialized); // Variables uint32_t pressureReading = 0; // Stores a 24 bit value @@ -188,8 +187,6 @@ MS5607_DATA_t MS5607_Driver::getSample(){ */ uint16_t MS5607_Driver::ReadCalibrationCoefficients(uint8_t PROM_READ_CMD) { - assert(initialized); - uint8_t dataInBuffer; HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET); diff --git a/MS5607Driver/README.md b/MS5607Driver/README.md index e69de29..2691964 100644 --- a/MS5607Driver/README.md +++ b/MS5607Driver/README.md @@ -0,0 +1 @@ +This driver gets pressure and temperature readings from the MS5607 barometers. diff --git a/MS5611Driver/Inc/MS5611Driver.hpp b/MS5611Driver/Inc/MS5611Driver.hpp index 957cebb..35edcdc 100644 --- a/MS5611Driver/Inc/MS5611Driver.hpp +++ b/MS5611Driver/Inc/MS5611Driver.hpp @@ -11,8 +11,6 @@ #include "cmsis_os.h" /************************************ * MACROS AND DEFINES ************************************/ /************************************ * TYPEDEFS ************************************/ -typedef uint8_t MS5611_REGISTER_t; - struct MS5611_DATA_t{ int16_t temp; uint32_t pressure; @@ -28,12 +26,14 @@ class MS5611_Driver{ hspi(hspi_), cs_gpio(cs_gpio_), cs_pin(cs_pin_){} MS5611_DATA_t getSample(); + private: - //constants + // constants GPIO_TypeDef* cs_gpio; uint16_t cs_pin; SPI_HandleTypeDef* hspi; + // helper functions bool SetRegister(MS5611_REGISTER_t reg, uint8_t val); uint16_t ReadCalibrationCoefficients(uint8_t PROM_READ_CMD); }; From 7cac9c18fdaa133667ac5c2d1d3f92fe81e69962 Mon Sep 17 00:00:00 2001 From: Noah Vickerson Date: Sat, 4 Jan 2025 11:14:25 -0700 Subject: [PATCH 4/4] changed naming conventions to fit with c++, improved readability of sample function --- MS5607Driver/Inc/MS5607Driver.hpp | 10 +- MS5607Driver/MS5607Driver.cpp | 155 ++++++++++++++++++------------ MS5611Driver/Inc/MS5611Driver.hpp | 10 +- MS5611Driver/MS5611Driver.cpp | 149 ++++++++++++++++------------ 4 files changed, 195 insertions(+), 129 deletions(-) diff --git a/MS5607Driver/Inc/MS5607Driver.hpp b/MS5607Driver/Inc/MS5607Driver.hpp index aad1367..b297267 100644 --- a/MS5607Driver/Inc/MS5607Driver.hpp +++ b/MS5607Driver/Inc/MS5607Driver.hpp @@ -10,6 +10,10 @@ #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; @@ -33,8 +37,10 @@ class MS5607_Driver{ uint16_t cs_pin; SPI_HandleTypeDef* hspi; - bool SetRegister(MS5607_REGISTER_t reg, uint8_t val); - uint16_t ReadCalibrationCoefficients(uint8_t PROM_READ_CMD); + uint16_t readCalibrationCoefficients(uint8_t PROM_READ_CMD); + uint32_t getTemperatureReading(); + uint32_t getPressureReading(); + void resetBarometer(); }; /************************************ * FUNCTION DECLARATIONS ************************************/ diff --git a/MS5607Driver/MS5607Driver.cpp b/MS5607Driver/MS5607Driver.cpp index b3b1ab4..c6a121b 100644 --- a/MS5607Driver/MS5607Driver.cpp +++ b/MS5607Driver/MS5607Driver.cpp @@ -8,21 +8,16 @@ #include "MS5607Driver.hpp" /************************************ * PRIVATE MACROS AND DEFINES ************************************/ /************************************ * VARIABLES ************************************/ -constexpr int TEMP_LOW = 2000; -constexpr int TEMP_VERY_LOW = -1500; -constexpr int CMD_SIZE = 1; -constexpr int CMD_TIMEOUT = 150; - // Barometer Commands (should not be modified, non-const due to HAL and C++ strictness) static uint8_t ADC_D1_512_CONV_CMD = 0x42; static uint8_t ADC_D2_512_CONV_CMD = 0x52; static uint8_t ADC_READ_CMD = 0x00; -static uint8_t PROM_READ_SENS_CMD = 0xA2; // make sure these are the correct commands vv +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 PROM_READ_TEMPSENS_CMD = 0xAC; static uint8_t READ_BYTE_CMD = 0x00; static uint8_t RESET_CMD = 0x1E; /************************************ * FUNCTION DECLARATIONS ************************************/ @@ -61,14 +56,10 @@ MS5607_DATA_t MS5607_Driver::getSample(){ // Variables uint32_t pressureReading = 0; // Stores a 24 bit value uint32_t temperatureReading = 0; // Stores a 24 bit value - uint8_t dataInBuffer; MS5611_DATA_t data; // Reset the barometer - 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); + resetBarometer(); // Read PROM for calibration coefficients uint16_t c1Sens = ReadCalibrationCoefficients(PROM_READ_SENS_CMD); @@ -84,58 +75,10 @@ MS5607_DATA_t MS5607_Driver::getSample(){ * Finally, update the data globally if the mutex is available. */ /* Read Digital Pressure (D1) ----------------------------------------*/ - - // 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); + pressureReading = getPressureReading(); /* Read Digital Temperature (D2) -------------------------------------*/ - - // 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); + temperatureReading = getTemperatureReading(); /* Calculate First-Order Temperature and Parameters ------------------*/ @@ -147,7 +90,7 @@ MS5607_DATA_t MS5607_Driver::getSample(){ /* Calculate Second-Order Temperature and Pressure -------------------*/ - if (temp < TEMP_LOW) // If the temperature is below 20�C + 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); @@ -185,7 +128,7 @@ MS5607_DATA_t MS5607_Driver::getSample(){ * coefficient. See the data sheet for the commands. * @return The read coefficient. */ -uint16_t MS5607_Driver::ReadCalibrationCoefficients(uint8_t PROM_READ_CMD) +uint16_t MS5607_Driver::readCalibrationCoefficients(uint8_t PROM_READ_CMD) { uint8_t dataInBuffer; @@ -206,7 +149,91 @@ uint16_t MS5607_Driver::ReadCalibrationCoefficients(uint8_t PROM_READ_CMD) 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; + +} diff --git a/MS5611Driver/Inc/MS5611Driver.hpp b/MS5611Driver/Inc/MS5611Driver.hpp index 35edcdc..2840bbc 100644 --- a/MS5611Driver/Inc/MS5611Driver.hpp +++ b/MS5611Driver/Inc/MS5611Driver.hpp @@ -10,6 +10,10 @@ #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; @@ -34,8 +38,10 @@ class MS5611_Driver{ SPI_HandleTypeDef* hspi; // helper functions - bool SetRegister(MS5611_REGISTER_t reg, uint8_t val); - uint16_t ReadCalibrationCoefficients(uint8_t PROM_READ_CMD); + uint16_t readCalibrationCoefficients(uint8_t PROM_READ_CMD); + uint32_t getTemperatureReading(); + uint32_t getPressureReading(); + void resetBarometer(); }; /************************************ * FUNCTION DECLARATIONS ************************************/ diff --git a/MS5611Driver/MS5611Driver.cpp b/MS5611Driver/MS5611Driver.cpp index 3deb77a..dcba3a6 100644 --- a/MS5611Driver/MS5611Driver.cpp +++ b/MS5611Driver/MS5611Driver.cpp @@ -8,11 +8,6 @@ #include "MS5611Driver.hpp" /************************************ * PRIVATE MACROS AND DEFINES ************************************/ /************************************ * VARIABLES ************************************/ -constexpr int TEMP_LOW = 2000; -constexpr int TEMP_VERY_LOW = -1500; -constexpr int CMD_SIZE = 1; -constexpr int CMD_TIMEOUT = 150; - // Barometer Commands (should not be modified, non-const due to HAL and C++ strictness) static uint8_t ADC_D1_512_CONV_CMD = 0x42; static uint8_t ADC_D2_512_CONV_CMD = 0x52; @@ -65,10 +60,7 @@ MS5611_DATA_t MS5611_Driver::getSample(){ MS5611_DATA_t data; // Reset the barometer - 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); + resetBarometer(); // Read PROM for calibration coefficients uint16_t c1Sens = ReadCalibrationCoefficients(PROM_READ_SENS_CMD); @@ -84,58 +76,10 @@ MS5611_DATA_t MS5611_Driver::getSample(){ * Finally, update the data globally if the mutex is available. */ /* Read Digital Pressure (D1) ----------------------------------------*/ - - // 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); + pressureReading = getPressureReading(); /* Read Digital Temperature (D2) -------------------------------------*/ - - // 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); + temperatureReading = getTemperatureReading(); /* Calculate First-Order Temperature and Parameters ------------------*/ @@ -147,7 +91,7 @@ MS5611_DATA_t MS5611_Driver::getSample(){ /* Calculate Second-Order Temperature and Pressure -------------------*/ - if (temp < TEMP_LOW) // If the temperature is below 20�C + if (temp < TEMP_LOW) // If the temperature is below 20C { int32_t t2 = ((int64_t)dT * dT) >> 31; int64_t off2 = 5 * (((int64_t)(temp - 2000) * (temp - 2000)) >> 1); @@ -185,7 +129,7 @@ MS5611_DATA_t MS5611_Driver::getSample(){ * coefficient. See the data sheet for the commands. * @return The read coefficient. */ -uint16_t MS5611_Driver::ReadCalibrationCoefficients(uint8_t PROM_READ_CMD) +uint16_t MS5611_Driver::readCalibrationCoefficients(uint8_t PROM_READ_CMD) { uint8_t dataInBuffer; @@ -207,7 +151,90 @@ uint16_t MS5611_Driver::ReadCalibrationCoefficients(uint8_t PROM_READ_CMD) return coefficient; } +/** + * @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 MS5611_Driver::getTemperatureReading() +{ + // Variables + 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(); +} + +/** + * @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 MS5611_Driver::getPressureReading() +{ + // Variables + 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 resets the barometer prior to sampling + */ +void MS5611_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); +}