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

github.com/nickshl/DevBoy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'STM32F415APP/DevCore/Drivers/StHalIic.cpp')
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalIic.cpp245
1 files changed, 245 insertions, 0 deletions
diff --git a/STM32F415APP/DevCore/Drivers/StHalIic.cpp b/STM32F415APP/DevCore/Drivers/StHalIic.cpp
new file mode 100644
index 0000000..2f231a1
--- /dev/null
+++ b/STM32F415APP/DevCore/Drivers/StHalIic.cpp
@@ -0,0 +1,245 @@
+//******************************************************************************
+// @file StHalIic.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: STM32 HAL I2C driver, implementation
+//
+// @copyright Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "StHalIic.h"
+
+// *****************************************************************************
+// *** This driver can be compiled only if I2C configured in CubeMX ********
+// *****************************************************************************
+#ifdef HAL_I2C_MODULE_ENABLED
+
+// *****************************************************************************
+// *** Public: Enable ******************************************************
+// *****************************************************************************
+Result StHalIic::Enable()
+{
+ // Set PE bit
+ __HAL_I2C_ENABLE(&hi2c);
+ // No errors to return
+ return Result::RESULT_OK;
+}
+
+// *****************************************************************************
+// *** Public: Disable *****************************************************
+// *****************************************************************************
+Result StHalIic::Disable()
+{
+ // Clear PE bit
+ __HAL_I2C_DISABLE(&hi2c);
+ // No errors to return
+ return Result::RESULT_OK;
+}
+
+// *****************************************************************************
+// *** Public: Reset *******************************************************
+// *****************************************************************************
+Result StHalIic::Reset()
+{
+ // Clear PE bit
+ CLEAR_BIT(hi2c.Instance->CR1, I2C_CR1_PE);
+ // PE must be kept low during at least 3 APB clock cycles in order to
+ // perform the software reset. Wait until it actually cleared.
+ while(READ_BIT(hi2c.Instance->CR1, I2C_CR1_PE));
+ // TODO: make some clock on the SCL line here
+ // Set PE bit
+ SET_BIT(hi2c.Instance->CR1, I2C_CR1_PE);
+ // No errors to return
+ return Result::RESULT_OK;
+}
+
+// *************************************************************************
+// *** Public: IsDeviceReady *******************************************
+// *************************************************************************
+Result StHalIic::IsDeviceReady(uint16_t addr, uint8_t retries)
+{
+ Result result;
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+ // Check device status
+ HAL_StatusTypeDef hal_result = HAL_I2C_IsDeviceReady(&hi2c1, addr, retries, i2c_tx_timeout_ms);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ // Return result
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Transfer ****************************************************
+// *****************************************************************************
+Result StHalIic::Transfer(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size, uint8_t* rx_buf_ptr, uint32_t rx_size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(tx_buf_ptr != nullptr)
+ {
+ // Transmit data
+ result = Write(addr, tx_buf_ptr, tx_size);
+ }
+
+ if((rx_buf_ptr != nullptr) && result.IsGood())
+ {
+ // Clear RX buffer
+ for(uint32_t i = 0; i < rx_size; i++)
+ {
+ rx_buf_ptr[i] = 0;
+ }
+ // Receive data
+ result = Read(addr, rx_buf_ptr, rx_size);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Write *******************************************************
+// *****************************************************************************
+Result StHalIic::Write(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(tx_buf_ptr != nullptr)
+ {
+ // Variable for store result from the HAL
+ HAL_StatusTypeDef hal_result = HAL_OK;
+
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+
+ // Transmit data
+ hal_result = HAL_I2C_Master_Transmit(&hi2c, addr, tx_buf_ptr, tx_size, i2c_tx_timeout_ms);
+
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Read ********************************************************
+// *****************************************************************************
+Result StHalIic::Read(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(rx_buf_ptr != nullptr)
+ {
+ // Variable for store result from the HAL
+ HAL_StatusTypeDef hal_result = HAL_OK;
+
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+
+ // Transmit data
+ hal_result = HAL_I2C_Master_Receive(&hi2c, addr, rx_buf_ptr, rx_size, i2c_tx_timeout_ms);
+
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: WriteAsync **************************************************
+// *****************************************************************************
+Result StHalIic::WriteAsync(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size)
+{
+ Result result = Result::ERR_NOT_IMPLEMENTED;
+
+ // Check DMA handler - if it is nullptr this function not implemented in hardware
+ if(hi2c.hdmatx != nullptr)
+ {
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+ // Receive data using DMA
+ HAL_StatusTypeDef hal_result = HAL_I2C_Master_Transmit_DMA(&hi2c, addr, tx_buf_ptr, tx_size);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: ReadAsync ***************************************************
+// *****************************************************************************
+Result StHalIic::ReadAsync(uint16_t addr, uint8_t* rx_buf_ptr, uint32_t rx_size)
+{
+ Result result = Result::ERR_NOT_IMPLEMENTED;
+
+ // Check DMA handler - if it is nullptr this function not implemented in hardware
+ if(hi2c.hdmarx != nullptr)
+ {
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+ // Receive data using DMA
+ HAL_StatusTypeDef hal_result = HAL_I2C_Master_Receive_DMA(&hi2c, addr, rx_buf_ptr, rx_size);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Transfer ****************************************************
+// *****************************************************************************
+bool StHalIic::IsBusy(void)
+{
+ return (hi2c.State != HAL_I2C_STATE_READY);
+}
+
+// *****************************************************************************
+// *** Private: ConvertResult **********************************************
+// *****************************************************************************
+Result StHalIic::ConvertResult(HAL_StatusTypeDef hal_result)
+{
+ Result result = Result::RESULT_OK;
+
+ // Convert operation result to Result
+ switch(hal_result)
+ {
+ case HAL_OK:
+ result = Result::RESULT_OK;
+ break;
+
+ case HAL_ERROR:
+ result = Result::ERR_I2C_GENERAL;
+ break;
+
+ case HAL_BUSY:
+ result = Result::ERR_I2C_BUSY;
+ break;
+
+ case HAL_TIMEOUT:
+ result = Result::ERR_I2C_TIMEOUT;
+ break;
+
+ default:
+ result = Result::ERR_SPI_UNKNOWN;
+ break;
+ }
+
+ // Return result
+ return result;
+}
+
+#endif