#include "i2c.hpp" #include "pindef.hpp" #include "stm32f4xx_hal_i2c.h" namespace driver::i2c { I2c::I2c(I2C_TypeDef* i2c, const uint32_t clockSpeed, const uint32_t dutyCycle, const uint32_t ownAddress1, const uint32_t addressingMode, const uint32_t dualAddressMode, const uint32_t ownAddress2, const uint32_t generalCallMode, const uint32_t noStretchMode) : mHandle{.Instance = i2c, .Init{.ClockSpeed = clockSpeed, .DutyCycle = dutyCycle, .OwnAddress1 = ownAddress1, .AddressingMode = addressingMode, .DualAddressMode = dualAddressMode, .OwnAddress2 = ownAddress2, .GeneralCallMode = generalCallMode, .NoStretchMode = noStretchMode}, .pBuffPtr = nullptr, .XferSize = 0, .XferCount = 0, .XferOptions = 0, .PreviousState = 0, .hdmatx = nullptr, .hdmarx = nullptr, .Lock = HAL_UNLOCKED, .State = HAL_I2C_STATE_RESET, .Mode = HAL_I2C_MODE_NONE, .ErrorCode = HAL_I2C_ERROR_NONE, .Devaddress = 0, .Memaddress = 0, .MemaddSize = 0, .EventCount = 0} {} bool I2c::init() { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (mHandle.Instance == I2C1) { __HAL_RCC_GPIOB_CLK_ENABLE(); /**I2C1 GPIO Configuration PB6 ------> I2C1_SCL PB7 ------> I2C1_SDA */ GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); __HAL_RCC_I2C1_CLK_ENABLE(); } return HAL_I2C_Init(&mHandle) == HAL_OK; } void I2c::deinit() {} HAL_StatusTypeDef I2c::write(const uint16_t slaveAddr, const uint16_t memAddr, std::vector& data) { // Slave address needs to be shifted to the left, so that the r/w bit can be set by the HAL method // Addressing mode for slaves is fixed to 8bit for now... return HAL_I2C_Mem_Write(&mHandle, slaveAddr << 1, memAddr, I2C_MEMADD_SIZE_8BIT, data.data(), data.size(), I2C_TIMEOUT_MS); } std::pair I2c::read(const uint16_t slaveAddr, const uint16_t memAddr) { uint8_t data; // Slave address needs to be shifted to the left, so that the r/w bit can be set by the HAL method auto state = HAL_I2C_Mem_Read(&mHandle, slaveAddr << 1, memAddr, I2C_MEMADD_SIZE_8BIT, &data, 1, I2C_TIMEOUT_MS); return {state, data}; } uint32_t I2c::getLastError() { return mHandle.ErrorCode; } } // namespace driver::i2c