diff options
author | Ben V. Brown <[email protected]> | 2024-02-18 09:42:08 +1100 |
---|---|---|
committer | GitHub <[email protected]> | 2024-02-18 09:42:08 +1100 |
commit | baf2f26e59da8408ce49cf072441ea0ee69a41c6 (patch) | |
tree | 28b11d26371ed62487dca91144a78a789272904b /source/Core | |
parent | 21a1012102c4ea7b0f153b1373b2e537baf8baef (diff) | |
download | IronOS-baf2f26e59da8408ce49cf072441ea0ee69a41c6.tar.gz IronOS-baf2f26e59da8408ce49cf072441ea0ee69a41c6.zip |
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 <[email protected]>
Diffstat (limited to 'source/Core')
49 files changed, 1652 insertions, 6555 deletions
diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index df45516b..0ad8f4d4 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 817f86e9..a9c8a227 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
- *
- * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
- *
- * 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 2c38ddb9..00000000 --- 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
- *
- * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
- *
- * 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 6fed0d53..91923dfa 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 0c0e9c3b..bbae08c7 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 bced8207..7eaf9027 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 b2319819..28e6ffe5 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 84425f0e..09472719 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 34fff543..54c0db51 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 ac489d52..d56f14eb 100644 --- a/source/Core/Drivers/MMA8652FC.cpp +++ b/source/Core/Drivers/MMA8652FC.cpp @@ -10,6 +10,10 @@ #include "cmsis_os.h"
#include <array>
+#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 03668e62..d8f046d1 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 04ce62e4..40811948 100644 --- a/source/Core/Drivers/OLED.hpp +++ b/source/Core/Drivers/OLED.hpp @@ -149,9 +149,10 @@ public: 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 0bffb671..8683672f 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 <Si7210.h>
-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 305c91ea..2bbc46be 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 <stdint.h>
+
+#ifdef MAG_SLEEP_SUPPORT
class Si7210 {
public:
// Return true if present
@@ -23,5 +26,5 @@ private: 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 03a10ff0..b437b026 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 8ca000c5..b4cb8987 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 3f97fdb9..9352ad4e 100644 --- a/source/Core/Inc/ScrollMessage.hpp +++ b/source/Core/Inc/ScrollMessage.hpp @@ -4,50 +4,21 @@ #include "portmacro.h" #include <stdint.h> /** - * 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 f46df53b..e332580e 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 3b3e85ad..a0c84b60 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 145cd6be..a5d3fe59 100644 --- a/source/Core/Inc/Types.h +++ b/source/Core/Inc/Types.h @@ -1,6 +1,6 @@ #ifndef TYPES_H_ #define TYPES_H_ -#include <stddef.h> +#include <stdint.h> // Used for temperature represented in C or x10C. // diff --git a/source/Core/Inc/settingsGUI.hpp b/source/Core/Inc/settingsGUI.hpp index f1d90852..6456da2a 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 44e28ad2..8ce45f96 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<uint8_t>(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 019c0938..48d6c8d5 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 d63cede3..ff7a2b51 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 6ec1d65f..540c6154 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 058e87af..05fc6c63 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 00000000..8f6fcee1 --- /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 a0684087..654e1d68 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 4da688f9..cacb5eb1 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 adf03ddd..a33e9ff8 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 fa2511e8..5672b38d 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 c09e71d0..d334d13b 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 c552e327..f499b0cc 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 00000000..b1f6e00e --- /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<uint8_t>(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 62ed5d0e..4e4a3aa7 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 5c3c47e7..ec97c252 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 d923871e..0a648889 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 df6b5805..1bbc133f 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 ce06e83b..2a840d78 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 65776970..50637259 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 5841e47c..173f7ea0 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 7e5cff17..8e3d7498 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 ab3f36f9..e204adf3 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 <stdbool.h> -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 fcd2972e..3a33d415 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 0f1bbd2a..08371648 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 13443e6c..42f3765e 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 <stdint.h> +#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 ea53c5c8..a6b072a7 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 92a99fc9..9e27f2eb 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 2c23108f..83c53efd 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;
|