Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nickshl/DevBoy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickshl <nicolai.shlapunov@gmail.com>2018-09-20 07:25:01 +0300
committernickshl <nicolai.shlapunov@gmail.com>2018-09-20 07:25:01 +0300
commitd5784223866b90221b6ccd52cb56f62164e344e1 (patch)
treefcc4d114002504901bb93b00663eab3932d3ad8c /STM32F415APP/DevCore
parente06bf2d8e4df28f5fb6d97f187dfed0f594480f4 (diff)
I2C interface, I2C driver and couple libraries. Also some other minor changes.
Diffstat (limited to 'STM32F415APP/DevCore')
-rw-r--r--STM32F415APP/DevCore/DevCfg.h53
-rw-r--r--STM32F415APP/DevCore/Display/DisplayDrv.cpp16
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalIic.cpp245
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalIic.h153
-rw-r--r--STM32F415APP/DevCore/Framework/Result.h23
-rw-r--r--STM32F415APP/DevCore/Interfaces/IIic.h156
-rw-r--r--STM32F415APP/DevCore/Libraries/BoschBME280.cpp402
-rw-r--r--STM32F415APP/DevCore/Libraries/BoschBME280.h306
-rw-r--r--STM32F415APP/DevCore/Libraries/Eeprom24.cpp114
-rw-r--r--STM32F415APP/DevCore/Libraries/Eeprom24.h107
-rw-r--r--STM32F415APP/DevCore/UiEngine/UiMenu.h2
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, &reg, 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, &reg, 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, &reg, 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, &reg, 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