#include "drivers/i2c/i2c.h" #include "stm32l1xx_hal.h" #include "stm32l1xx_hal_i2c.h" #include "core/gpio.h" #include "core/main.h" #include "core/csect.h" #include "core/config_pins.h" I2C_HandleTypeDef i2c_handle = { #if CONFIG_PERIF_TSENSI2C == CONFIG_PERIF_I2C1 .Instance = I2C1 #elif CONFIG_PERIF_TSENSI2C == CONFIG_PERIF_I2C2 .Instance = I2C2 #else #error Invalid I2C specified in 'config_pins.h': see 'CONFIG_PERIF_TSENSI2C' #endif }; static bool I2C_Init( eI2CPinMode_t ); static HAL_StatusTypeDef I2C_Master_Transmit( uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); static HAL_StatusTypeDef I2C_Master_Receive( uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); static void I2C_DeInit( eI2CPinMode_t ); const I2C_Handle_t I2C_Handle = { .Init = I2C_Init, .Transmit = I2C_Master_Transmit, .Receive = I2C_Master_Receive, .DeInit = I2C_DeInit, }; // HAL Callback: initialize I2C GPIO, CLOCK, NVIC...etc void HAL_I2C_MspInit( I2C_HandleTypeDef * hi2c ) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if( hi2c->Instance == I2C1 ) { __HAL_RCC_I2C1_CLK_ENABLE(); } if( hi2c->Instance == I2C2 ) { __HAL_RCC_I2C2_CLK_ENABLE(); } // Perform periferal reset MODIFY_REG(hi2c->Instance->CR1, (0), (I2C_CR1_SWRST)); MODIFY_REG(hi2c->Instance->CR1, (I2C_CR1_SWRST), (0)); if( hi2c->Instance == I2C1 ) { __HAL_RCC_I2C1_FORCE_RESET(); __HAL_RCC_I2C1_RELEASE_RESET(); HAL_NVIC_SetPriority( I2C1_EV_IRQn, I2C_INT_PRIORITY, 0); HAL_NVIC_EnableIRQ( I2C1_EV_IRQn ); } if( hi2c->Instance == I2C2 ) { __HAL_RCC_I2C2_FORCE_RESET(); __HAL_RCC_I2C2_RELEASE_RESET(); HAL_NVIC_SetPriority( I2C2_EV_IRQn, I2C_INT_PRIORITY, 0); HAL_NVIC_EnableIRQ( I2C2_EV_IRQn ); } // Configure the pin muxing - setup I2C pins GPIO_InitStruct.Pin = CONFIG_PIN__TSENSI2C__DA | CONFIG_PIN__TSENSI2C__CL; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; if( hi2c->Instance == I2C1 ) GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; if( hi2c->Instance == I2C2 ) GPIO_InitStruct.Alternate = GPIO_AF4_I2C2; HAL_GPIO_Init(CONFIG_PORT__TSENSI2C__DA_CL, &GPIO_InitStruct); } // HAL Callback: deinitialize I2C GPIO, CLOCK, NVIC...etc void HAL_I2C_MspDeInit( I2C_HandleTypeDef * hi2c ) { if( hi2c->Instance == I2C1 ) { HAL_NVIC_DisableIRQ( I2C1_EV_IRQn ); __HAL_RCC_I2C1_CLK_DISABLE(); } if( hi2c->Instance == I2C2 ) { HAL_NVIC_DisableIRQ( I2C2_EV_IRQn ); __HAL_RCC_I2C2_CLK_DISABLE(); } } static bool I2C_Init( eI2CPinMode_t pinmode ) { bool ret = false; i2c_handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; i2c_handle.Init.ClockSpeed = 100000; i2c_handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; i2c_handle.Init.DutyCycle = I2C_DUTYCYCLE_2; i2c_handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; i2c_handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; i2c_handle.Init.OwnAddress1 = 0; i2c_handle.Init.OwnAddress2 = 0; DI(); // Initialize I2C-bus if( HAL_OK == HAL_I2C_Init( &i2c_handle ) ) { ret = true; } EI(); if( !ret ) { // ERROR, deinitialize I2C_DeInit( pinmode ); } return ret; } static void I2C_DeInit( eI2CPinMode_t pinmode ) { { // I2C Pin Muxing GPIO_InitTypeDef GPIO_InitStruct = {0}; // Deinitialize I2C pins GPIO_InitStruct.Pin = CONFIG_PIN__TSENSI2C__DA | CONFIG_PIN__TSENSI2C__CL; switch( pinmode ) { case eI2CPinMode_KeepPullUp: GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // GPIO_InitStruct.Pull = GPIO_PULLUP; // required to guaranee the correct level break; case eI2CPinMode_KeepPullDown: GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // GPIO_InitStruct.Pull = GPIO_PULLDOWN; // required to guaranee the correct level break; default: GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; } GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(CONFIG_PORT__TSENSI2C__DA_CL, &GPIO_InitStruct); } DI(); // Deinitialize I2C-bus HAL_I2C_DeInit( &i2c_handle ); EI(); } static HAL_StatusTypeDef I2C_Master_Transmit( uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) { return HAL_I2C_Master_Transmit( &i2c_handle, DevAddress, pData, Size, Timeout ); } static HAL_StatusTypeDef I2C_Master_Receive( uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) { return HAL_I2C_Master_Receive( &i2c_handle, DevAddress, pData, Size, Timeout ); }