Merge pull request #457 from EdgeTX/I2C_STM32F4_HAL_Frankenmod

Fully rewrote I2C based on STM32F4 HAL
This commit is contained in:
Raphael Coeffic
2021-07-18 12:54:56 +02:00
committed by GitHub
8 changed files with 1631 additions and 272 deletions
+1 -1
View File
@@ -238,7 +238,7 @@ set(TARGET_SRC
)
if(HARDWARE_TOUCH)
set(TOUCH_DRIVER tp_gt911.cpp)
set(TOUCH_DRIVER tp_gt911.cpp i2c_driver.cpp)
add_definitions(-DHARDWARE_TOUCH)
endif()
+1 -1
View File
@@ -728,7 +728,7 @@
#define I2C_SCL_GPIO_PinSource GPIO_PinSource8
#define I2C_SDA_GPIO_PinSource GPIO_PinSource9
#endif
#define I2C_SPEED 400000
#define I2C_CLK_RATE 400000
// Haptic
#define HAPTIC_PWM
File diff suppressed because it is too large Load Diff
+385
View File
@@ -0,0 +1,385 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* OpenTX - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* The content of this file partially stems from STM32F4 HAL by STMicroelectronics.
*/
#pragma once
#include <stdint.h>
#define __IO volatile /*!< Defines 'read / write' permissions */
#define GPIO_NUMBER 16U
#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\
((__GPIOx__) == (GPIOB))? 1U :\
((__GPIOx__) == (GPIOC))? 2U :\
((__GPIOx__) == (GPIOD))? 3U :\
((__GPIOx__) == (GPIOE))? 4U :\
((__GPIOx__) == (GPIOF))? 5U :\
((__GPIOx__) == (GPIOG))? 6U :\
((__GPIOx__) == (GPIOH))? 7U :\
((__GPIOx__) == (GPIOI))? 8U :\
((__GPIOx__) == (GPIOJ))? 9U : 10U)
#define HAL_MAX_DELAY 0xFFFFFFFFU
/* AHB1 Peripheral Clock Enable Disable
* @brief Enable or disable the AHB1 peripheral clock.
* @note After reset, the peripheral clock (used for registers read/write access)
* is disabled and the application software has to enable this clock before
* using it.
*/
#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOH_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOHEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOHEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOA_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOAEN))
#define __HAL_RCC_GPIOB_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOBEN))
#define __HAL_RCC_GPIOC_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOCEN))
#define __HAL_RCC_GPIOH_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOHEN))
/* APB1 Peripheral Clock Enable Disable
* @brief Enable or disable the Low Speed APB (APB1) peripheral clock.
* @note After reset, the peripheral clock (used for registers read/write access)
* is disabled and the application software has to enable this clock before
* using it.
*/
#define __HAL_RCC_I2C1_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_I2C2_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_I2C3_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_I2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN))
#define __HAL_RCC_I2C2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C2EN))
#define __HAL_RCC_I2C3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C3EN))
#define __HAL_LOCK(__HANDLE__) \
do{ \
if((__HANDLE__)->Lock == HAL_LOCKED) \
{ \
return HAL_BUSY; \
} \
else \
{ \
(__HANDLE__)->Lock = HAL_LOCKED; \
} \
}while (0U)
#define __HAL_UNLOCK(__HANDLE__) \
do{ \
(__HANDLE__)->Lock = HAL_UNLOCKED; \
}while (0U)
/* Enable the specified I2C peripheral.
* @param __HANDLE__ specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
/* Disable the specified I2C peripheral.
* @param __HANDLE__ specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
// 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 */
#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */
#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */
#define I2C_TIMEOUT_STOP_FLAG 5U /*!< Timeout 5 ms */
#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */
// 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__) & (uint8_t)(~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)0x00FF)))
#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0)))
#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1))))
#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8)))
#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
// I2C duty cycle in fast mode
#define I2C_DUTYCYCLE_2 0x00000000U
#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY
// I2C addressing mode
#define I2C_ADDRESSINGMODE_7BIT 0x00004000U
#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U)
// I2C dual addressing mode
#define I2C_DUALADDRESS_DISABLE 0x00000000U
#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL
// I2C general call addressing mode
#define I2C_GENERALCALL_DISABLE 0x00000000U
#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC
// I2C nostretch mode
#define I2C_NOSTRETCH_DISABLE 0x00000000U
#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
// I2C Error Code definition
#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 */
#define HAL_I2C_ERROR_SIZE 0x00000040U /*!< Size Management error */
#define HAL_I2C_ERROR_DMA_PARAM 0x00000080U /*!< DMA Parameter Error */
#define HAL_I2C_WRONG_START 0x00000200U /*!< Wrong start Error */
// I2C XferOptions definition
#define I2C_FIRST_FRAME 0x00000001U
#define I2C_FIRST_AND_NEXT_FRAME 0x00000002U
#define I2C_NEXT_FRAME 0x00000004U
#define I2C_FIRST_AND_LAST_FRAME 0x00000008U
#define I2C_LAST_FRAME_NO_STOP 0x00000010U
#define I2C_LAST_FRAME 0x00000020U
// I2C states
#define I2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_I2C_STATE_BUSY_TX | (uint32_t)HAL_I2C_STATE_BUSY_RX) & (uint32_t)(~((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)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */
#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */
#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */
#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */
// I2C Analog Filter
#define I2C_ANALOGFILTER_ENABLE 0x00000000U
#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF
/* 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(0)
/* Clears the I2C pending flags which are cleared by writing 0 in a specific bit.
* @param __HANDLE__ specifies the I2C Handle.
* @param __FLAG__ specifies the flag to clear.
* This parameter can be any combination of the following values:
* @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 = (uint16_t)(~((__FLAG__) & I2C_FLAG_MASK)))
// HAL Status structures definition
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
// HAL lock structures definition
typedef enum
{
HAL_UNLOCKED = 0x00U,
HAL_LOCKED = 0x01U
} HAL_LockTypeDef;
/* HAL State structure definition
* 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 Peripheral initialization status
* 0 : Reset (Peripheral not initialized)
* 1 : Init done (Peripheral 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 (Peripheral in Address Listen Mode)
* b2 Intrinsic process state
* 0 : Ready
* 1 : Busy (Peripheral 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;
/* HAL Mode structure definition
* 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;
// 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 */
} HAL_I2C_InitTypeDef; // WARNING: renamed from I2C_InitTypeDef due to conflict
// I2C handle structure definition
typedef struct
{
I2C_TypeDef *Instance; /*!< I2C registers base address */
HAL_I2C_InitTypeDef Init; /*!< I2C communication parameters (MOD!) */
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;
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter);
HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter);
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);
+80 -252
View File
@@ -19,6 +19,7 @@
*/
#include "opentx.h"
#include "i2c_driver.h"
#include "tp_gt911.h"
#include "touch.h"
@@ -409,6 +410,8 @@ struct TouchData touchData;
uint16_t touchGT911fwver = 0;
uint32_t touchGT911hiccups = 0;
I2C_HandleTypeDef hi2c1;
static void TOUCH_AF_ExtiStop(void)
{
SYSCFG_EXTILineConfig(TOUCH_INT_EXTI_PortSource, TOUCH_INT_EXTI_PinSource1);
@@ -484,267 +487,75 @@ void TOUCH_AF_INT_Change(void)
GPIO_Init(TOUCH_INT_GPIO, &GPIO_InitStructure);
}
void I2C_Init()
void I2C_Init_Radio(void)
{
TRACE("I2C Init");
I2C_DeInit(I2C);
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C, &I2C_InitStructure);
I2C_Cmd(I2C, ENABLE);
GPIO_PinAFConfig(I2C_GPIO, I2C_SCL_GPIO_PinSource, I2C_GPIO_AF);
GPIO_PinAFConfig(I2C_GPIO, I2C_SDA_GPIO_PinSource, I2C_GPIO_AF);
GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN | I2C_SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
hi2c1.Instance = I2C;
hi2c1.Init.ClockSpeed = I2C_CLK_RATE;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
TRACE("I2C ERROR: HAL_I2C_Init() failed");
}
// Configure Analogue filter
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
TRACE("I2C ERROR: HAL_I2CEx_ConfigAnalogFilter() failed");
}
// Configure Digital filter
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
TRACE("I2C ERROR: HAL_I2CEx_ConfigDigitalFilter() failed");
}
}
bool I2C_WaitFlag(uint32_t flag)
bool I2C_GT911_WriteRegister(uint16_t reg, uint8_t * buf, uint8_t len)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (!I2C_GetFlagStatus(I2C, flag)) {
if ((timeout--) == 0) return false;
}
return true;
}
uint8_t uAddrAndBuf[258];
uAddrAndBuf[0] = (uint8_t)((reg & 0xFF00) >> 8);
uAddrAndBuf[1] = (uint8_t)(reg & 0x00FF);
bool I2C_WaitEvent(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (!I2C_CheckEvent(I2C, event)) {
if ((timeout--) == 0) return false;
}
return true;
}
bool I2C_WaitEventCleared(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (I2C_CheckEvent(I2C, event)) {
if ((timeout--) == 0) return false;
}
return true;
}
uint8_t I2C_GT911_WriteRegister(uint16_t reg, uint8_t * buf, uint8_t len)
{
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
{
TRACE("I2C WRITE ERROR: busy timeout");
return false;
}
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
{
TRACE("I2C WRITE ERROR: could not issue start");
return false;
}
I2C_Send7bitAddress(I2C, GT_CMD_WR, I2C_Direction_Transmitter);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
TRACE("I2C WRITE ERROR: could not send device address");
return false;
}
I2C_SendData(I2C, (uint8_t)((reg & 0xFF00) >> 8));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
TRACE("I2C WRITE ERROR: could not send register high address");
return false;
}
I2C_SendData(I2C, (uint8_t)(reg & 0x00FF));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
TRACE("I2C WRITE ERROR: could not send register low address");
return false;
}
/* While there is data to be written */
while (len--) {
I2C_SendData(I2C, *buf);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
if (len > 0)
{
TRACE("I2C WRITE ERROR: could not send data with %u bytes remaining", len+1 );
return false;
for (int i = 0;i < len;i++)
{
uAddrAndBuf[i + 2] = buf[i];
}
}
buf++;
}
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
TRACE("I2C WRITE ERROR: waiting for BTF failed.");
return false;
}
I2C_GenerateSTOP(I2C, ENABLE);
return true;
if (HAL_I2C_Master_Transmit(&hi2c1, GT911_I2C_ADDR << 1, uAddrAndBuf, len + 2, 100) != HAL_OK)
{
TRACE("I2C ERROR: WriteRegister failed");
return false;
}
return true;
}
bool I2C_GT911_ReadRegister(u16 reg, uint8_t * buf, uint8_t len)
bool I2C_GT911_ReadRegister(uint16_t reg, uint8_t * buf, uint8_t len)
{
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
{
TRACE("I2C READ ERROR: busy timeout");
return false;
}
uint8_t uRegAddr[2];
uRegAddr[0] = (uint8_t)((reg & 0xFF00) >> 8);
uRegAddr[1] = (uint8_t)(reg & 0x00FF);
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
{
TRACE("I2C READ ERROR: could not issue first step start");
return false;
}
I2C_Send7bitAddress(I2C, GT_CMD_WR, I2C_Direction_Transmitter);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
TRACE("I2C READ ERROR: could not send first step device address");
return false;
}
I2C_SendData(I2C, (uint8_t)((reg & 0xFF00) >> 8));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
TRACE("I2C READ ERROR: could not send register high address");
return false;
}
I2C_SendData(I2C, (uint8_t)(reg & 0x00FF));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
TRACE("I2C READ ERROR: could not send register low address");
return false;
}
// According to GP911 data sheet, repeated start is not listed, so we do full stop.
// See chapter 6.1.c, page 12, diagram for reading data
I2C_GenerateSTOP(I2C, ENABLE);
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
{
TRACE("I2C READ ERROR: timeout waiting for first stop");
return false;
}
// Enable Acknowledgement, clear POS flag
I2C_AcknowledgeConfig(I2C, ENABLE);
I2C_NACKPositionConfig(I2C, I2C_NACKPosition_Current);
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
{
TRACE("I2C READ ERROR: could not issue second step start");
return false;
}
I2C_Send7bitAddress(I2C, GT_CMD_RD, I2C_Direction_Receiver);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
TRACE("I2C READ ERROR: could not send second step device address");
return false;
}
if (len == 1) {
// Clear Ack bit
I2C_AcknowledgeConfig(I2C, DISABLE);
// EV6_1 -- must be atomic -- Clear ADDR, generate STOP
__disable_irq();
(void) I2C->SR2;
I2C_GenerateSTOP(I2C,ENABLE);
__enable_irq();
// Receive data EV7
if(!I2C_WaitFlag(I2C_FLAG_RXNE)) {
TRACE("I2C READ ERROR: timeout waiting for RxNE");
I2C_Init();
return false;
}
*buf++ = I2C_ReceiveData(I2C);
}
else if (len == 2) {
// Set POS flag
I2C_NACKPositionConfig(I2C, I2C_NACKPosition_Next);
// EV6_1 -- must be atomic and in this order
__disable_irq();
(void) I2C->SR2; // Clear ADDR flag
I2C_AcknowledgeConfig(I2C, DISABLE); // Clear Ack bit
__enable_irq();
// EV7_3 -- Wait for BTF, program stop, read data twice
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
return false;
}
__disable_irq();
I2C_GenerateSTOP(I2C,ENABLE);
*buf++ = I2C->DR;
__enable_irq();
*buf++ = I2C->DR;
}
else {
(void) I2C->SR2; // Clear ADDR flag
while (len-- != 3) {
// EV7 -- cannot guarantee 1 transfer completion time, wait for BTF
// instead of RXNE
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
if (HAL_I2C_Master_Transmit(&hi2c1, GT911_I2C_ADDR << 1, uRegAddr, 2, 10) != HAL_OK)
{
TRACE("I2C ERROR: ReadRegister write reg address failed");
return false;
}
*buf++ = I2C_ReceiveData(I2C);
}
// Data N-2 in DR, data N-1 in shift register,
// SCL stretched low until data N-2 is read
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
return false;
if (HAL_I2C_Master_Receive(&hi2c1, GT911_I2C_ADDR << 1, buf, len, 100) != HAL_OK)
{
TRACE("I2C ERROR: ReadRegister read reg address failed");
return false;
}
I2C_AcknowledgeConfig(I2C, DISABLE); // clear ack bit
*buf++ = I2C_ReceiveData(I2C); // receive byte N-2
// Wait for BTF, program stop, read data twice
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
return false;
}
__disable_irq();
I2C_GenerateSTOP(I2C,ENABLE);
*buf++ = I2C->DR;
__enable_irq();
*buf++ = I2C->DR;
}
return true;
return true;
}
bool I2C_GT911_SendConfig(void)
@@ -791,7 +602,7 @@ bool touchPanelInit(void)
TRACE("Touchpanel init start ...");
TOUCH_AF_GPIOConfig(); //SET RST=OUT INT=OUT INT=LOW
I2C_Init();
I2C_Init_Radio();
TPRST_LOW();
TPINT_HIGH();
@@ -827,7 +638,7 @@ bool touchPanelInit(void)
}
TRACE("Chip config Ver:%x", tmp[0]);
if (tmp[0] <= GT911_CFG_NUMER) //Config ver
if (tmp[0] < GT911_CFG_NUMER) //Config ver
{
TRACE("Sending new config %d", GT911_CFG_NUMER);
if (!I2C_GT911_SendConfig())
@@ -864,6 +675,23 @@ bool touchPanelInit(void)
}
}
bool I2C_ReInit(void)
{
TRACE("I2C ReInit");
touchPanelDeInit();
if (HAL_I2C_DeInit(&hi2c1) != HAL_OK)
TRACE("I2C ReInit - I2C DeInit failed");
// If DeInit fails, try to re-init anyway
if (!touchPanelInit())
{
TRACE("I2C ReInit - touchPanelInit failed");
return false;
}
return true;
}
#if defined(SIMU) || defined(SEMIHOSTING) || defined(DEBUG)
static const char* event2str(uint8_t ev)
{
@@ -888,10 +716,10 @@ void touchPanelRead()
{
uint8_t state = 0;
// if (!touchEventOccured)
// return;
if (!touchEventOccured)
return;
// touchEventOccured = false;
touchEventOccured = false;
uint32_t startReadStatus = RTOS_GET_MS();
do {
@@ -899,8 +727,8 @@ void touchPanelRead()
//ledRed();
touchGT911hiccups++;
TRACE("GT911 I2C read XY error");
touchPanelDeInit();
touchPanelInit();
if (!I2C_ReInit())
TRACE("I2C ReInit failed");
return;
}
@@ -921,8 +749,8 @@ void touchPanelRead()
//ledRed();
touchGT911hiccups++;
TRACE("GT911 I2C data read error");
touchPanelDeInit();
touchPanelInit();
if (!I2C_ReInit())
TRACE("I2C ReInit failed");
return;
}
if (touchState.event == TE_NONE || touchState.event == TE_UP ||
+17 -16
View File
@@ -30,28 +30,29 @@ extern bool touchPanelInit();
void touchPanelRead();
bool touchPanelEventOccured();
#define GT911_TIMEOUT 3 // 3ms
#define GT911_TIMEOUT 3 // 3ms
#define GT911_MAX_TP 5
#define GT911_CFG_NUMER 0x6C
#define GT911_CFG_NUMER 0x6D
//I2C
#define GT_CMD_WR 0X28
#define GT_CMD_RD 0X29
#define I2C_TIMEOUT_MAX 1000
#define GT911_I2C_ADDR 0x14
//#define GT_CMD_WR 0x28
//#define GT_CMD_RD 0x29
//#define I2C_TIMEOUT_MAX 1000
//GT9147
#define GT_CTRL_REG 0X8040
#define GT_CFGS_REG 0X8047
#define GT_CHECK_REG 0X80FF
#define GT_PID_REG 0X8140
//GT911
#define GT_CTRL_REG 0x8040
#define GT_CFGS_REG 0x8047
#define GT_CHECK_REG 0x80FF
#define GT_PID_REG 0x8140
#define GT_GSTID_REG 0X814E
#define GT_TP1_REG 0X8150
#define GT_TP2_REG 0X8158
#define GT_TP3_REG 0X8160
#define GT_TP4_REG 0X8168
#define GT_TP5_REG 0X8170
#define GT_GSTID_REG 0x814E
#define GT_TP1_REG 0x8150
#define GT_TP2_REG 0x8158
#define GT_TP3_REG 0x8160
#define GT_TP4_REG 0x8168
#define GT_TP5_REG 0x8170
#define GT911_READ_XY_REG 0x814E
#define GT911_CLEARBUF_REG 0x814E
+1 -1
View File
@@ -1968,7 +1968,7 @@
#define I2C_SDA_GPIO_PinSource GPIO_PinSource7
#define I2C_ADDRESS_VOLUME 0x5C
#endif
#define I2C_SPEED 400000
#define I2C_CLK_RATE 400000
#define I2C_ADDRESS_EEPROM 0xA2
#define I2C_FLASH_PAGESIZE 64
+1 -1
View File
@@ -37,7 +37,7 @@ void i2cInit()
GPIO_ResetBits(I2C_WP_GPIO, I2C_WP_GPIO_PIN);
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStructure.I2C_ClockSpeed = I2C_CLK_RATE;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;