From baf2f26e59da8408ce49cf072441ea0ee69a41c6 Mon Sep 17 00:00:00 2001
From: "Ben V. Brown" <5425387+Ralim@users.noreply.github.com>
Date: Sun, 18 Feb 2024 09:42:08 +1100
Subject: [PATCH] Big overhaul of the UI framework (#1749)
* Starting GUI render refactor to be more immediate mode
Update TemperatureAdjust.cpp
.
Cleanup Soldering
Sleep
SolderingProfiles
Soldering Rework
Rough pass GUI
Temp Adjust
Cleanup old OperatingMode
Debug Menu
* Update TemperatureAdjust.cpp
* Roughing some transition work
* Fixup! Hook in the init starter helper
* Better home screen button handler
* FIXUP! Fix typo's
.
* Update SettingsMenu.cpp
* More settings rework
* More settings rendering
* Fixup
* Transitions
Update SolderingProfile.cpp
Hook in transistions
* Update TemperatureAdjust.cpp
* Update push.yml
* Add auto-repeat to settings menu
* Miniware: Use IT for I2C writes
* Update USBPDDebug_HUSB238.cpp
* Force write screen on side animation cancel
.
* Refactor moving down the settings list
* Update settingsGUI.cpp
* Update I2C_Wrapper.cpp
* Update OLED.cpp
* Rework button handling
* Fix PD debug at boot
* Fixup not showing right menu options
* silence some warnings
* Style cleanup
* Fkit use bit-bang I2C for Miniware
* Update GUIRendering.md
* Fixup transition on enter soldering mode
* Save Settings
* Fixes for some animations not running
Dont bail on animations if keypress is still held
* Fixup settings acceleration
* OLED Up animation
* Link up/down on debug meny
* Make all accelerometers I2C bus aware
Update accelerometers_common.h
* Make I2C mag optional
* Miniware -> Only Bit-Bang I2C
* Fixup for scrollbar
FIXUP! Debug menu returns to home screen
FIXUP! Up oled animation
Fix temp exit
* Settings menu -> Both buttons return a menu layer
* Merge fixup
* Update BMA223.cpp
* Re-Enable OLED sleep
* Save Setting on temp adjust exit
* WiP on startup mode
* Some autostart working
* Add hibernation mode & more autostart fixes
* If cant CJC; go to startup
* Hibernate in sleep
* Cleanup scroll indicator
* FIXUP! Ensure startup warnings are linked in
* FIXUP! Ensure we render out temp change before timing out
* Ensure 100ms delay between CJC samples
* Fix not re-calculating menu length on entering menu
* Implement NegotiationinProgress for USB-PD
* Mask heating until PD finishes negotiation
* Fixup staying in hibernate correctly
* Warning timeout
* Show reset settings warning
* Correctly compensate help text start time
* Update GUIThread.cpp
* Update USBPD.cpp
* .
* Fixup sleep time
* Update printSleepCountdown.cpp
* replacing countdown with big plus while in boost mode
* bringing back the + 1 since it was missing when not in boost mode
* Bail on USB-PD check after 3 seconds incase of DC source
* Fix hibernate
* Update PIDThread.cpp
* did center plus symbol (boost mode)
* Big refactor to not make settings increment handler handle the "is last item" return
* Fixup boot logo
* Fix flashing
* Fixup recalculate the menu length on long hold
* Fixup missing menu entries
* Fix junk left on screen after user confirmation
* Re-order button handler to use custom, then default order to allow setting associated setting
* Attach setting for settings using custom handler
* Fix swap +/- keys
* Fix boost temp
* Implement last menu option for Language selector
* Wait for init before CJC runs
* Check last setting via increment value
* Update BSP.cpp
* removed = from >=
Otherwise incrementing would stop and the scroll bar would already flash at the second to last value.
* (Hacky) Fix for Settings reset
---------
Co-authored-by: discip <53649486+discip@users.noreply.github.com>
---
.github/workflows/push.yml | 12 +-
source/Core/BSP/Miniware/BSP.cpp | 7 -
.../Inc/stm32f1xx_hal_i2c.h | 634 ---
.../Src/stm32f1xx_hal_i2c.c | 4569 -----------------
source/Core/BSP/Miniware/configuration.h | 10 +
.../NMSIS/Core/Include/core_feature_base.h | 14 +-
source/Core/BSP/Pinecil/configuration.h | 11 +-
source/Core/BSP/Pinecilv2/ble_handlers.cpp | 8 +-
source/Core/BSP/Pinecilv2/configuration.h | 1 +
source/Core/Drivers/BMA223.hpp | 1 +
source/Core/Drivers/MMA8652FC.cpp | 4 +
source/Core/Drivers/OLED.cpp | 88 +-
source/Core/Drivers/OLED.hpp | 5 +-
source/Core/Drivers/Si7210.cpp | 4 +-
source/Core/Drivers/Si7210.h | 5 +-
source/Core/Drivers/TipThermoModel.h | 4 +-
source/Core/Drivers/USBPD.cpp | 11 +
source/Core/Inc/ScrollMessage.hpp | 57 +-
source/Core/Inc/Settings.h | 5 +-
source/Core/Inc/Translation.h | 3 +-
source/Core/Inc/Types.h | 2 +-
source/Core/Inc/settingsGUI.hpp | 14 +-
source/Core/LangSupport/lang_multi.cpp | 5 +-
source/Core/LangSupport/lang_single.cpp | 3 +-
source/Core/Src/ScrollMessage.cpp | 33 +-
source/Core/Src/Settings.cpp | 35 +-
source/Core/Src/settingsGUI.cpp | 400 +-
source/Core/Threads/GUIRendering.md | 40 +
source/Core/Threads/GUIThread.cpp | 215 +-
source/Core/Threads/OperatingModes/CJC.cpp | 66 +-
.../Core/Threads/OperatingModes/DebugMenu.cpp | 187 +-
.../Threads/OperatingModes/HomeScreen.cpp | 118 +-
.../Threads/OperatingModes/OperatingModes.cpp | 3 -
.../Threads/OperatingModes/OperatingModes.h | 75 +-
.../Threads/OperatingModes/SettingsMenu.cpp | 275 +
.../OperatingModes/ShowStartupWarnings.cpp | 123 +-
source/Core/Threads/OperatingModes/Sleep.cpp | 94 +-
.../Core/Threads/OperatingModes/Soldering.cpp | 272 +-
.../OperatingModes/SolderingProfile.cpp | 350 +-
.../OperatingModes/TemperatureAdjust.cpp | 200 +-
.../OperatingModes/USBPDDebug_FUSB.cpp | 144 +-
.../OperatingModes/USBPDDebug_HUSB238.cpp | 5 +-
.../utils/DrawTipTemperature.cpp | 1 +
.../utils/OperatingModeUtilities.h | 25 +-
.../OperatingModes/utils/ShowWarning.cpp | 10 +-
.../OperatingModes/utils/SolderingCommon.cpp | 23 +-
.../OperatingModes/utils/SolderingCommon.h | 15 +-
.../utils/printSleepCountdown.cpp | 2 +-
.../utils/shouldDeviceSleep.cpp | 10 +-
source/Core/Threads/PIDThread.cpp | 21 +-
50 files changed, 1663 insertions(+), 6556 deletions(-)
delete mode 100644 source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
create mode 100644 source/Core/Threads/GUIRendering.md
create mode 100644 source/Core/Threads/OperatingModes/SettingsMenu.cpp
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 42d20b7f8b..cb64cb5c54 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -1,6 +1,16 @@
name: CI
-on: [push, pull_request]
+on:
+ push:
+ branches:
+ - master
+ - dev
+ - main
+ pull_request:
+ branches:
+ - master
+ - dev
+ - main
jobs:
build:
diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp
index df45516b5d..0ad8f4d42b 100644
--- a/source/Core/BSP/Miniware/BSP.cpp
+++ b/source/Core/BSP/Miniware/BSP.cpp
@@ -360,14 +360,7 @@ uint8_t preStartChecks() {
}
#endif
-#ifdef POW_PD
- // If we are in the middle of negotiating PD, wait until timeout
- // Before turning on the heater
- if (!USBPowerDelivery::negotiationComplete()) {
- return 0;
- }
-#endif
return 1;
}
uint64_t getDeviceID() {
diff --git a/source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h b/source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
index 817f86e98c..a9c8a22765 100644
--- a/source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
+++ b/source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
@@ -1,639 +1,5 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_i2c.h
- * @author MCD Application Team
- * @brief Header file of I2C HAL module.
- ******************************************************************************
- * @attention
- *
- *
© COPYRIGHT(c) 2016 STMicroelectronics
- *
- * 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 STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 OF 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.
- *
- ******************************************************************************
- */
-/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_I2C_H
#define __STM32F1xx_HAL_I2C_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal_def.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup I2C
- * @{
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup I2C_Exported_Types I2C Exported Types
- * @{
- */
-
-/**
- * @brief I2C Configuration Structure definition
- */
-typedef struct {
- uint32_t ClockSpeed; /*!< Specifies the clock frequency.
- This parameter must be set to a value lower than 400kHz */
-
- uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
- This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
-
- uint32_t OwnAddress1; /*!< Specifies the first device own address.
- This parameter can be a 7-bit or 10-bit address. */
-
- uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
- This parameter can be a value of @ref I2C_addressing_mode */
-
- uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
- This parameter can be a value of @ref I2C_dual_addressing_mode */
-
- uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
- This parameter can be a 7-bit address. */
-
- uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
- This parameter can be a value of @ref I2C_general_call_addressing_mode */
-
- uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
- This parameter can be a value of @ref I2C_nostretch_mode */
-
-} I2C_InitTypeDef;
-
-/**
- * @brief HAL State structure definition
- * @note HAL I2C State value coding follow below described bitmap :
- * b7-b6 Error information
- * 00 : No Error
- * 01 : Abort (Abort user request on going)
- * 10 : Timeout
- * 11 : Error
- * b5 IP initilisation status
- * 0 : Reset (IP not initialized)
- * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called)
- * b4 (not used)
- * x : Should be set to 0
- * b3
- * 0 : Ready or Busy (No Listen mode ongoing)
- * 1 : Listen (IP in Address Listen Mode)
- * b2 Intrinsic process state
- * 0 : Ready
- * 1 : Busy (IP busy with some configuration or internal operations)
- * b1 Rx state
- * 0 : Ready (no Rx operation ongoing)
- * 1 : Busy (Rx operation ongoing)
- * b0 Tx state
- * 0 : Ready (no Tx operation ongoing)
- * 1 : Busy (Tx operation ongoing)
- */
-typedef enum {
- HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */
- HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */
- HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */
- HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */
- HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
- HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */
- HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission
- process is ongoing */
- HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception
- process is ongoing */
- HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */
- HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */
- HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */
-
-} HAL_I2C_StateTypeDef;
-
-/**
- * @brief HAL Mode structure definition
- * @note HAL I2C Mode value coding follow below described bitmap :
- * b7 (not used)
- * x : Should be set to 0
- * b6
- * 0 : None
- * 1 : Memory (HAL I2C communication is in Memory Mode)
- * b5
- * 0 : None
- * 1 : Slave (HAL I2C communication is in Slave Mode)
- * b4
- * 0 : None
- * 1 : Master (HAL I2C communication is in Master Mode)
- * b3-b2-b1-b0 (not used)
- * xxxx : Should be set to 0000
- */
-typedef enum {
- HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
- HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
- HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
- HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
-
-} HAL_I2C_ModeTypeDef;
-
-/**
- * @brief I2C handle Structure definition
- */
-typedef struct {
- I2C_TypeDef *Instance; /*!< I2C registers base address */
-
- I2C_InitTypeDef Init; /*!< I2C communication parameters */
-
- uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
-
- uint16_t XferSize; /*!< I2C transfer size */
-
- __IO uint16_t XferCount; /*!< I2C transfer counter */
-
- __IO uint32_t XferOptions; /*!< I2C transfer options */
-
- __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode
- context for internal usage */
-
- DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
-
- DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
-
- HAL_LockTypeDef Lock; /*!< I2C locking object */
-
- __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
-
- __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
-
- __IO uint32_t ErrorCode; /*!< I2C Error code */
-
- __IO uint32_t Devaddress; /*!< I2C Target device address */
-
- __IO uint32_t Memaddress; /*!< I2C Target memory address */
-
- __IO uint32_t MemaddSize; /*!< I2C Target memory address size */
-
- __IO uint32_t EventCount; /*!< I2C Event counter */
-
-} I2C_HandleTypeDef;
-
-/**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup I2C_Exported_Constants I2C Exported Constants
- * @{
- */
-
-/** @defgroup I2C_Error_Code I2C Error Code
- * @brief I2C Error Code
- * @{
- */
-#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */
-#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */
-#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */
-#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */
-#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */
-#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */
-#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */
-/**
- * @}
- */
-
-/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode
- * @{
- */
-#define I2C_DUTYCYCLE_2 0x00000000U
-#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY
-/**
- * @}
- */
-
-/** @defgroup I2C_addressing_mode I2C addressing mode
- * @{
- */
-#define I2C_ADDRESSINGMODE_7BIT 0x00004000U
-// #define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U)
-/**
- * @}
- */
-
-/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode
- * @{
- */
-#define I2C_DUALADDRESS_DISABLE 0x00000000U
-#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL
-/**
- * @}
- */
-
-/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode
- * @{
- */
-#define I2C_GENERALCALL_DISABLE 0x00000000U
-#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC
-/**
- * @}
- */
-
-/** @defgroup I2C_nostretch_mode I2C nostretch mode
- * @{
- */
-#define I2C_NOSTRETCH_DISABLE 0x00000000U
-#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
-/**
- * @}
- */
-
-/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size
- * @{
- */
-#define I2C_MEMADD_SIZE_8BIT 0x00000001U
-#define I2C_MEMADD_SIZE_16BIT 0x00000010U
-/**
- * @}
- */
-
-/** @defgroup I2C_XferDirection_definition I2C XferDirection definition
- * @{
- */
-#define I2C_DIRECTION_RECEIVE 0x00000000U
-#define I2C_DIRECTION_TRANSMIT 0x00000001U
-/**
- * @}
- */
-
-/** @defgroup I2C_XferOptions_definition I2C XferOptions definition
- * @{
- */
-#define I2C_FIRST_FRAME 0x00000001U
-#define I2C_NEXT_FRAME 0x00000002U
-#define I2C_FIRST_AND_LAST_FRAME 0x00000004U
-#define I2C_LAST_FRAME 0x00000008U
-/**
- * @}
- */
-
-/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition
- * @{
- */
-#define I2C_IT_BUF I2C_CR2_ITBUFEN
-#define I2C_IT_EVT I2C_CR2_ITEVTEN
-#define I2C_IT_ERR I2C_CR2_ITERREN
-/**
- * @}
- */
-
-/** @defgroup I2C_Flag_definition I2C Flag definition
- * @{
- */
-#define I2C_FLAG_SMBALERT 0x00018000U
-#define I2C_FLAG_TIMEOUT 0x00014000U
-#define I2C_FLAG_PECERR 0x00011000U
-#define I2C_FLAG_OVR 0x00010800U
-#define I2C_FLAG_AF 0x00010400U
-#define I2C_FLAG_ARLO 0x00010200U
-#define I2C_FLAG_BERR 0x00010100U
-#define I2C_FLAG_TXE 0x00010080U
-#define I2C_FLAG_RXNE 0x00010040U
-#define I2C_FLAG_STOPF 0x00010010U
-// #define I2C_FLAG_ADD10 0x00010008U
-#define I2C_FLAG_BTF 0x00010004U
-#define I2C_FLAG_ADDR 0x00010002U
-#define I2C_FLAG_SB 0x00010001U
-#define I2C_FLAG_DUALF 0x00100080U
-#define I2C_FLAG_SMBHOST 0x00100040U
-#define I2C_FLAG_SMBDEFAULT 0x00100020U
-#define I2C_FLAG_GENCALL 0x00100010U
-#define I2C_FLAG_TRA 0x00100004U
-#define I2C_FLAG_BUSY 0x00100002U
-#define I2C_FLAG_MSL 0x00100001U
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup I2C_Exported_Macros I2C Exported Macros
- * @{
- */
-
-/** @brief Reset I2C handle state
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET)
-
-/** @brief Enable or disable the specified I2C interrupts.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __INTERRUPT__: specifies the interrupt source to enable or disable.
- * This parameter can be one of the following values:
- * @arg I2C_IT_BUF: Buffer interrupt enable
- * @arg I2C_IT_EVT: Event interrupt enable
- * @arg I2C_IT_ERR: Error interrupt enable
- * @retval None
- */
-#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__))
-#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__)))
-
-/** @brief Checks if the specified I2C interrupt source is enabled or disabled.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __INTERRUPT__: specifies the I2C interrupt source to check.
- * This parameter can be one of the following values:
- * @arg I2C_IT_BUF: Buffer interrupt enable
- * @arg I2C_IT_EVT: Event interrupt enable
- * @arg I2C_IT_ERR: Error interrupt enable
- * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
- */
-#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
-
-/** @brief Checks whether the specified I2C flag is set or not.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg I2C_FLAG_SMBALERT: SMBus Alert flag
- * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
- * @arg I2C_FLAG_PECERR: PEC error in reception flag
- * @arg I2C_FLAG_OVR: Overrun/Underrun flag
- * @arg I2C_FLAG_AF: Acknowledge failure flag
- * @arg I2C_FLAG_ARLO: Arbitration lost flag
- * @arg I2C_FLAG_BERR: Bus error flag
- * @arg I2C_FLAG_TXE: Data register empty flag
- * @arg I2C_FLAG_RXNE: Data register not empty flag
- * @arg I2C_FLAG_STOPF: Stop detection flag
- * @arg I2C_FLAG_ADD10: 10-bit header sent flag
- * @arg I2C_FLAG_BTF: Byte transfer finished flag
- * @arg I2C_FLAG_ADDR: Address sent flag
- * Address matched flag
- * @arg I2C_FLAG_SB: Start bit flag
- * @arg I2C_FLAG_DUALF: Dual flag
- * @arg I2C_FLAG_SMBHOST: SMBus host header
- * @arg I2C_FLAG_SMBDEFAULT: SMBus default header
- * @arg I2C_FLAG_GENCALL: General call header flag
- * @arg I2C_FLAG_TRA: Transmitter/Receiver flag
- * @arg I2C_FLAG_BUSY: Bus busy flag
- * @arg I2C_FLAG_MSL: Master/Slave flag
- * @retval The new state of __FLAG__ (TRUE or FALSE).
- */
-#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) \
- ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U) ? ((((__HANDLE__)->Instance->SR1) & ((__FLAG__)&I2C_FLAG_MASK)) == ((__FLAG__)&I2C_FLAG_MASK)) \
- : ((((__HANDLE__)->Instance->SR2) & ((__FLAG__)&I2C_FLAG_MASK)) == ((__FLAG__)&I2C_FLAG_MASK)))
-
-/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @param __FLAG__: specifies the flag to clear.
- * This parameter can be any combination of the following values:
- * @arg I2C_FLAG_SMBALERT: SMBus Alert flag
- * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
- * @arg I2C_FLAG_PECERR: PEC error in reception flag
- * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
- * @arg I2C_FLAG_AF: Acknowledge failure flag
- * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
- * @arg I2C_FLAG_BERR: Bus error flag
- * @retval None
- */
-#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__)&I2C_FLAG_MASK))
-
-/** @brief Clears the I2C ADDR pending flag.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \
- do { \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR1; \
- tmpreg = (__HANDLE__)->Instance->SR2; \
- UNUSED(tmpreg); \
- } while (0U)
-
-/** @brief Clears the I2C STOPF pending flag.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \
- do { \
- __IO uint32_t tmpreg = 0x00U; \
- tmpreg = (__HANDLE__)->Instance->SR1; \
- (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \
- UNUSED(tmpreg); \
- } while (0U)
-
-/** @brief Enable the I2C peripheral.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE)
-
-/** @brief Disable the I2C peripheral.
- * @param __HANDLE__: specifies the I2C Handle.
- * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral.
- * @retval None
- */
-#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE)
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup I2C_Exported_Functions
- * @{
- */
-
-/** @addtogroup I2C_Exported_Functions_Group1
- * @{
- */
-/* Initialization/de-initialization functions **********************************/
-HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
-HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c);
-/**
- * @}
- */
-
-/** @addtogroup I2C_Exported_Functions_Group2
- * @{
- */
-/* I/O operation functions *****************************************************/
-/******* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
-HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
-
-/******* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-
-HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress);
-HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c);
-HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
-
-/******* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
-
-/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
-void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode);
-void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
-void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
-/**
- * @}
- */
-
-/** @addtogroup I2C_Exported_Functions_Group3
- * @{
- */
-/* Peripheral State, Mode and Errors functions *********************************/
-HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c);
-HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c);
-uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup I2C_Private_Constants I2C Private Constants
- * @{
- */
-#define I2C_FLAG_MASK 0x0000FFFFU
-#define I2C_MIN_PCLK_FREQ_STANDARD 2000000U /*!< 2 MHz */
-#define I2C_MIN_PCLK_FREQ_FAST 4000000U /*!< 4 MHz */
-/**
- * @}
- */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup I2C_Private_Macros I2C Private Macros
- * @{
- */
-
-#define I2C_MIN_PCLK_FREQ(__PCLK__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__PCLK__) < I2C_MIN_PCLK_FREQ_STANDARD) : ((__PCLK__) < I2C_MIN_PCLK_FREQ_FAST))
-#define I2C_CCR_CALCULATION(__PCLK__, __SPEED__, __COEFF__) (((((__PCLK__)-1U) / ((__SPEED__) * (__COEFF__))) + 1U) & I2C_CCR_CCR)
-#define I2C_FREQRANGE(__PCLK__) ((__PCLK__) / 1000000U)
-#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__)*300U) / 1000U) + 1U))
-#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) ((I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U) < 4U) ? 4U : I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U))
-#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) \
- (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2) ? I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 3U) : (I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 25U) | I2C_DUTYCYCLE_16_9))
-#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) \
- (((__SPEED__) <= 100000U) ? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) \
- : ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U) ? 1U \
- : ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS))
-
-#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0)))
-#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))
-
-#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
-#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300U))) >> 7U) | (uint16_t)(0x00F0U))))
-#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300U))) >> 7U) | (uint16_t)(0x00F1U))))
-
-#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U)))
-#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU))))
-
-/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters
- * @{
- */
-#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || ((CYCLE) == I2C_DUTYCYCLE_16_9))
-#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT))
-#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || ((ADDRESS) == I2C_DUALADDRESS_ENABLE))
-#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || ((CALL) == I2C_GENERALCALL_ENABLE))
-#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || ((STRETCH) == I2C_NOSTRETCH_ENABLE))
-#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || ((SIZE) == I2C_MEMADD_SIZE_16BIT))
-#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0) && ((SPEED) <= 400000U))
-#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & (uint32_t)(0xFFFFFC00U)) == 0U)
-#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & (uint32_t)(0xFFFFFF01U)) == 0U)
-#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || ((REQUEST) == I2C_NEXT_FRAME) || ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || ((REQUEST) == I2C_LAST_FRAME))
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup I2C_Private_Functions I2C Private Functions
- * @{
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __STM32F1xx_HAL_I2C_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c b/source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
deleted file mode 100644
index 2c38ddb99f..0000000000
--- a/source/Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
+++ /dev/null
@@ -1,4569 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f1xx_hal_i2c.c
- * @author MCD Application Team
- * @brief I2C HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Inter Integrated Circuit (I2C) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral State, Mode and Error functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The I2C HAL driver can be used as follows:
-
- (#) Declare a I2C_HandleTypeDef handle structure, for example:
- I2C_HandleTypeDef hi2c;
-
- (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API:
- (##) Enable the I2Cx interface clock
- (##) I2C pins configuration
- (+++) Enable the clock for the I2C GPIOs
- (+++) Configure I2C pins as alternate function open-drain
- (##) NVIC configuration if you need to use interrupt process
- (+++) Configure the I2Cx interrupt priority
- (+++) Enable the NVIC I2C IRQ Channel
- (##) DMA Configuration if you need to use DMA process
- (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive channel
- (+++) Enable the DMAx interface clock using
- (+++) Configure the DMA handle parameters
- (+++) Configure the DMA Tx or Rx channel
- (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle
- (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
- the DMA Tx or Rx channel
-
- (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,
- Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure.
-
- (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware
- (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API.
-
- (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady()
-
- (#) For I2C IO and IO MEM operations, three operation modes are available within this driver :
-
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit()
- (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive()
- (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit()
- (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive()
-
- *** Polling mode IO MEM operation ***
- =====================================
- [..]
- (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write()
- (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read()
-
-
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Transmit in master mode an amount of data in non blocking mode using HAL_I2C_Master_Transmit_IT()
- (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback
- (+) Receive in master mode an amount of data in non blocking mode using HAL_I2C_Master_Receive_IT()
- (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback
- (+) Transmit in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Transmit_IT()
- (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback
- (+) Receive in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Receive_IT()
- (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback
- (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2C_ErrorCallback
- (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
- (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
-
- *** Interrupt mode IO sequential operation ***
- ==============================================
- [..]
- (@) These interfaces allow to manage a sequential transfer with a repeated start condition
- when a direction change during transfer
- [..]
- (+) A specific option field manage the different steps of a sequential transfer
- (+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below:
- (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode
- (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
- and data to transfer without a final stop condition
- (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
- and with new data to transfer if the direction change or manage only the new data to transfer
- if no direction change and without a final stop condition in both cases
- (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
- and with new data to transfer if the direction change or manage only the new data to transfer
- if no direction change and with a final stop condition in both cases
-
- (+) Differents sequential I2C interfaces are listed below:
- (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT()
- (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
- (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Receive_IT()
- (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
- (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
- (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
- (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT()
- (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can
- add his own code to check the Address Match Code and the transmission direction request by master (Write/Read).
- (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_ListenCpltCallback()
- (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Transmit_IT()
- (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
- (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Receive_IT()
- (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
- (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2C_ErrorCallback()
-
- *** Interrupt mode IO MEM operation ***
- =======================================
- [..]
- (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using
- HAL_I2C_Mem_Write_IT()
- (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback
- (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using
- HAL_I2C_Mem_Read_IT()
- (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback
- (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2C_ErrorCallback
-
- *** DMA mode IO operation ***
- ==============================
- [..]
- (+) Transmit in master mode an amount of data in non blocking mode (DMA) using
- HAL_I2C_Master_Transmit_DMA()
- (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback
- (+) Receive in master mode an amount of data in non blocking mode (DMA) using
- HAL_I2C_Master_Receive_DMA()
- (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback
- (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using
- HAL_I2C_Slave_Transmit_DMA()
- (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback
- (+) Receive in slave mode an amount of data in non blocking mode (DMA) using
- HAL_I2C_Slave_Receive_DMA()
- (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback
- (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2C_ErrorCallback
- (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
- (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
- add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
-
- *** DMA mode IO MEM operation ***
- =================================
- [..]
- (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using
- HAL_I2C_Mem_Write_DMA()
- (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback
- (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using
- HAL_I2C_Mem_Read_DMA()
- (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can
- add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback
- (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2C_ErrorCallback
-
-
- *** I2C HAL driver macros list ***
- ==================================
- [..]
- Below the list of most used macros in I2C HAL driver.
-
- (+) __HAL_I2C_ENABLE: Enable the I2C peripheral
- (+) __HAL_I2C_DISABLE: Disable the I2C peripheral
- (+) __HAL_I2C_GET_FLAG : Checks whether the specified I2C flag is set or not
- (+) __HAL_I2C_CLEAR_FLAG : Clear the specified I2C pending flag
- (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt
- (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt
-
- [..]
- (@) You can refer to the I2C HAL driver header file for more useful macros
-
- *** I2C Workarounds linked to Silicon Limitation ***
- ====================================================
- [..]
- Below the list of all silicon limitations implemented for HAL on STM32F1xx product.
- (@) See ErrataSheet to know full silicon limitation list of your product.
-
- (#) Workarounds Implemented inside I2C HAL Driver
- (##) Wrong data read into data register (Polling and Interrupt mode)
- (##) Start cannot be generated after a misplaced Stop
- (##) Some software events must be managed before the current byte is being transferred:
- Workaround: Use DMA in general, except when the Master is receiving a single byte.
- For Interupt mode, I2C should have the highest priority in the application.
- (##) Mismatch on the "Setup time for a repeated Start condition" timing parameter:
- Workaround: Reduce the frequency down to 88 kHz or use the I2C Fast-mode if
- supported by the slave.
- (##) Data valid time (tVD;DAT) violated without the OVR flag being set:
- Workaround: If the slave device allows it, use the clock stretching mechanism
- by programming NoStretchMode = I2C_NOSTRETCH_DISABLE in HAL_I2C_Init.
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * 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 STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 OF 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.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f1xx_hal.h"
-
-/** @addtogroup STM32F1xx_HAL_Driver
- * @{
- */
-
-/** @defgroup I2C I2C
- * @brief I2C HAL module driver
- * @{
- */
-
-#ifdef HAL_I2C_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup I2C_Private_Define
- * @{
- */
-#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */
-#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */
-#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */
-
-/* Private define for @ref PreviousState usage */
-#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(uint32_t)HAL_I2C_STATE_READY))) /*!< Mask State define, keep only RX and TX bits */
-#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */
-#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */
-#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */
-#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */
-#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */
-
-/**
- * @}
- */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup I2C_Private_Functions
- * @{
- */
-/* Private functions to handle DMA transfer */
-static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma);
-static void I2C_DMAError(DMA_HandleTypeDef *hdma);
-static void I2C_DMAAbort(DMA_HandleTypeDef *hdma);
-
-static void I2C_ITError(I2C_HandleTypeDef *hi2c);
-
-static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
-static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c);
-
-/* Private functions for I2C transfer IRQ handler */
-static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c);
-
-/**
- * @}
- */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup I2C_Exported_Functions I2C Exported Functions
- * @{
- */
-
-/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
-@verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This subsection provides a set of functions allowing to initialize and
- de-initialize the I2Cx peripheral:
-
- (+) User must Implement HAL_I2C_MspInit() function in which he configures
- all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC).
-
- (+) Call the function HAL_I2C_Init() to configure the selected device with
- the selected configuration:
- (++) Communication Speed
- (++) Duty cycle
- (++) Addressing mode
- (++) Own Address 1
- (++) Dual Addressing mode
- (++) Own Address 2
- (++) General call mode
- (++) Nostretch mode
-
- (+) Call the function HAL_I2C_DeInit() to restore the default configuration
- of the selected I2Cx peripheral.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Initializes the I2C according to the specified parameters
- * in the I2C_InitTypeDef and create the associated handle.
- * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) {
- uint32_t freqrange = 0U;
- uint32_t pclk1 = 0U;
-
- /* Check the I2C handle allocation */
- if (hi2c == NULL) {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
- assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed));
- assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle));
- assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1));
- assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode));
- assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode));
- assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2));
- assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode));
- assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode));
-
- if (hi2c->State == HAL_I2C_STATE_RESET) {
- /* Allocate lock resource and initialize it */
- hi2c->Lock = HAL_UNLOCKED;
- /* Init the low level hardware : GPIO, CLOCK, NVIC */
- HAL_I2C_MspInit(hi2c);
- }
-
- hi2c->State = HAL_I2C_STATE_BUSY;
-
- /* Disable the selected I2C peripheral */
- __HAL_I2C_DISABLE(hi2c);
-
- /* Get PCLK1 frequency */
- pclk1 = HAL_RCC_GetPCLK1Freq();
-
- /* Check the minimum allowed PCLK1 frequency */
- if (I2C_MIN_PCLK_FREQ(pclk1, hi2c->Init.ClockSpeed) == 1U) {
- return HAL_ERROR;
- }
-
- /* Calculate frequency range */
- freqrange = I2C_FREQRANGE(pclk1);
-
- /*---------------------------- I2Cx CR2 Configuration ----------------------*/
- /* Configure I2Cx: Frequency range */
- hi2c->Instance->CR2 = freqrange;
-
- /*---------------------------- I2Cx TRISE Configuration --------------------*/
- /* Configure I2Cx: Rise Time */
- hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed);
-
- /*---------------------------- I2Cx CCR Configuration ----------------------*/
- /* Configure I2Cx: Speed */
- hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle);
-
- /*---------------------------- I2Cx CR1 Configuration ----------------------*/
- /* Configure I2Cx: Generalcall and NoStretch mode */
- hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode);
-
- /*---------------------------- I2Cx OAR1 Configuration ---------------------*/
- /* Configure I2Cx: Own Address1 and addressing mode */
- hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1);
-
- /*---------------------------- I2Cx OAR2 Configuration ---------------------*/
- /* Configure I2Cx: Dual mode and Own Address2 */
- hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2);
-
- /* Enable the selected I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
-
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- return HAL_OK;
-}
-
-/**
- * @brief DeInitializes the I2C peripheral.
- * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) {
- /* Check the I2C handle allocation */
- if (hi2c == NULL) {
- return HAL_ERROR;
- }
-
- /* Check the parameters */
- assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
-
- hi2c->State = HAL_I2C_STATE_BUSY;
-
- /* Disable the I2C Peripheral Clock */
- __HAL_I2C_DISABLE(hi2c);
-
- /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
- HAL_I2C_MspDeInit(hi2c);
-
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->State = HAL_I2C_STATE_RESET;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Release Lock */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
-}
-
-/**
- * @brief I2C MSP Init.
- * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval None
- */
-__weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief I2C MSP DeInit
- * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval None
- */
-__weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2C_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
-@verbatim
- ===============================================================================
- ##### IO operation functions #####
- ===============================================================================
- [..]
- This subsection provides a set of functions allowing to manage the I2C data
- transfers.
-
- (#) There are two modes of transfer:
- (++) Blocking mode : The communication is performed in the polling mode.
- The status of all data processing is returned by the same function
- after finishing transfer.
- (++) No-Blocking mode : The communication is performed using Interrupts
- or DMA. These functions return the status of the transfer startup.
- The end of the data processing will be indicated through the
- dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when
- using DMA mode.
-
- (#) Blocking mode functions are :
- (++) HAL_I2C_Master_Transmit()
- (++) HAL_I2C_Master_Receive()
- (++) HAL_I2C_Slave_Transmit()
- (++) HAL_I2C_Slave_Receive()
- (++) HAL_I2C_Mem_Write()
- (++) HAL_I2C_Mem_Read()
- (++) HAL_I2C_IsDeviceReady()
-
- (#) No-Blocking mode functions with Interrupt are :
- (++) HAL_I2C_Master_Transmit_IT()
- (++) HAL_I2C_Master_Receive_IT()
- (++) HAL_I2C_Slave_Transmit_IT()
- (++) HAL_I2C_Slave_Receive_IT()
- (++) HAL_I2C_Master_Sequential_Transmit_IT()
- (++) HAL_I2C_Master_Sequential_Receive_IT()
- (++) HAL_I2C_Slave_Sequential_Transmit_IT()
- (++) HAL_I2C_Slave_Sequential_Receive_IT()
- (++) HAL_I2C_Mem_Write_IT()
- (++) HAL_I2C_Mem_Read_IT()
-
- (#) No-Blocking mode functions with DMA are :
- (++) HAL_I2C_Master_Transmit_DMA()
- (++) HAL_I2C_Master_Receive_DMA()
- (++) HAL_I2C_Slave_Transmit_DMA()
- (++) HAL_I2C_Slave_Receive_DMA()
- (++) HAL_I2C_Mem_Write_DMA()
- (++) HAL_I2C_Mem_Read_DMA()
-
- (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
- (++) HAL_I2C_MemTxCpltCallback()
- (++) HAL_I2C_MemRxCpltCallback()
- (++) HAL_I2C_MasterTxCpltCallback()
- (++) HAL_I2C_MasterRxCpltCallback()
- (++) HAL_I2C_SlaveTxCpltCallback()
- (++) HAL_I2C_SlaveRxCpltCallback()
- (++) HAL_I2C_ErrorCallback()
- (++) HAL_I2C_AbortCpltCallback()
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Transmits in master mode an amount of data in blocking mode.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param Timeout Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) {
- uint32_t tickstart = 0x00U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) {
- return HAL_BUSY;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Send Slave Address */
- if (I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_ERROR;
- } else {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- while (hi2c->XferSize > 0U) {
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
- hi2c->XferSize--;
-
- if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) {
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
- hi2c->XferSize--;
- }
-
- /* Wait until BTF flag is set */
- if (I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
- }
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receives in master mode an amount of data in blocking mode.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param Timeout Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) {
- uint32_t tickstart = 0x00U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) {
- return HAL_BUSY;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Send Slave Address */
- if (I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_ERROR;
- } else {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
-
- if (hi2c->XferSize == 0U) {
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- } else if (hi2c->XferSize == 1U) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Re-enable IRQs */
- __enable_irq();
- } else if (hi2c->XferSize == 2U) {
- /* Enable Pos */
- hi2c->Instance->CR1 |= I2C_CR1_POS;
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Re-enable IRQs */
- __enable_irq();
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- }
-
- while (hi2c->XferSize > 0U) {
- if (hi2c->XferSize <= 3U) {
- /* One byte */
- if (hi2c->XferSize == 1U) {
- /* Wait until RXNE flag is set */
- if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) {
- return HAL_TIMEOUT;
- } else {
- return HAL_ERROR;
- }
- }
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- /* Two bytes */
- else if (hi2c->XferSize == 2U) {
- /* Wait until BTF flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- /* Re-enable IRQs */
- __enable_irq();
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- /* 3 Last bytes */
- else {
- /* Wait until BTF flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- /* Wait until BTF flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- /* Re-enable IRQs */
- __enable_irq();
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- } else {
- /* Wait until RXNE flag is set */
- if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) {
- return HAL_TIMEOUT;
- } else {
- return HAL_ERROR;
- }
- }
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- }
- }
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Transmits in slave mode an amount of data in blocking mode.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param Timeout Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) {
- uint32_t tickstart = 0x00U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Enable Address Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Wait until ADDR flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- while (hi2c->XferSize > 0U) {
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
- hi2c->XferSize--;
-
- if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) {
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
- hi2c->XferSize--;
- }
- }
-
- /* Wait until AF flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Clear AF flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
-
- /* Disable Address Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive in slave mode an amount of data in blocking mode
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param Timeout Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) {
- uint32_t tickstart = 0x00U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Enable Address Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Wait until ADDR flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- while (hi2c->XferSize > 0U) {
- /* Wait until RXNE flag is set */
- if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) {
- return HAL_TIMEOUT;
- } else {
- return HAL_ERROR;
- }
- }
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- }
-
- /* Wait until STOP flag is set */
- if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Clear STOP flag */
- __HAL_I2C_CLEAR_STOPFLAG(hi2c);
-
- /* Disable Address Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
- hi2c->Devaddress = DevAddress;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
- hi2c->Devaddress = DevAddress;
-
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sequential transmit in master mode an amount of data in non-blocking mode with Interrupt
- * @note This interface allow to manage repeated start condition when a direction change during transfer
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) {
- __IO uint32_t Prev_State = 0x00U;
- __IO uint32_t count = 0x00U;
-
- /* Check the parameters */
- assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Check Busy Flag only if FIRST call of Master interface */
- if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = XferOptions;
- hi2c->XferSize = hi2c->XferCount;
- hi2c->Devaddress = DevAddress;
-
- Prev_State = hi2c->PreviousState;
-
- /* Generate Start */
- if ((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) {
- /* Generate Start condition if first transfer */
- if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) {
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- } else {
- /* Generate ReStart */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- }
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sequential receive in master mode an amount of data in non-blocking mode with Interrupt
- * @note This interface allow to manage repeated start condition when a direction change during transfer
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) {
- __IO uint32_t count = 0U;
-
- /* Check the parameters */
- assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Check Busy Flag only if FIRST call of Master interface */
- if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = XferOptions;
- hi2c->XferSize = hi2c->XferCount;
- hi2c->Devaddress = DevAddress;
-
- if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) {
- /* Generate Start condition if first transfer */
- if ((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate ReStart */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- }
- }
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Enable Address Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferSize = Size;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
-
- /* Enable Address Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sequential transmit in slave mode an amount of data in no-blocking mode with Interrupt
- * @note This interface allow to manage repeated start condition when a direction change during transfer
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) {
- /* Check the parameters */
- assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
- if (hi2c->State == HAL_I2C_STATE_LISTEN) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = XferOptions;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Sequential receive in slave mode an amount of data in non-blocking mode with Interrupt
- * @note This interface allow to manage repeated start condition when a direction change during transfer
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) {
- /* Check the parameters */
- assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
- if (hi2c->State == HAL_I2C_STATE_LISTEN) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = XferOptions;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Enable the Address listen mode with Interrupt.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) {
- if (hi2c->State == HAL_I2C_STATE_READY) {
- hi2c->State = HAL_I2C_STATE_LISTEN;
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Enable Address Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Enable EVT and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Disable the Address listen mode with Interrupt.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) {
- /* Declaration of tmp to prevent undefined behavior of volatile usage */
- uint32_t tmp;
-
- /* Disable Address listen mode only if a transfer is not ongoing */
- if (hi2c->State == HAL_I2C_STATE_LISTEN) {
- tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
- hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Disable Address Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Disable EVT and ERR interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Transmit in master mode an amount of data in non-blocking mode with DMA
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
- hi2c->Devaddress = DevAddress;
-
- if (hi2c->XferSize > 0U) {
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
-
- /* Set the unused DMA callbacks to NULL */
- hi2c->hdmatx->XferHalfCpltCallback = NULL;
- hi2c->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
-
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
-
- /* Enable DMA Request */
- hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
- }
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive in master mode an amount of data in non-blocking mode with DMA
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_MASTER;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
- hi2c->Devaddress = DevAddress;
-
- if (hi2c->XferSize > 0U) {
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
-
- /* Set the unused DMA callbacks to NULL */
- hi2c->hdmarx->XferHalfCpltCallback = NULL;
- hi2c->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
-
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
-
- /* Enable DMA Request */
- hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
- }
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Abort a master I2C process communication with Interrupt.
- * @note This abort can be called only if state is ready
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(DevAddress);
-
- /* Abort Master transfer during Receive or Transmit process */
- if (hi2c->Mode == HAL_I2C_MODE_MASTER) {
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_ABORT;
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- hi2c->XferCount = 0U;
-
- /* Disable EVT, BUF and ERR interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Call the corresponding callback to inform upper layer of End of Transfer */
- I2C_ITError(hi2c);
-
- return HAL_OK;
- } else {
- /* Wrong usage of abort function */
- /* This function should be used only in case of abort monitored by master device */
- return HAL_ERROR;
- }
-}
-
-/**
- * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
-
- /* Set the unused DMA callbacks to NULL */
- hi2c->hdmatx->XferHalfCpltCallback = NULL;
- hi2c->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
-
- /* Enable Address Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
- /* Enable EVT and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
-
- /* Enable DMA Request */
- hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Receive in slave mode an amount of data in non-blocking mode with DMA
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- if ((pData == NULL) || (Size == 0U)) {
- return HAL_ERROR;
- }
-
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_SLAVE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
-
- /* Set the unused DMA callbacks to NULL */
- hi2c->hdmarx->XferHalfCpltCallback = NULL;
- hi2c->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
-
- /* Enable Address Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
- /* Enable EVT and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
-
- /* Enable DMA Request */
- hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-/**
- * @brief Write an amount of data in blocking mode to a specific memory address
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param Timeout Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) {
- uint32_t tickstart = 0x00U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- /* Check the parameters */
- assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) {
- return HAL_BUSY;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_MEM;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Send Slave Address and Memory Address */
- if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_ERROR;
- } else {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
-
- while (hi2c->XferSize > 0U) {
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) {
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- }
-
- /* Wait until BTF flag is set */
- if (I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Read an amount of data in blocking mode from a specific memory address
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @param Timeout Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) {
- uint32_t tickstart = 0x00U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- /* Check the parameters */
- assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) {
- return HAL_BUSY;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_MEM;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- /* Send Slave Address and Memory Address */
- if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_ERROR;
- } else {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
-
- if (hi2c->XferSize == 0U) {
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- } else if (hi2c->XferSize == 1U) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Re-enable IRQs */
- __enable_irq();
- } else if (hi2c->XferSize == 2U) {
- /* Enable Pos */
- hi2c->Instance->CR1 |= I2C_CR1_POS;
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Re-enable IRQs */
- __enable_irq();
- } else {
- /* Enable Acknowledge */
- SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- }
-
- while (hi2c->XferSize > 0U) {
- if (hi2c->XferSize <= 3U) {
- /* One byte */
- if (hi2c->XferSize == 1U) {
- /* Wait until RXNE flag is set */
- if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) {
- return HAL_TIMEOUT;
- } else {
- return HAL_ERROR;
- }
- }
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- /* Two bytes */
- else if (hi2c->XferSize == 2U) {
- /* Wait until BTF flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- /* Re-enable IRQs */
- __enable_irq();
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- /* 3 Last bytes */
- else {
- /* Wait until BTF flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- software sequence must complete before the current byte end of transfer */
- __disable_irq();
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- /* Wait until BTF flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- /* Re-enable IRQs */
- __enable_irq();
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- } else {
- /* Wait until RXNE flag is set */
- if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) {
- return HAL_TIMEOUT;
- } else {
- return HAL_ERROR;
- }
- }
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
-
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- }
- }
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- /* Check the parameters */
- assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_MEM;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferSize = Size;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->Devaddress = DevAddress;
- hi2c->Memaddress = MemAddress;
- hi2c->MemaddSize = MemAddSize;
- hi2c->EventCount = 0U;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- /* Check the parameters */
- assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_MEM;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferSize = Size;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->Devaddress = DevAddress;
- hi2c->Memaddress = MemAddress;
- hi2c->MemaddSize = MemAddSize;
- hi2c->EventCount = 0U;
-
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- if (hi2c->XferSize > 0U) {
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
-
- /* Enable EVT, BUF and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
- }
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) {
- __IO uint32_t count = 0U;
-
- uint32_t tickstart = 0x00U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- /* Check the parameters */
- assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_MEM;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferSize = Size;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
-
- if (hi2c->XferSize > 0U) {
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
-
- /* Set the unused DMA callbacks to NULL */
- hi2c->hdmatx->XferHalfCpltCallback = NULL;
- hi2c->hdmatx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
-
- /* Send Slave Address and Memory Address */
- if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_ERROR;
- } else {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
- /* Enable ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR);
-
- /* Enable DMA Request */
- hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
- }
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param pData Pointer to data buffer
- * @param Size Amount of data to be read
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) {
- uint32_t tickstart = 0x00U;
- __IO uint32_t count = 0U;
-
- /* Init tickstart for timeout management*/
- tickstart = HAL_GetTick();
-
- /* Check the parameters */
- assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
- do {
- if (count-- == 0U) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- } while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY_RX;
- hi2c->Mode = HAL_I2C_MODE_MEM;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Prepare transfer parameters */
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->XferSize = hi2c->XferCount;
-
- if (hi2c->XferSize > 0U) {
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
-
- /* Set the unused DMA callbacks to NULL */
- hi2c->hdmarx->XferAbortCallback = NULL;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
-
- /* Send Slave Address and Memory Address */
- if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_ERROR;
- } else {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
-
- if (Size == 1U) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
- } else {
- /* Enable Last DMA bit */
- hi2c->Instance->CR2 |= I2C_CR2_LAST;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Note : The I2C interrupts must be enabled after unlocking current process
- to avoid the risk of I2C interrupt handle execution before current
- process unlock */
- /* Enable ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR);
-
- /* Enable DMA Request */
- hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
- } else {
- /* Send Slave Address and Memory Address */
- if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_ERROR;
- } else {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- }
-
- return HAL_OK;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief Checks if target device is ready for communication.
- * @note This function is used with Memory devices
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param Trials Number of trials
- * @param Timeout Timeout duration
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) {
- uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- if (hi2c->State == HAL_I2C_STATE_READY) {
- /* Wait until BUSY flag is reset */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) {
- return HAL_BUSY;
- }
-
- /* Process Locked */
- __HAL_LOCK(hi2c);
-
- /* Check if the I2C is already enabled */
- if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) {
- /* Enable I2C peripheral */
- __HAL_I2C_ENABLE(hi2c);
- }
-
- /* Disable Pos */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- hi2c->State = HAL_I2C_STATE_BUSY;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
-
- do {
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Wait until SB flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Send slave address */
- hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
-
- /* Wait until ADDR or AF flag are set */
- /* Get tick */
- tickstart = HAL_GetTick();
-
- tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
- tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
- tmp3 = hi2c->State;
- while ((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) {
- if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) {
- hi2c->State = HAL_I2C_STATE_TIMEOUT;
- }
- tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
- tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
- tmp3 = hi2c->State;
- }
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Check if the ADDR flag has been set */
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Clear ADDR Flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Wait until BUSY flag is reset */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_OK;
- } else {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Clear AF Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
-
- /* Wait until BUSY flag is reset */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
- }
- } while (I2C_Trials++ < Trials);
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_ERROR;
- } else {
- return HAL_BUSY;
- }
-}
-
-/**
- * @brief This function handles I2C event interrupt request.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) {
- uint32_t sr2itflags = READ_REG(hi2c->Instance->SR2);
- uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1);
- uint32_t itsources = READ_REG(hi2c->Instance->CR2);
-
- uint32_t CurrentMode = hi2c->Mode;
-
- /* Master or Memory mode selected */
- if ((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) {
- /* SB Set ----------------------------------------------------------------*/
- if (((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) {
- I2C_Master_SB(hi2c);
- }
- /* ADDR Set --------------------------------------------------------------*/
- else if (((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) {
- I2C_Master_ADDR(hi2c);
- }
-
- /* I2C in mode Transmitter -----------------------------------------------*/
- if ((sr2itflags & I2C_FLAG_TRA) != RESET) {
- /* TXE set and BTF reset -----------------------------------------------*/
- if (((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) {
- I2C_MasterTransmit_TXE(hi2c);
- }
- /* BTF set -------------------------------------------------------------*/
- else if (((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) {
- I2C_MasterTransmit_BTF(hi2c);
- }
- }
- /* I2C in mode Receiver --------------------------------------------------*/
- else {
- /* RXNE set and BTF reset -----------------------------------------------*/
- if (((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) {
- I2C_MasterReceive_RXNE(hi2c);
- }
- /* BTF set -------------------------------------------------------------*/
- else if (((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) {
- I2C_MasterReceive_BTF(hi2c);
- }
- }
- }
- /* Slave mode selected */
-#if 0
- else
- {
- /* ADDR set --------------------------------------------------------------*/
- if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET))
- {
- I2C_Slave_ADDR(hi2c);
- }
- /* STOPF set --------------------------------------------------------------*/
- else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET))
- {
- I2C_Slave_STOPF(hi2c);
- }
- /* I2C in mode Transmitter -----------------------------------------------*/
- else if((sr2itflags & I2C_FLAG_TRA) != RESET)
- {
- /* TXE set and BTF reset -----------------------------------------------*/
- if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET))
- {
- I2C_SlaveTransmit_TXE(hi2c);
- }
- /* BTF set -------------------------------------------------------------*/
- else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET))
- {
- I2C_SlaveTransmit_BTF(hi2c);
- }
- }
- /* I2C in mode Receiver --------------------------------------------------*/
- else
- {
- /* RXNE set and BTF reset ----------------------------------------------*/
- if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET))
- {
- I2C_SlaveReceive_RXNE(hi2c);
- }
- /* BTF set -------------------------------------------------------------*/
- else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET))
- {
- I2C_SlaveReceive_BTF(hi2c);
- }
- }
- }
-#endif
-}
-
-/**
- * @brief This function handles I2C error interrupt request.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) {
- uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U;
- uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1);
- uint32_t itsources = READ_REG(hi2c->Instance->CR2);
-
- /* I2C Bus error interrupt occurred ----------------------------------------*/
- if (((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) {
- hi2c->ErrorCode |= HAL_I2C_ERROR_BERR;
-
- /* Clear BERR flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
-
- /* Workaround: Start cannot be generated after a misplaced Stop */
- SET_BIT(hi2c->Instance->CR1, I2C_CR1_SWRST);
- }
-
- /* I2C Arbitration Loss error interrupt occurred ---------------------------*/
- if (((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) {
- hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO;
-
- /* Clear ARLO flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
- }
-
- /* I2C Acknowledge failure error interrupt occurred ------------------------*/
- if (((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) {
- tmp1 = hi2c->Mode;
- tmp2 = hi2c->XferCount;
- tmp3 = hi2c->State;
- tmp4 = hi2c->PreviousState;
- if ((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) &&
- ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) {
- } else {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
-
- /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */
- if (hi2c->Mode == HAL_I2C_MODE_MASTER) {
- /* Generate Stop */
- SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
- }
-
- /* Clear AF flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
- }
- }
-
- /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/
- if (((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) {
- hi2c->ErrorCode |= HAL_I2C_ERROR_OVR;
- /* Clear OVR flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
- }
-
- /* Call the Error Callback in case of Error detected -----------------------*/
- if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE) {
- I2C_ITError(hi2c);
- }
-}
-
-/**
- * @brief Master Tx Transfer completed callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_MasterTxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Master Rx Transfer completed callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_MasterRxCpltCallback can be implemented in the user file
- */
-}
-
-/** @brief Slave Tx Transfer completed callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_SlaveTxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Slave Rx Transfer completed callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_SlaveRxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Slave Address Match callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferOptions_definition
- * @param AddrMatchCode Address Match Code
- * @retval None
- */
-__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
- UNUSED(TransferDirection);
- UNUSED(AddrMatchCode);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_AddrCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Listen Complete callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_ListenCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Memory Tx Transfer completed callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_MemTxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief Memory Rx Transfer completed callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_MemRxCpltCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief I2C error callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_ErrorCallback can be implemented in the user file
- */
-}
-
-/**
- * @brief I2C abort callback.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval None
- */
-__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hi2c);
-
- /* NOTE : This function should not be modified, when the callback is needed,
- the HAL_I2C_AbortCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
- * @brief Peripheral State and Errors functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral State, Mode and Error functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
-
-@endverbatim
- * @{
- */
-
-/**
- * @brief Return the I2C handle state.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval HAL state
- */
-HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) {
- /* Return I2C handle state */
- return hi2c->State;
-}
-
-/**
- * @brief Return the I2C Master, Slave, Memory or no mode.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL mode
- */
-HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c) { return hi2c->Mode; }
-
-/**
- * @brief Return the I2C error code
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval I2C Error Code
- */
-uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) { return hi2c->ErrorCode; }
-
-/**
- * @}
- */
-
-/**
- * @brief Handle TXE flag for Master
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) {
- /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
- uint32_t CurrentState = hi2c->State;
- uint32_t CurrentMode = hi2c->Mode;
- uint32_t CurrentXferOptions = hi2c->XferOptions;
-
- if ((hi2c->XferSize == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX)) {
- /* Call TxCpltCallback() directly if no stop mode is set */
- if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) {
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- HAL_I2C_MasterTxCpltCallback(hi2c);
- } else /* Generate Stop condition then Call TxCpltCallback() */
- {
- /* Disable EVT, BUF and ERR interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- if (hi2c->Mode == HAL_I2C_MODE_MEM) {
- hi2c->Mode = HAL_I2C_MODE_NONE;
- HAL_I2C_MemTxCpltCallback(hi2c);
- } else {
- hi2c->Mode = HAL_I2C_MODE_NONE;
- HAL_I2C_MasterTxCpltCallback(hi2c);
- }
- }
- } else if ((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentMode == HAL_I2C_MODE_MEM) && (CurrentState == HAL_I2C_STATE_BUSY_RX))) {
- if (hi2c->XferCount == 0U) {
- /* Disable BUF interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
- } else {
- if (hi2c->Mode == HAL_I2C_MODE_MEM) {
- if (hi2c->EventCount == 0) {
- /* If Memory address size is 8Bit */
- if (hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT) {
- /* Send Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
-
- hi2c->EventCount += 2;
- }
- /* If Memory address size is 16Bit */
- else {
- /* Send MSB of Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress);
-
- hi2c->EventCount++;
- }
- } else if (hi2c->EventCount == 1) {
- /* Send LSB of Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
-
- hi2c->EventCount++;
- } else if (hi2c->EventCount == 2) {
- if (hi2c->State == HAL_I2C_STATE_BUSY_RX) {
- /* Generate Restart */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- } else if (hi2c->State == HAL_I2C_STATE_BUSY_TX) {
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
- }
- }
- } else {
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief Handle BTF flag for Master transmitter
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c) {
- /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
- uint32_t CurrentXferOptions = hi2c->XferOptions;
-
- if (hi2c->State == HAL_I2C_STATE_BUSY_TX) {
- if (hi2c->XferCount != 0U) {
- /* Write data to DR */
- hi2c->Instance->DR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
- } else {
- /* Call TxCpltCallback() directly if no stop mode is set */
- if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) {
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
- hi2c->Mode = HAL_I2C_MODE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- HAL_I2C_MasterTxCpltCallback(hi2c);
- } else /* Generate Stop condition then Call TxCpltCallback() */
- {
- /* Disable EVT, BUF and ERR interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- if (hi2c->Mode == HAL_I2C_MODE_MEM) {
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- HAL_I2C_MemTxCpltCallback(hi2c);
- } else {
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- HAL_I2C_MasterTxCpltCallback(hi2c);
- }
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief Handle RXNE flag for Master
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) {
- if (hi2c->State == HAL_I2C_STATE_BUSY_RX) {
- uint32_t tmp = 0U;
-
- tmp = hi2c->XferCount;
- if (tmp > 3U) {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferCount--;
- } else if ((tmp == 2U) || (tmp == 3U)) {
- if (hi2c->XferOptions != I2C_NEXT_FRAME) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Enable Pos */
- hi2c->Instance->CR1 |= I2C_CR1_POS;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
- }
-
- /* Disable BUF interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
- } else {
- if (hi2c->XferOptions != I2C_NEXT_FRAME) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
- }
-
- /* Disable EVT, BUF and ERR interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferCount--;
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->PreviousState = I2C_STATE_NONE;
-
- if (hi2c->Mode == HAL_I2C_MODE_MEM) {
- hi2c->Mode = HAL_I2C_MODE_NONE;
- HAL_I2C_MemRxCpltCallback(hi2c);
- } else {
- hi2c->Mode = HAL_I2C_MODE_NONE;
- HAL_I2C_MasterRxCpltCallback(hi2c);
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief Handle BTF flag for Master receiver
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) {
- /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
- uint32_t CurrentXferOptions = hi2c->XferOptions;
-
- if (hi2c->XferCount == 3U) {
- if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
- }
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferCount--;
- } else if (hi2c->XferCount == 2U) {
- /* Prepare next transfer or stop current transfer */
- if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) {
- if (CurrentXferOptions != I2C_NEXT_FRAME) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
- }
-
- /* Disable EVT and ERR interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
- } else {
- /* Disable EVT and ERR interrupt */
- __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- }
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferCount--;
-
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferCount--;
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->PreviousState = I2C_STATE_NONE;
-
- if (hi2c->Mode == HAL_I2C_MODE_MEM) {
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- HAL_I2C_MemRxCpltCallback(hi2c);
- } else {
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- HAL_I2C_MasterRxCpltCallback(hi2c);
- }
- } else {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- hi2c->XferCount--;
- }
- return HAL_OK;
-}
-
-/**
- * @brief Handle SB flag for Master
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c) {
- if (hi2c->Mode == HAL_I2C_MODE_MEM) {
- if (hi2c->EventCount == 0U) {
- /* Send slave address */
- hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
- } else {
- hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);
- }
- } else {
- if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) {
- /* Send slave 7 Bits address */
- if (hi2c->State == HAL_I2C_STATE_BUSY_TX) {
- hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
- } else {
- hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);
- }
- } else {
- if (hi2c->EventCount == 0U) {
- /* Send header of slave address */
- hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress);
- } else if (hi2c->EventCount == 1U) {
- /* Send header of slave address */
- hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress);
- }
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Handle ADDR flag for Master
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) {
- /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
- uint32_t CurrentMode = hi2c->Mode;
- uint32_t CurrentXferOptions = hi2c->XferOptions;
- uint32_t Prev_State = hi2c->PreviousState;
-
- if (hi2c->State == HAL_I2C_STATE_BUSY_RX) {
- if ((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM)) {
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- } else {
- if (hi2c->XferCount == 0U) {
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- } else if (hi2c->XferCount == 1U) {
- if (CurrentXferOptions == I2C_NO_OPTION_FRAME) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- } else {
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- }
- }
- /* Prepare next transfer or stop current transfer */
- else if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (Prev_State != I2C_STATE_MASTER_BUSY_RX)) {
- if (hi2c->XferOptions != I2C_NEXT_FRAME) {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- } else {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- }
- } else if (hi2c->XferCount == 2U) {
- if (hi2c->XferOptions != I2C_NEXT_FRAME) {
- /* Enable Pos */
- hi2c->Instance->CR1 |= I2C_CR1_POS;
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- }
-
- if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) {
- /* Enable Last DMA bit */
- hi2c->Instance->CR2 |= I2C_CR2_LAST;
- }
- } else {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) {
- /* Enable Last DMA bit */
- hi2c->Instance->CR2 |= I2C_CR2_LAST;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- }
-
- /* Reset Event counter */
- hi2c->EventCount = 0U;
- }
- } else {
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief I2C interrupts error process
- * @param hi2c I2C handle.
- * @retval None
- */
-static void I2C_ITError(I2C_HandleTypeDef *hi2c) {
- /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
- uint32_t CurrentState = hi2c->State;
-
- if ((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) {
- /* keep HAL_I2C_STATE_LISTEN */
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_LISTEN;
- } else {
- /* If state is an abort treatment on going, don't change state */
- /* This change will be do later */
- if ((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) {
- hi2c->State = HAL_I2C_STATE_READY;
- }
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->Mode = HAL_I2C_MODE_NONE;
- }
-
- /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */
- hi2c->Instance->CR1 &= ~I2C_CR1_POS;
-
- /* Abort DMA transfer */
- if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) {
- hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN;
-
- if (hi2c->hdmatx->State != HAL_DMA_STATE_READY) {
- /* Set the DMA Abort callback :
- will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
- hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
-
- if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) {
- /* Disable I2C peripheral to prevent dummy data in buffer */
- __HAL_I2C_DISABLE(hi2c);
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Call Directly XferAbortCallback function in case of error */
- hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
- }
- } else {
- /* Set the DMA Abort callback :
- will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
- hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
-
- if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) {
- /* Store Last receive data if any */
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- }
-
- /* Disable I2C peripheral to prevent dummy data in buffer */
- __HAL_I2C_DISABLE(hi2c);
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */
- hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
- }
- }
- } else if (hi2c->State == HAL_I2C_STATE_ABORT) {
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Store Last receive data if any */
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- }
-
- /* Disable I2C peripheral to prevent dummy data in buffer */
- __HAL_I2C_DISABLE(hi2c);
-
- /* Call the corresponding callback to inform upper layer of End of Transfer */
- HAL_I2C_AbortCpltCallback(hi2c);
- } else {
- /* Store Last receive data if any */
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) {
- /* Read data from DR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->DR;
- }
-
- /* Call user error callback */
- HAL_I2C_ErrorCallback(hi2c);
- }
- /* STOP Flag is not set after a NACK reception */
- /* So may inform upper layer that listen phase is stopped */
- /* during NACK error treatment */
- if ((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) {
- hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
- HAL_I2C_ListenCpltCallback(hi2c);
- }
-}
-
-/**
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) {
- /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
- uint32_t CurrentXferOptions = hi2c->XferOptions;
-
- /* Generate Start condition if first transfer */
- if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) {
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- } else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) {
- /* Generate ReStart */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- }
-
- /* Wait until SB flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) {
- /* Send slave address */
- hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
- }
-
- /* Wait until ADDR flag is set */
- if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Master sends target device address for read request.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) {
- /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
- uint32_t CurrentXferOptions = hi2c->XferOptions;
-
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start condition if first transfer */
- if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) {
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- } else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) {
- /* Generate ReStart */
- hi2c->Instance->CR1 |= I2C_CR1_START;
- }
-
- /* Wait until SB flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) {
- /* Send slave address */
- hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
- }
-
- /* Wait until ADDR flag is set */
- if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Master sends target device address followed by internal memory address for write request.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) {
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Wait until SB flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Send slave address */
- hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
-
- /* Wait until ADDR flag is set */
- if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* If Memory address size is 8Bit */
- if (MemAddSize == I2C_MEMADD_SIZE_8BIT) {
- /* Send Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
- }
- /* If Memory address size is 16Bit */
- else {
- /* Send MSB of Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress);
-
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Send LSB of Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Master sends target device address followed by internal memory address for read request.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @param DevAddress Target device address: The device 7 bits address value
- * in datasheet must be shifted to the left before calling the interface
- * @param MemAddress Internal memory address
- * @param MemAddSize Size of internal memory address
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) {
- /* Enable Acknowledge */
- hi2c->Instance->CR1 |= I2C_CR1_ACK;
-
- /* Generate Start */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Wait until SB flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Send slave address */
- hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
-
- /* Wait until ADDR flag is set */
- if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
-
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* If Memory address size is 8Bit */
- if (MemAddSize == I2C_MEMADD_SIZE_8BIT) {
- /* Send Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
- }
- /* If Memory address size is 16Bit */
- else {
- /* Send MSB of Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress);
-
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Send LSB of Memory Address */
- hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
- }
-
- /* Wait until TXE flag is set */
- if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- /* Generate Restart */
- hi2c->Instance->CR1 |= I2C_CR1_START;
-
- /* Wait until SB flag is set */
- if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) {
- return HAL_TIMEOUT;
- }
-
- /* Send slave address */
- hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
-
- /* Wait until ADDR flag is set */
- if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) {
- if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) {
- return HAL_ERROR;
- } else {
- return HAL_TIMEOUT;
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief DMA I2C process complete callback.
- * @param hdma DMA handle
- * @retval None
- */
-static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma) {
- I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
- uint32_t CurrentState = hi2c->State;
- uint32_t CurrentMode = hi2c->Mode;
-
- if ((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) {
- /* Disable DMA Request */
- hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN;
-
- hi2c->XferCount = 0U;
-
- /* Enable EVT and ERR interrupt */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
- } else {
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Disable Last DMA */
- hi2c->Instance->CR2 &= ~I2C_CR2_LAST;
-
- /* Disable DMA Request */
- hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN;
-
- hi2c->XferCount = 0U;
-
- /* Check if Errors has been detected during transfer */
- if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE) {
- HAL_I2C_ErrorCallback(hi2c);
- } else {
- hi2c->State = HAL_I2C_STATE_READY;
-
- if (hi2c->Mode == HAL_I2C_MODE_MEM) {
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- HAL_I2C_MemRxCpltCallback(hi2c);
- } else {
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- HAL_I2C_MasterRxCpltCallback(hi2c);
- }
- }
- }
-}
-
-/**
- * @brief DMA I2C communication error callback.
- * @param hdma DMA handle
- * @retval None
- */
-static void I2C_DMAError(DMA_HandleTypeDef *hdma) {
- I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- hi2c->XferCount = 0U;
-
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
-
- HAL_I2C_ErrorCallback(hi2c);
-}
-
-/**
- * @brief DMA I2C communication abort callback
- * (To be called at end of DMA Abort procedure).
- * @param hdma: DMA handle.
- * @retval None
- */
-static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) {
- I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
- /* Disable Acknowledge */
- hi2c->Instance->CR1 &= ~I2C_CR1_ACK;
-
- hi2c->XferCount = 0U;
-
- /* Reset XferAbortCallback */
- hi2c->hdmatx->XferAbortCallback = NULL;
- hi2c->hdmarx->XferAbortCallback = NULL;
-
- /* Check if come from abort from user */
- if (hi2c->State == HAL_I2C_STATE_ABORT) {
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
-
- /* Disable I2C peripheral to prevent dummy data in buffer */
- __HAL_I2C_DISABLE(hi2c);
-
- /* Call the corresponding callback to inform upper layer of End of Transfer */
- HAL_I2C_AbortCpltCallback(hi2c);
- } else {
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Disable I2C peripheral to prevent dummy data in buffer */
- __HAL_I2C_DISABLE(hi2c);
-
- /* Call the corresponding callback to inform upper layer of End of Transfer */
- HAL_I2C_ErrorCallback(hi2c);
- }
-}
-
-/**
- * @brief This function handles I2C Communication Timeout.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @param Flag specifies the I2C flag to check.
- * @param Status The new Flag status (SET or RESET).
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) {
- /* Wait until flag is set */
- while ((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) {
- /* Check for the Timeout */
- if (Timeout != HAL_MAX_DELAY) {
- if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
- hi2c->Mode = HAL_I2C_MODE_NONE;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- }
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief This function handles I2C Communication Timeout for Master addressing phase.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for I2C module
- * @param Flag specifies the I2C flag to check.
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) {
- while (__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) {
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) {
- /* Generate Stop */
- hi2c->Instance->CR1 |= I2C_CR1_STOP;
-
- /* Clear AF Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
-
- hi2c->ErrorCode = HAL_I2C_ERROR_AF;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_ERROR;
- }
-
- /* Check for the Timeout */
- if (Timeout != HAL_MAX_DELAY) {
- if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) {
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief This function handles I2C Communication Timeout for specific usage of TXE flag.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) {
- while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) {
- /* Check if a NACK is detected */
- if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) {
- return HAL_ERROR;
- }
-
- /* Check for the Timeout */
- if (Timeout != HAL_MAX_DELAY) {
- if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief This function handles I2C Communication Timeout for specific usage of BTF flag.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) {
- while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) {
- /* Check if a NACK is detected */
- if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) {
- return HAL_ERROR;
- }
-
- /* Check for the Timeout */
- if (Timeout != HAL_MAX_DELAY) {
- if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief This function handles I2C Communication Timeout for specific usage of STOP flag.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) {
- while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) {
- /* Check if a NACK is detected */
- if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) {
- return HAL_ERROR;
- }
-
- /* Check for the Timeout */
- if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @param Timeout Timeout duration
- * @param Tickstart Tick start value
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) {
-
- while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) {
- /* Check if a STOPF is detected */
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) {
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_ERROR;
- }
-
- /* Check for the Timeout */
- if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_TIMEOUT;
- }
- }
- return HAL_OK;
-}
-
-/**
- * @brief This function handles Acknowledge failed detection during an I2C Communication.
- * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
- * @retval HAL status
- */
-static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) {
- if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) {
- /* Clear NACKF Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
-
- hi2c->ErrorCode = HAL_I2C_ERROR_AF;
- hi2c->PreviousState = I2C_STATE_NONE;
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- return HAL_ERROR;
- }
- return HAL_OK;
-}
-/**
- * @}
- */
-
-#endif /* HAL_I2C_MODULE_ENABLED */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/source/Core/BSP/Miniware/configuration.h b/source/Core/BSP/Miniware/configuration.h
index 6fed0d5341..91923dfa7e 100644
--- a/source/Core/BSP/Miniware/configuration.h
+++ b/source/Core/BSP/Miniware/configuration.h
@@ -177,6 +177,9 @@
#define TIP_RESISTANCE 75 // x10 ohms, 7.5 typical for ts100 tips
#define POW_DC
+#define I2C_SOFT_BUS_1 1
+#define OLED_I2CBB1 1
+#define ACCEL_I2CBB1 1
#define TEMP_TMP36
#endif /* TS100 */
@@ -241,6 +244,9 @@
#define POW_QC
#define TEMP_TMP36
+#define I2C_SOFT_BUS_1 1
+#define OLED_I2CBB1 1
+#define ACCEL_I2CBB1 1
#endif /* TS80 */
#ifdef MODEL_TS80P
@@ -257,6 +263,10 @@
#define USB_PD_EPR_WATTAGE 0 /*No EPR*/
#define POW_QC 1
#define TEMP_NTC
+#define I2C_SOFT_BUS_2 1
+#define I2C_SOFT_BUS_1 1
+#define OLED_I2CBB1 1
+#define ACCEL_I2CBB1 1
#define SC7_ORI_FLIP
#endif /* TS80P */
diff --git a/source/Core/BSP/Pinecil/Vendor/NMSIS/Core/Include/core_feature_base.h b/source/Core/BSP/Pinecil/Vendor/NMSIS/Core/Include/core_feature_base.h
index 0c0e9c3b62..bbae08c7d1 100644
--- a/source/Core/BSP/Pinecil/Vendor/NMSIS/Core/Include/core_feature_base.h
+++ b/source/Core/BSP/Pinecil/Vendor/NMSIS/Core/Include/core_feature_base.h
@@ -282,7 +282,7 @@ typedef union {
*/
#define __RV_CSR_SWAP(csr, val) \
({ \
- register rv_csr_t __v = (unsigned long)(val); \
+ volatile rv_csr_t __v = (unsigned long)(val); \
__ASM volatile("csrrw %0, " STRINGIFY(csr) ", %1" : "=r"(__v) : "rK"(__v) : "memory"); \
__v; \
})
@@ -297,7 +297,7 @@ typedef union {
*/
#define __RV_CSR_READ(csr) \
({ \
- register rv_csr_t __v; \
+ volatile rv_csr_t __v; \
__ASM volatile("csrr %0, " STRINGIFY(csr) : "=r"(__v) : : "memory"); \
__v; \
})
@@ -312,7 +312,7 @@ typedef union {
*/
#define __RV_CSR_WRITE(csr, val) \
({ \
- register rv_csr_t __v = (rv_csr_t)(val); \
+ volatile rv_csr_t __v = (rv_csr_t)(val); \
__ASM volatile("csrw " STRINGIFY(csr) ", %0" : : "rK"(__v) : "memory"); \
})
@@ -328,7 +328,7 @@ typedef union {
*/
#define __RV_CSR_READ_SET(csr, val) \
({ \
- register rv_csr_t __v = (rv_csr_t)(val); \
+ volatile rv_csr_t __v = (rv_csr_t)(val); \
__ASM volatile("csrrs %0, " STRINGIFY(csr) ", %1" : "=r"(__v) : "rK"(__v) : "memory"); \
__v; \
})
@@ -343,7 +343,7 @@ typedef union {
*/
#define __RV_CSR_SET(csr, val) \
({ \
- register rv_csr_t __v = (rv_csr_t)(val); \
+ volatile rv_csr_t __v = (rv_csr_t)(val); \
__ASM volatile("csrs " STRINGIFY(csr) ", %0" : : "rK"(__v) : "memory"); \
})
@@ -359,7 +359,7 @@ typedef union {
*/
#define __RV_CSR_READ_CLEAR(csr, val) \
({ \
- register rv_csr_t __v = (rv_csr_t)(val); \
+ volatile rv_csr_t __v = (rv_csr_t)(val); \
__ASM volatile("csrrc %0, " STRINGIFY(csr) ", %1" : "=r"(__v) : "rK"(__v) : "memory"); \
__v; \
})
@@ -374,7 +374,7 @@ typedef union {
*/
#define __RV_CSR_CLEAR(csr, val) \
({ \
- register rv_csr_t __v = (rv_csr_t)(val); \
+ volatile rv_csr_t __v = (rv_csr_t)(val); \
__ASM volatile("csrc " STRINGIFY(csr) ", %0" : : "rK"(__v) : "memory"); \
})
#endif /* __ASSEMBLY__ */
diff --git a/source/Core/BSP/Pinecil/configuration.h b/source/Core/BSP/Pinecil/configuration.h
index bced820735..7eaf902777 100644
--- a/source/Core/BSP/Pinecil/configuration.h
+++ b/source/Core/BSP/Pinecil/configuration.h
@@ -147,11 +147,12 @@
#define POW_PD 1
#define USB_PD_EPR_WATTAGE 0 /*No EPR (Yet?) */
-#define POW_PD_EXT 0
-#define POW_QC 1
-#define POW_DC 1
-#define POW_QC_20V 1
-#define ENABLE_QC2 1
+#define POW_PD_EXT 0
+#define POW_QC 1
+#define POW_DC 1
+#define POW_QC_20V 1
+#define ENABLE_QC2 1
+#define MAG_SLEEP_SUPPORT 1
#define TEMP_TMP36
#define ACCEL_BMA
#define ACCEL_SC7
diff --git a/source/Core/BSP/Pinecilv2/ble_handlers.cpp b/source/Core/BSP/Pinecilv2/ble_handlers.cpp
index b231981919..28e6ffe5cb 100644
--- a/source/Core/BSP/Pinecilv2/ble_handlers.cpp
+++ b/source/Core/BSP/Pinecilv2/ble_handlers.cpp
@@ -34,7 +34,7 @@
#endif
extern TickType_t lastMovementTime;
-extern OperatingMode currentMode;
+extern OperatingMode currentOperatingMode;
int ble_char_read_status_callback(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset) {
if (attr == NULL || attr->uuid == NULL) {
@@ -123,7 +123,7 @@ int ble_char_read_status_callback(struct bt_conn *conn, const struct bt_gatt_att
break;
case 13:
// Operating mode
- temp = currentMode;
+ temp = (uint32_t)currentOperatingMode;
memcpy(buf, &temp, sizeof(temp));
return sizeof(temp);
break;
@@ -162,7 +162,7 @@ int ble_char_read_bulk_value_callback(struct bt_conn *conn, const struct bt_gatt
TipThermoModel::getTipMaxInC(), // 9 - max temp
TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0), true), // 10 - Raw tip in μV
abs(getRawHallEffect()), // 11 - hall sensor
- currentMode, // 12 - Operating mode
+ (uint32_t)currentOperatingMode, // 12 - Operating mode
x10WattHistory.average(), // 13 - Estimated Wattage *10
};
int lenToCopy = sizeof(bulkData) - offset;
@@ -203,6 +203,8 @@ int ble_char_read_bulk_value_callback(struct bt_conn *conn, const struct bt_gatt
memcpy(buf, &id, sizeof(id));
return sizeof(id);
}
+ default:
+ break;
}
return 0;
}
diff --git a/source/Core/BSP/Pinecilv2/configuration.h b/source/Core/BSP/Pinecilv2/configuration.h
index 84425f0e1a..094727195c 100644
--- a/source/Core/BSP/Pinecilv2/configuration.h
+++ b/source/Core/BSP/Pinecilv2/configuration.h
@@ -153,6 +153,7 @@
#define POW_QC_20V 1 // Supported features
#define POW_EPR 1
#define ENABLE_QC2 1
+#define MAG_SLEEP_SUPPORT 1
#define DEVICE_HAS_VALIDATION_SUPPORT
#define TEMP_NTC
#define ACCEL_BMA
diff --git a/source/Core/Drivers/BMA223.hpp b/source/Core/Drivers/BMA223.hpp
index 34fff54364..54c0db517c 100644
--- a/source/Core/Drivers/BMA223.hpp
+++ b/source/Core/Drivers/BMA223.hpp
@@ -9,6 +9,7 @@
#define CORE_DRIVERS_BMA223_HPP_
#include "BMA223_defines.h"
#include "BSP.h"
+#include "accelerometers_common.h"
#include "I2C_Wrapper.hpp"
#include "accelerometers_common.h"
diff --git a/source/Core/Drivers/MMA8652FC.cpp b/source/Core/Drivers/MMA8652FC.cpp
index ac489d525d..d56f14eb0b 100644
--- a/source/Core/Drivers/MMA8652FC.cpp
+++ b/source/Core/Drivers/MMA8652FC.cpp
@@ -10,6 +10,10 @@
#include "cmsis_os.h"
#include
+#include "MMA8652FC.hpp"
+#include "accelerometers_common.h"
+#include "cmsis_os.h"
+
static const ACCEL_I2C_CLASS::I2C_REG i2c_registers[] = {
{ CTRL_REG2, 0, 0}, // Normal mode
{ CTRL_REG2, 0x40, 2}, // Reset all registers to POR values
diff --git a/source/Core/Drivers/OLED.cpp b/source/Core/Drivers/OLED.cpp
index 03668e624a..d8f046d174 100644
--- a/source/Core/Drivers/OLED.cpp
+++ b/source/Core/Drivers/OLED.cpp
@@ -262,7 +262,8 @@ void OLED::maskScrollIndicatorOnOLED() {
* If forward is true, this displays a forward navigation to the second framebuffer contents.
* Otherwise a rewinding navigation animation is shown to the second framebuffer contents.
*/
-void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
+void OLED::transitionSecondaryFramebuffer(const bool forwardNavigation, const TickType_t viewEnterTime) {
+ bool buttonsReleased = getButtonState() == BUTTON_NONE;
uint8_t *stripBackPointers[4];
stripBackPointers[0] = &secondFrameBuffer[FRAMEBUFFER_START + 0];
stripBackPointers[1] = &secondFrameBuffer[FRAMEBUFFER_START + OLED_WIDTH];
@@ -317,10 +318,14 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
refresh(); // Now refresh to write out the contents to the new page
vTaskDelayUntil(&startDraw, TICKS_100MS / 7);
- if (getButtonState() != BUTTON_NONE) {
+ buttonsReleased |= getButtonState() == BUTTON_NONE;
+ if (getButtonState() != BUTTON_NONE && buttonsReleased) {
+ memcpy(screenBuffer + FRAMEBUFFER_START, secondFrameBuffer + FRAMEBUFFER_START, sizeof(screenBuffer) - FRAMEBUFFER_START);
+ refresh(); // Now refresh to write out the contents to the new page
return;
}
}
+ refresh(); //
}
void OLED::useSecondaryFramebuffer(bool useSecondary) {
@@ -330,6 +335,7 @@ void OLED::useSecondaryFramebuffer(bool useSecondary) {
setFramebuffer(screenBuffer);
}
}
+
/**
* This assumes that the current display output buffer has the current on screen contents
* Then the secondary buffer has the "new" contents to be slid up onto the screen
@@ -337,8 +343,9 @@ void OLED::useSecondaryFramebuffer(bool useSecondary) {
*
* **This function blocks until the transition has completed or user presses button**
*/
-void OLED::transitionScrollDown() {
- TickType_t startDraw = xTaskGetTickCount();
+void OLED::transitionScrollDown(const TickType_t viewEnterTime) {
+ TickType_t startDraw = xTaskGetTickCount();
+ bool buttonsReleased = getButtonState() == BUTTON_NONE;
for (uint8_t heightPos = 0; heightPos < OLED_HEIGHT; heightPos++) {
// For each line, we shuffle all bits up a row
@@ -365,9 +372,9 @@ void OLED::transitionScrollDown() {
// Finally on the bottom row; we shuffle it up ready
secondFrameBuffer[fourthStripPos] >>= 1;
#else
- // Move the MSB off the first strip, and pop MSB from second strip onto the first strip
+ // Move the LSB off the first strip, and pop MSB from second strip onto the first strip
screenBuffer[firstStripPos] = (screenBuffer[firstStripPos] >> 1) | ((screenBuffer[secondStripPos] & 0x01) << 7);
- // Now shuffle off the second strip MSB, and replace it with the MSB of the secondary buffer
+ // Now shuffle off the second strip MSB, and replace it with the LSB of the secondary buffer
screenBuffer[secondStripPos] = (screenBuffer[secondStripPos] >> 1) | ((secondFrameBuffer[firstStripPos] & 0x01) << 7);
// Finally, do the shuffle on the second frame buffer
secondFrameBuffer[firstStripPos] = (secondFrameBuffer[firstStripPos] >> 1) | ((secondFrameBuffer[secondStripPos] & 0x01) << 7);
@@ -375,7 +382,62 @@ void OLED::transitionScrollDown() {
secondFrameBuffer[secondStripPos] >>= 1;
#endif /* OLED_128x32 */
}
- if (getButtonState() != BUTTON_NONE) {
+ buttonsReleased |= getButtonState() == BUTTON_NONE;
+ if (getButtonState() != BUTTON_NONE && buttonsReleased) {
+ // Exit early, but have to transition whole buffer
+ memcpy(screenBuffer + FRAMEBUFFER_START, secondFrameBuffer + FRAMEBUFFER_START, sizeof(screenBuffer) - FRAMEBUFFER_START);
+ refresh(); // Now refresh to write out the contents to the new page
+ return;
+ }
+ refresh(); // Now refresh to write out the contents to the new page
+ vTaskDelayUntil(&startDraw, TICKS_100MS / 7);
+ }
+}
+/**
+ * This assumes that the current display output buffer has the current on screen contents
+ * Then the secondary buffer has the "new" contents to be slid down onto the screen
+ * Sadly we cant use the hardware scroll as some devices with the 128x32 screens dont have the GRAM for holding both screens at once
+ *
+ * **This function blocks until the transition has completed or user presses button**
+ */
+void OLED::transitionScrollUp(const TickType_t viewEnterTime) {
+ TickType_t startDraw = xTaskGetTickCount();
+ bool buttonsReleased = getButtonState() == BUTTON_NONE;
+
+ for (uint8_t heightPos = 0; heightPos < OLED_HEIGHT; heightPos++) {
+ // For each line, we shuffle all bits down a row
+ for (uint8_t xPos = 0; xPos < OLED_WIDTH; xPos++) {
+ const uint16_t firstStripPos = FRAMEBUFFER_START + xPos;
+ const uint16_t secondStripPos = firstStripPos + OLED_WIDTH;
+#ifdef OLED_128x32
+ // For 32 pixel high OLED's we have four strips to tailchain
+ const uint16_t thirdStripPos = secondStripPos + OLED_WIDTH;
+ const uint16_t fourthStripPos = thirdStripPos + OLED_WIDTH;
+ // We are shffling LSB's off the end and pushing bits down
+ screenBuffer[fourthStripPos] = (screenBuffer[fourthStripPos] << 1) | ((screenBuffer[thirdStripPos] & 0x80) >> 7);
+ screenBuffer[thirdStripPos] = (screenBuffer[thirdStripPos] << 1) | ((screenBuffer[secondStripPos] & 0x80) >> 7);
+ screenBuffer[secondStripPos] = (screenBuffer[secondStripPos] << 1) | ((screenBuffer[firstStripPos] & 0x80) >> 7);
+ screenBuffer[firstStripPos] = (screenBuffer[firstStripPos] << 1) | ((secondFrameBuffer[fourthStripPos] & 0x80) >> 7);
+
+ secondFrameBuffer[fourthStripPos] = (secondFrameBuffer[fourthStripPos] << 1) | ((secondFrameBuffer[thirdStripPos] & 0x80) >> 7);
+ secondFrameBuffer[thirdStripPos] = (secondFrameBuffer[thirdStripPos] << 1) | ((secondFrameBuffer[secondStripPos] & 0x80) >> 7);
+ secondFrameBuffer[secondStripPos] = (secondFrameBuffer[secondStripPos] << 1) | ((secondFrameBuffer[firstStripPos] & 0x80) >> 7);
+ // Finally on the bottom row; we shuffle it up ready
+ secondFrameBuffer[firstStripPos] <<= 1;
+#else
+ // We pop the LSB off the bottom row, and replace the MSB in that byte with the LSB of the row above
+ screenBuffer[secondStripPos] = (screenBuffer[secondStripPos] << 1) | ((screenBuffer[firstStripPos] & 0x80) >> 7);
+ // Move the LSB off the first strip, and pop MSB from second strip onto the first strip
+ screenBuffer[firstStripPos] = (screenBuffer[firstStripPos] << 1) | ((secondFrameBuffer[secondStripPos] & 0x80) >> 7);
+
+ // Finally, do the shuffle on the second frame buffer
+ secondFrameBuffer[secondStripPos] = (secondFrameBuffer[secondStripPos] << 1) | ((secondFrameBuffer[firstStripPos] & 0x80) >> 7);
+ // Finally on the bottom row; we shuffle it up ready
+ secondFrameBuffer[firstStripPos] <<= 1;
+#endif /* OLED_128x32 */
+ }
+ buttonsReleased |= getButtonState() == BUTTON_NONE;
+ if (getButtonState() != BUTTON_NONE && buttonsReleased) {
// Exit early, but have to transition whole buffer
memcpy(screenBuffer + FRAMEBUFFER_START, secondFrameBuffer + FRAMEBUFFER_START, sizeof(screenBuffer) - FRAMEBUFFER_START);
refresh(); // Now refresh to write out the contents to the new page
@@ -428,14 +490,18 @@ void OLED::setRotation(bool leftHanded) {
}
void OLED::setBrightness(uint8_t contrast) {
- OLED_Setup_Array[15].val = contrast;
- I2C_CLASS::writeRegistersBulk(DEVICEADDR_OLED, &OLED_Setup_Array[14], 2);
+ if (OLED_Setup_Array[15].val != contrast) {
+ OLED_Setup_Array[15].val = contrast;
+ I2C_CLASS::writeRegistersBulk(DEVICEADDR_OLED, &OLED_Setup_Array[14], 2);
+ }
}
void OLED::setInverseDisplay(bool inverse) {
uint8_t normalInverseCmd = inverse ? 0xA7 : 0xA6;
- OLED_Setup_Array[21].val = normalInverseCmd;
- I2C_CLASS::I2C_RegisterWrite(DEVICEADDR_OLED, 0x80, normalInverseCmd);
+ if (OLED_Setup_Array[21].val != normalInverseCmd) {
+ OLED_Setup_Array[21].val = normalInverseCmd;
+ I2C_CLASS::I2C_RegisterWrite(DEVICEADDR_OLED, 0x80, normalInverseCmd);
+ }
}
// print a string to the current cursor location, len chars MAX
diff --git a/source/Core/Drivers/OLED.hpp b/source/Core/Drivers/OLED.hpp
index 04ce62e491..408119488c 100644
--- a/source/Core/Drivers/OLED.hpp
+++ b/source/Core/Drivers/OLED.hpp
@@ -149,9 +149,10 @@ class OLED {
static void drawHeatSymbol(uint8_t state);
static void drawScrollIndicator(uint8_t p, uint8_t h); // Draws a scrolling position indicator
static void maskScrollIndicatorOnOLED();
- static void transitionSecondaryFramebuffer(bool forwardNavigation);
+ static void transitionSecondaryFramebuffer(const bool forwardNavigation, const TickType_t viewEnterTime);
static void useSecondaryFramebuffer(bool useSecondary);
- static void transitionScrollDown();
+ static void transitionScrollDown(const TickType_t viewEnterTime);
+ static void transitionScrollUp(const TickType_t viewEnterTime);
private:
static bool checkDisplayBufferChecksum() {
diff --git a/source/Core/Drivers/Si7210.cpp b/source/Core/Drivers/Si7210.cpp
index 0bffb671a4..8683672f01 100644
--- a/source/Core/Drivers/Si7210.cpp
+++ b/source/Core/Drivers/Si7210.cpp
@@ -13,7 +13,8 @@
#include "Si7210_defines.h"
#include "accelerometers_common.h"
#include
-bool Si7210::detect() { return ACCEL_I2C_CLASS::wakePart(SI7210_ADDRESS); }
+#ifdef MAG_SLEEP_SUPPORT
+bool Si7210::detect() { return FRToSI2C::wakePart(SI7210_ADDRESS); }
bool Si7210::init() {
// Turn on auto increment and sanity check ID
@@ -185,3 +186,4 @@ bool Si7210::set_high_range() {
worked &= write_reg(SI7210_A5, 0, val);
return worked;
}
+#endif // MAG_SLEEP_SUPPORT
\ No newline at end of file
diff --git a/source/Core/Drivers/Si7210.h b/source/Core/Drivers/Si7210.h
index 305c91ea0a..2bbc46bea6 100644
--- a/source/Core/Drivers/Si7210.h
+++ b/source/Core/Drivers/Si7210.h
@@ -7,7 +7,10 @@
#ifndef CORE_DRIVERS_SI7210_H_
#define CORE_DRIVERS_SI7210_H_
+#include "configuration.h"
#include
+
+#ifdef MAG_SLEEP_SUPPORT
class Si7210 {
public:
// Return true if present
@@ -23,5 +26,5 @@ class Si7210 {
static bool get_field_strength(int16_t *field);
static bool set_high_range();
};
-
+#endif // MAG_SLEEP_SUPPORT
#endif /* CORE_DRIVERS_SI7210_H_ */
diff --git a/source/Core/Drivers/TipThermoModel.h b/source/Core/Drivers/TipThermoModel.h
index 03a10ff0f9..b437b02683 100644
--- a/source/Core/Drivers/TipThermoModel.h
+++ b/source/Core/Drivers/TipThermoModel.h
@@ -5,11 +5,11 @@
* Author: ralim
*/
-#ifndef SRC_TIPTHERMOMODEL_H_
-#define SRC_TIPTHERMOMODEL_H_
#include "BSP.h"
#include "Types.h"
#include "stdint.h"
+#ifndef SRC_TIPTHERMOMODEL_H_
+#define SRC_TIPTHERMOMODEL_H_
class TipThermoModel {
public:
// These are the main two functions
diff --git a/source/Core/Drivers/USBPD.cpp b/source/Core/Drivers/USBPD.cpp
index 8ca000c504..b4cb8987eb 100644
--- a/source/Core/Drivers/USBPD.cpp
+++ b/source/Core/Drivers/USBPD.cpp
@@ -29,6 +29,7 @@ bool EPREvaluateCapabilityFunc(const epr_pd_msg *capabilities, pd_msg *r
FUSB302 fusb((0x22 << 1), fusb_read_buf, fusb_write_buf, ms_delay); // Create FUSB driver
PolicyEngine pe(fusb, get_ms_timestamp, ms_delay, pdbs_dpm_get_sink_capability, pdbs_dpm_evaluate_capability, EPREvaluateCapabilityFunc, USB_PD_EPR_WATTAGE);
int USBPowerDelivery::detectionState = 0;
+bool haveSeenCapabilityOffer = false;
uint16_t requested_voltage_mv = 0;
/* The current draw when the output is disabled */
@@ -51,6 +52,15 @@ void USBPowerDelivery::step() {
}
void USBPowerDelivery::PPSTimerCallback() { pe.TimersCallback(); }
+bool USBPowerDelivery::negotiationInProgress() {
+ if (USBPowerDelivery::negotiationComplete()) {
+ return false;
+ }
+ if (haveSeenCapabilityOffer) {
+ return false;
+ }
+ return true;
+}
bool USBPowerDelivery::negotiationComplete() {
if (!fusbPresent()) {
return true;
@@ -268,6 +278,7 @@ bool EPREvaluateCapabilityFunc(const epr_pd_msg *capabilities, pd_msg *request)
bool pdbs_dpm_evaluate_capability(const pd_msg *capabilities, pd_msg *request) {
memset(lastCapabilities, 0, sizeof(lastCapabilities));
memcpy(lastCapabilities, capabilities->obj, sizeof(uint32_t) * 7);
+ haveSeenCapabilityOffer = true;
/* Get the number of PDOs */
uint8_t numobj = PD_NUMOBJ_GET(capabilities);
diff --git a/source/Core/Inc/ScrollMessage.hpp b/source/Core/Inc/ScrollMessage.hpp
index 3f97fdb996..9352ad4e5f 100644
--- a/source/Core/Inc/ScrollMessage.hpp
+++ b/source/Core/Inc/ScrollMessage.hpp
@@ -4,50 +4,21 @@
#include "portmacro.h"
#include
/**
- * A helper class for showing a full-screen scrolling message.
+ * A helper for showing a full-screen scrolling message.
*/
-class ScrollMessage {
- TickType_t messageStart = 0;
- int16_t lastOffset = -1;
- /**
- * Calcualte the width in pixels of the message string, in the large
- * font and taking into account multi-byte chars.
- *
- * @param message The null-terminated message string.
- */
- static uint16_t messageWidth(const char *message);
-
-public:
- ScrollMessage() {}
-
- /**
- * Resets this `ScrollMessage` instance to its initial state.
- */
- void reset() {
- messageStart = 0;
- lastOffset = -1;
- }
-
- /**
- * Gets whether this `ScrollMessage` instance is in its initial state.
- */
- bool isReset() const { return messageStart == 0; }
-
- /**
- * Draw and update the scroll message if needed.
- *
- * This function does not call `OLED::refresh()`. If this function
- * returns `true`, the caller shall call `OLED::refresh()` to draw the
- * modified framebuffer to the OLED screen.
- *
- * @param message The null-terminated message string. This must be the
- * same string as the previous call, unless this `ScrollMessage` instance
- * is in its initial state or `reset()` has been called.
- * @param currentTick The current tick as returned by `xTaskGetTickCount()`.
- * @return Whether the OLED framebuffer has been modified.
- */
- bool drawUpdate(const char *message, TickType_t currentTick);
-};
+/**
+ * Draw and update the scroll message if needed.
+ *
+ * This function does not call `OLED::refresh()`. If this function
+ * returns `true`, the caller shall call `OLED::refresh()` to draw the
+ * modified framebuffer to the OLED screen.
+ *
+ * @param message The null-terminated message string. This must be the
+ * same string as the previous call, unless this `ScrollMessage` instance
+ * is in its initial state or `reset()` has been called.
+ * @param currentTick The current tick as returned by `xTaskGetTickCount()` offset to 0 at start of scrolling.
+ */
+void drawScrollingText(const char *message, TickType_t currentTickOffset);
#endif /* SCROLL_MESSAGE_HPP_ */
diff --git a/source/Core/Inc/Settings.h b/source/Core/Inc/Settings.h
index f46df53bd9..e332580ee9 100644
--- a/source/Core/Inc/Settings.h
+++ b/source/Core/Inc/Settings.h
@@ -107,8 +107,9 @@ void resetSettings();
uint16_t getSettingValue(const enum SettingsOptions option);
// Returns true if setting is now on the last value (next iteration will wrap)
-bool nextSettingValue(const enum SettingsOptions option);
-bool prevSettingValue(const enum SettingsOptions option);
+void nextSettingValue(const enum SettingsOptions option);
+void prevSettingValue(const enum SettingsOptions option);
+bool isLastSettingValue(const enum SettingsOptions option);
void setSettingValue(const enum SettingsOptions option, const uint16_t newValue);
diff --git a/source/Core/Inc/Translation.h b/source/Core/Inc/Translation.h
index 3b3e85ad7e..a0c84b603e 100644
--- a/source/Core/Inc/Translation.h
+++ b/source/Core/Inc/Translation.h
@@ -183,6 +183,7 @@ const char *translatedString(uint16_t index);
void prepareTranslations();
void settings_displayLanguageSwitch(void);
bool settings_showLanguageSwitch(void);
-bool settings_setLanguageSwitch(void);
+void settings_setLanguageSwitch(void);
+bool isLastLanguageOption(void);
#endif /* TRANSLATION_H_ */
diff --git a/source/Core/Inc/Types.h b/source/Core/Inc/Types.h
index 145cd6beb3..a5d3fe59ff 100644
--- a/source/Core/Inc/Types.h
+++ b/source/Core/Inc/Types.h
@@ -1,6 +1,6 @@
#ifndef TYPES_H_
#define TYPES_H_
-#include
+#include
// Used for temperature represented in C or x10C.
//
diff --git a/source/Core/Inc/settingsGUI.hpp b/source/Core/Inc/settingsGUI.hpp
index f1d9085253..6456da2a5b 100644
--- a/source/Core/Inc/settingsGUI.hpp
+++ b/source/Core/Inc/settingsGUI.hpp
@@ -8,11 +8,11 @@
#ifndef GUI_HPP_
#define GUI_HPP_
#include "BSP.h"
+#include "Buttons.hpp"
#include "FreeRTOS.h"
#include "Settings.h"
#include "Translation.h"
-
#define PRESS_ACCEL_STEP (TICKS_100MS / 3)
#define PRESS_ACCEL_INTERVAL_MIN TICKS_100MS
#define PRESS_ACCEL_INTERVAL_MAX (TICKS_100MS * 3)
@@ -26,9 +26,8 @@ typedef struct {
// The settings description index, please use the `SETTINGS_DESC` macro with
// the `SettingsItemIndex` enum. Use 0 for no description.
uint8_t description;
- // return true if increment reached the maximum value
- bool (*const incrementHandler)(void);
- void (*const draw)(void);
+ void (*const incrementHandler)(void);
+ void (*const draw)(void); // Must not be nullptr, as that marks end of menu
bool (*const isVisible)(void);
// If this is set, we will automatically use the settings increment handler instead, set >= num settings to disable
SettingsOptions autoSettingOption;
@@ -36,8 +35,9 @@ typedef struct {
uint8_t shortDescriptionSize;
} menuitem;
-void enterSettingsMenu();
-void warnUser(const char *warning, const TickType_t timeout);
-extern const menuitem rootSettingsMenu[];
+void enterSettingsMenu();
+bool warnUser(const char *warning, const ButtonState buttons);
+extern const menuitem rootSettingsMenu[];
+extern const menuitem *subSettingsMenus[];
#endif /* GUI_HPP_ */
diff --git a/source/Core/LangSupport/lang_multi.cpp b/source/Core/LangSupport/lang_multi.cpp
index 44e28ad209..8ce45f9643 100644
--- a/source/Core/LangSupport/lang_multi.cpp
+++ b/source/Core/LangSupport/lang_multi.cpp
@@ -63,12 +63,13 @@ void prepareTranslations() {
}
}
-bool settings_setLanguageSwitch(void) {
+void settings_setLanguageSwitch(void) {
selectedLangIndex = (selectedLangIndex + 1) % LanguageCount;
writeSelectedLanguageToSettings();
prepareTranslations();
- return selectedLangIndex == (LanguageCount - 1);
}
bool settings_showLanguageSwitch(void) { return true; }
void settings_displayLanguageSwitch(void) { OLED::printWholeScreen(translatedString(Tr->SettingsShortNames[static_cast(SettingsItemIndex::LanguageSwitch)])); }
+
+bool isLastLanguageOption(void) { return selectedLangIndex == (LanguageCount - 1); }
\ No newline at end of file
diff --git a/source/Core/LangSupport/lang_single.cpp b/source/Core/LangSupport/lang_single.cpp
index 019c0938c3..48d6c8d55d 100644
--- a/source/Core/LangSupport/lang_single.cpp
+++ b/source/Core/LangSupport/lang_single.cpp
@@ -1,6 +1,7 @@
#include "Translation.h"
-bool settings_setLanguageSwitch(void) { return false; }
+void settings_setLanguageSwitch(void) {}
void settings_displayLanguageSwitch(void) {}
bool settings_showLanguageSwitch(void) { return false; }
+bool isLastLanguageOption(void) { return true; }
\ No newline at end of file
diff --git a/source/Core/Src/ScrollMessage.cpp b/source/Core/Src/ScrollMessage.cpp
index d63cede373..ff7a2b5135 100644
--- a/source/Core/Src/ScrollMessage.cpp
+++ b/source/Core/Src/ScrollMessage.cpp
@@ -28,19 +28,20 @@ static uint16_t str_display_len(const char *const str) {
return count;
}
-uint16_t ScrollMessage::messageWidth(const char *message) { return FONT_12_WIDTH * str_display_len(message); }
-
-bool ScrollMessage::drawUpdate(const char *message, TickType_t currentTick) {
- bool lcdRefresh = false;
+/**
+ * Calculate the width in pixels of the message string, in the large
+ * font and taking into account multi-byte chars.
+ *
+ * @param message The null-terminated message string.
+ */
+uint16_t messageWidth(const char *message) { return FONT_12_WIDTH * str_display_len(message); }
- if (messageStart == 0) {
- messageStart = currentTick;
- lcdRefresh = true;
- }
+void drawScrollingText(const char *message, TickType_t currentTickOffset) {
+ OLED::clearScreen();
int16_t messageOffset;
uint16_t msgWidth = messageWidth(message);
if (msgWidth > OLED_WIDTH) {
- messageOffset = ((currentTick - messageStart) / (getSettingValue(SettingsOptions::DescriptionScrollSpeed) == 1 ? TICKS_100MS / 10 : (TICKS_100MS / 5)));
+ messageOffset = (currentTickOffset / (getSettingValue(SettingsOptions::DescriptionScrollSpeed) == 1 ? TICKS_100MS / 10 : (TICKS_100MS / 5)));
messageOffset %= msgWidth + OLED_WIDTH; // Roll around at the end
if (messageOffset < OLED_WIDTH) {
// Snap the message to the left edge.
@@ -54,15 +55,7 @@ bool ScrollMessage::drawUpdate(const char *message, TickType_t currentTick) {
messageOffset = (OLED_WIDTH - msgWidth) / 2 + msgWidth;
}
- if (lastOffset != messageOffset) {
- OLED::clearScreen();
-
- //^ Rolling offset based on time
- OLED::setCursor((OLED_WIDTH - messageOffset), 0);
- OLED::print(message, FontStyle::LARGE);
- lastOffset = messageOffset;
- lcdRefresh = true;
- }
-
- return lcdRefresh;
+ //^ Rolling offset based on time
+ OLED::setCursor((OLED_WIDTH - messageOffset), 0);
+ OLED::print(message, FontStyle::LARGE);
}
diff --git a/source/Core/Src/Settings.cpp b/source/Core/Src/Settings.cpp
index 6ec1d65fc7..540c61549d 100644
--- a/source/Core/Src/Settings.cpp
+++ b/source/Core/Src/Settings.cpp
@@ -188,7 +188,7 @@ uint16_t getSettingValue(const enum SettingsOptions option) { return systemSetti
// Increment by the step size to the next value. If past the end wrap to the minimum
// Returns true if we are on the _last_ value
-bool nextSettingValue(const enum SettingsOptions option) {
+void nextSettingValue(const enum SettingsOptions option) {
const auto constants = settingsConstants[(int)option];
if (systemSettings.settingsValues[(int)option] == (constants.max)) {
// Already at max, wrap to the start
@@ -200,13 +200,38 @@ bool nextSettingValue(const enum SettingsOptions option) {
// Otherwise increment
systemSettings.settingsValues[(int)option] += constants.increment;
}
- // Return if we are at the max
- return constants.max == systemSettings.settingsValues[(int)option];
}
+bool isLastSettingValue(const enum SettingsOptions option) {
+ const auto constants = settingsConstants[(int)option];
+ uint16_t max = constants.max;
+ // handle temp unit limitations
+ if (option == SettingsOptions::SolderingTemp) {
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ max = MAX_TEMP_F;
+ } else {
+ max = MAX_TEMP_C;
+ }
+ } else if (option == SettingsOptions::BoostTemp) {
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ max = MAX_TEMP_F;
+ } else {
+ max = MAX_TEMP_C;
+ }
+ } else if (option == SettingsOptions::SleepTemp) {
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ max = 580;
+ } else {
+ max = 300;
+ }
+ } else if (option == SettingsOptions::UILanguage) {
+ return isLastLanguageOption();
+ }
+ return systemSettings.settingsValues[(int)option] > (max - constants.increment);
+}
// Step backwards on the settings item
// Return true if we are at the end (min)
-bool prevSettingValue(const enum SettingsOptions option) {
+void prevSettingValue(const enum SettingsOptions option) {
const auto constants = settingsConstants[(int)option];
if (systemSettings.settingsValues[(int)option] == (constants.min)) {
// Already at min, wrap to the max
@@ -218,8 +243,6 @@ bool prevSettingValue(const enum SettingsOptions option) {
// Otherwise decrement
systemSettings.settingsValues[(int)option] -= constants.increment;
}
- // Return if we are at the min
- return constants.min == systemSettings.settingsValues[(int)option];
}
uint16_t lookupHallEffectThreshold() {
diff --git a/source/Core/Src/settingsGUI.cpp b/source/Core/Src/settingsGUI.cpp
index 058e87af28..05fc6c63f8 100644
--- a/source/Core/Src/settingsGUI.cpp
+++ b/source/Core/Src/settingsGUI.cpp
@@ -14,8 +14,6 @@
#include "configuration.h"
#include "main.hpp"
-void gui_Menu(const menuitem *menu);
-
#ifdef POW_DC
static void displayInputVRange(void);
static bool showInputVOptions(void);
@@ -36,16 +34,17 @@ static void displayShutdownTime(void);
static bool showSleepOptions(void);
#ifndef NO_SLEEP_MODE
-static bool setSleepTemp(void);
+static void setSleepTemp(void);
static void displaySleepTemp(void);
static void displaySleepTime(void);
#endif /* *not* NO_SLEEP_MODE */
-static bool setTempF(void);
+static void setTempF(void);
static void displayTempF(void);
static void displayAdvancedSolderingScreens(void);
static void displayAdvancedIDLEScreens(void);
static void displayScrollSpeed(void);
+static void displayReverseButtonTempChangeEnabled(void);
static void displayPowerLimit(void);
#ifdef BLE_ENABLED
@@ -53,20 +52,20 @@ static void displayBluetoothLE(void);
#endif /* BLE_ENABLED */
#ifndef NO_DISPLAY_ROTATE
-static bool setDisplayRotation(void);
+static void setDisplayRotation(void);
static void displayDisplayRotation(void);
#endif /* *not* NO_DISPLAY_ROTATE */
-static bool setBoostTemp(void);
+static void setBoostTemp(void);
static void displayBoostTemp(void);
#ifdef PROFILE_SUPPORT
-static bool setProfilePreheatTemp();
-static bool setProfilePhase1Temp();
-static bool setProfilePhase2Temp();
-static bool setProfilePhase3Temp();
-static bool setProfilePhase4Temp();
-static bool setProfilePhase5Temp();
+static void setProfilePreheatTemp();
+static void setProfilePhase1Temp();
+static void setProfilePhase2Temp();
+static void setProfilePhase3Temp();
+static void setProfilePhase4Temp();
+static void setProfilePhase5Temp();
static void displayProfilePhases(void);
static void displayProfilePreheatTemp(void);
static void displayProfilePreheatSpeed(void);
@@ -91,13 +90,10 @@ static bool showProfilePhase5Options(void);
static void displayAutomaticStartMode(void);
static void displayLockingMode(void);
static void displayCoolingBlinkEnabled(void);
-static bool setResetSettings(void);
-static void displayResetSettings(void);
-static bool setCalibrate(void);
+static void setResetSettings(void);
+static void setCalibrate(void);
static void displayCalibrate(void);
-static bool setCalibrateVIN(void);
-static void displayCalibrateVIN(void);
-static void displayReverseButtonTempChangeEnabled(void);
+static void setCalibrateVIN(void);
static void displayTempChangeShortStep(void);
static void displayTempChangeLongStep(void);
static void displayPowerPulse(void);
@@ -120,17 +116,12 @@ static bool showHallEffect(void);
#if defined(POW_DC) || defined(POW_QC)
static void displayPowerMenu(void);
-static bool enterPowerMenu(void);
#endif /* POW_DC or POW_QC */
static void displaySolderingMenu(void);
-static bool enterSolderingMenu(void);
static void displayPowerSavingMenu(void);
-static bool enterPowerSavingMenu(void);
static void displayUIMenu(void);
-static bool enterUIMenu(void);
static void displayAdvancedMenu(void);
-static bool enterAdvancedMenu(void);
/*
* Root Settings Menu
@@ -196,6 +187,7 @@ static bool enterAdvancedMenu(void);
*
*/
+void noOpDisplay() {}
/* vvv !!!DISABLE CLANG-FORMAT for menuitems initialization!!! vvv */
/* clang-format off */
@@ -216,16 +208,16 @@ const menuitem rootSettingsMenu[] {
*/
#if defined(POW_DC) || defined(POW_QC)
/* Power */
- {0, enterPowerMenu, displayPowerMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
+ {0, nullptr, displayPowerMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
#endif
/* Soldering */
- {0, enterSolderingMenu, displaySolderingMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
+ {0, nullptr, displaySolderingMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
/* Sleep Options Menu */
- {0, enterPowerSavingMenu, displayPowerSavingMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
+ {0, nullptr, displayPowerSavingMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
/* UI Menu */
- {0, enterUIMenu, displayUIMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
+ {0, nullptr, displayUIMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
/* Advanced Menu */
- {0, enterAdvancedMenu, displayAdvancedMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
+ {0, nullptr, displayAdvancedMenu, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
/* Language Switch */
{0, settings_setLanguageSwitch, settings_displayLanguageSwitch, settings_showLanguageSwitch, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0},
/* vvvv end of menu marker. DO NOT REMOVE vvvv */
@@ -287,7 +279,7 @@ const menuitem solderingMenu[] = {
* Profile Cooldown Max Temperature Change Per Second
*/
/* Boost Temp */
- {SETTINGS_DESC(SettingsItemIndex::BoostTemperature), setBoostTemp, displayBoostTemp, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::BoostTemperature, 5},
+ {SETTINGS_DESC(SettingsItemIndex::BoostTemperature), setBoostTemp, displayBoostTemp, nullptr, SettingsOptions::BoostTemp, SettingsItemIndex::BoostTemperature, 5},
/* Auto start */
{SETTINGS_DESC(SettingsItemIndex::AutoStart), nullptr, displayAutomaticStartMode, nullptr, SettingsOptions::AutoStartMode, SettingsItemIndex::AutoStart, 7},
/* Temp change short step */
@@ -300,27 +292,27 @@ const menuitem solderingMenu[] = {
/* Profile Phases */
{SETTINGS_DESC(SettingsItemIndex::ProfilePhases), nullptr, displayProfilePhases, nullptr, SettingsOptions::ProfilePhases, SettingsItemIndex::ProfilePhases, 7},
/* Profile Preheat Temp */
- {SETTINGS_DESC(SettingsItemIndex::ProfilePreheatTemp), setProfilePreheatTemp, displayProfilePreheatTemp, showProfileOptions, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePreheatTemp, 5},
+ {SETTINGS_DESC(SettingsItemIndex::ProfilePreheatTemp), setProfilePreheatTemp, displayProfilePreheatTemp, showProfileOptions, SettingsOptions::ProfilePreheatTemp, SettingsItemIndex::ProfilePreheatTemp, 5},
/* Profile Preheat Speed */
{SETTINGS_DESC(SettingsItemIndex::ProfilePreheatSpeed), nullptr, displayProfilePreheatSpeed, showProfileOptions, SettingsOptions::ProfilePreheatSpeed, SettingsItemIndex::ProfilePreheatSpeed, 5},
/* Phase 1 Temp */
- {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase1Temp, displayProfilePhase1Temp, showProfileOptions, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase1Temp, 5},
+ {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase1Temp, displayProfilePhase1Temp, showProfileOptions, SettingsOptions::ProfilePhase1Temp, SettingsItemIndex::ProfilePhase1Temp, 5},
/* Phase 1 Duration */
{SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase1Duration, showProfileOptions, SettingsOptions::ProfilePhase1Duration, SettingsItemIndex::ProfilePhase1Duration, 5},
/* Phase 2 Temp */
- {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase2Temp, displayProfilePhase2Temp, showProfilePhase2Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase2Temp, 5},
+ {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase2Temp, displayProfilePhase2Temp, showProfilePhase2Options, SettingsOptions::ProfilePhase1Temp, SettingsItemIndex::ProfilePhase2Temp, 5},
/* Phase 2 Duration */
{SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase2Duration, showProfilePhase2Options, SettingsOptions::ProfilePhase2Duration, SettingsItemIndex::ProfilePhase2Duration, 5},
/* Phase 3 Temp */
- {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase3Temp, displayProfilePhase3Temp, showProfilePhase3Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase3Temp, 5},
+ {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase3Temp, displayProfilePhase3Temp, showProfilePhase3Options, SettingsOptions::ProfilePhase1Temp, SettingsItemIndex::ProfilePhase3Temp, 5},
/* Phase 3 Duration */
{SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase3Duration, showProfilePhase3Options, SettingsOptions::ProfilePhase3Duration, SettingsItemIndex::ProfilePhase3Duration, 5},
/* Phase 4 Temp */
- {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase4Temp, displayProfilePhase4Temp, showProfilePhase4Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase4Temp, 5},
+ {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase4Temp, displayProfilePhase4Temp, showProfilePhase4Options, SettingsOptions::ProfilePhase1Temp, SettingsItemIndex::ProfilePhase4Temp, 5},
/* Phase 4 Duration */
{SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase4Duration, showProfilePhase4Options, SettingsOptions::ProfilePhase4Duration, SettingsItemIndex::ProfilePhase4Duration, 5},
/* Phase 5 Temp */
- {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase5Temp, displayProfilePhase5Temp, showProfilePhase5Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase5Temp, 5},
+ {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase5Temp, displayProfilePhase5Temp, showProfilePhase5Options, SettingsOptions::ProfilePhase1Temp, SettingsItemIndex::ProfilePhase5Temp, 5},
/* Phase 5 Duration */
{SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase5Duration, showProfilePhase5Options, SettingsOptions::ProfilePhase5Duration, SettingsItemIndex::ProfilePhase5Duration, 5},
/* Profile Cooldown Speed */
@@ -343,7 +335,7 @@ const menuitem PowerSavingMenu[] = {
{SETTINGS_DESC(SettingsItemIndex::MotionSensitivity), nullptr, displaySensitivity, nullptr, SettingsOptions::Sensitivity, SettingsItemIndex::MotionSensitivity, 7},
#ifndef NO_SLEEP_MODE
/* Sleep Temp */
- {SETTINGS_DESC(SettingsItemIndex::SleepTemperature), setSleepTemp, displaySleepTemp, showSleepOptions, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::SleepTemperature, 5},
+ {SETTINGS_DESC(SettingsItemIndex::SleepTemperature), setSleepTemp, displaySleepTemp, showSleepOptions, SettingsOptions::SleepTemp, SettingsItemIndex::SleepTemperature, 5},
/* Sleep Time */
{SETTINGS_DESC(SettingsItemIndex::SleepTimeout), nullptr, displaySleepTime, showSleepOptions, SettingsOptions::SleepTime, SettingsItemIndex::SleepTimeout, 5},
#endif /* *not* NO_SLEEP_MODE */
@@ -374,10 +366,10 @@ const menuitem UIMenu[] = {
* Detailed Soldering
*/
/* Temperature units, this has to be the first element in the array to work with the logic in enterUIMenu() */
- {SETTINGS_DESC(SettingsItemIndex::TemperatureUnit), setTempF, displayTempF, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::TemperatureUnit, 7},
+ {SETTINGS_DESC(SettingsItemIndex::TemperatureUnit), setTempF, displayTempF, nullptr, SettingsOptions::TemperatureInF, SettingsItemIndex::TemperatureUnit, 7},
#ifndef NO_DISPLAY_ROTATE
/* Display Rotation */
- {SETTINGS_DESC(SettingsItemIndex::DisplayRotation), setDisplayRotation, displayDisplayRotation, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::DisplayRotation, 7},
+ {SETTINGS_DESC(SettingsItemIndex::DisplayRotation), setDisplayRotation, displayDisplayRotation, nullptr, SettingsOptions::OrientationMode, SettingsItemIndex::DisplayRotation, 7},
#endif /* *not* NO_DISPLAY_ROTATE */
/* Cooling blink warning */
{SETTINGS_DESC(SettingsItemIndex::CooldownBlink), nullptr, displayCoolingBlinkEnabled, nullptr, SettingsOptions::CoolingTempBlink, SettingsItemIndex::CooldownBlink, 7},
@@ -422,9 +414,9 @@ const menuitem advancedMenu[] = {
/* Power limit */
{SETTINGS_DESC(SettingsItemIndex::PowerLimit), nullptr, displayPowerLimit, nullptr, SettingsOptions::PowerLimit, SettingsItemIndex::PowerLimit, 4},
/* Calibrate Cold Junktion Compensation at next boot */
- {SETTINGS_DESC(SettingsItemIndex::CalibrateCJC), setCalibrate, displayCalibrate, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::CalibrateCJC, 7},
+ {SETTINGS_DESC(SettingsItemIndex::CalibrateCJC), setCalibrate, displayCalibrate, nullptr, SettingsOptions::CalibrateCJC, SettingsItemIndex::CalibrateCJC, 7},
/* Voltage input cal */
- {SETTINGS_DESC(SettingsItemIndex::VoltageCalibration), setCalibrateVIN, displayCalibrateVIN, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::VoltageCalibration, 5},
+ {SETTINGS_DESC(SettingsItemIndex::VoltageCalibration), setCalibrateVIN, noOpDisplay, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::VoltageCalibration, 5},
/* Power Pulse adjustment */
{SETTINGS_DESC(SettingsItemIndex::PowerPulsePower), nullptr, displayPowerPulse, nullptr, SettingsOptions::KeepAwakePulse, SettingsItemIndex::PowerPulsePower, 5},
/* Power Pulse Wait adjustment */
@@ -432,7 +424,7 @@ const menuitem advancedMenu[] = {
/* Power Pulse Duration adjustment */
{SETTINGS_DESC(SettingsItemIndex::PowerPulseDuration), nullptr, displayPowerPulseDuration, showPowerPulseOptions, SettingsOptions::KeepAwakePulseDuration, SettingsItemIndex::PowerPulseDuration, 7},
/* Resets settings */
- {SETTINGS_DESC(SettingsItemIndex::SettingsReset), setResetSettings, displayResetSettings, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::SettingsReset, 7},
+ {SETTINGS_DESC(SettingsItemIndex::SettingsReset), setResetSettings, noOpDisplay, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::SettingsReset, 7},
/* vvvv end of menu marker. DO NOT REMOVE vvvv */
{0, nullptr, nullptr, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0}
/* ^^^^ end of menu marker. DO NOT REMOVE ^^^^ */
@@ -440,6 +432,12 @@ const menuitem advancedMenu[] = {
/* clang-format on */
+const menuitem *subSettingsMenus[] {
+#if defined(POW_DC) || defined(POW_QC) || defined(POW_PD)
+ powerMenu,
+#endif
+ solderingMenu, PowerSavingMenu, UIMenu, advancedMenu,
+};
/* ^^^ !!!ENABLE CLANG-FORMAT back!!! ^^^ */
/**
@@ -460,10 +458,9 @@ static void printShortDescription(SettingsItemIndex settingsItemIndex, uint16_t
}
static int userConfirmation(const char *message) {
- ScrollMessage scrollMessage;
-
+ TickType_t tickStart = xTaskGetTickCount();
for (;;) {
- bool lcdRefresh = scrollMessage.drawUpdate(message, xTaskGetTickCount());
+ drawScrollingText(message, xTaskGetTickCount() - tickStart);
ButtonState buttons = getButtonState();
switch (buttons) {
@@ -481,10 +478,8 @@ static int userConfirmation(const char *message) {
return 0;
}
- if (lcdRefresh) {
- OLED::refresh();
- osDelay(40);
- }
+ OLED::refresh();
+ osDelay(40);
}
return 0;
}
@@ -538,7 +533,7 @@ static void displayPDVpdo(void) { OLED::drawCheckbox(getSettingValue(SettingsOpt
#endif /* POW_PD */
-static bool setBoostTemp(void) {
+static void setBoostTemp(void) {
uint16_t value = getSettingValue(SettingsOptions::BoostTemp);
if (getSettingValue(SettingsOptions::TemperatureInF)) {
if (value == 0) {
@@ -551,18 +546,17 @@ static bool setBoostTemp(void) {
value = 0; // jump to off
}
setSettingValue(SettingsOptions::BoostTemp, value);
- return value >= (MAX_TEMP_F - 10);
- }
- if (value == 0) {
- value = MIN_BOOST_TEMP_C; // loop back at 250
} else {
- value += 10; // Go up 10C at a time
- }
- if (value > MAX_TEMP_C) {
- value = 0; // Go to off state
+ if (value == 0) {
+ value = MIN_BOOST_TEMP_C; // loop back at 250
+ } else {
+ value += 10; // Go up 10C at a time
+ }
+ if (value > MAX_TEMP_C) {
+ value = 0; // Go to off state
+ }
}
setSettingValue(SettingsOptions::BoostTemp, value);
- return value >= MAX_TEMP_C;
}
static void displayBoostTemp(void) {
@@ -618,7 +612,7 @@ static void displayLockingMode(void) {
static void displayProfilePhases(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhases), 1, FontStyle::LARGE); }
-static bool setProfileTemp(const enum SettingsOptions option) {
+static void setProfileTemp(const enum SettingsOptions option) {
// If in C, 5 deg, if in F 10 deg
uint16_t temp = getSettingValue(option);
if (getSettingValue(SettingsOptions::TemperatureInF)) {
@@ -627,23 +621,21 @@ static bool setProfileTemp(const enum SettingsOptions option) {
temp = MIN_TEMP_F;
}
setSettingValue(option, temp);
- return temp == MAX_TEMP_F;
} else {
temp += 5;
if (temp > MAX_TEMP_C) {
temp = MIN_TEMP_C;
}
setSettingValue(option, temp);
- return temp == MAX_TEMP_C;
}
}
-static bool setProfilePreheatTemp(void) { return setProfileTemp(SettingsOptions::ProfilePreheatTemp); }
-static bool setProfilePhase1Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase1Temp); }
-static bool setProfilePhase2Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase2Temp); }
-static bool setProfilePhase3Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase3Temp); }
-static bool setProfilePhase4Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase4Temp); }
-static bool setProfilePhase5Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase5Temp); }
+static void setProfilePreheatTemp(void) { return setProfileTemp(SettingsOptions::ProfilePreheatTemp); }
+static void setProfilePhase1Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase1Temp); }
+static void setProfilePhase2Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase2Temp); }
+static void setProfilePhase3Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase3Temp); }
+static void setProfilePhase4Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase4Temp); }
+static void setProfilePhase5Temp(void) { return setProfileTemp(SettingsOptions::ProfilePhase5Temp); }
static void displayProfilePreheatTemp(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePreheatTemp), 3, FontStyle::LARGE); }
static void displayProfilePhase1Temp(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase1Temp), 3, FontStyle::LARGE); }
@@ -678,7 +670,7 @@ static bool showSleepOptions(void) { return getSettingValue(SettingsOptions::Sen
#ifndef NO_SLEEP_MODE
-static bool setSleepTemp(void) {
+static void setSleepTemp(void) {
// If in C, 10 deg, if in F 20 deg
uint16_t temp = getSettingValue(SettingsOptions::SleepTemp);
if (getSettingValue(SettingsOptions::TemperatureInF)) {
@@ -687,14 +679,12 @@ static bool setSleepTemp(void) {
temp = 60;
}
setSettingValue(SettingsOptions::SleepTemp, temp);
- return temp == 580;
} else {
temp += 10;
if (temp > 300) {
temp = 10;
}
setSettingValue(SettingsOptions::SleepTemp, temp);
- return temp == 300;
}
}
@@ -751,8 +741,8 @@ static void setTempF(const enum SettingsOptions option) {
setSettingValue(option, Temp);
}
-static bool setTempF(void) {
- bool res = nextSettingValue(SettingsOptions::TemperatureInF);
+static void setTempF(void) {
+ nextSettingValue(SettingsOptions::TemperatureInF);
setTempF(SettingsOptions::BoostTemp);
setTempF(SettingsOptions::SolderingTemp);
#ifndef NO_SLEEP_MODE
@@ -766,15 +756,14 @@ static bool setTempF(void) {
setTempF(SettingsOptions::ProfilePhase4Temp);
setTempF(SettingsOptions::ProfilePhase5Temp);
#endif /* PROFILE_SUPPORT */
- return res;
}
static void displayTempF(void) { OLED::printSymbolDeg(FontStyle::LARGE); }
#ifndef NO_DISPLAY_ROTATE
-static bool setDisplayRotation(void) {
- bool res = nextSettingValue(SettingsOptions::OrientationMode);
+static void setDisplayRotation(void) {
+ nextSettingValue(SettingsOptions::OrientationMode);
switch (getSettingValue(SettingsOptions::OrientationMode)) {
case orientationMode_t::RIGHT:
OLED::setRotation(false);
@@ -788,7 +777,6 @@ static bool setDisplayRotation(void) {
default:
break;
}
- return res;
}
static void displayDisplayRotation(void) {
@@ -838,13 +826,13 @@ static void displayAnimationLoop(void) { OLED::drawCheckbox(getSettingValue(Sett
static void displayBrightnessLevel(void) {
OLED::printNumber((getSettingValue(SettingsOptions::OLEDBrightness) / BRIGHTNESS_STEP + 1), 1, FontStyle::LARGE);
- // While not optimal to apply this here, it is _very_ convienient
+ // While not optimal to apply this here, it is _very_ convenient
OLED::setBrightness(getSettingValue(SettingsOptions::OLEDBrightness));
}
static void displayInvertColor(void) {
OLED::drawCheckbox(getSettingValue(SettingsOptions::OLEDInversion));
- // While not optimal to apply this here, it is _very_ convienient
+ // While not optimal to apply this here, it is _very_ convenient
OLED::setInverseDisplay(getSettingValue(SettingsOptions::OLEDInversion));
}
@@ -883,7 +871,7 @@ static void displayPowerLimit(void) {
}
}
-static bool setCalibrate(void) {
+static void setCalibrate(void) {
if (getSettingValue(SettingsOptions::CalibrateCJC) < 1) {
if (userConfirmation(translatedString(Tr->SettingsCalibrationWarning))) {
// User confirmed
@@ -893,12 +881,11 @@ static bool setCalibrate(void) {
} else {
setSettingValue(SettingsOptions::CalibrateCJC, 0);
}
- return false;
}
static void displayCalibrate(void) { OLED::drawCheckbox(getSettingValue(SettingsOptions::CalibrateCJC)); }
-static bool setCalibrateVIN(void) {
+static void setCalibrateVIN(void) {
// Jump to the voltage calibration subscreen
OLED::clearScreen();
@@ -925,10 +912,10 @@ static bool setCalibrateVIN(void) {
saveSettings();
OLED::clearScreen();
OLED::setCursor(0, 0);
- warnUser(translatedString(Tr->CalibrationDone), 3 * TICKS_SECOND);
+ warnUser(translatedString(Tr->CalibrationDone), getButtonState());
OLED::refresh();
waitForButtonPressOrTimeout(0.5 * TICKS_SECOND);
- return false;
+ return;
case BUTTON_NONE:
default:
break;
@@ -937,11 +924,8 @@ static bool setCalibrateVIN(void) {
OLED::refresh();
osDelay(40);
}
- return false;
}
-static void displayCalibrateVIN(void) {}
-
static void displayPowerPulse(void) {
if (getSettingValue(SettingsOptions::KeepAwakePulse)) {
OLED::printNumber(getSettingValue(SettingsOptions::KeepAwakePulse) / 10, 1, FontStyle::LARGE);
@@ -958,17 +942,19 @@ static void displayPowerPulseWait(void) { OLED::printNumber(getSettingValue(Sett
static void displayPowerPulseDuration(void) { OLED::printNumber(getSettingValue(SettingsOptions::KeepAwakePulseDuration), 1, FontStyle::LARGE); }
-static bool setResetSettings(void) {
+static void setResetSettings(void) {
if (userConfirmation(translatedString(Tr->SettingsResetWarning))) {
resetSettings();
- warnUser(translatedString(Tr->ResetOKMessage), 3 * TICKS_SECOND);
+ OLED::clearScreen();
+ while (!warnUser(translatedString(Tr->ResetOKMessage), getButtonState())) {
+ OLED::refresh();
+ vTaskDelay(TICKS_100MS);
+ OLED::clearScreen();
+ }
reboot();
}
- return false;
}
-static void displayResetSettings(void) {}
-
// Indicates whether a menu transition is in progress, so that the menu icon
// animation is paused during the transition.
static bool animOpenState = false;
@@ -1016,243 +1002,13 @@ static void displayMenu(size_t index) {
#if defined(POW_DC) || defined(POW_QC)
static void displayPowerMenu(void) { displayMenu(0); }
-static bool enterPowerMenu(void) {
- gui_Menu(powerMenu);
- return false;
-}
+
#endif /* POW_DC or POW_QC */
static void displaySolderingMenu(void) { displayMenu(1); }
-static bool enterSolderingMenu(void) {
- gui_Menu(solderingMenu);
- return false;
-}
static void displayPowerSavingMenu(void) { displayMenu(2); }
-static bool enterPowerSavingMenu(void) {
- gui_Menu(PowerSavingMenu);
- return false;
-}
static void displayUIMenu(void) { displayMenu(3); }
-static bool enterUIMenu(void) {
- gui_Menu(HasFahrenheit ? UIMenu : UIMenu + 1);
- return false;
-}
static void displayAdvancedMenu(void) { displayMenu(4); }
-static bool enterAdvancedMenu(void) {
- gui_Menu(advancedMenu);
- return false;
-}
-
-uint8_t gui_getMenuLength(const menuitem *menu) {
- uint8_t scrollContentSize = 0;
- for (uint8_t i = 0; menu[i].draw != nullptr; i++) {
- if (menu[i].isVisible == nullptr) {
- scrollContentSize += 1; // Always visible
- } else if (menu[i].isVisible()) {
- scrollContentSize += 1; // Selectively visible and chosen to show
- }
- }
- return scrollContentSize;
-}
-
-void gui_Menu(const menuitem *menu) {
- // Draw the settings menu and provide iteration support etc
-
- // This is used to detect whether a menu-exit transition should be played.
- static bool wasInGuiMenu;
- wasInGuiMenu = true;
-
- enum class NavState {
- Idle,
- Entering,
- ScrollingDown,
- Exiting,
- };
-
- uint8_t currentScreen = 0; // Current screen index in the menu struct
- uint8_t screensSkipped = 0; // Number of screens skipped due to being disabled
- TickType_t autoRepeatTimer = 0;
- TickType_t autoRepeatAcceleration = 0;
- bool earlyExit = false;
- bool lcdRefresh = true;
-
- ButtonState lastButtonState = BUTTON_NONE;
- uint8_t scrollContentSize = gui_getMenuLength(menu);
-
- bool scrollBlink = false;
- bool lastValue = false;
- NavState navState = NavState::Entering;
-
- ScrollMessage scrollMessage;
-
- while ((menu[currentScreen].draw != nullptr) && earlyExit == false) {
- bool valueChanged = false;
- // Handle menu transition:
- if (navState != NavState::Idle) {
- // Check if this menu item shall be skipped. If it shall be skipped,
- // `draw()` returns true. Draw on the secondary framebuffer as we want
- // to keep the primary framebuffer intact for the upcoming transition
- // animation.
- OLED::useSecondaryFramebuffer(true);
- if (menu[currentScreen].isVisible != nullptr) {
- if (!menu[currentScreen].isVisible()) {
- currentScreen++;
- screensSkipped++;
- OLED::useSecondaryFramebuffer(false);
- continue;
- }
- }
-
- animOpenState = true;
- // The menu entering/exiting transition uses the secondary framebuffer,
- // but the scroll down transition does not.
- OLED::setCursor(0, 0);
- OLED::clearScreen();
- if (menu[currentScreen].shortDescriptionSize > 0) {
- printShortDescription(menu[currentScreen].shortDescriptionIndex, menu[currentScreen].shortDescriptionSize);
- }
- menu[currentScreen].draw();
- if (navState == NavState::ScrollingDown) {
- // Play the scroll down animation.
- OLED::maskScrollIndicatorOnOLED();
- OLED::transitionScrollDown();
- OLED::useSecondaryFramebuffer(false);
- } else {
- // The menu was drawn in a secondary framebuffer.
- // Now we play a transition from the pre-drawn primary
- // framebuffer to the new buffer.
- // The extra buffer is discarded at the end of the transition.
- OLED::useSecondaryFramebuffer(false);
- OLED::transitionSecondaryFramebuffer(navState == NavState::Entering);
- }
- animOpenState = false;
- navState = NavState::Idle;
- }
-
- // If the user has hesitated for >=3 seconds, show the long text
- // Otherwise "draw" the option
- if ((xTaskGetTickCount() - lastButtonTime < (TICKS_SECOND * 3)) || menu[currentScreen].description == 0) {
- lcdRefresh = true;
- OLED::setCursor(0, 0);
- OLED::clearScreen();
- if (menu[currentScreen].shortDescriptionSize > 0) {
- printShortDescription(menu[currentScreen].shortDescriptionIndex, menu[currentScreen].shortDescriptionSize);
- }
- menu[currentScreen].draw();
- uint8_t indicatorHeight = OLED_HEIGHT / scrollContentSize;
- uint8_t position = OLED_HEIGHT * (currentScreen - screensSkipped) / scrollContentSize;
- if (lastValue) {
- scrollBlink = !scrollBlink;
- }
- if (!lastValue || !scrollBlink) {
- OLED::drawScrollIndicator(position, indicatorHeight);
- }
- } else {
- // Draw description
- const char *description = translatedString(Tr->SettingsDescriptions[menu[currentScreen].description - 1]);
- lcdRefresh |= scrollMessage.drawUpdate(description, xTaskGetTickCount());
- }
-
- if (lcdRefresh) {
- OLED::refresh(); // update the LCD
- osDelay(40);
- lcdRefresh = false;
- }
-
- ButtonState buttons = getButtonState();
-
- if (buttons != lastButtonState) {
- autoRepeatAcceleration = 0;
- lastButtonState = buttons;
- }
-
- auto callIncrementHandler = [&]() {
- wasInGuiMenu = false;
- valueChanged = true;
- bool res = false;
- if ((int)menu[currentScreen].autoSettingOption < (int)SettingsOptions::SettingsOptionsLength) {
- res = nextSettingValue(menu[currentScreen].autoSettingOption);
- } else if (menu[currentScreen].incrementHandler != nullptr) {
- res = menu[currentScreen].incrementHandler();
- } else {
- earlyExit = true;
- }
- if (wasInGuiMenu) {
- navState = NavState::Exiting;
- }
- wasInGuiMenu = true;
- return res;
- };
-
- switch (buttons) {
- case BUTTON_BOTH:
- earlyExit = true; // will make us exit next loop
- scrollMessage.reset();
- break;
- case BUTTON_F_SHORT:
- // increment
- if (scrollMessage.isReset()) {
- lastValue = callIncrementHandler();
- } else {
- scrollMessage.reset();
- }
- break;
- case BUTTON_B_SHORT:
- if (scrollMessage.isReset()) {
- currentScreen++;
- navState = NavState::ScrollingDown;
- lastValue = false;
- } else {
- scrollMessage.reset();
- }
- break;
- case BUTTON_F_LONG:
- if (xTaskGetTickCount() + autoRepeatAcceleration > autoRepeatTimer + PRESS_ACCEL_INTERVAL_MAX) {
- if ((lastValue = callIncrementHandler())) {
- autoRepeatTimer = 1000;
- } else {
- autoRepeatTimer = 0;
- }
- autoRepeatTimer += xTaskGetTickCount();
- scrollMessage.reset();
- autoRepeatAcceleration += PRESS_ACCEL_STEP;
- }
- break;
- case BUTTON_B_LONG:
- if (xTaskGetTickCount() - autoRepeatTimer + autoRepeatAcceleration > PRESS_ACCEL_INTERVAL_MAX) {
- currentScreen++;
- navState = NavState::ScrollingDown;
- autoRepeatTimer = xTaskGetTickCount();
- scrollMessage.reset();
- autoRepeatAcceleration += PRESS_ACCEL_STEP;
- }
- break;
- case BUTTON_NONE:
- default:
- break;
- }
-
- if ((PRESS_ACCEL_INTERVAL_MAX - autoRepeatAcceleration) < PRESS_ACCEL_INTERVAL_MIN) {
- autoRepeatAcceleration = PRESS_ACCEL_INTERVAL_MAX - PRESS_ACCEL_INTERVAL_MIN;
- }
-
- if ((xTaskGetTickCount() - lastButtonTime) > (TICKS_SECOND * 2 * 60)) {
- // If user has not pressed any buttons in 30 seconds, exit back a menu layer
- // This will trickle the user back to the main screen eventually
- earlyExit = true;
- scrollMessage.reset();
- }
- if (valueChanged) {
- // If user changed value, update the scroll content size
- scrollContentSize = gui_getMenuLength(menu);
- }
- }
-}
-
-void enterSettingsMenu() {
- gui_Menu(rootSettingsMenu); // Call the root menu
- saveSettings();
-}
diff --git a/source/Core/Threads/GUIRendering.md b/source/Core/Threads/GUIRendering.md
new file mode 100644
index 0000000000..8f6fcee18e
--- /dev/null
+++ b/source/Core/Threads/GUIRendering.md
@@ -0,0 +1,40 @@
+# GUI Rendering
+
+The GUI aims to be somewhat similar to immediate mode rendering, where the screen is re-rendered each sweep.
+This is due to a few aims:
+
+1. Functions should try and contain their state to the context struct (helps keep state usage flatter)
+2. Allows external events to change the state
+3. Means state can be read/write over BLE or other external control interfaces
+
+## Transitions
+
+When changing the view to a new view it can be preferable to transition using an animation.
+The tooling provides for left, right and down animations at this point.
+The use of these gives a notion of "direction" when navigating the menu.
+
+```
+ ┌───────────┐
+ │ Debug Menu│
+ └─────┬─────┘
+ │
+ │
+ │
+┌──────────────┐ ┌────┴─────┐ ┌──────────────────┐ ┌─────────────────┐
+│Soldering Mode│ │ │ │ │ │ │
+│ OR ├───────────┤Home Menu ├───────────┤Settings Main Menu├───────────┤Settings sub menu│
+│Reflow Mode│ │ │ │ │ │ │
+└──────────────┘ └──────────┘ └──────────────────┘ └─────────┬───────┘
+ │
+ ┌─────────┴───────┐
+ │ │
+ │Settings sub menu│
+ │ │
+ └─────────────────┘
+```
+
+The downside of supporting transitions is that for these to work, the code should render the screen _first_ then return the new state.
+This ensures there is a good working copy in the buffer before the transition changes the view.
+
+The code that handles the dispatch will run a new render pass again to get the new buffer contents and then transition between the two for you.
+At the moment scrolling "Up" isn't implemented but the enumeration is there so that its implementation can follow.
diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp
index a068408701..654e1d6870 100644
--- a/source/Core/Threads/GUIThread.cpp
+++ b/source/Core/Threads/GUIThread.cpp
@@ -32,8 +32,179 @@ extern "C" {
#endif
// File local variables
+#define MOVEMENT_INACTIVITY_TIME (60 * configTICK_RATE_HZ)
+#define BUTTON_INACTIVITY_TIME (60 * configTICK_RATE_HZ)
-extern bool heaterThermalRunaway;
+ButtonState buttonsAtDeviceBoot; // We record button state at startup, incase of jumping to debug modes
+OperatingMode currentOperatingMode = OperatingMode::InitialisationDone; // Current mode we are rendering
+guiContext context; // Context passed to functions to aid in state during render passes
+
+OperatingMode handle_post_init_state();
+OperatingMode guiHandleDraw(void) {
+ OLED::clearScreen(); // Clear ready for render pass
+ // Read button state
+ ButtonState buttons = getButtonState();
+ // Enforce screen on if buttons pressed, movement, hot tip etc
+ if (buttons != BUTTON_NONE) {
+ OLED::setDisplayState(OLED::DisplayState::ON);
+ } else {
+ // Buttons are none; check if we can sleep display
+ uint32_t tipTemp = TipThermoModel::getTipInC();
+ if ((tipTemp < 50) && getSettingValue(SettingsOptions::Sensitivity) &&
+ (((xTaskGetTickCount() - lastMovementTime) > MOVEMENT_INACTIVITY_TIME) && ((xTaskGetTickCount() - lastButtonTime) > BUTTON_INACTIVITY_TIME))) {
+ OLED::setDisplayState(OLED::DisplayState::OFF);
+ setStatusLED(LED_OFF);
+ } else {
+ OLED::setDisplayState(OLED::DisplayState::ON);
+ if (tipTemp > 55) {
+ setStatusLED(LED_COOLING_STILL_HOT);
+ } else {
+ setStatusLED(LED_STANDBY);
+ }
+ }
+ }
+ // Dispatch button state to gui mode
+ OperatingMode newMode = currentOperatingMode;
+ switch (currentOperatingMode) {
+ case OperatingMode::StartupWarnings:
+ newMode = showWarnings(buttons, &context);
+ break;
+ case OperatingMode::UsbPDDebug:
+#ifdef HAS_POWER_DEBUG_MENU
+ newMode = showPDDebug(buttons, &context);
+ break;
+#else
+ newMode = OperatingMode::InitialisationDone;
+#endif
+ case OperatingMode::StartupLogo:
+ showBootLogo();
+
+ if (getSettingValue(SettingsOptions::AutoStartMode) == autoStartMode_t::SLEEP) {
+ lastMovementTime = lastButtonTime = 0; // We mask the values so that sleep goes until user moves again or presses a button
+ newMode = OperatingMode::Sleeping;
+ } else if (getSettingValue(SettingsOptions::AutoStartMode) == autoStartMode_t::SOLDER) {
+ lastMovementTime = lastButtonTime = xTaskGetTickCount(); // Move forward so we dont go to sleep
+ newMode = OperatingMode::Soldering;
+ } else if (getSettingValue(SettingsOptions::AutoStartMode) == autoStartMode_t::ZERO) {
+ lastMovementTime = lastButtonTime = 0; // We mask the values so that sleep goes until user moves again or presses a button
+ newMode = OperatingMode::Hibernating;
+ } else {
+ newMode = OperatingMode::HomeScreen;
+ }
+
+ break;
+ default:
+ /* Fallthrough */
+ case OperatingMode::HomeScreen:
+ newMode = drawHomeScreen(buttons, &context);
+ break;
+ case OperatingMode::Soldering:
+ context.scratch_state.state4 = 0;
+ newMode = gui_solderingMode(buttons, &context);
+ break;
+ case OperatingMode::SolderingProfile:
+ newMode = gui_solderingProfileMode(buttons, &context);
+ break;
+ case OperatingMode::Sleeping:
+ newMode = gui_SolderingSleepingMode(buttons, &context);
+ break;
+ case OperatingMode::TemperatureAdjust:
+ newMode = gui_solderingTempAdjust(buttons, &context);
+ break;
+ case OperatingMode::DebugMenuReadout:
+ newMode = showDebugMenu(buttons, &context);
+ break;
+ case OperatingMode::CJCCalibration:
+ newMode = performCJCC(buttons, &context);
+ break;
+ case OperatingMode::SettingsMenu:
+ newMode = gui_SettingsMenu(buttons, &context);
+ break;
+ case OperatingMode::InitialisationDone:
+ newMode = handle_post_init_state();
+ break;
+ case OperatingMode::Hibernating:
+ context.scratch_state.state4 = 1;
+ gui_SolderingSleepingMode(buttons, &context);
+ if (lastButtonTime > 0 || lastMovementTime > 0) {
+ newMode = OperatingMode::Soldering;
+ }
+ break;
+ case OperatingMode::ThermalRunaway:
+ /*TODO*/
+ newMode = OperatingMode::HomeScreen;
+ break;
+ };
+ return newMode;
+}
+void guiRenderLoop(void) {
+ OperatingMode newMode = guiHandleDraw(); // This does the screen drawing
+
+ // Post draw we handle any state transitions
+
+ if (newMode != currentOperatingMode) {
+ context.viewEnterTime = xTaskGetTickCount();
+ context.previousMode = currentOperatingMode;
+ // If the previous mode is the startup logo; we dont want to return to it, but instead dispatch out to either home or soldering
+ if (currentOperatingMode == OperatingMode::StartupLogo) {
+ if (getSettingValue(SettingsOptions::AutoStartMode)) {
+ context.previousMode = OperatingMode::Soldering;
+ } else {
+ newMode = OperatingMode::HomeScreen;
+ }
+ }
+ memset(&context.scratch_state, 0, sizeof(context.scratch_state));
+ currentOperatingMode = newMode;
+ }
+ // If the transition marker is set, we need to make the next draw occur to the secondary buffer so we have something to transition to
+ if (context.transitionMode != TransitionAnimation::None) {
+ OLED::useSecondaryFramebuffer(true);
+ // Now we need to fill the secondary buffer with the _next_ frame to transistion to
+ guiHandleDraw();
+ OLED::useSecondaryFramebuffer(false);
+ // Now dispatch the transition
+ switch (context.transitionMode) {
+ case TransitionAnimation::Down:
+ OLED::transitionScrollDown(context.viewEnterTime);
+ break;
+ case TransitionAnimation::Left:
+ OLED::transitionSecondaryFramebuffer(false, context.viewEnterTime);
+ break;
+ case TransitionAnimation::Right:
+ OLED::transitionSecondaryFramebuffer(true, context.viewEnterTime);
+ break;
+ case TransitionAnimation::Up:
+ OLED::transitionScrollUp(context.viewEnterTime);
+
+ case TransitionAnimation::None:
+ default:
+ break; // Do nothing on unknown
+ }
+
+ context.transitionMode = TransitionAnimation::None; // Clear transition flag
+ }
+ // Render done, draw it out
+ OLED::refresh();
+}
+
+OperatingMode handle_post_init_state() {
+#ifdef HAS_POWER_DEBUG_MENU
+#ifdef DEBUG_POWER_MENU_BUTTON_B
+ if (buttonsAtDeviceBoot == BUTTON_B_LONG || buttonsAtDeviceBoot == BUTTON_B_SHORT) {
+#else
+ if (buttonsAtDeviceBoot == BUTTON_F_LONG || buttonsAtDeviceBoot == BUTTON_F_SHORT) {
+#endif
+ buttonsAtDeviceBoot = BUTTON_NONE;
+ return OperatingMode::UsbPDDebug;
+ }
+#endif
+
+ if (getSettingValue(SettingsOptions::CalibrateCJC) > 0) {
+ return OperatingMode::CJCCalibration;
+ }
+
+ return OperatingMode::StartupWarnings;
+}
/* StartGUITask function */
void startGUITask(void const *argument) {
@@ -47,42 +218,22 @@ void startGUITask(void const *argument) {
bool buttonLockout = false;
renderHomeScreenAssets();
getTipRawTemp(1); // reset filter
+ memset(&context, 0, sizeof(context));
OLED::setRotation(getSettingValue(SettingsOptions::OrientationMode) & 1);
- // If the front button is held down, on supported devices, show PD debugging metrics
-#ifdef HAS_POWER_DEBUG_MENU
-#ifdef DEBUG_POWER_MENU_BUTTON_B
- if (getButtonB()) {
-#else
- if (getButtonA()) {
-#endif
- showPDDebug();
- }
-#endif
- if (getSettingValue(SettingsOptions::CalibrateCJC) > 0) {
- performCJCC();
+ // Read boot button state
+ if (getButtonA()) {
+ buttonsAtDeviceBoot = BUTTON_F_LONG;
}
-
- uint16_t logoMode = getSettingValue(SettingsOptions::LOGOTime);
- uint16_t startMode = getSettingValue(SettingsOptions::AutoStartMode);
- // If the boot logo is enabled (but it times out) and the autostart mode is enabled (but not set to sleep w/o heat), start heating during boot logo
- if (logoMode && logoMode < logoMode_t::ONETIME && startMode && startMode < autoStartMode_t::ZERO) {
- uint16_t sleepTempDegC = getSettingValue(SettingsOptions::SleepTemp);
- if (getSettingValue(SettingsOptions::TemperatureInF)) {
- sleepTempDegC = TipThermoModel::convertFtoC(sleepTempDegC);
- }
- // Only heat to sleep temperature (but no higher than 75°C for safety)
- currentTempTargetDegC = min(sleepTempDegC, 75);
+ if (getButtonB()) {
+ buttonsAtDeviceBoot = BUTTON_B_LONG;
}
- showBootLogo();
- showWarnings();
- if (getSettingValue(SettingsOptions::AutoStartMode)) {
- // jump directly to the autostart mode
- gui_solderingMode(getSettingValue(SettingsOptions::AutoStartMode) - 1);
- buttonLockout = true;
+ TickType_t startRender = xTaskGetTickCount();
+ for (;;) {
+ guiRenderLoop();
+ resetWatchdog();
+ vTaskDelayUntil(&startRender, TICKS_100MS * 4 / 10); // Try and maintain 20-25fps ish update rate, way to fast but if we can its nice
}
-
- drawHomeScreen(buttonLockout);
}
diff --git a/source/Core/Threads/OperatingModes/CJC.cpp b/source/Core/Threads/OperatingModes/CJC.cpp
index 4da688f96e..cacb5eb18f 100644
--- a/source/Core/Threads/OperatingModes/CJC.cpp
+++ b/source/Core/Threads/OperatingModes/CJC.cpp
@@ -1,39 +1,49 @@
#include "OperatingModes.h"
-void performCJCC(void) {
+OperatingMode performCJCC(const ButtonState buttons, guiContext *cxt) {
// Calibrate Cold Junction Compensation directly at boot, before internal components get warm.
- OLED::refresh();
- osDelay(50);
+
+ // While we wait for the pre-start checks to finish, we cant run CJC (as the pre-start checks control the tip)
+ if (preStartChecks() == 0) {
+ OLED::setCursor(0, 0);
+ OLED::print(translatedString(Tr->CJCCalibrating), FontStyle::SMALL);
+ return OperatingMode::CJCCalibration;
+ }
+
if (!isTipDisconnected() && abs(int(TipThermoModel::getTipInC() - getHandleTemperature(0) / 10)) < 10) {
- uint16_t setoffset = 0;
+ // Take 16 samples, only sample
+ if (cxt->scratch_state.state1 < 16) {
+ if ((xTaskGetTickCount() - cxt->scratch_state.state4) > TICKS_100MS) {
+ cxt->scratch_state.state3 += getTipRawTemp(1);
+ cxt->scratch_state.state1++;
+ cxt->scratch_state.state4 = xTaskGetTickCount();
+ }
+ OLED::setCursor(0, 0);
+ OLED::print(translatedString(Tr->CJCCalibrating), FontStyle::SMALL);
+ OLED::setCursor(0, 8);
+ OLED::print(SmallSymbolDot, FontStyle::SMALL);
+ for (uint8_t x = 0; x < (cxt->scratch_state.state1 / 4); x++) {
+ OLED::print(SmallSymbolDot, FontStyle::SMALL);
+ }
+
+ return OperatingMode::CJCCalibration;
+ }
+
// If the thermo-couple at the end of the tip, and the handle are at
// equilibrium, then the output should be zero, as there is no temperature
// differential.
- while (setoffset == 0) {
- uint32_t offset = 0;
- for (uint8_t i = 0; i < 16; i++) {
- offset += getTipRawTemp(1);
- // cycle through the filter a fair bit to ensure we're stable.
- OLED::clearScreen();
- OLED::setCursor(0, 0);
- OLED::print(translatedString(Tr->CJCCalibrating), FontStyle::SMALL);
- OLED::setCursor(0, 8);
- OLED::print(SmallSymbolDot, FontStyle::SMALL);
- for (uint8_t x = 0; x < (i / 4); x++) {
- OLED::print(SmallSymbolDot, FontStyle::SMALL);
- }
- OLED::refresh();
- osDelay(100);
- }
- setoffset = TipThermoModel::convertTipRawADCTouV(offset / 16, true);
+
+ uint16_t setOffset = TipThermoModel::convertTipRawADCTouV(cxt->scratch_state.state3 / 16, true);
+ setSettingValue(SettingsOptions::CalibrationOffset, setOffset);
+ if (warnUser(translatedString(Tr->CalibrationDone), buttons)) {
+ // Preventing to repeat calibration at boot automatically (only one shot).
+ setSettingValue(SettingsOptions::CalibrateCJC, 0);
+ saveSettings();
+ return OperatingMode::InitialisationDone;
}
- setSettingValue(SettingsOptions::CalibrationOffset, setoffset);
- OLED::clearScreen();
- warnUser(translatedString(Tr->CalibrationDone), 3 * TICKS_SECOND);
- OLED::refresh();
- // Preventing to repeat calibration at boot automatically (only one shot).
- setSettingValue(SettingsOptions::CalibrateCJC, 0);
- saveSettings();
+ return OperatingMode::CJCCalibration;
}
+ // Cant run calibration without the tip and for temps to be close
+ return OperatingMode::StartupWarnings;
}
diff --git a/source/Core/Threads/OperatingModes/DebugMenu.cpp b/source/Core/Threads/OperatingModes/DebugMenu.cpp
index adf03ddde1..a33e9ff8fb 100644
--- a/source/Core/Threads/OperatingModes/DebugMenu.cpp
+++ b/source/Core/Threads/OperatingModes/DebugMenu.cpp
@@ -1,111 +1,102 @@
#include "OperatingModes.h"
-extern osThreadId GUITaskHandle;
-extern osThreadId MOVTaskHandle;
-extern osThreadId PIDTaskHandle;
-extern OperatingMode currentMode;
+extern osThreadId GUITaskHandle;
+extern osThreadId MOVTaskHandle;
+extern osThreadId PIDTaskHandle;
-void showDebugMenu(void) {
- currentMode = OperatingMode::debug;
- uint8_t screen = 0;
- ButtonState b;
- for (;;) {
- OLED::clearScreen(); // Ensure the buffer starts clean
- OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left)
- OLED::print(SmallSymbolVersionNumber, FontStyle::SMALL); // Print version number
- OLED::setCursor(0, 8); // second line
- OLED::print(DebugMenu[screen], FontStyle::SMALL);
- switch (screen) {
- case 0: // Build Date
- break;
- case 1: // Device ID
- {
- uint64_t id = getDeviceID();
+OperatingMode showDebugMenu(const ButtonState buttons, guiContext *cxt) {
+ OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left)
+ OLED::print(SmallSymbolVersionNumber, FontStyle::SMALL); // Print version number
+ OLED::setCursor(0, 8); // second line
+ OLED::print(DebugMenu[cxt->scratch_state.state1], FontStyle::SMALL);
+ switch (cxt->scratch_state.state1) {
+ case 0: // Build Date
+ break;
+ case 1: // Device ID
+ {
+ uint64_t id = getDeviceID();
#ifdef DEVICE_HAS_VALIDATION_CODE
- // If device has validation code; then we want to take over both lines of the screen
- OLED::clearScreen(); // Ensure the buffer starts clean
- OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left)
- OLED::print(DebugMenu[screen], FontStyle::SMALL);
- OLED::drawHex(getDeviceValidation(), FontStyle::SMALL, 8);
- OLED::setCursor(0, 8); // second line
+ // If device has validation code; then we want to take over both lines of the screen
+ OLED::clearScreen(); // Ensure the buffer starts clean
+ OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left)
+ OLED::print(DebugMenu[cxt->scratch_state.state1], FontStyle::SMALL);
+ OLED::drawHex(getDeviceValidation(), FontStyle::SMALL, 8);
+ OLED::setCursor(0, 8); // second line
#endif
- OLED::drawHex((uint32_t)(id >> 32), FontStyle::SMALL, 8);
- OLED::drawHex((uint32_t)(id & 0xFFFFFFFF), FontStyle::SMALL, 8);
- } break;
- case 2: // ACC Type
- OLED::print(AccelTypeNames[(int)DetectedAccelerometerVersion], FontStyle::SMALL);
- break;
- case 3: // Power Negotiation Status
- OLED::print(PowerSourceNames[getPowerSourceNumber()], FontStyle::SMALL);
- break;
- case 4: // Input Voltage
- printVoltage();
- break;
- case 5: // Temp in °C
- OLED::printNumber(TipThermoModel::getTipInC(), 6, FontStyle::SMALL);
- break;
- case 6: // Handle Temp in °C
- OLED::printNumber(getHandleTemperature(0) / 10, 6, FontStyle::SMALL);
- OLED::print(SmallSymbolDot, FontStyle::SMALL);
- OLED::printNumber(getHandleTemperature(0) % 10, 1, FontStyle::SMALL);
- break;
- case 7: // Max Temp Limit in °C
- OLED::printNumber(TipThermoModel::getTipMaxInC(), 6, FontStyle::SMALL);
- break;
- case 8: // System Uptime
- OLED::printNumber(xTaskGetTickCount() / TICKS_100MS, 8, FontStyle::SMALL);
- break;
- case 9: // Movement Timestamp
- OLED::printNumber(lastMovementTime / TICKS_100MS, 8, FontStyle::SMALL);
- break;
- case 10: // Tip Resistance in Ω large to pad over so that we cover ID left overs
- OLED::printNumber(getTipResistanceX10() / 10, 6, FontStyle::SMALL);
- OLED::print(SmallSymbolDot, FontStyle::SMALL);
- OLED::printNumber(getTipResistanceX10() % 10, 1, FontStyle::SMALL);
- break;
- case 11: // Raw Tip in µV
- OLED::printNumber(TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0), true), 8, FontStyle::SMALL);
- break;
- case 12: // Tip Cold Junction Compensation Offset in µV
- OLED::printNumber(getSettingValue(SettingsOptions::CalibrationOffset), 8, FontStyle::SMALL);
- break;
- case 13: // High Water Mark for GUI
- OLED::printNumber(uxTaskGetStackHighWaterMark(GUITaskHandle), 8, FontStyle::SMALL);
- break;
- case 14: // High Water Mark for Movement Task
- OLED::printNumber(uxTaskGetStackHighWaterMark(MOVTaskHandle), 8, FontStyle::SMALL);
- break;
- case 15: // High Water Mark for PID Task
- OLED::printNumber(uxTaskGetStackHighWaterMark(PIDTaskHandle), 8, FontStyle::SMALL);
- break;
- break;
+ OLED::drawHex((uint32_t)(id >> 32), FontStyle::SMALL, 8);
+ OLED::drawHex((uint32_t)(id & 0xFFFFFFFF), FontStyle::SMALL, 8);
+ } break;
+ case 2: // ACC Type
+ OLED::print(AccelTypeNames[(int)DetectedAccelerometerVersion], FontStyle::SMALL);
+ break;
+ case 3: // Power Negotiation Status
+ OLED::print(PowerSourceNames[getPowerSourceNumber()], FontStyle::SMALL);
+ break;
+ case 4: // Input Voltage
+ printVoltage();
+ break;
+ case 5: // Temp in °C
+ OLED::printNumber(TipThermoModel::getTipInC(), 6, FontStyle::SMALL);
+ break;
+ case 6: // Handle Temp in °C
+ OLED::printNumber(getHandleTemperature(0) / 10, 6, FontStyle::SMALL);
+ OLED::print(SmallSymbolDot, FontStyle::SMALL);
+ OLED::printNumber(getHandleTemperature(0) % 10, 1, FontStyle::SMALL);
+ break;
+ case 7: // Max Temp Limit in °C
+ OLED::printNumber(TipThermoModel::getTipMaxInC(), 6, FontStyle::SMALL);
+ break;
+ case 8: // System Uptime
+ OLED::printNumber(xTaskGetTickCount() / TICKS_100MS, 8, FontStyle::SMALL);
+ break;
+ case 9: // Movement Timestamp
+ OLED::printNumber(lastMovementTime / TICKS_100MS, 8, FontStyle::SMALL);
+ break;
+ case 10: // Tip Resistance in Ω
+ OLED::printNumber(getTipResistanceX10() / 10, 6, FontStyle::SMALL); // large to pad over so that we cover ID left overs
+ OLED::print(SmallSymbolDot, FontStyle::SMALL);
+ OLED::printNumber(getTipResistanceX10() % 10, 1, FontStyle::SMALL);
+ break;
+ case 11: // Raw Tip in µV
+ OLED::printNumber(TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0), true), 8, FontStyle::SMALL);
+ break;
+ case 12: // Tip Cold Junction Compensation Offset in µV
+ OLED::printNumber(getSettingValue(SettingsOptions::CalibrationOffset), 8, FontStyle::SMALL);
+ break;
+ case 13: // High Water Mark for GUI
+ OLED::printNumber(uxTaskGetStackHighWaterMark(GUITaskHandle), 8, FontStyle::SMALL);
+ break;
+ case 14: // High Water Mark for Movement Task
+ OLED::printNumber(uxTaskGetStackHighWaterMark(MOVTaskHandle), 8, FontStyle::SMALL);
+ break;
+ case 15: // High Water Mark for PID Task
+ OLED::printNumber(uxTaskGetStackHighWaterMark(PIDTaskHandle), 8, FontStyle::SMALL);
+ break;
+ break;
#ifdef HALL_SENSOR
- case 16: // Raw Hall Effect Value
- {
- int16_t hallEffectStrength = getRawHallEffect();
- if (hallEffectStrength < 0) {
- hallEffectStrength = -hallEffectStrength;
- }
- OLED::printNumber(hallEffectStrength, 6, FontStyle::SMALL);
- } break;
+ case 16: // Raw Hall Effect Value
+ {
+ int16_t hallEffectStrength = getRawHallEffect();
+ if (hallEffectStrength < 0) {
+ hallEffectStrength = -hallEffectStrength;
+ }
+ OLED::printNumber(hallEffectStrength, 6, FontStyle::SMALL);
+ } break;
#endif
- default:
- break;
- }
+ default:
+ break;
+ }
- OLED::refresh();
- b = getButtonState();
- if (b == BUTTON_B_SHORT) {
- return;
- } else if (b == BUTTON_F_SHORT) {
- screen++;
+ if (buttons == BUTTON_B_SHORT) {
+ cxt->transitionMode = TransitionAnimation::Down;
+ return OperatingMode::HomeScreen;
+ } else if (buttons == BUTTON_F_SHORT) {
+ cxt->scratch_state.state1++;
#ifdef HALL_SENSOR
- screen = screen % 17;
+ cxt->scratch_state.state1 = cxt->scratch_state.state1 % 17;
#else
- screen = screen % 16;
+ cxt->scratch_state.state1 = cxt->scratch_state.state1 % 16;
#endif
- }
-
- GUIDelay();
}
+ return OperatingMode::DebugMenuReadout; // Stay in debug menu
}
diff --git a/source/Core/Threads/OperatingModes/HomeScreen.cpp b/source/Core/Threads/OperatingModes/HomeScreen.cpp
index fa2511e8ac..5672b38da8 100644
--- a/source/Core/Threads/OperatingModes/HomeScreen.cpp
+++ b/source/Core/Threads/OperatingModes/HomeScreen.cpp
@@ -2,14 +2,10 @@
#include "Buttons.hpp"
#include "OperatingModes.h"
-#define MOVEMENT_INACTIVITY_TIME (60 * configTICK_RATE_HZ)
-#define BUTTON_INACTIVITY_TIME (60 * configTICK_RATE_HZ)
-
-uint8_t buttonAF[sizeof(buttonA)];
-uint8_t buttonBF[sizeof(buttonB)];
-uint8_t disconnectedTipF[sizeof(disconnectedTip)];
-extern OperatingMode currentMode;
-bool showExitMenuTransition = false;
+uint8_t buttonAF[sizeof(buttonA)];
+uint8_t buttonBF[sizeof(buttonB)];
+uint8_t disconnectedTipF[sizeof(disconnectedTip)];
+bool showExitMenuTransition = false;
void renderHomeScreenAssets(void) {
@@ -24,59 +20,50 @@ void renderHomeScreenAssets(void) {
}
}
-void handleButtons(bool *buttonLockout) {
- ButtonState buttons = getButtonState();
- if (buttons != BUTTON_NONE) {
- OLED::setDisplayState(OLED::DisplayState::ON);
- }
- if (buttons != BUTTON_NONE && *buttonLockout) {
- buttons = BUTTON_NONE;
+OperatingMode handleHomeButtons(const ButtonState buttons, guiContext *cxt) {
+ if (buttons != BUTTON_NONE && cxt->scratch_state.state1 == 0) {
+ return OperatingMode::HomeScreen; // Ignore button press
} else {
- *buttonLockout = false;
+ cxt->scratch_state.state1 = 1;
}
switch (buttons) {
case BUTTON_NONE:
// Do nothing
break;
case BUTTON_BOTH:
- // Not used yet
- // In multi-language this might be used to reset language on a long hold
- // or some such
break;
case BUTTON_B_LONG:
- // Show the version information
- showDebugMenu();
+ cxt->transitionMode = TransitionAnimation::Up;
+ return OperatingMode::DebugMenuReadout;
break;
case BUTTON_F_LONG:
#ifdef PROFILE_SUPPORT
if (!isTipDisconnected()) {
- gui_solderingProfileMode(); // enter profile mode
- *buttonLockout = true;
+ cxt->transitionMode = TransitionAnimation::Left;
+ return OperatingMode::SolderingProfile;
+ } else {
+ return OperatingMode::HomeScreen;
}
#else
- gui_solderingTempAdjust();
- saveSettings();
+ cxt->transitionMode = TransitionAnimation::Left;
+ return OperatingMode::TemperatureAdjust;
#endif
break;
case BUTTON_F_SHORT:
if (!isTipDisconnected()) {
- gui_solderingMode(0); // enter soldering mode
- *buttonLockout = true;
+ cxt->transitionMode = TransitionAnimation::Left;
+ return OperatingMode::Soldering;
}
break;
case BUTTON_B_SHORT:
- currentMode = OperatingMode::settings;
- enterSettingsMenu(); // enter the settings menu
- {
- OLED::useSecondaryFramebuffer(true);
- showExitMenuTransition = true;
- }
- *buttonLockout = true;
+ cxt->transitionMode = TransitionAnimation::Right;
+ return OperatingMode::SettingsMenu;
break;
default:
break;
}
+ return OperatingMode::HomeScreen;
}
void drawDetailedHomeScreen(uint32_t tipTemp) {
@@ -181,55 +168,22 @@ void drawSimplifiedHomeScreen(uint32_t tipTemp) {
}
}
}
-void drawHomeScreen(bool buttonLockout) {
-
- for (;;) {
- currentMode = OperatingMode::idle;
- handleButtons(&buttonLockout);
-
- currentTempTargetDegC = 0; // ensure tip is off
- getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0);
- uint32_t tipTemp = TipThermoModel::getTipInC();
- // Preemptively turn the display on. Turn it off if and only if
- // the tip temperature is below 50 degrees C *and* motion sleep
- // detection is enabled *and* there has been no activity (movement or
- // button presses) in a while.
- // This is zero cost really as state is only changed on display updates
- OLED::setDisplayState(OLED::DisplayState::ON);
+OperatingMode drawHomeScreen(const ButtonState buttons, guiContext *cxt) {
- if ((tipTemp < 50) && getSettingValue(SettingsOptions::Sensitivity) &&
- (((xTaskGetTickCount() - lastMovementTime) > MOVEMENT_INACTIVITY_TIME) && ((xTaskGetTickCount() - lastButtonTime) > BUTTON_INACTIVITY_TIME))) {
- OLED::setDisplayState(OLED::DisplayState::OFF);
- setStatusLED(LED_OFF);
- } else {
- OLED::setDisplayState(OLED::DisplayState::ON);
- if (tipTemp > 55) {
- setStatusLED(LED_COOLING_STILL_HOT);
- } else {
- setStatusLED(LED_STANDBY);
- }
- }
+ currentTempTargetDegC = 0; // ensure tip is off
+ getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0);
+ uint32_t tipTemp = TipThermoModel::getTipInC();
- // Clear the lcd buffer
- OLED::clearScreen();
- if (OLED::getRotation()) {
- OLED::setCursor(50, 0);
- } else {
- OLED::setCursor(-1, 0);
- }
- if (getSettingValue(SettingsOptions::DetailedIDLE)) {
- drawDetailedHomeScreen(tipTemp);
- } else {
- drawSimplifiedHomeScreen(tipTemp);
- }
-
- if (showExitMenuTransition) {
- OLED::useSecondaryFramebuffer(false);
- OLED::transitionSecondaryFramebuffer(false);
- showExitMenuTransition = false;
- } else {
- OLED::refresh();
- GUIDelay();
- }
+ // Setup LCD Cursor location
+ if (OLED::getRotation()) {
+ OLED::setCursor(50, 0);
+ } else {
+ OLED::setCursor(-1, 0);
+ }
+ if (getSettingValue(SettingsOptions::DetailedIDLE)) {
+ drawDetailedHomeScreen(tipTemp);
+ } else {
+ drawSimplifiedHomeScreen(tipTemp);
}
+ return handleHomeButtons(buttons, cxt);
}
diff --git a/source/Core/Threads/OperatingModes/OperatingModes.cpp b/source/Core/Threads/OperatingModes/OperatingModes.cpp
index c09e71d0a1..d334d13b4e 100644
--- a/source/Core/Threads/OperatingModes/OperatingModes.cpp
+++ b/source/Core/Threads/OperatingModes/OperatingModes.cpp
@@ -3,6 +3,3 @@
//
#include "OperatingModes.h"
-
-// Global variables
-OperatingMode currentMode = OperatingMode::idle;
\ No newline at end of file
diff --git a/source/Core/Threads/OperatingModes/OperatingModes.h b/source/Core/Threads/OperatingModes/OperatingModes.h
index c552e327c2..f499b0cccb 100644
--- a/source/Core/Threads/OperatingModes/OperatingModes.h
+++ b/source/Core/Threads/OperatingModes/OperatingModes.h
@@ -24,29 +24,64 @@ extern "C" {
#include "pd.h"
#endif
-// Exposed modes
-enum OperatingMode {
- idle = 0,
- soldering = 1,
- boost = 2,
- sleeping = 3,
- settings = 4,
- debug = 5
+enum class OperatingMode {
+ StartupLogo = 0, // Showing the startup logo
+ CJCCalibration, // Cold Junction Calibration
+ StartupWarnings, // Startup checks and warnings
+ InitialisationDone, // Special state we use just before we to home screen at first startup. Allows jumping to extra startup states
+ HomeScreen, // Home/Idle screen that is the main launchpad to other modes
+ Soldering, // Main soldering operating mode
+ SolderingProfile, // Soldering by following a profile, used for reflow for example
+ Sleeping, // Sleep state holds iron at lower sleep temp
+ Hibernating, // Like sleeping but keeps heater fully off until woken
+ SettingsMenu, // Settings Menu
+ DebugMenuReadout, // Debug metrics
+ TemperatureAdjust, // Set point temperature adjustment
+ UsbPDDebug, // USB PD debugging information
+ ThermalRunaway, // Thermal Runaway warning state.
+};
+
+enum class TransitionAnimation {
+ None = 0,
+ Right = 1,
+ Left = 2,
+ Down = 3,
+ Up = 4,
+};
+
+// Generic context struct used for gui functions to be able to retain state
+struct guiContext {
+ TickType_t viewEnterTime; // Set to ticks when this view state was first entered
+ OperatingMode previousMode;
+ TransitionAnimation transitionMode;
+ // Below is scratch state, this is retained over re-draws but blown away on state change
+ struct scratch {
+ uint16_t state1; // 16 bit state scratch
+ uint16_t state2; // 16 bit state scratch
+ uint32_t state3; // 32 bit state scratch
+ uint32_t state4; // 32 bit state scratch
+ uint16_t state5; // 16 bit state scratch
+ uint16_t state6; // 16 bit state scratch
+
+ } scratch_state;
};
// Main functions
-void performCJCC(void); // Used to calibrate the Cold Junction offset
-void gui_solderingTempAdjust(void); // For adjusting the setpoint temperature of the iron
-int gui_SolderingSleepingMode(bool stayOff, bool autoStarted); // Sleep mode
-void gui_solderingMode(uint8_t jumpToSleep); // Main mode for hot pointy tool
-void gui_solderingProfileMode(); // Profile mode for hot likely-not-so-pointy tool
-void showDebugMenu(void); // Debugging values
-void showPDDebug(void); // Debugging menu that shows PD adaptor info
-void showWarnings(void); // Shows user warnings if required
-void drawHomeScreen(bool buttonLockout) __attribute__((noreturn)); // IDLE / Home screen
-void renderHomeScreenAssets(void); // Called to act as start delay and used to render out flipped images for home screen graphics
+OperatingMode gui_SolderingSleepingMode(const ButtonState buttons, guiContext *cxt); // Sleep mode
+OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt); // Main mode for hot pointy tool
+OperatingMode gui_solderingTempAdjust(const ButtonState buttons, guiContext *cxt); // For adjusting the setpoint temperature of the iron
+OperatingMode drawHomeScreen(const ButtonState buttons, guiContext *cxt); // IDLE / Home screen
+OperatingMode gui_SettingsMenu(const ButtonState buttons, guiContext *cxt); //
+
+OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cxt); // Profile mode for hot likely-not-so-pointy tool
+OperatingMode performCJCC(const ButtonState buttons, guiContext *cxt); // Used to calibrate the Cold Junction offset
+OperatingMode showDebugMenu(const ButtonState buttons, guiContext *cxt); // Debugging values
+OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt); // Debugging menu that shows PD adaptor info
+OperatingMode showWarnings(const ButtonState buttons, guiContext *cxt); // Shows user warnings if required
// Common helpers
-int8_t getPowerSourceNumber(void); // Returns number ID of power source
-TemperatureType_t getTipTemp(void); // Returns temperature of the tip in *C/*F (based on user settings)
+int8_t getPowerSourceNumber(void); // Returns number ID of power source
+void renderHomeScreenAssets(void); // Called to act as start delay and used to render out flipped images for home screen graphics
+
+extern bool heaterThermalRunaway;
#endif
diff --git a/source/Core/Threads/OperatingModes/SettingsMenu.cpp b/source/Core/Threads/OperatingModes/SettingsMenu.cpp
new file mode 100644
index 0000000000..b1f6e00ec1
--- /dev/null
+++ b/source/Core/Threads/OperatingModes/SettingsMenu.cpp
@@ -0,0 +1,275 @@
+#include "OperatingModes.h"
+#include "ScrollMessage.hpp"
+
+#define HELP_TEXT_TIMEOUT_TICKS (TICKS_SECOND * 3)
+/*
+ * The settings menu is the most complex bit of GUI code we have
+ * The menu consists of a two tier menu
+ * Main menu -> Categories
+ * Secondary menu -> Settings
+ *
+ * For each entry in the menu
+ */
+
+/**
+ * Prints two small lines (or one line for CJK) of short description for
+ * setting items and prepares cursor after it.
+ * @param settingsItemIndex Index of the setting item.
+ * @param cursorCharPosition Custom cursor char position to set after printing
+ * description.
+ */
+static void printShortDescription(SettingsItemIndex settingsItemIndex, uint16_t cursorCharPosition) {
+ // print short description (default single line, explicit double line)
+ uint8_t shortDescIndex = static_cast(settingsItemIndex);
+ OLED::printWholeScreen(translatedString(Tr->SettingsShortNames[shortDescIndex]));
+
+ // prepare cursor for value
+ // make room for scroll indicator
+ OLED::setCursor(cursorCharPosition * FONT_12_WIDTH - 2, 0);
+}
+
+// Render a menu, based on the position given
+// This will either draw the menu item, or the help text depending on how long its been since button press
+void render_menu(const menuitem *item, guiContext *cxt) {
+ // If recent interaction or not help text draw the entry
+ if ((xTaskGetTickCount() - lastButtonTime < HELP_TEXT_TIMEOUT_TICKS) || item->description == 0) {
+
+ if (item->shortDescriptionSize > 0) {
+ printShortDescription(item->shortDescriptionIndex, item->shortDescriptionSize);
+ }
+ item->draw();
+ } else {
+
+ uint16_t *isRenderingHelp = &(cxt->scratch_state.state6);
+ *isRenderingHelp = 1;
+ // Draw description
+ const char *description = translatedString(Tr->SettingsDescriptions[item->description - 1]);
+ drawScrollingText(description, (xTaskGetTickCount() - lastButtonTime) - HELP_TEXT_TIMEOUT_TICKS);
+ }
+}
+
+uint16_t getMenuLength(const menuitem *menu, const uint16_t stop) {
+ // walk this menu to find the length
+ uint16_t counter = 0;
+ for (uint16_t pos = 0; pos < stop; pos++) {
+ // End of list
+ if (menu[pos].draw == nullptr) {
+ return counter;
+ }
+ // Otherwise increment for each visible item (null == always, or if not check function)
+ if (menu[pos].isVisible == nullptr || menu[pos].isVisible()) {
+ counter++;
+ }
+ }
+ return counter;
+}
+
+OperatingMode moveToNextEntry(guiContext *cxt) {
+ uint16_t *mainEntry = &(cxt->scratch_state.state1);
+ uint16_t *subEntry = &(cxt->scratch_state.state2);
+ uint16_t *currentMenuLength = &(cxt->scratch_state.state5);
+ uint16_t *isRenderingHelp = &(cxt->scratch_state.state6);
+
+ if (*isRenderingHelp) {
+ *isRenderingHelp = 0;
+ } else {
+ *currentMenuLength = 0; // Reset menu length
+ // Scroll down
+ // We can increment freely _once_
+ cxt->transitionMode = TransitionAnimation::Down;
+ if (*subEntry == 0) {
+ (*mainEntry) += 1;
+
+ if (rootSettingsMenu[*mainEntry].draw == nullptr) {
+ // We are off the end of the menu now
+ saveSettings();
+ cxt->transitionMode = TransitionAnimation::Left;
+ return OperatingMode::HomeScreen;
+ }
+ // Check if visible
+ if (rootSettingsMenu[*mainEntry].isVisible != nullptr && !rootSettingsMenu[*mainEntry].isVisible()) {
+ // We need to move on as this one isn't visible
+ return moveToNextEntry(cxt);
+ }
+ } else {
+ (*subEntry) += 1;
+
+ // If the new entry is null, we need to exit
+ if (subSettingsMenus[*mainEntry][(*subEntry) - 1].draw == nullptr) {
+ (*subEntry) = 0; // Reset back to the main menu
+ cxt->transitionMode = TransitionAnimation::Left;
+ // Have to break early to avoid the below check underflowing
+ return OperatingMode::SettingsMenu;
+ }
+ // Check if visible
+ if (subSettingsMenus[*mainEntry][(*subEntry) - 1].isVisible != nullptr && !subSettingsMenus[*mainEntry][(*subEntry) - 1].isVisible()) {
+ // We need to move on as this one isn't visible
+ return moveToNextEntry(cxt);
+ }
+ }
+ }
+ return OperatingMode::SettingsMenu;
+}
+
+OperatingMode gui_SettingsMenu(const ButtonState buttons, guiContext *cxt) {
+ // Render out the current settings menu
+ // State 1 -> Root menu
+ // State 2 -> Sub entry
+ // Draw main entry if sub-entry is 0, otherwise draw sub-entry
+
+ uint16_t *mainEntry = &(cxt->scratch_state.state1);
+ uint16_t *subEntry = &(cxt->scratch_state.state2);
+ uint32_t *autoRepeatAcceleration = &(cxt->scratch_state.state3);
+ uint32_t *autoRepeatTimer = &(cxt->scratch_state.state4);
+ uint16_t *currentMenuLength = &(cxt->scratch_state.state5);
+ uint16_t *isRenderingHelp = &(cxt->scratch_state.state6);
+
+ const menuitem *currentMenu;
+ // Draw the currently on screen item
+ uint16_t currentScreen;
+ if (*subEntry == 0) {
+ // Drawing main menu
+ currentMenu = rootSettingsMenu;
+ currentScreen = *mainEntry;
+ } else {
+ // Drawing sub menu
+ currentMenu = subSettingsMenus[*mainEntry];
+ currentScreen = (*subEntry) - 1;
+ }
+ render_menu(&(currentMenu[currentScreen]), cxt);
+
+ // Update the cached menu length if unknown
+ if (*currentMenuLength == 0) {
+ // We walk the current menu to find the length
+ *currentMenuLength = getMenuLength(currentMenu, 128 /* Max length of any menu*/);
+ }
+
+ if (*isRenderingHelp == 0) {
+ // Draw scroll
+
+ // Get virtual pos by counting entries from start to _here_
+ uint16_t currentVirtualPosition = getMenuLength(currentMenu, currentScreen + 1);
+ if (currentVirtualPosition > 0) {
+ currentVirtualPosition--;
+ }
+ // The height of the indicator is screen res height / total menu entries
+ uint8_t indicatorHeight = OLED_HEIGHT / *currentMenuLength;
+
+ if (indicatorHeight == 0) {
+ indicatorHeight = 1; // always at least 1 pixel
+ }
+
+ uint16_t position = (OLED_HEIGHT * (uint16_t)currentVirtualPosition) / *currentMenuLength;
+
+ bool showScrollbar = true;
+
+ // Store if its the last option for this setting
+ bool isLastOptionForSetting = false;
+ if ((int)currentMenu[currentScreen].autoSettingOption < (int)SettingsOptions::SettingsOptionsLength) {
+ isLastOptionForSetting = isLastSettingValue(currentMenu[currentScreen].autoSettingOption);
+ }
+
+ // Last settings menu entry, reset scroll show back so it flashes
+ if (isLastOptionForSetting) {
+ showScrollbar = false;
+ }
+
+ // Or Flash it
+ showScrollbar |= (xTaskGetTickCount() % (TICKS_SECOND / 4) < (TICKS_SECOND / 8));
+
+ if (showScrollbar) {
+ OLED::drawScrollIndicator((uint8_t)position, indicatorHeight);
+ }
+ }
+ // Now handle user button input
+
+ auto callIncrementHandler = [&]() {
+ if (currentMenu[currentScreen].incrementHandler != nullptr) {
+ currentMenu[currentScreen].incrementHandler();
+ } else if ((int)currentMenu[currentScreen].autoSettingOption < (int)SettingsOptions::SettingsOptionsLength) {
+ nextSettingValue(currentMenu[currentScreen].autoSettingOption);
+ }
+ return false;
+ };
+
+ //
+ OperatingMode newMode = OperatingMode::SettingsMenu;
+ switch (buttons) {
+ case BUTTON_NONE:
+ (*autoRepeatAcceleration) = 0; // reset acceleration
+ (*autoRepeatTimer) = 0; // reset acceleration
+ break;
+ case BUTTON_BOTH:
+ if (*subEntry == 0) {
+ saveSettings();
+ cxt->transitionMode = TransitionAnimation::Left;
+ return OperatingMode::HomeScreen;
+ } else {
+ cxt->transitionMode = TransitionAnimation::Left;
+ *subEntry = 0;
+ return OperatingMode::SettingsMenu;
+ }
+ break;
+
+ case BUTTON_F_LONG:
+ if (xTaskGetTickCount() + (*autoRepeatAcceleration) > (*autoRepeatTimer) + PRESS_ACCEL_INTERVAL_MAX) {
+ callIncrementHandler();
+ // Update the check for if its the last version
+ bool isLastOptionForSetting = false;
+ if ((int)currentMenu[currentScreen].autoSettingOption < (int)SettingsOptions::SettingsOptionsLength) {
+ isLastOptionForSetting = isLastSettingValue(currentMenu[currentScreen].autoSettingOption);
+ }
+
+ if (isLastOptionForSetting) {
+ (*autoRepeatTimer) = TICKS_SECOND * 2;
+ } else {
+ (*autoRepeatTimer) = 0;
+ }
+ (*autoRepeatTimer) += xTaskGetTickCount();
+ (*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
+ *currentMenuLength = 0; // Reset incase menu visible changes
+ }
+ break;
+ case BUTTON_F_SHORT:
+ // Increment setting
+ if (*isRenderingHelp) {
+ *isRenderingHelp = 0;
+ } else {
+ *currentMenuLength = 0; // Reset incase menu visible changes
+ if (*subEntry == 0) {
+ // In a root menu, if its null handler we enter the menu
+ if (currentMenu[currentScreen].incrementHandler != nullptr) {
+ currentMenu[currentScreen].incrementHandler();
+ } else {
+ (*subEntry) += 1;
+ cxt->transitionMode = TransitionAnimation::Right;
+ }
+ } else {
+ callIncrementHandler();
+ }
+ }
+ break;
+ case BUTTON_B_LONG:
+ if (xTaskGetTickCount() + (*autoRepeatAcceleration) > (*autoRepeatTimer) + PRESS_ACCEL_INTERVAL_MAX) {
+ (*autoRepeatTimer) = xTaskGetTickCount();
+ (*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
+ } else {
+ break;
+ }
+ /* Fall through*/
+ case BUTTON_B_SHORT:
+ // Increment menu item
+
+ newMode = moveToNextEntry(cxt);
+ break;
+
+ default:
+ break;
+ }
+ if ((PRESS_ACCEL_INTERVAL_MAX - (*autoRepeatAcceleration)) < PRESS_ACCEL_INTERVAL_MIN) {
+ (*autoRepeatAcceleration) = PRESS_ACCEL_INTERVAL_MAX - PRESS_ACCEL_INTERVAL_MIN;
+ }
+
+ // Otherwise we stay put for next render iteration
+ return newMode;
+}
\ No newline at end of file
diff --git a/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp b/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp
index 62ed5d0e8b..4e4a3aa7f6 100644
--- a/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp
+++ b/source/Core/Threads/OperatingModes/ShowStartupWarnings.cpp
@@ -1,56 +1,95 @@
#include "HUB238.hpp"
#include "OperatingModes.h"
-void showWarnings(void) {
+OperatingMode showWarnings(const ButtonState buttons, guiContext *cxt) {
// Display alert if settings were reset
- if (settingsWereReset) {
- warnUser(translatedString(Tr->SettingsResetMessage), 10 * TICKS_SECOND);
- }
+
+ switch (cxt->scratch_state.state1) {
+ case 0: // Settings reset warning
+ if (settingsWereReset) {
+ if (warnUser(translatedString(Tr->SettingsResetMessage), buttons)) {
+ settingsWereReset = false;
+ cxt->scratch_state.state1 = 1;
+ }
+ } else {
+ cxt->scratch_state.state1 = 1;
+ }
+ break;
+ case 1: // Device validations
#ifdef DEVICE_HAS_VALIDATION_SUPPORT
- if (getDeviceValidationStatus()) {
- // Warn user this device might be counterfeit
- warnUser(translatedString(Tr->DeviceFailedValidationWarning), 10 * TICKS_SECOND);
- }
+ if (getDeviceValidationStatus()) {
+ // Warn user this device might be counterfeit
+ if (warnUser(translatedString(Tr->DeviceFailedValidationWarning), buttons)) {
+ cxt->scratch_state.state1 = 2;
+ }
+ } else {
+ cxt->scratch_state.state1 = 2;
+ }
+#else
+ cxt->scratch_state.state1 = 2;
#endif
+ break;
+ case 2: // Accelerometer detection
+ if (DetectedAccelerometerVersion == AccelType::Scanning) {
+ break;
+ }
+ // Display alert if accelerometer is not detected
+ if (DetectedAccelerometerVersion == AccelType::None) {
+ if (getSettingValue(SettingsOptions::AccelMissingWarningCounter) < 2) {
-#ifndef NO_WARN_MISSING
- // We also want to alert if accel or pd is not detected / not responding
- // In this case though, we dont want to nag the user _too_ much
- // So only show first 2 times
- while (DetectedAccelerometerVersion == AccelType::Scanning) {
- osDelay(5);
- resetWatchdog();
- }
- // Display alert if accelerometer is not detected
- if (DetectedAccelerometerVersion == AccelType::None) {
- if (getSettingValue(SettingsOptions::AccelMissingWarningCounter) < 2) {
- nextSettingValue(SettingsOptions::AccelMissingWarningCounter);
- saveSettings();
- warnUser(translatedString(Tr->NoAccelerometerMessage), 10 * TICKS_SECOND);
+ if (warnUser(translatedString(Tr->NoAccelerometerMessage), buttons)) {
+ cxt->scratch_state.state1 = 3;
+ nextSettingValue(SettingsOptions::AccelMissingWarningCounter);
+ saveSettings();
+ }
+ } else {
+ cxt->scratch_state.state1 = 3;
+ }
+ } else {
+ cxt->scratch_state.state1 = 3;
}
- }
+ break;
+ case 3:
+
#ifdef POW_PD
- // We expect pd to be present
- resetWatchdog();
- if (!USBPowerDelivery::fusbPresent()) {
- if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) {
- nextSettingValue(SettingsOptions::PDMissingWarningCounter);
- saveSettings();
- warnUser(translatedString(Tr->NoPowerDeliveryMessage), 10 * TICKS_SECOND);
+ // We expect pd to be present
+ if (!USBPowerDelivery::fusbPresent()) {
+ if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) {
+ if (warnUser(translatedString(Tr->NoPowerDeliveryMessage), buttons)) {
+ nextSettingValue(SettingsOptions::PDMissingWarningCounter);
+ saveSettings();
+ cxt->scratch_state.state1 = 4;
+ }
+ } else {
+ cxt->scratch_state.state1 = 4;
+ }
+ } else {
+ cxt->scratch_state.state1 = 4;
}
- }
-#endif /*POW_PD*/
+#else
#if POW_PD_EXT == 1
- if (!hub238_probe()) {
- if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) {
- nextSettingValue(SettingsOptions::PDMissingWarningCounter);
- saveSettings();
- warnUser(translatedString(Tr->NoPowerDeliveryMessage), 10 * TICKS_SECOND);
+ if (!hub238_probe()) {
+ if (getSettingValue(SettingsOptions::PDMissingWarningCounter) < 2) {
+ if (warnUser(translatedString(Tr->NoPowerDeliveryMessage), buttons)) {
+ cxt->scratch_state.state1 = 4;
+ nextSettingValue(SettingsOptions::PDMissingWarningCounter);
+ saveSettings();
+ }
+ } else {
+ cxt->scratch_state.state1 = 4;
+ }
+ } else {
+ cxt->scratch_state.state1 = 4;
}
- }
+#else
+ cxt->scratch_state.state1 = 4;
#endif /*POW_PD_EXT==1*/
- // If tip looks to be shorted, yell at user and dont auto dismiss
- if (isTipShorted()) {
- warnUser(translatedString(Tr->WarningTipShorted), portMAX_DELAY);
+#endif /*POW_PD*/
+
+ break;
+ default:
+ // We are off the end, warnings done
+ return OperatingMode::StartupLogo;
}
-#endif /*NO_WARN_MISSING*/
+
+ return OperatingMode::StartupWarnings; // Stay in warnings
}
diff --git a/source/Core/Threads/OperatingModes/Sleep.cpp b/source/Core/Threads/OperatingModes/Sleep.cpp
index 5c3c47e763..ec97c25246 100644
--- a/source/Core/Threads/OperatingModes/Sleep.cpp
+++ b/source/Core/Threads/OperatingModes/Sleep.cpp
@@ -1,64 +1,70 @@
#include "OperatingModes.h"
-extern OperatingMode currentMode;
-
-int gui_SolderingSleepingMode(bool stayOff, bool autoStarted) {
-#ifndef NO_SLEEP_MODE
+OperatingMode gui_SolderingSleepingMode(const ButtonState buttons, guiContext *cxt) {
+#ifdef NO_SLEEP_MODE
+ return OperatingMode::Soldering;
+#endif
// Drop to sleep temperature and display until movement or button press
- currentMode = OperatingMode::sleeping;
- for (;;) {
- // user moved or pressed a button, go back to soldering
- // If in the first two seconds we disable this to let accelerometer warm up
+ // user moved or pressed a button, go back to soldering
+ // If in the first two seconds we disable this to let accelerometer warm up
#ifdef POW_DC
- if (checkForUnderVoltage()) {
- // return non-zero on error
- return 1;
- }
+ if (checkForUnderVoltage()) {
+ return OperatingMode::HomeScreen; // return non-zero on error
+ }
#endif
+ if (cxt->scratch_state.state4) {
+ // Hibernating mode
+ currentTempTargetDegC = 0;
+ } else {
if (getSettingValue(SettingsOptions::TemperatureInF)) {
- currentTempTargetDegC = stayOff ? 0 : TipThermoModel::convertFtoC(min(getSettingValue(SettingsOptions::SleepTemp), getSettingValue(SettingsOptions::SolderingTemp)));
+ currentTempTargetDegC = TipThermoModel::convertFtoC(min(getSettingValue(SettingsOptions::SleepTemp), getSettingValue(SettingsOptions::SolderingTemp)));
} else {
- currentTempTargetDegC = stayOff ? 0 : min(getSettingValue(SettingsOptions::SleepTemp), getSettingValue(SettingsOptions::SolderingTemp));
+ currentTempTargetDegC = min(getSettingValue(SettingsOptions::SleepTemp), getSettingValue(SettingsOptions::SolderingTemp));
}
+ }
+ // draw the lcd
+ uint16_t tipTemp = getSettingValue(SettingsOptions::TemperatureInF) ? TipThermoModel::getTipInF() : TipThermoModel::getTipInC();
- // draw the lcd
- TemperatureType_t tipTemp = getTipTemp();
-
- OLED::clearScreen();
- OLED::setCursor(0, 0);
- if (getSettingValue(SettingsOptions::DetailedSoldering)) {
- OLED::print(translatedString(Tr->SleepingAdvancedString), FontStyle::SMALL);
- OLED::setCursor(0, 8);
- OLED::print(translatedString(Tr->SleepingTipAdvancedString), FontStyle::SMALL);
- OLED::printNumber(tipTemp, 3, FontStyle::SMALL);
- OLED::printSymbolDeg(FontStyle::SMALL);
- OLED::print(SmallSymbolSpace, FontStyle::SMALL);
- printVoltage();
- OLED::print(SmallSymbolVolts, FontStyle::SMALL);
+ OLED::clearScreen();
+ OLED::setCursor(0, 0);
+ if (getSettingValue(SettingsOptions::DetailedSoldering)) {
+ OLED::print(translatedString(Tr->SleepingAdvancedString), FontStyle::SMALL);
+ OLED::setCursor(0, 8);
+ OLED::print(translatedString(Tr->SleepingTipAdvancedString), FontStyle::SMALL);
+ OLED::printNumber(tipTemp, 3, FontStyle::SMALL);
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ OLED::print(SmallSymbolDegF, FontStyle::SMALL);
} else {
- OLED::print(translatedString(Tr->SleepingSimpleString), FontStyle::LARGE);
- OLED::printNumber(tipTemp, 3, FontStyle::LARGE);
- OLED::printSymbolDeg(FontStyle::EXTRAS);
+ OLED::print(SmallSymbolDegC, FontStyle::SMALL);
}
- OLED::refresh();
- GUIDelay();
+ OLED::print(SmallSymbolSpace, FontStyle::SMALL);
+ printVoltage();
+ OLED::print(SmallSymbolVolts, FontStyle::SMALL);
+ } else {
+ OLED::print(translatedString(Tr->SleepingSimpleString), FontStyle::LARGE);
+ OLED::printNumber(tipTemp, 3, FontStyle::LARGE);
+ OLED::printSymbolDeg(FontStyle::EXTRAS);
+ }
- if (!shouldBeSleeping(autoStarted)) {
- return 0;
- }
+ OLED::refresh();
+ GUIDelay();
- if (shouldShutdown()) {
- // shutdown
- currentTempTargetDegC = 0;
- // we want to exit soldering mode
- return 1;
- }
+ if (!shouldBeSleeping()) {
+ return cxt->previousMode;
}
-#endif
- return 0;
+ if (shouldShutdown()) {
+ // shutdown
+ currentTempTargetDegC = 0;
+ return OperatingMode::HomeScreen;
+ }
+ if (cxt->scratch_state.state4) {
+ return OperatingMode::Hibernating;
+ } else {
+ return OperatingMode::Sleeping;
+ }
}
diff --git a/source/Core/Threads/OperatingModes/Soldering.cpp b/source/Core/Threads/OperatingModes/Soldering.cpp
index d923871ea9..0a64888919 100644
--- a/source/Core/Threads/OperatingModes/Soldering.cpp
+++ b/source/Core/Threads/OperatingModes/Soldering.cpp
@@ -1,10 +1,62 @@
#include "OperatingModes.h"
#include "SolderingCommon.h"
+// State 1 = button locking
+// State 2 = boost mode
+// State 3 = buzzer timer
-extern OperatingMode currentMode;
-
-void gui_solderingMode(uint8_t jumpToSleep) {
+OperatingMode handleSolderingButtons(const ButtonState buttons, guiContext *cxt) {
+ if (cxt->scratch_state.state1 == 1) {
+ // Buttons are currently locked
+ if (buttons == BUTTON_F_LONG) {
+ if (getSettingValue(SettingsOptions::BoostTemp) && (getSettingValue(SettingsOptions::LockingMode) == 1)) {
+ cxt->scratch_state.state2 = 1;
+ }
+ } else if (buttons == BUTTON_BOTH_LONG) {
+ // Unlocking
+ if (warnUser(translatedString(Tr->UnlockingKeysString), buttons)) {
+ cxt->scratch_state.state1 = 0;
+ }
+ } else if (buttons != BUTTON_NONE) {
+ // Do nothing and display a lock warning
+ warnUser(translatedString(Tr->WarningKeysLockedString), buttons);
+ }
+ return OperatingMode::Soldering;
+ }
+ // otherwise we are unlocked
+ switch (buttons) {
+ case BUTTON_NONE:
+ cxt->scratch_state.state2 = 0;
+ break;
+ case BUTTON_BOTH:
+ /*Fall through*/
+ case BUTTON_B_LONG:
+ cxt->transitionMode = TransitionAnimation::Right;
+ return OperatingMode::HomeScreen;
+ case BUTTON_F_LONG:
+ // if boost mode is enabled turn it on
+ if (getSettingValue(SettingsOptions::BoostTemp)) {
+ cxt->scratch_state.state2 = 1;
+ }
+ break;
+ case BUTTON_F_SHORT:
+ case BUTTON_B_SHORT:
+ cxt->transitionMode = TransitionAnimation::Left;
+ return OperatingMode::TemperatureAdjust;
+ case BUTTON_BOTH_LONG:
+ if (getSettingValue(SettingsOptions::LockingMode) != 0) {
+ // Lock buttons
+ if (warnUser(translatedString(Tr->LockingKeysString), buttons)) {
+ cxt->scratch_state.state1 = 1;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return OperatingMode::Soldering;
+}
+OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt) {
/*
* * Soldering (gui_solderingMode)
* -> Main loop where we draw temp, and animations
@@ -19,98 +71,58 @@ void gui_solderingMode(uint8_t jumpToSleep) {
* --> Double button to exit
* --> Long hold double button to toggle key lock
*/
- bool boostModeOn = false;
- bool buttonsLocked = false;
- bool converged = false;
- currentMode = OperatingMode::soldering;
- TickType_t buzzerEnd = 0;
+ // Update the setpoints for the temperature
+ if (cxt->scratch_state.state2) {
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ currentTempTargetDegC = TipThermoModel::convertFtoC(getSettingValue(SettingsOptions::BoostTemp));
+ } else {
+ currentTempTargetDegC = (getSettingValue(SettingsOptions::BoostTemp));
+ }
+ } else {
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ currentTempTargetDegC = TipThermoModel::convertFtoC(getSettingValue(SettingsOptions::SolderingTemp));
+ } else {
+ currentTempTargetDegC = (getSettingValue(SettingsOptions::SolderingTemp));
+ }
+ }
- if (jumpToSleep) {
- if (gui_SolderingSleepingMode(jumpToSleep == 2, true) == 1) {
- lastButtonTime = xTaskGetTickCount();
- return; // If the function returns non-0 then exit
+ // Update status
+ int error = currentTempTargetDegC - TipThermoModel::getTipInC();
+ if (error >= -10 && error <= 10) {
+ // converged
+ if (!cxt->scratch_state.state5) {
+ setBuzzer(true);
+ cxt->scratch_state.state3 = xTaskGetTickCount() + TICKS_SECOND / 3;
+ cxt->scratch_state.state5 = true;
}
+ setStatusLED(LED_HOT);
+ } else {
+ setStatusLED(LED_HEATING);
+ cxt->scratch_state.state5 = false;
}
- for (;;) {
- ButtonState buttons = getButtonState();
- if (buttonsLocked && (getSettingValue(SettingsOptions::LockingMode) != 0)) { // If buttons locked
- switch (buttons) {
- case BUTTON_NONE:
- boostModeOn = false;
- break;
- case BUTTON_BOTH_LONG:
- // Unlock buttons
- buttonsLocked = false;
- warnUser(translatedString(Tr->UnlockingKeysString), TICKS_SECOND);
- break;
- case BUTTON_F_LONG:
- // if boost mode is enabled turn it on
- if (getSettingValue(SettingsOptions::BoostTemp) && (getSettingValue(SettingsOptions::LockingMode) == 1)) {
- boostModeOn = true;
- currentMode = OperatingMode::boost;
- }
- break;
- // fall through
- case BUTTON_BOTH:
- case BUTTON_B_LONG:
- case BUTTON_F_SHORT:
- case BUTTON_B_SHORT:
- // Do nothing and display a lock warning
- warnUser(translatedString(Tr->WarningKeysLockedString), TICKS_SECOND / 2);
- break;
- default:
- break;
- }
- } else { // Button not locked
- switch (buttons) {
- case BUTTON_NONE:
- // stay
- boostModeOn = false;
- currentMode = OperatingMode::soldering;
- break;
- case BUTTON_BOTH:
- case BUTTON_B_LONG:
- return; // exit on back long hold
- case BUTTON_F_LONG:
- // if boost mode is enabled turn it on
- if (getSettingValue(SettingsOptions::BoostTemp)) {
- boostModeOn = true;
- currentMode = OperatingMode::boost;
- }
- break;
- case BUTTON_F_SHORT:
- case BUTTON_B_SHORT: {
- uint16_t oldTemp = getSettingValue(SettingsOptions::SolderingTemp);
- gui_solderingTempAdjust(); // goto adjust temp mode
- if (oldTemp != getSettingValue(SettingsOptions::SolderingTemp)) {
- saveSettings(); // only save on change
- }
- } break;
- case BUTTON_BOTH_LONG:
- if (getSettingValue(SettingsOptions::LockingMode) != 0) {
- // Lock buttons
- buttonsLocked = true;
- warnUser(translatedString(Tr->LockingKeysString), TICKS_SECOND);
- }
- break;
- default:
- break;
- }
+ if (cxt->scratch_state.state3 != 0 && xTaskGetTickCount() >= cxt->scratch_state.state3) {
+ setBuzzer(false);
+ }
+
+ // Draw in the screen details
+ if (getSettingValue(SettingsOptions::DetailedSoldering)) {
+ if (OLED::getRotation()) {
+ OLED::setCursor(50, 0);
+ } else {
+ OLED::setCursor(-1, 0);
}
- // else we update the screen information
- OLED::clearScreen();
- // Draw in the screen details
- if (getSettingValue(SettingsOptions::DetailedSoldering)) {
+ gui_drawTipTemp(true, FontStyle::LARGE);
+
+ if (cxt->scratch_state.state2) { // Boost mode is on
if (OLED::getRotation()) {
- OLED::setCursor(50, 0);
+ OLED::setCursor(34, 0);
} else {
- OLED::setCursor(-1, 0);
+ OLED::setCursor(50, 0);
}
-
- gui_drawTipTemp(true, FontStyle::LARGE);
-
+ OLED::print(LargeSymbolPlus, FontStyle::LARGE);
+ } else {
#ifndef NO_SLEEP_MODE
if (getSettingValue(SettingsOptions::Sensitivity) && getSettingValue(SettingsOptions::SleepTime)) {
if (OLED::getRotation()) {
@@ -121,69 +133,43 @@ void gui_solderingMode(uint8_t jumpToSleep) {
printCountdownUntilSleep(getSleepTimeout());
}
#endif
-
- if (boostModeOn) {
- if (OLED::getRotation()) {
- OLED::setCursor(38, 8);
- } else {
- OLED::setCursor(55, 8);
- }
- OLED::print(SmallSymbolPlus, FontStyle::SMALL);
+ if (OLED::getRotation()) {
+ OLED::setCursor(32, 8);
} else {
- if (OLED::getRotation()) {
- OLED::setCursor(32, 8);
- } else {
- OLED::setCursor(47, 8);
- }
- OLED::print(PowerSourceNames[getPowerSourceNumber()], FontStyle::SMALL, 2);
+ OLED::setCursor(47, 8);
}
-
- detailedPowerStatus();
-
- } else {
- basicSolderingStatus(boostModeOn);
+ OLED::print(PowerSourceNames[getPowerSourceNumber()], FontStyle::SMALL, 2);
}
- OLED::refresh();
- // Update the setpoints for the temperature
- if (boostModeOn) {
- if (getSettingValue(SettingsOptions::TemperatureInF)) {
- currentTempTargetDegC = TipThermoModel::convertFtoC(getSettingValue(SettingsOptions::BoostTemp));
- } else {
- currentTempTargetDegC = (getSettingValue(SettingsOptions::BoostTemp));
- }
- } else {
- if (getSettingValue(SettingsOptions::TemperatureInF)) {
- currentTempTargetDegC = TipThermoModel::convertFtoC(getSettingValue(SettingsOptions::SolderingTemp));
- } else {
- currentTempTargetDegC = (getSettingValue(SettingsOptions::SolderingTemp));
- }
- }
+ detailedPowerStatus();
- if (checkExitSoldering()) {
- setBuzzer(false);
- return;
- }
+ } else {
+ basicSolderingStatus(cxt->scratch_state.state2);
+ }
+ // Check if we should bail due to undervoltage for example
+ if (checkExitSoldering()) {
+ setBuzzer(false);
+ cxt->transitionMode = TransitionAnimation::Right;
+ return OperatingMode::HomeScreen;
+ }
+#ifdef NO_SLEEP_MODE
- // Update status
- int error = currentTempTargetDegC - TipThermoModel::getTipInC();
- if (error >= -10 && error <= 10) {
- // converged
- if (!converged) {
- setBuzzer(true);
- buzzerEnd = xTaskGetTickCount() + TICKS_SECOND / 3;
- converged = true;
- }
- setStatusLED(LED_HOT);
- } else {
- setStatusLED(LED_HEATING);
- converged = false;
- }
- if (buzzerEnd != 0 && xTaskGetTickCount() >= buzzerEnd) {
- setBuzzer(false);
- }
+ if (shouldShutdown()) {
+ // shutdown
+ currentTempTargetDegC = 0;
+ cxt->transitionMode = TransitionAnimation::Right;
+ return OperatingMode::HomeScreen;
+ }
+#endif
+ if (shouldBeSleeping()) {
+ return OperatingMode::Sleeping;
+ }
- // slow down ui update rate
- GUIDelay();
+ if (heaterThermalRunaway) {
+ currentTempTargetDegC = 0; // heater control off
+ heaterThermalRunaway = false;
+ cxt->transitionMode = TransitionAnimation::Right;
+ return OperatingMode::ThermalRunaway;
}
+ return handleSolderingButtons(buttons, cxt);
}
diff --git a/source/Core/Threads/OperatingModes/SolderingProfile.cpp b/source/Core/Threads/OperatingModes/SolderingProfile.cpp
index df6b580569..1bbc133f7b 100644
--- a/source/Core/Threads/OperatingModes/SolderingProfile.cpp
+++ b/source/Core/Threads/OperatingModes/SolderingProfile.cpp
@@ -2,222 +2,212 @@
#include "OperatingModes.h"
#include "SolderingCommon.h"
-extern OperatingMode currentMode;
-
-void gui_solderingProfileMode() {
+OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cxt) {
/*
- * * Soldering (gui_solderingMode)
+ * * Soldering
* -> Main loop where we draw temp, and animations
- * PID control
* --> Long hold back button to exit
* --> Double button to exit
*/
- currentMode = OperatingMode::soldering;
-
- TickType_t buzzerEnd = 0;
- bool waitForRelease = true;
- TickType_t phaseStartTime = xTaskGetTickCount();
+ uint16_t tipTemp = 0;
- uint16_t tipTemp = 0;
- uint8_t profilePhase = 0;
-
- uint16_t phaseElapsedSeconds = 0;
- uint16_t phaseTotalSeconds = 0;
- uint16_t phaseStartTemp = 0;
- uint16_t phaseEndTemp = getSettingValue(SettingsOptions::ProfilePreheatTemp);
+ // If this is during init, start at preheat
+ if (cxt->scratch_state.state1 == 0) {
+ cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePreheatTemp);
+ }
uint16_t phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfilePreheatSpeed);
uint16_t profileCurrentTargetTemp = 0;
- for (;;) {
- ButtonState buttons = getButtonState();
- if (buttons) {
- if (waitForRelease) {
- buttons = BUTTON_NONE;
- }
- } else {
- waitForRelease = false;
- }
-
- switch (buttons) {
- case BUTTON_NONE:
- break;
- case BUTTON_BOTH:
- case BUTTON_B_LONG:
- return; // exit on back long hold
- case BUTTON_F_LONG:
- case BUTTON_F_SHORT:
- case BUTTON_B_SHORT:
- // Not used yet
- break;
- default:
- break;
- }
+ switch (buttons) {
+ case BUTTON_BOTH:
+ case BUTTON_B_LONG:
+ cxt->transitionMode = TransitionAnimation::Right;
+ return OperatingMode::HomeScreen; // exit on back long hold
+ case BUTTON_F_LONG:
+ case BUTTON_F_SHORT:
+ case BUTTON_B_SHORT:
+ case BUTTON_NONE:
+ // Not used yet
+ break;
+ default:
+ break;
+ }
- tipTemp = getTipTemp();
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ tipTemp = TipThermoModel::getTipInF();
+ } else {
+ tipTemp = TipThermoModel::getTipInC();
+ }
+ // If time of entering is unknown; then we start now
+ if (cxt->scratch_state.state3 == 0) {
+ cxt->scratch_state.state3 = xTaskGetTickCount();
+ }
- // if start temp is unknown (preheat), we're setting it now
- if (phaseStartTemp == 0) {
- phaseStartTemp = tipTemp;
- // if this is hotter than the preheat temperature, we should fail
- if (phaseStartTemp >= 55) {
- warnUser(translatedString(Tr->TooHotToStartProfileWarning), 10 * TICKS_SECOND);
- return;
- }
+ // if start temp is unknown (preheat), we're setting it now
+ if (cxt->scratch_state.state6 == 0) {
+ cxt->scratch_state.state6 = tipTemp;
+ // if this is hotter than the preheat temperature, we should fail
+ if (cxt->scratch_state.state6 >= 55) {
+ warnUser(translatedString(Tr->TooHotToStartProfileWarning), buttons);
+ return OperatingMode::HomeScreen;
}
-
- phaseElapsedSeconds = (xTaskGetTickCount() - phaseStartTime) / TICKS_SECOND;
-
- // have we finished this phase?
- if (phaseElapsedSeconds >= phaseTotalSeconds && tipTemp == phaseEndTemp) {
- profilePhase++;
-
- phaseStartTemp = phaseEndTemp;
- phaseStartTime = xTaskGetTickCount();
- phaseElapsedSeconds = 0;
-
- if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) {
- // done with all phases, lets go to cooldown
- phaseTotalSeconds = 0;
- phaseEndTemp = 0;
- phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfileCooldownSpeed);
+ }
+ uint16_t phaseElapsedSeconds = (xTaskGetTickCount() - cxt->scratch_state.state3) / TICKS_SECOND;
+
+ // have we finished this phase?
+ if (phaseElapsedSeconds >= cxt->scratch_state.state2 && tipTemp == cxt->scratch_state.state5) {
+ cxt->scratch_state.state1++;
+ cxt->scratch_state.state6 = cxt->scratch_state.state5;
+ cxt->scratch_state.state3 = xTaskGetTickCount();
+ phaseElapsedSeconds = 0;
+ if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
+ // done with all phases, lets go to cooldown
+ cxt->scratch_state.state2 = 0;
+ cxt->scratch_state.state5 = 0;
+ phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfileCooldownSpeed);
+ } else {
+ // set up next phase
+ switch (cxt->scratch_state.state1) {
+ case 1:
+ cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase1Duration);
+ cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase1Temp);
+ break;
+ case 2:
+ cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase2Duration);
+ cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase2Temp);
+ break;
+ case 3:
+ cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase3Duration);
+ cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase3Temp);
+ break;
+ case 4:
+ cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase4Duration);
+ cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase4Temp);
+ break;
+ case 5:
+ cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase5Duration);
+ cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase5Temp);
+ break;
+ default:
+ break;
+ }
+ if (cxt->scratch_state.state6 < cxt->scratch_state.state5) {
+ phaseTicksPerDegree = (cxt->scratch_state.state2 * TICKS_SECOND) / (cxt->scratch_state.state5 - cxt->scratch_state.state6);
} else {
- // set up next phase
- switch (profilePhase) {
- case 1:
- phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase1Duration);
- phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase1Temp);
- break;
- case 2:
- phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase2Duration);
- phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase2Temp);
- break;
- case 3:
- phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase3Duration);
- phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase3Temp);
- break;
- case 4:
- phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase4Duration);
- phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase4Temp);
- break;
- case 5:
- phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase5Duration);
- phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase5Temp);
- break;
- default:
- break;
- }
- if (phaseStartTemp < phaseEndTemp) {
- phaseTicksPerDegree = (phaseTotalSeconds * TICKS_SECOND) / (phaseEndTemp - phaseStartTemp);
- } else {
- phaseTicksPerDegree = (phaseTotalSeconds * TICKS_SECOND) / (phaseStartTemp - phaseEndTemp);
- }
+ phaseTicksPerDegree = (cxt->scratch_state.state2 * TICKS_SECOND) / (cxt->scratch_state.state6 - cxt->scratch_state.state5);
}
}
+ }
- // cooldown phase done?
- if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) {
- if (TipThermoModel::getTipInC() < 55) {
- // we're done, let the buzzer beep too
- setStatusLED(LED_STANDBY);
- if (buzzerEnd == 0) {
- setBuzzer(true);
- buzzerEnd = xTaskGetTickCount() + TICKS_SECOND / 3;
- }
+ // cooldown phase done?
+ if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
+ if (TipThermoModel::getTipInC() < 55) {
+ // we're done, let the buzzer beep too
+ setStatusLED(LED_STANDBY);
+ if (cxt->scratch_state.state4 == 0) {
+ setBuzzer(true);
+ cxt->scratch_state.state4 = xTaskGetTickCount() + TICKS_SECOND / 3;
}
}
+ }
- // determine current target temp
- if (phaseStartTemp < phaseEndTemp) {
- if (profileCurrentTargetTemp < phaseEndTemp) {
- profileCurrentTargetTemp = phaseStartTemp + ((xTaskGetTickCount() - phaseStartTime) / phaseTicksPerDegree);
- }
+ // determine current target temp
+ if (cxt->scratch_state.state6 < cxt->scratch_state.state5) {
+ if (profileCurrentTargetTemp < cxt->scratch_state.state5) {
+ profileCurrentTargetTemp = cxt->scratch_state.state6 + ((xTaskGetTickCount() - cxt->viewEnterTime) / phaseTicksPerDegree);
+ }
+ } else {
+ if (profileCurrentTargetTemp > cxt->scratch_state.state5) {
+ profileCurrentTargetTemp = cxt->scratch_state.state6 - ((xTaskGetTickCount() - cxt->viewEnterTime) / phaseTicksPerDegree);
+ }
+ }
+
+ // Draw in the screen details
+ if (getSettingValue(SettingsOptions::DetailedSoldering)) {
+ // print temperature
+ if (OLED::getRotation()) {
+ OLED::setCursor(48, 0);
} else {
- if (profileCurrentTargetTemp > phaseEndTemp) {
- profileCurrentTargetTemp = phaseStartTemp - ((xTaskGetTickCount() - phaseStartTime) / phaseTicksPerDegree);
- }
+ OLED::setCursor(0, 0);
}
- OLED::clearScreen();
- // Draw in the screen details
- if (getSettingValue(SettingsOptions::DetailedSoldering)) {
- // print temperature
- if (OLED::getRotation()) {
- OLED::setCursor(48, 0);
- } else {
- OLED::setCursor(0, 0);
- }
+ OLED::printNumber(tipTemp, 3, FontStyle::SMALL);
+ OLED::print(SmallSymbolSlash, FontStyle::SMALL);
+ OLED::printNumber(profileCurrentTargetTemp, 3, FontStyle::SMALL);
- OLED::printNumber(tipTemp, 3, FontStyle::SMALL);
- OLED::print(SmallSymbolSlash, FontStyle::SMALL);
- OLED::printNumber(profileCurrentTargetTemp, 3, FontStyle::SMALL);
- OLED::printSymbolDeg(FontStyle::SMALL);
-
- // print phase
- if (profilePhase > 0 && profilePhase <= getSettingValue(SettingsOptions::ProfilePhases)) {
- if (OLED::getRotation()) {
- OLED::setCursor(36, 0);
- } else {
- OLED::setCursor(55, 0);
- }
- OLED::printNumber(profilePhase, 1, FontStyle::SMALL);
- }
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ OLED::print(SmallSymbolDegF, FontStyle::SMALL);
+ } else {
+ OLED::print(SmallSymbolDegC, FontStyle::SMALL);
+ }
- // print time progress / preheat / cooldown
+ // print phase
+ if (cxt->scratch_state.state1 > 0 && cxt->scratch_state.state1 <= getSettingValue(SettingsOptions::ProfilePhases)) {
if (OLED::getRotation()) {
- OLED::setCursor(42, 8);
+ OLED::setCursor(36, 0);
} else {
- OLED::setCursor(0, 8);
+ OLED::setCursor(55, 0);
}
+ OLED::printNumber(cxt->scratch_state.state1, 1, FontStyle::SMALL);
+ }
- if (profilePhase == 0) {
- OLED::print(translatedString(Tr->ProfilePreheatString), FontStyle::SMALL);
- } else if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) {
- OLED::print(translatedString(Tr->ProfileCooldownString), FontStyle::SMALL);
- } else {
- OLED::printNumber(phaseElapsedSeconds / 60, 1, FontStyle::SMALL);
- OLED::print(SmallSymbolColon, FontStyle::SMALL);
- OLED::printNumber(phaseElapsedSeconds % 60, 2, FontStyle::SMALL, false);
-
- OLED::print(SmallSymbolSlash, FontStyle::SMALL);
-
- // blink if we can't keep up with the time goal
- if (phaseElapsedSeconds < phaseTotalSeconds + 2 || (xTaskGetTickCount() / TICKS_SECOND) % 2 == 0) {
- OLED::printNumber(phaseTotalSeconds / 60, 1, FontStyle::SMALL);
- OLED::print(SmallSymbolColon, FontStyle::SMALL);
- OLED::printNumber(phaseTotalSeconds % 60, 2, FontStyle::SMALL, false);
- }
- }
-
- detailedPowerStatus();
-
+ // print time progress / preheat / cooldown
+ if (OLED::getRotation()) {
+ OLED::setCursor(42, 8);
} else {
- basicSolderingStatus(false);
+ OLED::setCursor(0, 8);
}
- OLED::refresh();
- // Update the setpoints for the temperature
- if (getSettingValue(SettingsOptions::TemperatureInF)) {
- currentTempTargetDegC = TipThermoModel::convertFtoC(profileCurrentTargetTemp);
+ if (cxt->scratch_state.state1 == 0) {
+ OLED::print(translatedString(Tr->ProfilePreheatString), FontStyle::SMALL);
+ } else if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
+ OLED::print(translatedString(Tr->ProfileCooldownString), FontStyle::SMALL);
} else {
- currentTempTargetDegC = profileCurrentTargetTemp;
- }
+ OLED::printNumber(phaseElapsedSeconds / 60, 1, FontStyle::SMALL);
+ OLED::print(SmallSymbolColon, FontStyle::SMALL);
+ OLED::printNumber(phaseElapsedSeconds % 60, 2, FontStyle::SMALL, false);
- if (checkExitSoldering() || (buzzerEnd != 0 && xTaskGetTickCount() >= buzzerEnd)) {
- setBuzzer(false);
- return;
- }
+ OLED::print(SmallSymbolSlash, FontStyle::SMALL);
- // Update LED status
- if (profilePhase == 0) {
- setStatusLED(LED_HEATING);
- } else if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) {
- setStatusLED(LED_COOLING_STILL_HOT);
- } else {
- setStatusLED(LED_HOT);
+ // blink if we can't keep up with the time goal
+ if (phaseElapsedSeconds < cxt->scratch_state.state2 + 2 || (xTaskGetTickCount() / TICKS_SECOND) % 2 == 0) {
+ OLED::printNumber(cxt->scratch_state.state2 / 60, 1, FontStyle::SMALL);
+ OLED::print(SmallSymbolColon, FontStyle::SMALL);
+ OLED::printNumber(cxt->scratch_state.state2 % 60, 2, FontStyle::SMALL, false);
+ }
}
- // slow down ui update rate
- GUIDelay();
+ detailedPowerStatus();
+
+ } else {
+ basicSolderingStatus(false);
+ }
+
+ // Update the setpoints for the temperature
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ currentTempTargetDegC = TipThermoModel::convertFtoC(profileCurrentTargetTemp);
+ } else {
+ currentTempTargetDegC = profileCurrentTargetTemp;
+ }
+
+ if (checkExitSoldering() || (cxt->scratch_state.state4 != 0 && xTaskGetTickCount() >= cxt->scratch_state.state4)) {
+ setBuzzer(false);
+ return OperatingMode::HomeScreen;
+ }
+ if (heaterThermalRunaway) {
+ currentTempTargetDegC = 0; // heater control off
+ heaterThermalRunaway = false;
+ return OperatingMode::ThermalRunaway;
+ }
+
+ // Update LED status
+ if (cxt->scratch_state.state1 == 0) {
+ setStatusLED(LED_HEATING);
+ } else if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
+ setStatusLED(LED_COOLING_STILL_HOT);
+ } else {
+ setStatusLED(LED_HOT);
}
+ return OperatingMode::SolderingProfile;
}
diff --git a/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp b/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp
index ce06e83bad..2a840d780b 100644
--- a/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp
+++ b/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp
@@ -1,120 +1,106 @@
#include "OperatingModes.h"
-void gui_solderingTempAdjust(void) {
- TickType_t lastChange = xTaskGetTickCount();
- currentTempTargetDegC = 0; // Turn off heater while adjusting temp
- TickType_t autoRepeatTimer = 0;
- uint8_t autoRepeatAcceleration = 0;
-#ifndef PROFILE_SUPPORT
- bool waitForRelease = false;
- ButtonState buttons = getButtonState();
+OperatingMode gui_solderingTempAdjust(const ButtonState buttonIn, guiContext *cxt) {
- if (buttons != BUTTON_NONE) {
- // Temp adjust entered by long-pressing F button.
- waitForRelease = true;
- }
-#else
- ButtonState buttons;
-#endif
-
- for (;;) {
- OLED::setCursor(0, 0);
- OLED::clearScreen();
- buttons = getButtonState();
- if (buttons) {
- lastChange = xTaskGetTickCount();
-#ifndef PROFILE_SUPPORT
- if (waitForRelease) {
- buttons = BUTTON_NONE;
- }
+ currentTempTargetDegC = 0; // Turn off heater while adjusting temp
+ uint16_t *waitForRelease = &(cxt->scratch_state.state1);
+ uint32_t *autoRepeatTimer = &(cxt->scratch_state.state3);
+ uint16_t *autoRepeatAcceleration = &(cxt->scratch_state.state2);
+ ButtonState buttons = buttonIn;
+ if (*waitForRelease == 0) {
+ // When we first enter we wait for the user to release buttons before enabling changes
+ if (buttons != BUTTON_NONE) {
+ buttons = BUTTON_NONE;
} else {
- waitForRelease = false;
-#endif
- }
- int16_t delta = 0;
- switch (buttons) {
- case BUTTON_NONE:
- // stay
- autoRepeatAcceleration = 0;
- break;
- case BUTTON_BOTH:
- // exit
- return;
- break;
- case BUTTON_B_LONG:
- if (xTaskGetTickCount() - autoRepeatTimer + autoRepeatAcceleration > PRESS_ACCEL_INTERVAL_MAX) {
- delta = -getSettingValue(SettingsOptions::TempChangeLongStep);
- autoRepeatTimer = xTaskGetTickCount();
- autoRepeatAcceleration += PRESS_ACCEL_STEP;
- }
- break;
- case BUTTON_B_SHORT:
- delta = -getSettingValue(SettingsOptions::TempChangeShortStep);
- break;
- case BUTTON_F_LONG:
- if (xTaskGetTickCount() - autoRepeatTimer + autoRepeatAcceleration > PRESS_ACCEL_INTERVAL_MAX) {
- delta = getSettingValue(SettingsOptions::TempChangeLongStep);
- autoRepeatTimer = xTaskGetTickCount();
- autoRepeatAcceleration += PRESS_ACCEL_STEP;
- }
- break;
- case BUTTON_F_SHORT:
- delta = getSettingValue(SettingsOptions::TempChangeShortStep);
- break;
- default:
- break;
+ (*waitForRelease)++;
}
- if ((PRESS_ACCEL_INTERVAL_MAX - autoRepeatAcceleration) < PRESS_ACCEL_INTERVAL_MIN) {
- autoRepeatAcceleration = PRESS_ACCEL_INTERVAL_MAX - PRESS_ACCEL_INTERVAL_MIN;
- }
- // If buttons are flipped; flip the delta
- if (getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled)) {
- delta = -delta;
- }
- if (delta != 0) {
- // constrain between the set temp limits, i.e. 10-450 C
- int16_t newTemp = getSettingValue(SettingsOptions::SolderingTemp);
- newTemp += delta;
- // Round to nearest increment of delta
- delta = abs(delta);
- newTemp = (newTemp / delta) * delta;
+ }
- if (getSettingValue(SettingsOptions::TemperatureInF)) {
- if (newTemp > MAX_TEMP_F) {
- newTemp = MAX_TEMP_F;
- }
- if (newTemp < MIN_TEMP_F) {
- newTemp = MIN_TEMP_F;
- }
- } else {
- if (newTemp > MAX_TEMP_C) {
- newTemp = MAX_TEMP_C;
- }
- if (newTemp < MIN_TEMP_C) {
- newTemp = MIN_TEMP_C;
- }
- }
- setSettingValue(SettingsOptions::SolderingTemp, (uint16_t)newTemp);
+ OLED::setCursor(0, 0);
+
+ int16_t delta = 0;
+ switch (buttons) {
+ case BUTTON_NONE:
+ // stay
+ (*autoRepeatAcceleration) = 0;
+ break;
+ case BUTTON_BOTH:
+ // exit
+ saveSettings();
+ cxt->transitionMode = TransitionAnimation::Right;
+ return cxt->previousMode;
+ case BUTTON_B_LONG:
+ if (xTaskGetTickCount() - (*autoRepeatTimer) + (*autoRepeatAcceleration) > PRESS_ACCEL_INTERVAL_MAX) {
+ delta = -getSettingValue(SettingsOptions::TempChangeLongStep);
+ (*autoRepeatTimer) = xTaskGetTickCount();
+ (*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
}
- if (xTaskGetTickCount() - lastChange > (TICKS_SECOND * 2)) {
- return; // exit if user just doesn't press anything for a bit
+ break;
+ case BUTTON_B_SHORT:
+ delta = -getSettingValue(SettingsOptions::TempChangeShortStep);
+ break;
+ case BUTTON_F_LONG:
+ if (xTaskGetTickCount() - (*autoRepeatTimer) + (*autoRepeatAcceleration) > PRESS_ACCEL_INTERVAL_MAX) {
+ delta = getSettingValue(SettingsOptions::TempChangeLongStep);
+ (*autoRepeatTimer) = xTaskGetTickCount();
+ (*autoRepeatAcceleration) += PRESS_ACCEL_STEP;
}
+ break;
+ case BUTTON_F_SHORT:
+ delta = getSettingValue(SettingsOptions::TempChangeShortStep);
+ break;
+ default:
+ break;
+ }
+ if ((PRESS_ACCEL_INTERVAL_MAX - (*autoRepeatAcceleration)) < PRESS_ACCEL_INTERVAL_MIN) {
+ (*autoRepeatAcceleration) = PRESS_ACCEL_INTERVAL_MAX - PRESS_ACCEL_INTERVAL_MIN;
+ }
+ // If buttons are flipped; flip the delta
+ if (getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled)) {
+ delta = -delta;
+ }
+ if (delta != 0) {
+ // constrain between the set temp limits, i.e. 10-450 C
+ int16_t newTemp = getSettingValue(SettingsOptions::SolderingTemp);
+ newTemp += delta;
+ // Round to nearest increment of delta
+ delta = abs(delta);
+ newTemp = (newTemp / delta) * delta;
- if (OLED::getRotation()) {
- OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolPlus : LargeSymbolMinus, FontStyle::LARGE);
+ if (getSettingValue(SettingsOptions::TemperatureInF)) {
+ if (newTemp > MAX_TEMP_F) {
+ newTemp = MAX_TEMP_F;
+ } else if (newTemp < MIN_TEMP_F) {
+ newTemp = MIN_TEMP_F;
+ }
} else {
- OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolMinus : LargeSymbolPlus, FontStyle::LARGE);
+ if (newTemp > MAX_TEMP_C) {
+ newTemp = MAX_TEMP_C;
+ } else if (newTemp < MIN_TEMP_C) {
+ newTemp = MIN_TEMP_C;
+ }
}
+ setSettingValue(SettingsOptions::SolderingTemp, (uint16_t)newTemp);
+ }
+ if (OLED::getRotation()) {
+ OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolPlus : LargeSymbolMinus, FontStyle::LARGE);
+ } else {
+ OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolMinus : LargeSymbolPlus, FontStyle::LARGE);
+ }
- OLED::print(LargeSymbolSpace, FontStyle::LARGE);
- OLED::printNumber(getSettingValue(SettingsOptions::SolderingTemp), 3, FontStyle::LARGE);
- OLED::printSymbolDeg(FontStyle::EXTRAS);
- OLED::print(LargeSymbolSpace, FontStyle::LARGE);
- if (OLED::getRotation()) {
- OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolMinus : LargeSymbolPlus, FontStyle::LARGE);
- } else {
- OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolPlus : LargeSymbolMinus, FontStyle::LARGE);
- }
- OLED::refresh();
- GUIDelay();
+ OLED::print(LargeSymbolSpace, FontStyle::LARGE);
+ OLED::printNumber(getSettingValue(SettingsOptions::SolderingTemp), 3, FontStyle::LARGE);
+ OLED::printSymbolDeg(FontStyle::EXTRAS);
+ OLED::print(LargeSymbolSpace, FontStyle::LARGE);
+ if (OLED::getRotation()) {
+ OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolMinus : LargeSymbolPlus, FontStyle::LARGE);
+ } else {
+ OLED::print(getSettingValue(SettingsOptions::ReverseButtonTempChangeEnabled) ? LargeSymbolPlus : LargeSymbolMinus, FontStyle::LARGE);
+ }
+
+ if (xTaskGetTickCount() - lastButtonTime > (TICKS_SECOND * 3)) {
+ saveSettings();
+ cxt->transitionMode = TransitionAnimation::Right;
+ return cxt->previousMode; // exit if user just doesn't press anything for a bit
}
+ return OperatingMode::TemperatureAdjust; // Stay in temp adjust
}
diff --git a/source/Core/Threads/OperatingModes/USBPDDebug_FUSB.cpp b/source/Core/Threads/OperatingModes/USBPDDebug_FUSB.cpp
index 65776970ff..50637259cf 100644
--- a/source/Core/Threads/OperatingModes/USBPDDebug_FUSB.cpp
+++ b/source/Core/Threads/OperatingModes/USBPDDebug_FUSB.cpp
@@ -2,93 +2,85 @@
#ifdef POW_PD
#ifdef HAS_POWER_DEBUG_MENU
-void showPDDebug(void) {
+OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt) {
// Print out the USB-PD state
// Basically this is like the Debug menu, but instead we want to print out the PD status
- uint8_t screen = 0;
- ButtonState b;
- for (;;) {
- OLED::clearScreen(); // Ensure the buffer starts clean
- OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left)
- OLED::print(SmallSymbolPDDebug, FontStyle::SMALL); // Print Title
- OLED::setCursor(0, 8); // second line
- if (screen == 0) {
- // Print the PD state machine
- OLED::print(SmallSymbolState, FontStyle::SMALL);
- OLED::print(SmallSymbolSpace, FontStyle::SMALL);
- OLED::printNumber(USBPowerDelivery::getStateNumber(), 2, FontStyle::SMALL, true);
- OLED::print(SmallSymbolSpace, FontStyle::SMALL);
- // Also print vbus mod status
- if (USBPowerDelivery::fusbPresent()) {
- if (USBPowerDelivery::negotiationComplete() || (xTaskGetTickCount() > (TICKS_SECOND * 10))) {
- if (!USBPowerDelivery::isVBUSConnected()) {
- OLED::print(SmallSymbolNoVBus, FontStyle::SMALL);
- } else {
- OLED::print(SmallSymbolVBus, FontStyle::SMALL);
- }
+ uint16_t *screen = &(cxt->scratch_state.state1);
+ OLED::setCursor(0, 0); // Position the cursor at the 0,0 (top left)
+ OLED::print(SmallSymbolPDDebug, FontStyle::SMALL); // Print Title
+ OLED::setCursor(0, 8); // second line
+ if ((*screen) == 0) {
+ // Print the PD state machine
+ OLED::print(SmallSymbolState, FontStyle::SMALL);
+ OLED::print(SmallSymbolSpace, FontStyle::SMALL);
+ OLED::printNumber(USBPowerDelivery::getStateNumber(), 2, FontStyle::SMALL, true);
+ OLED::print(SmallSymbolSpace, FontStyle::SMALL);
+ // Also print vbus mod status
+ if (USBPowerDelivery::fusbPresent()) {
+ if (USBPowerDelivery::negotiationComplete() || (xTaskGetTickCount() > (TICKS_SECOND * 10))) {
+ if (!USBPowerDelivery::isVBUSConnected()) {
+ OLED::print(SmallSymbolNoVBus, FontStyle::SMALL);
+ } else {
+ OLED::print(SmallSymbolVBus, FontStyle::SMALL);
}
}
- } else {
- // Print out the Proposed power options one by one
- auto lastCaps = USBPowerDelivery::getLastSeenCapabilities();
- if ((screen - 1) < 11) {
- int voltage_mv = 0;
- int min_voltage = 0;
- int current_a_x100 = 0;
- int wattage = 0;
+ }
+ } else {
+ // Print out the Proposed power options one by one
+ auto lastCaps = USBPowerDelivery::getLastSeenCapabilities();
+ if (((*screen) - 1) < 11) {
+ int voltage_mv = 0;
+ int min_voltage = 0;
+ int current_a_x100 = 0;
+ int wattage = 0;
- if ((lastCaps[screen - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
- voltage_mv = PD_PDV2MV(PD_PDO_SRC_FIXED_VOLTAGE_GET(lastCaps[screen - 1])); // voltage in mV units
- current_a_x100 = PD_PDO_SRC_FIXED_CURRENT_GET(lastCaps[screen - 1]); // current in 10mA units
- } else if (((lastCaps[screen - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED) && ((lastCaps[screen - 1] & PD_APDO_TYPE) == PD_APDO_TYPE_AVS)) {
- voltage_mv = PD_PAV2MV(PD_APDO_AVS_MAX_VOLTAGE_GET(lastCaps[screen - 1]));
- min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(lastCaps[screen - 1]));
- // Last value is wattage
- wattage = PD_APDO_AVS_MAX_POWER_GET(lastCaps[screen - 1]);
- } else if (((lastCaps[screen - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED) && ((lastCaps[screen - 1] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS)) {
- voltage_mv = PD_PAV2MV(PD_APDO_PPS_MAX_VOLTAGE_GET(lastCaps[screen - 1]));
- min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(lastCaps[screen - 1]));
- current_a_x100 = PD_PAI2CA(PD_APDO_PPS_CURRENT_GET(lastCaps[screen - 1])); // max current in 10mA units
+ if ((lastCaps[(*screen) - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
+ voltage_mv = PD_PDV2MV(PD_PDO_SRC_FIXED_VOLTAGE_GET(lastCaps[(*screen) - 1])); // voltage in mV units
+ current_a_x100 = PD_PDO_SRC_FIXED_CURRENT_GET(lastCaps[(*screen) - 1]); // current in 10mA units
+ } else if (((lastCaps[(*screen) - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED) && ((lastCaps[(*screen) - 1] & PD_APDO_TYPE) == PD_APDO_TYPE_AVS)) {
+ voltage_mv = PD_PAV2MV(PD_APDO_AVS_MAX_VOLTAGE_GET(lastCaps[(*screen) - 1]));
+ min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(lastCaps[(*screen) - 1]));
+ // Last value is wattage
+ wattage = PD_APDO_AVS_MAX_POWER_GET(lastCaps[(*screen) - 1]);
+ } else if (((lastCaps[(*screen) - 1] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED) && ((lastCaps[(*screen) - 1] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS)) {
+ voltage_mv = PD_PAV2MV(PD_APDO_PPS_MAX_VOLTAGE_GET(lastCaps[(*screen) - 1]));
+ min_voltage = PD_PAV2MV(PD_APDO_PPS_MIN_VOLTAGE_GET(lastCaps[(*screen) - 1]));
+ current_a_x100 = PD_PAI2CA(PD_APDO_PPS_CURRENT_GET(lastCaps[(*screen) - 1])); // max current in 10mA units
+ }
+ // Skip not used entries
+ if (voltage_mv == 0) {
+ (*screen) += 1;
+ } else {
+ // print out this entry of the proposal
+ OLED::printNumber(*screen, 2, FontStyle::SMALL, true); // print the entry number
+ OLED::print(SmallSymbolSpace, FontStyle::SMALL);
+ if (min_voltage > 0) {
+ OLED::printNumber(min_voltage / 1000, 2, FontStyle::SMALL, true); // print the voltage
+ OLED::print(SmallSymbolMinus, FontStyle::SMALL);
}
- // Skip not used entries
- if (voltage_mv == 0) {
- screen++;
+ OLED::printNumber(voltage_mv / 1000, 2, FontStyle::SMALL, true); // print the voltage
+ OLED::print(SmallSymbolVolts, FontStyle::SMALL);
+ OLED::print(SmallSymbolSpace, FontStyle::SMALL);
+ if (wattage) {
+ OLED::printNumber(wattage, 3, FontStyle::SMALL, true); // print the current in 0.1A res
+ OLED::print(SmallSymbolWatts, FontStyle::SMALL);
} else {
- // print out this entry of the proposal
- OLED::printNumber(screen, 2, FontStyle::SMALL, true); // print the entry number
- OLED::print(SmallSymbolSpace, FontStyle::SMALL);
- if (min_voltage > 0) {
- OLED::printNumber(min_voltage / 1000, 2, FontStyle::SMALL, true); // print the voltage
- OLED::print(SmallSymbolMinus, FontStyle::SMALL);
- }
- OLED::printNumber(voltage_mv / 1000, 2, FontStyle::SMALL, true); // print the voltage
- OLED::print(SmallSymbolVolts, FontStyle::SMALL);
- OLED::print(SmallSymbolSpace, FontStyle::SMALL);
- if (wattage) {
- OLED::printNumber(wattage, 3, FontStyle::SMALL, true); // print the current in 0.1A res
- OLED::print(SmallSymbolWatts, FontStyle::SMALL);
- } else {
- OLED::printNumber(current_a_x100 / 100, 2, FontStyle::SMALL, true); // print the current in 0.1A res
- OLED::print(SmallSymbolDot, FontStyle::SMALL);
- OLED::printNumber(current_a_x100 % 100, 2, FontStyle::SMALL, false); // print the current in 0.1A res
- OLED::print(SmallSymbolAmps, FontStyle::SMALL);
- }
+ OLED::printNumber(current_a_x100 / 100, 2, FontStyle::SMALL, true); // print the current in 0.1A res
+ OLED::print(SmallSymbolDot, FontStyle::SMALL);
+ OLED::printNumber(current_a_x100 % 100, 2, FontStyle::SMALL, false); // print the current in 0.1A res
+ OLED::print(SmallSymbolAmps, FontStyle::SMALL);
}
- } else {
- screen = 0;
}
+ } else {
+ (*screen) = 0;
}
-
- OLED::refresh();
- b = getButtonState();
- if (b == BUTTON_B_SHORT) {
- return;
- } else if (b == BUTTON_F_SHORT) {
- screen++;
- }
-
- GUIDelay();
}
+ if (buttons == BUTTON_B_SHORT) {
+ return OperatingMode::InitialisationDone;
+ } else if (buttons == BUTTON_F_SHORT) {
+ (*screen) += 1;
+ }
+ return OperatingMode::UsbPDDebug;
}
#endif
#endif
diff --git a/source/Core/Threads/OperatingModes/USBPDDebug_HUSB238.cpp b/source/Core/Threads/OperatingModes/USBPDDebug_HUSB238.cpp
index 5841e47ce5..173f7ea0e0 100644
--- a/source/Core/Threads/OperatingModes/USBPDDebug_HUSB238.cpp
+++ b/source/Core/Threads/OperatingModes/USBPDDebug_HUSB238.cpp
@@ -2,7 +2,7 @@
#include "OperatingModes.h"
#if POW_PD_EXT == 1
#ifdef HAS_POWER_DEBUG_MENU
-void showPDDebug(void) {
+OperatingMode showPDDebug(const ButtonState buttons, guiContext *cxt) {
// Print out the USB-PD state
// Basically this is like the Debug menu, but instead we want to print out the PD status
uint8_t screen = 0;
@@ -44,13 +44,14 @@ void showPDDebug(void) {
OLED::refresh();
b = getButtonState();
if (b == BUTTON_B_SHORT) {
- return;
+ return OperatingMode::InitialisationDone;
} else if (b == BUTTON_F_SHORT) {
screen++;
}
GUIDelay();
}
+ return OperatingMode::UsbPDDebug;
}
#endif
#endif
diff --git a/source/Core/Threads/OperatingModes/utils/DrawTipTemperature.cpp b/source/Core/Threads/OperatingModes/utils/DrawTipTemperature.cpp
index 7e5cff175d..8e3d749834 100644
--- a/source/Core/Threads/OperatingModes/utils/DrawTipTemperature.cpp
+++ b/source/Core/Threads/OperatingModes/utils/DrawTipTemperature.cpp
@@ -1,5 +1,6 @@
#include "OperatingModeUtilities.h"
#include "OperatingModes.h"
+#include "SolderingCommon.h"
#include "TipThermoModel.h"
void gui_drawTipTemp(bool symbol, const FontStyle font) {
diff --git a/source/Core/Threads/OperatingModes/utils/OperatingModeUtilities.h b/source/Core/Threads/OperatingModes/utils/OperatingModeUtilities.h
index ab3f36f993..e204adf369 100644
--- a/source/Core/Threads/OperatingModes/utils/OperatingModeUtilities.h
+++ b/source/Core/Threads/OperatingModes/utils/OperatingModeUtilities.h
@@ -1,18 +1,19 @@
#ifndef OPERATING_MODE_UTILITIES_H_
#define OPERATING_MODE_UTILITIES_H_
+#include "Buttons.hpp"
#include "OLED.hpp"
#include
-void GUIDelay(); //
-bool checkForUnderVoltage(void); //
-uint32_t getSleepTimeout(void); //
-bool shouldBeSleeping(bool inAutoStart); //
-bool shouldShutdown(void); //
-void gui_drawTipTemp(bool symbol, const FontStyle font); //
-void printVoltage(void); //
-void warnUser(const char *warning, const TickType_t timeout); //
-void gui_drawBatteryIcon(void); //
-bool checkForUnderVoltage(void); //
-uint16_t min(uint16_t a, uint16_t b); //
-void printCountdownUntilSleep(int sleepThres); //
+void GUIDelay(); //
+bool checkForUnderVoltage(void); //
+uint32_t getSleepTimeout(void); //
+bool shouldBeSleeping(); //
+bool shouldShutdown(void); //
+void gui_drawTipTemp(bool symbol, const FontStyle font); //
+void printVoltage(void); //
+bool warnUser(const char *warning, const ButtonState buttons); //
+void gui_drawBatteryIcon(void); //
+bool checkForUnderVoltage(void); //
+uint16_t min(uint16_t a, uint16_t b); //
+void printCountdownUntilSleep(int sleepThres); //
#endif
\ No newline at end of file
diff --git a/source/Core/Threads/OperatingModes/utils/ShowWarning.cpp b/source/Core/Threads/OperatingModes/utils/ShowWarning.cpp
index fcd2972e28..3a33d41559 100644
--- a/source/Core/Threads/OperatingModes/utils/ShowWarning.cpp
+++ b/source/Core/Threads/OperatingModes/utils/ShowWarning.cpp
@@ -1,8 +1,12 @@
#include "Buttons.hpp"
#include "OperatingModeUtilities.h"
-void warnUser(const char *warning, const TickType_t timeout) {
+#include "OperatingModes.h"
+bool warnUser(const char *warning, const ButtonState buttons) {
OLED::clearScreen();
OLED::printWholeScreen(warning);
- OLED::refresh();
- waitForButtonPressOrTimeout(timeout);
+ // Also timeout after 5 seconds
+ if ((xTaskGetTickCount() - lastButtonTime) > TICKS_SECOND * 5) {
+ return true;
+ }
+ return buttons != BUTTON_NONE;
}
diff --git a/source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp b/source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp
index 0f1bbd2a3c..083716482c 100644
--- a/source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp
+++ b/source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp
@@ -4,6 +4,7 @@
#include "SolderingCommon.h"
#include "OperatingModes.h"
+#include "Types.h"
#include "configuration.h"
#include "history.hpp"
@@ -106,30 +107,8 @@ bool checkExitSoldering(void) {
}
}
#endif
-#ifdef NO_SLEEP_MODE
- // No sleep mode, but still want shutdown timeout
-
- if (shouldShutdown()) {
- // shutdown
- currentTempTargetDegC = 0;
- lastMovementTime = xTaskGetTickCount(); // We manually move the movement time to now such that shutdown timer is reset
-
- return true; // we want to exit soldering mode
- }
-#endif
- if (shouldBeSleeping(false)) {
- if (gui_SolderingSleepingMode(false, false)) {
- return true; // If the function returns non-0 then exit
- }
- }
// If we have tripped thermal runaway, turn off heater and show warning
- if (heaterThermalRunaway) {
- currentTempTargetDegC = 0; // heater control off
- warnUser(translatedString(Tr->WarningThermalRunaway), 10 * TICKS_SECOND);
- heaterThermalRunaway = false;
- return true;
- }
return false;
}
diff --git a/source/Core/Threads/OperatingModes/utils/SolderingCommon.h b/source/Core/Threads/OperatingModes/utils/SolderingCommon.h
index 13443e6cce..42f3765ebb 100644
--- a/source/Core/Threads/OperatingModes/utils/SolderingCommon.h
+++ b/source/Core/Threads/OperatingModes/utils/SolderingCommon.h
@@ -1,8 +1,11 @@
-#ifndef SOLDERING_COMMON_H
-#define SOLDERING_COMMON_H
+#include "Types.h"
+#include
+#ifndef SOLDERING_COMMON_H_
+#define SOLDERING_COMMON_H_
-void detailedPowerStatus();
-void basicSolderingStatus(bool boostModeOn);
-bool checkExitSoldering();
+void detailedPowerStatus();
+void basicSolderingStatus(bool boostModeOn);
+bool checkExitSoldering();
+TemperatureType_t getTipTemp(void);
-#endif //SOLDERING_COMMON_H
+#endif // SOLDERING_COMMON_H_
diff --git a/source/Core/Threads/OperatingModes/utils/printSleepCountdown.cpp b/source/Core/Threads/OperatingModes/utils/printSleepCountdown.cpp
index ea53c5c8af..a6b072a7e7 100644
--- a/source/Core/Threads/OperatingModes/utils/printSleepCountdown.cpp
+++ b/source/Core/Threads/OperatingModes/utils/printSleepCountdown.cpp
@@ -17,4 +17,4 @@ void printCountdownUntilSleep(int sleepThres) {
OLED::print(SmallSymbolSeconds, FontStyle::SMALL);
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/source/Core/Threads/OperatingModes/utils/shouldDeviceSleep.cpp b/source/Core/Threads/OperatingModes/utils/shouldDeviceSleep.cpp
index 92a99fc9d4..9e27f2ebd0 100644
--- a/source/Core/Threads/OperatingModes/utils/shouldDeviceSleep.cpp
+++ b/source/Core/Threads/OperatingModes/utils/shouldDeviceSleep.cpp
@@ -4,15 +4,13 @@
TickType_t lastHallEffectSleepStart = 0;
extern TickType_t lastMovementTime;
-bool shouldBeSleeping(bool inAutoStart) {
+bool shouldBeSleeping() {
#ifndef NO_SLEEP_MODE
// Return true if the iron should be in sleep mode
if (getSettingValue(SettingsOptions::Sensitivity) && getSettingValue(SettingsOptions::SleepTime)) {
- if (inAutoStart) {
- // In auto start we are asleep until movement
- if (lastMovementTime == 0 && lastButtonTime == 0) {
- return true;
- }
+ // In auto start we are asleep until movement
+ if (lastMovementTime == 0 && lastButtonTime == 0) {
+ return true;
}
if (lastMovementTime > 0 || lastButtonTime > 0) {
if (((xTaskGetTickCount() - lastMovementTime) > getSleepTimeout()) && ((xTaskGetTickCount() - lastButtonTime) > getSleepTimeout())) {
diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp
index 2c23108f24..83c53efd64 100644
--- a/source/Core/Threads/PIDThread.cpp
+++ b/source/Core/Threads/PIDThread.cpp
@@ -16,6 +16,12 @@
#include "power.hpp"
#include "task.h"
+#ifdef POW_PD
+#if POW_PD == 1
+#include "USBPD.h"
+#endif
+#endif
+
static TickType_t powerPulseWaitUnit = 25 * TICKS_100MS; // 2.5 s
static TickType_t powerPulseDurationUnit = (5 * TICKS_100MS) / 2; // 250 ms
TaskHandle_t pidTaskNotification = NULL;
@@ -38,7 +44,9 @@ void startPIDTask(void const *argument __unused) {
currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will
// be over-ridden rapidly
- pidTaskNotification = xTaskGetCurrentTaskHandle();
+
+ pidTaskNotification = xTaskGetCurrentTaskHandle();
+
TemperatureType_t PIDTempTarget = 0;
// Pre-seed the adc filters
for (int i = 0; i < 32; i++) {
@@ -51,6 +59,17 @@ void startPIDTask(void const *argument __unused) {
resetWatchdog();
ulTaskNotifyTake(pdTRUE, 2000);
}
+// Wait for PD if its in the middle of negotiation
+#ifdef POW_PD
+#if POW_PD == 1
+ // This is an FUSB based PD capable device
+ // Wait up to 3 seconds for USB-PD to settle
+ while (USBPowerDelivery::negotiationInProgress() && xTaskGetTickCount() < (TICKS_SECOND * 3)) {
+ resetWatchdog();
+ ulTaskNotifyTake(pdTRUE, TICKS_100MS);
+ }
+#endif
+#endif
int32_t x10WattsOut = 0;