diff options
author | nickshl <nicolai.shlapunov@gmail.com> | 2018-09-20 07:25:01 +0300 |
---|---|---|
committer | nickshl <nicolai.shlapunov@gmail.com> | 2018-09-20 07:25:01 +0300 |
commit | d5784223866b90221b6ccd52cb56f62164e344e1 (patch) | |
tree | fcc4d114002504901bb93b00663eab3932d3ad8c /STM32F415APP/DevCore | |
parent | e06bf2d8e4df28f5fb6d97f187dfed0f594480f4 (diff) |
I2C interface, I2C driver and couple libraries. Also some other minor changes.
Diffstat (limited to 'STM32F415APP/DevCore')
-rw-r--r-- | STM32F415APP/DevCore/DevCfg.h | 53 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Display/DisplayDrv.cpp | 16 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Drivers/StHalIic.cpp | 245 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Drivers/StHalIic.h | 153 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Framework/Result.h | 23 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Interfaces/IIic.h | 156 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Libraries/BoschBME280.cpp | 402 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Libraries/BoschBME280.h | 306 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Libraries/Eeprom24.cpp | 114 | ||||
-rw-r--r-- | STM32F415APP/DevCore/Libraries/Eeprom24.h | 107 | ||||
-rw-r--r-- | STM32F415APP/DevCore/UiEngine/UiMenu.h | 2 |
11 files changed, 1561 insertions, 16 deletions
diff --git a/STM32F415APP/DevCore/DevCfg.h b/STM32F415APP/DevCore/DevCfg.h index a07a63b..3871b1b 100644 --- a/STM32F415APP/DevCore/DevCfg.h +++ b/STM32F415APP/DevCore/DevCfg.h @@ -54,24 +54,59 @@ #include "Result.h"
#include "Rtos.h"
+// Include for all hardware stuff
+#include "main.h"
+
+// *** ADC *****************************************************************
+#ifdef HAL_ADC_MODULE_ENABLED
#include "adc.h"
+#else
+typedef uint32_t ADC_HandleTypeDef; // Dummy ADC handle for compilation
+#endif
+// *** SPI *****************************************************************
+#ifdef HAL_SPI_MODULE_ENABLED
#include "spi.h"
+#else
+typedef uint32_t SPI_HandleTypeDef; // Dummy SPI handle for compilation
+#endif
+// *** I2C *****************************************************************
+#ifdef HAL_I2C_MODULE_ENABLED
+#include "i2c.h"
+#else
+typedef uint32_t I2C_HandleTypeDef; // Dummy I2C handle for compilation
+#endif
+// *** TIM *****************************************************************
+#ifdef HAL_TIM_MODULE_ENABLED
#include "tim.h"
+#else
+typedef uint32_t TIM_HandleTypeDef; // Dummy TIM handle for compilation
+#endif
+
#include "usb_device.h"
// *****************************************************************************
// *** Configuration *******************************************************
// *****************************************************************************
-// Display SPI handle
-static SPI_HandleTypeDef* const TFT_HSPI = &hspi1;
-// Touchscreen SPI handle
-static SPI_HandleTypeDef* const TOUCH_HSPI = &hspi1;
-
-// Sound Timer handle
-static TIM_HandleTypeDef* const SOUND_HTIM = &htim4;
-// Sound Timer channel
-static const uint32_t SOUND_CHANNEL = TIM_CHANNEL_2;
+// *** SPI Handles *********************************************************
+#ifdef HAL_SPI_MODULE_ENABLED
+ // Display SPI handle
+ static SPI_HandleTypeDef* const TFT_HSPI = &hspi1;
+ // Touchscreen SPI handle
+ static SPI_HandleTypeDef* const TOUCH_HSPI = &hspi1;
+#endif
+// *** I2C Handles *********************************************************
+#ifdef HAL_I2C_MODULE_ENABLED
+ // BME280 I2C handle
+ static I2C_HandleTypeDef& BME280_HI2C = hi2c1;
+#endif
+// *** TIM Handles *********************************************************
+#ifdef HAL_TIM_MODULE_ENABLED
+ // Sound Timer handle
+ static TIM_HandleTypeDef* const SOUND_HTIM = &htim4;
+ // Sound Timer channel
+ static const uint32_t SOUND_CHANNEL = TIM_CHANNEL_2;
+#endif
// *** Applications tasks stack sizes ****************************************
const static uint16_t APPLICATION_TASK_STACK_SIZE = 1024U;
diff --git a/STM32F415APP/DevCore/Display/DisplayDrv.cpp b/STM32F415APP/DevCore/Display/DisplayDrv.cpp index 251c634..16c1eac 100644 --- a/STM32F415APP/DevCore/Display/DisplayDrv.cpp +++ b/STM32F415APP/DevCore/Display/DisplayDrv.cpp @@ -133,18 +133,22 @@ Result DisplayDrv::Loop() // Try to take mutex. 1 ms should be enough.
if(touchscreen_mutex.Lock(1U) == Result::RESULT_OK)
{
+ // Set prescaler for SPI it display share save SPI with touchscreen
if(tft_hspi == touch_hspi)
{
- // Set prescaler for SPI
MODIFY_REG(tft_hspi->Instance->CR1, (uint32_t)SPI_CR1_BR_Msk, SPI_BAUDRATEPRESCALER_64);
- // Get touch coordinates
- tmp_is_touch = touch.GetXY(tmp_tx, tmp_ty);
+ }
+ // Get touch coordinates
+ tmp_is_touch = touch.GetXY(tmp_tx, tmp_ty);
+ // Reset prescaler for SPI it display share save SPI with touchscreen
+ if(tft_hspi == touch_hspi)
+ {
// Restore prescaler for SPI
MODIFY_REG(tft_hspi->Instance->CR1, (uint32_t)SPI_CR1_BR_Msk, SPI_BAUDRATEPRESCALER_2);
- // Give semaphore for drawing frame - we can enter in this "if" statement
- // only if mutex taken
- touchscreen_mutex.Release();
}
+ // Give semaphore for drawing frame - we can enter in this "if" statement
+ // only if mutex taken
+ touchscreen_mutex.Release();
}
// If touch state changed (move)
if(is_touch && tmp_is_touch && ((tx != tmp_tx) || (ty != tmp_ty)) )
diff --git a/STM32F415APP/DevCore/Drivers/StHalIic.cpp b/STM32F415APP/DevCore/Drivers/StHalIic.cpp new file mode 100644 index 0000000..2f231a1 --- /dev/null +++ b/STM32F415APP/DevCore/Drivers/StHalIic.cpp @@ -0,0 +1,245 @@ +//******************************************************************************
+// @file StHalIic.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: STM32 HAL I2C driver, implementation
+//
+// @copyright Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "StHalIic.h"
+
+// *****************************************************************************
+// *** This driver can be compiled only if I2C configured in CubeMX ********
+// *****************************************************************************
+#ifdef HAL_I2C_MODULE_ENABLED
+
+// *****************************************************************************
+// *** Public: Enable ******************************************************
+// *****************************************************************************
+Result StHalIic::Enable()
+{
+ // Set PE bit
+ __HAL_I2C_ENABLE(&hi2c);
+ // No errors to return
+ return Result::RESULT_OK;
+}
+
+// *****************************************************************************
+// *** Public: Disable *****************************************************
+// *****************************************************************************
+Result StHalIic::Disable()
+{
+ // Clear PE bit
+ __HAL_I2C_DISABLE(&hi2c);
+ // No errors to return
+ return Result::RESULT_OK;
+}
+
+// *****************************************************************************
+// *** Public: Reset *******************************************************
+// *****************************************************************************
+Result StHalIic::Reset()
+{
+ // Clear PE bit
+ CLEAR_BIT(hi2c.Instance->CR1, I2C_CR1_PE);
+ // PE must be kept low during at least 3 APB clock cycles in order to
+ // perform the software reset. Wait until it actually cleared.
+ while(READ_BIT(hi2c.Instance->CR1, I2C_CR1_PE));
+ // TODO: make some clock on the SCL line here
+ // Set PE bit
+ SET_BIT(hi2c.Instance->CR1, I2C_CR1_PE);
+ // No errors to return
+ return Result::RESULT_OK;
+}
+
+// *************************************************************************
+// *** Public: IsDeviceReady *******************************************
+// *************************************************************************
+Result StHalIic::IsDeviceReady(uint16_t addr, uint8_t retries)
+{
+ Result result;
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+ // Check device status
+ HAL_StatusTypeDef hal_result = HAL_I2C_IsDeviceReady(&hi2c1, addr, retries, i2c_tx_timeout_ms);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ // Return result
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Transfer ****************************************************
+// *****************************************************************************
+Result StHalIic::Transfer(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size, uint8_t* rx_buf_ptr, uint32_t rx_size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(tx_buf_ptr != nullptr)
+ {
+ // Transmit data
+ result = Write(addr, tx_buf_ptr, tx_size);
+ }
+
+ if((rx_buf_ptr != nullptr) && result.IsGood())
+ {
+ // Clear RX buffer
+ for(uint32_t i = 0; i < rx_size; i++)
+ {
+ rx_buf_ptr[i] = 0;
+ }
+ // Receive data
+ result = Read(addr, rx_buf_ptr, rx_size);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Write *******************************************************
+// *****************************************************************************
+Result StHalIic::Write(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(tx_buf_ptr != nullptr)
+ {
+ // Variable for store result from the HAL
+ HAL_StatusTypeDef hal_result = HAL_OK;
+
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+
+ // Transmit data
+ hal_result = HAL_I2C_Master_Transmit(&hi2c, addr, tx_buf_ptr, tx_size, i2c_tx_timeout_ms);
+
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Read ********************************************************
+// *****************************************************************************
+Result StHalIic::Read(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(rx_buf_ptr != nullptr)
+ {
+ // Variable for store result from the HAL
+ HAL_StatusTypeDef hal_result = HAL_OK;
+
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+
+ // Transmit data
+ hal_result = HAL_I2C_Master_Receive(&hi2c, addr, rx_buf_ptr, rx_size, i2c_tx_timeout_ms);
+
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: WriteAsync **************************************************
+// *****************************************************************************
+Result StHalIic::WriteAsync(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size)
+{
+ Result result = Result::ERR_NOT_IMPLEMENTED;
+
+ // Check DMA handler - if it is nullptr this function not implemented in hardware
+ if(hi2c.hdmatx != nullptr)
+ {
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+ // Receive data using DMA
+ HAL_StatusTypeDef hal_result = HAL_I2C_Master_Transmit_DMA(&hi2c, addr, tx_buf_ptr, tx_size);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: ReadAsync ***************************************************
+// *****************************************************************************
+Result StHalIic::ReadAsync(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size)
+{
+ Result result = Result::ERR_NOT_IMPLEMENTED;
+
+ // Check DMA handler - if it is nullptr this function not implemented in hardware
+ if(hi2c.hdmarx != nullptr)
+ {
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+ // Receive data using DMA
+ HAL_StatusTypeDef hal_result = HAL_I2C_Master_Receive_DMA(&hi2c, addr, rx_buf_ptr, rx_size);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Transfer ****************************************************
+// *****************************************************************************
+bool StHalIic::IsBusy(void)
+{
+ return (hi2c.State != HAL_I2C_STATE_READY);
+}
+
+// *****************************************************************************
+// *** Private: ConvertResult **********************************************
+// *****************************************************************************
+Result StHalIic::ConvertResult(HAL_StatusTypeDef hal_result)
+{
+ Result result = Result::RESULT_OK;
+
+ // Convert operation result to Result
+ switch(hal_result)
+ {
+ case HAL_OK:
+ result = Result::RESULT_OK;
+ break;
+
+ case HAL_ERROR:
+ result = Result::ERR_I2C_GENERAL;
+ break;
+
+ case HAL_BUSY:
+ result = Result::ERR_I2C_BUSY;
+ break;
+
+ case HAL_TIMEOUT:
+ result = Result::ERR_I2C_TIMEOUT;
+ break;
+
+ default:
+ result = Result::ERR_SPI_UNKNOWN;
+ break;
+ }
+
+ // Return result
+ return result;
+}
+
+#endif
diff --git a/STM32F415APP/DevCore/Drivers/StHalIic.h b/STM32F415APP/DevCore/Drivers/StHalIic.h new file mode 100644 index 0000000..b06c8fa --- /dev/null +++ b/STM32F415APP/DevCore/Drivers/StHalIic.h @@ -0,0 +1,153 @@ +//******************************************************************************
+// @file StHalIic.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: STM32 HAL I2C driver, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef StmHalIic_h
+#define StmHalIic_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+#include "IIic.h"
+
+// *****************************************************************************
+// *** This driver can be compiled only if UART configured in CubeMX *******
+// *****************************************************************************
+#ifndef HAL_I2C_MODULE_ENABLED
+ typedef uint32_t I2C_HandleTypeDef; // Dummy I2C handle for header compilation
+#endif
+
+// *****************************************************************************
+// *** STM32 HAL I2C Driver Class ******************************************
+// *****************************************************************************
+class StHalIic : public IIic
+{
+ public:
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit StHalIic(I2C_HandleTypeDef& hi2c_ref) : hi2c(hi2c_ref) {};
+
+ // *************************************************************************
+ // *** Public: Destructor **********************************************
+ // *************************************************************************
+ ~StHalIic() {};
+
+ // *************************************************************************
+ // *** Public: Init ****************************************************
+ // *************************************************************************
+ virtual Result Init() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Enable **************************************************
+ // *************************************************************************
+ virtual Result Enable();
+
+ // *************************************************************************
+ // *** Public: Disable *************************************************
+ // *************************************************************************
+ virtual Result Disable();
+
+ // *************************************************************************
+ // *** Public: Reset ***************************************************
+ // *************************************************************************
+ virtual Result Reset();
+
+ // *************************************************************************
+ // *** Public: IsDeviceReady *******************************************
+ // *************************************************************************
+ virtual Result IsDeviceReady(uint16_t addr, uint8_t retries = 1U);
+
+ // *************************************************************************
+ // *** Public: Transfer ************************************************
+ // *************************************************************************
+ virtual Result Transfer(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size,
+ uint8_t* rx_buf_ptr, uint32_t rx_size);
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ virtual Result Write(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size);
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ virtual Result Read(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size);
+
+ // *************************************************************************
+ // *** Public: WriteAsync **********************************************
+ // *************************************************************************
+ virtual Result WriteAsync(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size);
+
+ // *************************************************************************
+ // *** Public: ReadAsync ***********************************************
+ // *************************************************************************
+ virtual Result ReadAsync(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size);
+
+ // *************************************************************************
+ // *** Public: IsBusy **************************************************
+ // *************************************************************************
+ virtual bool IsBusy(void);
+
+ private:
+ // Reference to the I2C handle
+ I2C_HandleTypeDef& hi2c;
+
+ // *************************************************************************
+ // *** Private: ConvertResult ******************************************
+ // *************************************************************************
+ Result ConvertResult(HAL_StatusTypeDef hal_result);
+
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ StHalIic();
+ StHalIic(const StHalIic&);
+ StHalIic& operator=(const StHalIic);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/Framework/Result.h b/STM32F415APP/DevCore/Framework/Result.h index 7d2bcf2..74d27b9 100644 --- a/STM32F415APP/DevCore/Framework/Result.h +++ b/STM32F415APP/DevCore/Framework/Result.h @@ -66,6 +66,8 @@ class Result ERR_NULL_PTR,
ERR_BAD_PARAMETER,
ERR_INVALID_ITEM,
+ ERR_NOT_IMPLEMENTED,
+ ERR_BUSY,
// *** RTOS errors ***************************************************
ERR_TASK_CREATE,
@@ -86,6 +88,27 @@ class Result ERR_SEMAPHORE_TAKE,
ERR_SEMAPHORE_GIVE,
+ // *** UART errors ***************************************************
+ ERR_UART_GENERAL,
+ ERR_UART_TRANSMIT,
+ ERR_UART_RECEIVE,
+ ERR_UART_EMPTY,
+ ERR_UART_BUSY,
+ ERR_UART_TIMEOUT,
+ ERR_UART_UNKNOWN,
+
+ // *** I2C errors ****************************************************
+ ERR_I2C_GENERAL,
+ ERR_I2C_BUSY,
+ ERR_I2C_TIMEOUT,
+ ERR_I2C_UNKNOWN,
+
+ // *** SPI errors ****************************************************
+ ERR_SPI_GENERAL,
+ ERR_SPI_BUSY,
+ ERR_SPI_TIMEOUT,
+ ERR_SPI_UNKNOWN,
+
// *** Elements count ************************************************
RESULTS_CNT
};
diff --git a/STM32F415APP/DevCore/Interfaces/IIic.h b/STM32F415APP/DevCore/Interfaces/IIic.h new file mode 100644 index 0000000..5e35ee1 --- /dev/null +++ b/STM32F415APP/DevCore/Interfaces/IIic.h @@ -0,0 +1,156 @@ +//******************************************************************************
+// @file IIic.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: I2C driver interface, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef IIic_h
+#define IIic_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+
+// *****************************************************************************
+// *** I2C Driver Interface ************************************************
+// *****************************************************************************
+class IIic
+{
+ public:
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit IIic() {};
+
+ // *************************************************************************
+ // *** Public: Destructor **********************************************
+ // *************************************************************************
+ virtual ~IIic() {};
+
+ // *************************************************************************
+ // *** Public: Init ****************************************************
+ // *************************************************************************
+ virtual Result Init() = 0;
+
+ // *************************************************************************
+ // *** Public: DeInit **************************************************
+ // *************************************************************************
+ virtual Result DeInit() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Enable **************************************************
+ // *************************************************************************
+ virtual Result Enable() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Disable *************************************************
+ // *************************************************************************
+ virtual Result Disable() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Reset ***************************************************
+ // *************************************************************************
+ virtual Result Reset() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: IsDeviceReady *******************************************
+ // *************************************************************************
+ virtual Result IsDeviceReady(uint16_t addr, uint8_t retries = 1U) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Transfer ************************************************
+ // *************************************************************************
+ virtual Result Transfer(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size, uint8_t* rx_buf_ptr, uint32_t rx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ virtual Result Write(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ virtual Result Read(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: WriteAsync **********************************************
+ // *************************************************************************
+ virtual Result WriteAsync(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: ReadAsync ***********************************************
+ // *************************************************************************
+ virtual Result ReadAsync(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: IsBusy **************************************************
+ // *************************************************************************
+ virtual bool IsBusy(void) {return false;}
+
+ // *************************************************************************
+ // *** Public: SetTxTimeout ********************************************
+ // *************************************************************************
+ virtual void SetTxTimeout(uint16_t timeout_ms) {i2c_tx_timeout_ms = timeout_ms;}
+
+ // *************************************************************************
+ // *** Public: SetRxTimeout ********************************************
+ // *************************************************************************
+ virtual void SetRxTimeout(uint16_t timeout_ms) {i2c_rx_timeout_ms = timeout_ms;}
+
+ protected:
+ // Timeout for I2C TX operation
+ uint16_t i2c_tx_timeout_ms = 5U;
+
+ // Timeout for I2C RX operation
+ uint16_t i2c_rx_timeout_ms = 5U;
+
+ private:
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ IIic(const IIic&);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/Libraries/BoschBME280.cpp b/STM32F415APP/DevCore/Libraries/BoschBME280.cpp new file mode 100644 index 0000000..27029ed --- /dev/null +++ b/STM32F415APP/DevCore/Libraries/BoschBME280.cpp @@ -0,0 +1,402 @@ +//****************************************************************************** +// @file BoschBME280.cpp +// @author Nicolai Shlapunov +// +// @details DevCore: Bosch BME280 library, implementation +// +// @copyright Copyright (c) 2018, Devtronic & Nicolai Shlapunov +// All rights reserved. +// +// @section SUPPORT +// +// Devtronic invests time and resources providing this open source code, +// please support Devtronic and open-source hardware/software by +// donations and/or purchasing products from Devtronic. +// +//****************************************************************************** + +// ***************************************************************************** +// *** Includes ************************************************************ +// ***************************************************************************** +#include "BoschBME280.h" + +// ***************************************************************************** +// *** Initialize ********************************************************** +// ***************************************************************************** +Result BoschBME280::Initialize() +{ + Result result = Result::RESULT_OK; + + result = iic.Enable(); + + if(result.IsGood()) + { + // Read Chip ID + result = Read8(BME280_REGISTER_CHIPID, sensor_id); + // Check if Chip ID is correct + if(result.IsGood() && (sensor_id != 0x60)) + { + result = Result::ERR_I2C_GENERAL; + } + } + + if(result.IsGood()) + { + // Reset the device + Write8(BME280_REGISTER_SOFTRESET, 0xB6); + } + + if(result.IsGood()) + { + // Wait for chip to wake up + RtosTick::DelayMs(5U); + } + + if(result.IsGood()) + { + // If chip is still reading calibration + while((result = IsReadingCalibration()) == Result::ERR_BUSY) + { + // Wait for chip to wake up + RtosTick::DelayMs(1U); + } + } + + if(result.IsGood()) + { + // Read trimming parameters, see DS 4.2.2 + result = ReadCoefficients(); + } + + if(result.IsGood()) + { + // Set default sampling values + result = SetSampling(); + } + + if(result.IsGood()) + { + RtosTick::DelayMs(100U); + } + + return result; +} + +// ****************************************************************************** +// *** SetSampling ********************************************************** +// ****************************************************************************** +Result BoschBME280::SetSampling(SensorModeType mode, + SensorSamplingType temperature_sampling, + SensorSamplingType pressurre_sampling, + SensorSamplingType humidity_sampling, + SensorFilterType filter, + StandbyDurationType duration) +{ + Result result = Result::RESULT_OK; + + config_reg.spi3w_en = 0U; + config_reg.reserved = 0U; + config_reg.filter = filter; + config_reg.t_sb = duration; + result |= Write8(BME280_REGISTER_CONFIG, reinterpret_cast<uint8_t const&>(config_reg)); + + // REGISTER_CONTROL should be set after setting the CONTROLHUMID register, + // otherwise the values will not be applied (see datasheet 5.4.3) + ctrl_hum_reg.reserved = 0U; + ctrl_hum_reg.osrs_h = humidity_sampling; + result = Write8(BME280_REGISTER_CONTROLHUMID, reinterpret_cast<uint8_t const&>(ctrl_hum_reg)); + + ctrl_meas_reg.mode = mode; + ctrl_meas_reg.osrs_t = temperature_sampling; + ctrl_meas_reg.osrs_p = pressurre_sampling; + result |= Write8(BME280_REGISTER_CONTROL, reinterpret_cast<uint8_t const&>(ctrl_meas_reg)); + + return result; +} + +// ****************************************************************************** +// *** TakeMeasurement ****************************************************** +// ****************************************************************************** +Result BoschBME280::TakeMeasurement() +{ + Result result = Result::RESULT_OK; + + if(ctrl_meas_reg.mode == MODE_FORCED) + { + // set to forced mode, i.e. "take next measurement" + Write8(BME280_REGISTER_CONTROL, reinterpret_cast<uint8_t const&>(ctrl_meas_reg)); + // Variable + uint8_t status = 0U; + // Read status + result = Read8(BME280_REGISTER_STATUS, status); + // Wait until measurement has been completed + while(result.IsGood() && (status & 0x08)) + { + RtosTick::DelayMs(1U); + // Read status + result = Read8(BME280_REGISTER_STATUS, status); + } + } + + // Read RAW values + if(result.IsGood()) + { + uint8_t addr = BME280_REGISTER_PRESSUREDATA; + // Local variable for read data(24 bit + 24 bit + 16 bit) + uint8_t array[3U+3U+2U] = {0U}; + // Read all registers at once + result = iic.Transfer(i2c_addr, &addr, sizeof(addr), array, sizeof(array)); + // Create RAW ADC data + if(result.IsGood()) + { + // Pressure + adc_pressure = 0; + result = ReverseArray((uint8_t*)&adc_pressure, &array[0U], 3U); + adc_pressure >>= 4; + // Temperature + adc_temperature = 0; + result |= ReverseArray((uint8_t*)&adc_temperature, &array[3U], 3U); + adc_temperature >>= 4; + // Humidity + adc_humidity = 0; + result |= ReverseArray((uint8_t*)&adc_humidity, &array[3U+3U], 2U); + // Ņalculating t_fine for calculation Pressure & Humidity + (void) GetTemperature_x100(); + } + } + + return result; +} + +// ****************************************************************************** +// *** GetTemperature_x100 ************************************************** +// ****************************************************************************** +int32_t BoschBME280::GetTemperature_x100(void) +{ + int32_t temp_x100 = 0; + int32_t var1, var2; + + int32_t adc = adc_temperature; + + if (adc != 0x800000) + { + var1 = (((adc >> 3) - ((int32_t)bme280_calibration.dig_t1 << 1)) * ((int32_t)bme280_calibration.dig_t2)) >> 11; + + var2 = (((((adc >> 4) - ((int32_t)bme280_calibration.dig_t1)) * ((adc >> 4) - ((int32_t)bme280_calibration.dig_t1))) >> 12) * ((int32_t)bme280_calibration.dig_t3)) >> 14; + + t_fine = var1 + var2; + + temp_x100 = (t_fine * 5 + 128) >> 8; + } + + return temp_x100; +} + +// ****************************************************************************** +// *** GetPressure_x256 ***************************************************** +// ****************************************************************************** +int32_t BoschBME280::GetPressure_x256(void) +{ + int64_t var1, var2, press_x256 = 0; + + int32_t adc = adc_pressure; + if(adc != 0x800000) + { + var1 = ((int64_t)t_fine) - 128000; + var2 = var1 * var1 * (int64_t)bme280_calibration.dig_p6; + var2 = var2 + ((var1 * (int64_t)bme280_calibration.dig_p5) << 17); + var2 = var2 + (((int64_t)bme280_calibration.dig_p4) << 35); + var1 = ((var1 * var1 * (int64_t)bme280_calibration.dig_p3) >> 8) + ((var1 * (int64_t)bme280_calibration.dig_p2) << 12); + var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)bme280_calibration.dig_p1) >> 33; + + if (var1 == 0) + { + press_x256 = 0; // Avoid exception caused by division by zero + } + else + { + press_x256 = 1048576 - adc; + press_x256 = (((press_x256 << 31) - var2) * 3125) / var1; + var1 = (((int64_t)bme280_calibration.dig_p9) * (press_x256 >> 13) * (press_x256 >> 13)) >> 25; + var2 = (((int64_t)bme280_calibration.dig_p8) * press_x256) >> 19; + // Result + press_x256 = ((press_x256 + var1 + var2) >> 8) + (((int64_t)bme280_calibration.dig_p7) << 4); + } + } + + return (int32_t)press_x256; +} + +// ****************************************************************************** +// *** GetHumidity_x1024 **************************************************** +// ****************************************************************************** +int32_t BoschBME280::GetHumidity_x1024(void) +{ + int32_t adc = adc_humidity; + int32_t v_x1_u32r = 0; + + // value in case humidity measurement was disabled + if(adc != 0x8000) + { + v_x1_u32r = (t_fine - ((int32_t)76800)); + + v_x1_u32r = (((((adc << 14) - (((int32_t)bme280_calibration.dig_h4) << 20) - + (((int32_t)bme280_calibration.dig_h5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * + (((((((v_x1_u32r * ((int32_t)bme280_calibration.dig_h6)) >> 10) * + (((v_x1_u32r * ((int32_t)bme280_calibration.dig_h3)) >> 11) + ((int32_t)32768))) >> 10) + + ((int32_t)2097152)) * ((int32_t)bme280_calibration.dig_h2) + 8192) >> 14)); + + v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)bme280_calibration.dig_h1)) >> 4)); + + v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; + v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; + } + + return (v_x1_u32r >> 12); +} + +// ****************************************************************************** +// *** ReadCoefficients ***************************************************** +// ****************************************************************************** +Result BoschBME280::ReadCoefficients(void) +{ + Result result = Result::RESULT_OK; + + result |= Read16(BME280_REGISTER_DIG_T1, bme280_calibration.dig_t1); + result |= Read16(BME280_REGISTER_DIG_T2, bme280_calibration.dig_t2); + result |= Read16(BME280_REGISTER_DIG_T3, bme280_calibration.dig_t3); + + result |= Read16(BME280_REGISTER_DIG_P1, bme280_calibration.dig_p1); + result |= Read16(BME280_REGISTER_DIG_P2, bme280_calibration.dig_p2); + result |= Read16(BME280_REGISTER_DIG_P3, bme280_calibration.dig_p3); + result |= Read16(BME280_REGISTER_DIG_P4, bme280_calibration.dig_p4); + result |= Read16(BME280_REGISTER_DIG_P5, bme280_calibration.dig_p5); + result |= Read16(BME280_REGISTER_DIG_P6, bme280_calibration.dig_p6); + result |= Read16(BME280_REGISTER_DIG_P7, bme280_calibration.dig_p7); + result |= Read16(BME280_REGISTER_DIG_P8, bme280_calibration.dig_p8); + result |= Read16(BME280_REGISTER_DIG_P9, bme280_calibration.dig_p9); + + result |= Read8(BME280_REGISTER_DIG_H1, bme280_calibration.dig_h1); + result |= Read16(BME280_REGISTER_DIG_H2, bme280_calibration.dig_h2); + result |= Read8(BME280_REGISTER_DIG_H3, bme280_calibration.dig_h3); + + // Variables for store values + uint8_t dig_h4; + uint8_t dig_h45; + uint8_t dig_h5; + // Read values + result |= Read8(BME280_REGISTER_DIG_H4, dig_h4); + result |= Read8(BME280_REGISTER_DIG_H45, dig_h45); + result |= Read8(BME280_REGISTER_DIG_H5, dig_h5); + // Make digit from values + bme280_calibration.dig_h4 = (dig_h4 << 4) | (dig_h45 & 0xF); + bme280_calibration.dig_h5 = (dig_h5 << 4) | (dig_h45 >> 4); + + result |= Read8(BME280_REGISTER_DIG_H6, bme280_calibration.dig_h6); + + return result; +} + +// ****************************************************************************** +// *** Check is chip still reading calibration data ************************* +// ****************************************************************************** +Result BoschBME280::IsReadingCalibration(void) +{ + Result result = Result::RESULT_OK; + + uint8_t status = 0U; + // Read status + result = Read8(BME280_REGISTER_STATUS, status); + // Check result + if(result.IsGood()) + { + if((status & 1U) != 0U) + { + result = Result::ERR_BUSY; + } + } + + return result; +} + +// ****************************************************************************** +// *** Read register value(8-bit unsigned) ********************************** +// ****************************************************************************** +Result BoschBME280::Read8(uint8_t reg, uint8_t& value) +{ + return iic.Transfer(i2c_addr, ®, sizeof(reg), &value, sizeof(value)); +} + +// ****************************************************************************** +// *** Read register value(8-bit signed) ************************************ +// ****************************************************************************** +Result BoschBME280::Read8(uint8_t reg, int8_t& value) +{ + return iic.Transfer(i2c_addr, ®, sizeof(reg), (uint8_t*)&value, sizeof(value)); +} + +// ****************************************************************************** +// *** Write register value(8-bit) ****************************************** +// ****************************************************************************** +Result BoschBME280::Write8(uint8_t reg, uint8_t value) +{ + uint8_t buf[2]; + buf[0] = reg; + buf[1] = value; + return iic.Write(i2c_addr, buf, sizeof(buf)); +} + +// ****************************************************************************** +// *** Read register value(16-bit unsigned) ********************************* +// ****************************************************************************** +Result BoschBME280::Read16(uint8_t reg, uint16_t& value, bool reverse) +{ + Result result = Result::RESULT_OK; + + // Read data + result = iic.Transfer(i2c_addr, ®, sizeof(reg), (uint8_t*)&value, sizeof(value)); + // Change endian if needed + if(reverse) + { + value = (value >> 8) | (value << 8); + } + + return result; +} + +// ****************************************************************************** +// *** Read register value(16-bit signed) *********************************** +// ****************************************************************************** +Result BoschBME280::Read16(uint8_t reg, int16_t& value, bool reverse) +{ + Result result = Result::RESULT_OK; + + // Read data + result = iic.Transfer(i2c_addr, ®, sizeof(reg), (uint8_t*)&value, sizeof(value)); + // Change endian if needed + if(reverse) + { + value = (value >> 8) | (value << 8); + } + + return result; +} + +// ****************************************************************************** +// *** Reverse byte order in array ****************************************** +// ****************************************************************************** +Result BoschBME280::ReverseArray(uint8_t* dst, uint8_t* src, uint32_t size) +{ + Result result = Result::ERR_NULL_PTR; + + if((dst != nullptr) && (src != nullptr)) + { + for(uint32_t i = 0U; i < size; i++) + { + dst[i] = src[size - i - 1U]; + } + result = Result::RESULT_OK; + } + + return result; +} diff --git a/STM32F415APP/DevCore/Libraries/BoschBME280.h b/STM32F415APP/DevCore/Libraries/BoschBME280.h new file mode 100644 index 0000000..fe38c35 --- /dev/null +++ b/STM32F415APP/DevCore/Libraries/BoschBME280.h @@ -0,0 +1,306 @@ +//****************************************************************************** +// @file DevCfg.h +// @author Nicolai Shlapunov +// +// @details Bosch BMPE280: Library, header +// +// @section LICENSE +// +// Software License Agreement (Modified BSD License) +// +// Copyright (c) 2018, Devtronic & Nicolai Shlapunov +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the Devtronic nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// 4. Redistribution and use of this software other than as permitted under +// this license is void and will automatically terminate your rights under +// this license. +// +// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// @section SUPPORT +// +// Devtronic invests time and resources providing this open source code, +// please support Devtronic and open-source hardware/software by +// donations and/or purchasing products from Devtronic. +// +//****************************************************************************** + +#ifndef BoschBME280_h +#define BoschBME280_h + +// ***************************************************************************** +// *** Includes ************************************************************ +// ***************************************************************************** +#include "DevCfg.h" +#include "IIic.h" + +// ***************************************************************************** +// *** Bosch BME280 library ************************************************* +// ***************************************************************************** +class BoschBME280 +{ + public: + // ************************************************************************* + // *** Sampling rates ************************************************** + // ************************************************************************* + enum SensorSamplingType + { + SAMPLING_NONE = 0x00, // 000 = skipped + SAMPLING_X1, // 001 = x1 + SAMPLING_X2, // 010 = x2 + SAMPLING_X4, // 011 = x4 + SAMPLING_X8, // 100 = x8 + SAMPLING_X16 // 101 and above = x16 + }; + + // ************************************************************************* + // *** Power modes ***************************************************** + // ************************************************************************* + enum SensorModeType + { + MODE_SLEEP = 0x00, // 00 = sleep + MODE_FORCED = 0x01, // 01 or 10 = forced + MODE_NORMAL = 0x11 // 11 = normal + }; + + // ************************************************************************* + // *** Filter values *************************************************** + // ************************************************************************* + enum SensorFilterType + { + FILTER_OFF = 0x00, // 000 = filter off + FILTER_X2, // 001 = x2 filter + FILTER_X4, // 010 = x4 filter + FILTER_X8, // 011 = x8 filter + FILTER_X16, // 100 and above = 16x filter + }; + + // ************************************************************************* + // *** Standby duration ************************************************ + // ************************************************************************* + enum StandbyDurationType + { + STANDBY_MS_0_5 = 0x00, // 000 = 0.5 ms + STANDBY_MS_10 = 0x06, // 110 = 10 ms + STANDBY_MS_20 = 0x07, // 111 = 20 ms + STANDBY_MS_62_5 = 0x01, // 001 = 62.5 ms + STANDBY_MS_125 = 0x02, // 010 = 125 ms + STANDBY_MS_250 = 0x03, // 100 = 500 ms + STANDBY_MS_500 = 0x04, // 101 = 1000 ms + STANDBY_MS_1000 = 0x05 // 011 = 250 ms + }; + + // ************************************************************************* + // *** Constructor ***************************************************** + // ************************************************************************* + BoschBME280(IIic& iic_ref) : iic(iic_ref) {}; + + // ************************************************************************* + // *** Initialize ****************************************************** + // ************************************************************************* + Result Initialize(); + + // ************************************************************************* + // *** SetSampling ***************************************************** + // ************************************************************************* + Result SetSampling(SensorModeType mode = MODE_NORMAL, + SensorSamplingType temperature_sampling = SAMPLING_X16, + SensorSamplingType pressure_sampling = SAMPLING_X16, + SensorSamplingType humidity_sampling = SAMPLING_X16, + SensorFilterType filter = FILTER_OFF, + StandbyDurationType duration = STANDBY_MS_0_5); + + // ************************************************************************* + // *** TakeMeasurement ************************************************* + // ************************************************************************* + Result TakeMeasurement(); + + // ************************************************************************* + // *** GetTemperature_x100 ********************************************* + // ************************************************************************* + int32_t GetTemperature_x100(void); + + // ************************************************************************* + // *** GetPressure_x256 ************************************************ + // ************************************************************************* + int32_t GetPressure_x256(void); + + // ************************************************************************* + // *** GetHumidity_x1024 *********************************************** + // ************************************************************************* + int32_t GetHumidity_x1024(void); + + private: + + // *** default I2C address ********************************************** + const uint8_t BME280_ADDRESS = 0x76; + + // *** Register addresses ********************************************* + enum Registers + { + BME280_REGISTER_DIG_T1 = 0x88, + BME280_REGISTER_DIG_T2 = 0x8A, + BME280_REGISTER_DIG_T3 = 0x8C, + + BME280_REGISTER_DIG_P1 = 0x8E, + BME280_REGISTER_DIG_P2 = 0x90, + BME280_REGISTER_DIG_P3 = 0x92, + BME280_REGISTER_DIG_P4 = 0x94, + BME280_REGISTER_DIG_P5 = 0x96, + BME280_REGISTER_DIG_P6 = 0x98, + BME280_REGISTER_DIG_P7 = 0x9A, + BME280_REGISTER_DIG_P8 = 0x9C, + BME280_REGISTER_DIG_P9 = 0x9E, + + BME280_REGISTER_DIG_H1 = 0xA1, + BME280_REGISTER_DIG_H2 = 0xE1, + BME280_REGISTER_DIG_H3 = 0xE3, + BME280_REGISTER_DIG_H4 = 0xE4, + BME280_REGISTER_DIG_H45 = 0xE5, + BME280_REGISTER_DIG_H5 = 0xE6, + BME280_REGISTER_DIG_H6 = 0xE7, + + BME280_REGISTER_CHIPID = 0xD0, + BME280_REGISTER_SOFTRESET = 0xE0, + + BME280_REGISTER_CONTROLHUMID = 0xF2, + BME280_REGISTER_STATUS = 0XF3, + BME280_REGISTER_CONTROL = 0xF4, + BME280_REGISTER_CONFIG = 0xF5, + BME280_REGISTER_PRESSUREDATA = 0xF7, + BME280_REGISTER_TEMPDATA = 0xFA, + BME280_REGISTER_HUMIDDATA = 0xFD + }; + + // Reference to I2C interface + IIic& iic; + // I2C address + uint8_t i2c_addr = BME280_ADDRESS; + // Sensor ID + uint8_t sensor_id = 0; + + // Some data for calculate pressure & humidity + int32_t t_fine = 0; + // Variables for store raw values + int32_t adc_temperature = 0; + int32_t adc_pressure = 0; + uint16_t adc_humidity = 0; + + // *** Calibration data structure ************************************** + struct CalibrationData + { + // Temperature compensation values + uint16_t dig_t1; + int16_t dig_t2; + int16_t dig_t3; + + // Pressure compensation values + uint16_t dig_p1; + int16_t dig_p2; + int16_t dig_p3; + int16_t dig_p4; + int16_t dig_p5; + int16_t dig_p6; + int16_t dig_p7; + int16_t dig_p8; + int16_t dig_p9; + + // Humidity compensation values + uint8_t dig_h1; + int16_t dig_h2; + uint8_t dig_h3; + int16_t dig_h4; + int16_t dig_h5; + int8_t dig_h6; + }; + CalibrationData bme280_calibration; + + // *** Configuration register structure ********************************* + struct Config + { + uint8_t spi3w_en : 1; + uint8_t reserved : 1; + uint8_t filter : 3; // Filter settings + uint8_t t_sb : 3; // Inactive duration (StandBy time) in normal mode + }; + Config config_reg; + + // *** Measurement control register ************************************* + struct CtrlMeas + { + uint8_t mode : 2; // Device mode + uint8_t osrs_p : 3; // Pressure oversampling + uint8_t osrs_t : 3; // Temperature oversampling + }; + CtrlMeas ctrl_meas_reg; + + // *** Humidity control register structure ***************************** + struct CtrlHum + { + uint8_t osrs_h : 3; + uint8_t reserved : 5; + }; + CtrlHum ctrl_hum_reg; + + // ************************************************************************* + // *** Read Coefficients *********************************************** + // ************************************************************************* + Result ReadCoefficients(void); + + // ************************************************************************* + // *** Check is chip still reading calibration data ******************** + // ************************************************************************* + Result IsReadingCalibration(void); + + // ************************************************************************* + // *** Write register value(8-bit) ************************************* + // ************************************************************************* + Result Write8(uint8_t reg, uint8_t value); + + // ************************************************************************* + // *** Read register value(8-bit unsigned) ***************************** + // ************************************************************************* + Result Read8(uint8_t reg, uint8_t& value); + + // ************************************************************************* + // *** Read register value(8-bit signed) ******************************* + // ************************************************************************* + Result Read8(uint8_t reg, int8_t& value); + + // ************************************************************************* + // *** Read register value(16-bit unsigned) **************************** + // ************************************************************************* + Result Read16(uint8_t reg, uint16_t& value, bool reverse = false); + + // ************************************************************************* + // *** Read register value(16-bit signed) ****************************** + // ************************************************************************* + Result Read16(uint8_t reg, int16_t& value, bool reverse = false); + + // ************************************************************************* + // *** Reverse byte order in array ************************************* + // ************************************************************************* + Result ReverseArray(uint8_t* dst, uint8_t* src, uint32_t size); +}; + +#endif diff --git a/STM32F415APP/DevCore/Libraries/Eeprom24.cpp b/STM32F415APP/DevCore/Libraries/Eeprom24.cpp new file mode 100644 index 0000000..0ed374f --- /dev/null +++ b/STM32F415APP/DevCore/Libraries/Eeprom24.cpp @@ -0,0 +1,114 @@ +//******************************************************************************
+// @file Eeprom24.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: EEPROM 24C*** driver, implementation
+//
+// @copyright Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "Eeprom24.h"
+
+// *****************************************************************************
+// *** Public: Init ********************************************************
+// *****************************************************************************
+Result Eeprom24::Init()
+{
+ Result result = Result::RESULT_OK;
+ iic.SetTxTimeout(10U);
+ iic.SetRxTimeout(100U);
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Read ********************************************************
+// *****************************************************************************
+Result Eeprom24::Read(uint16_t addr, uint8_t* rx_buf_ptr, uint16_t size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ // Check input parameters
+ if(rx_buf_ptr != nullptr)
+ {
+ // Transfer: write two bytes address then read data
+ result = iic.Transfer(I2C_ADDR, (uint8_t*)&addr, sizeof(addr), rx_buf_ptr, size);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Write *******************************************************
+// *****************************************************************************
+Result Eeprom24::Write(uint16_t addr, uint8_t* tx_buf_ptr, uint16_t size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ // Check input parameters
+ if(tx_buf_ptr != nullptr)
+ {
+ // Clear result to enter in to cycle
+ result = Result::RESULT_OK;
+ // Allocate buffer for address + data
+ uint8_t buf[2U + PAGE_SIZE_BYTES];
+ // Cycle for write pages
+ while(size && result.IsGood())
+ {
+ // Get data size
+ uint8_t data_size = size < PAGE_SIZE_BYTES ? size : PAGE_SIZE_BYTES;
+ // For the first page
+ if((addr % PAGE_SIZE_BYTES) != 0U)
+ {
+ // Calculate data size from start address to the end of current page
+ data_size = PAGE_SIZE_BYTES - (addr % PAGE_SIZE_BYTES);
+ // If size less than remaining page bytes - use size
+ data_size = size < data_size ? size : data_size;
+ }
+ // Decrease number of remaining bytes
+ size -= data_size;
+ // Store address
+ *((uint16_t*)buf) = addr;
+ // Copy data
+ memcpy(buf + 2U, tx_buf_ptr, data_size);
+ // Transfer
+ result = iic.Write(I2C_ADDR, buf, 2U + data_size);
+
+ // Wait until writing finished
+ if(result.IsGood())
+ {
+ // Check device response
+ result = iic.IsDeviceReady(I2C_ADDR);
+ // Clear repetition counter for tracking timeout
+ repetition_cnt = 0U;
+ // Wait until write operation finished
+ while(result.IsBad())
+ {
+ // Delay 1 ms for start writing
+ RtosTick::DelayMs(1U);
+ // Check is device ready
+ result = iic.IsDeviceReady(I2C_ADDR);
+ // Check timeout
+ if(repetition_cnt > WRITING_TIMEOUT_MS)
+ {
+ result = Result::ERR_I2C_TIMEOUT;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
diff --git a/STM32F415APP/DevCore/Libraries/Eeprom24.h b/STM32F415APP/DevCore/Libraries/Eeprom24.h new file mode 100644 index 0000000..ff39150 --- /dev/null +++ b/STM32F415APP/DevCore/Libraries/Eeprom24.h @@ -0,0 +1,107 @@ +//******************************************************************************
+// @file Eeprom24.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: EEPROM 24C*** driver, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef Eeprom24_h
+#define Eeprom24_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+#include "IIic.h"
+
+// *****************************************************************************
+// *** EEPROM 24C*** Driver Class ******************************************
+// *****************************************************************************
+class Eeprom24
+{
+ public:
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit Eeprom24(IIic& iic_ref) : iic(iic_ref) {};
+
+ // *************************************************************************
+ // *** Public: Init ****************************************************
+ // *************************************************************************
+ Result Init();
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ Result Read(uint16_t addr, uint8_t* rx_buf_ptr, uint16_t size);
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ Result Write(uint16_t addr, uint8_t* tx_buf_ptr, uint16_t size);
+
+ private:
+ // Chip address
+ static const uint8_t I2C_ADDR = 0x50U;
+
+ // Page size in bytes
+ static const uint8_t PAGE_SIZE_BYTES = 64U;
+
+ // Writing timeout in ms
+ static const uint8_t WRITING_TIMEOUT_MS = 10U;
+
+ // Repetition counter for tracking timeout
+ uint8_t repetition_cnt = 0U;
+
+ // Reference to the I2C handle
+ IIic& iic;
+
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ Eeprom24();
+ Eeprom24(const Eeprom24&);
+ Eeprom24& operator=(const Eeprom24);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/UiEngine/UiMenu.h b/STM32F415APP/DevCore/UiEngine/UiMenu.h index a9e2c8c..6e57062 100644 --- a/STM32F415APP/DevCore/UiEngine/UiMenu.h +++ b/STM32F415APP/DevCore/UiEngine/UiMenu.h @@ -96,7 +96,7 @@ class UiMenu private:
// Max allowed menu items on the screen
- static const uint32_t MAX_MENU_ITEMS = 10U;
+ static const uint32_t MAX_MENU_ITEMS = 16U;
const char* header_str; // Menu header
String::FontType header_font; // Header font
|