128 lines
2.9 KiB
C++

#include <sta/devices/stm32/bus/i2c.hpp>
#include <sta/debug/assert.hpp>
#include <cstring>
#ifdef STA_STM32_I2C_ENABLED
namespace sta
{
STM32I2C::STM32I2C(I2C_HandleTypeDef * handle, Mutex * mutex)
: I2C{mutex}, handle_{handle}
{
STA_ASSERT(handle != nullptr);
}
void STM32I2C::transfer(uint8_t value)
{
HAL_StatusTypeDef res;
if (master_)
{
res = HAL_I2C_Master_Transmit(handle_, address_, &value, 1, timeout_);
} else {
res = HAL_I2C_Slave_Transmit(handle_, &value, 1, timeout_);
}
STA_ASSERT(res == HAL_OK);
}
void STM32I2C::transfer16(uint16_t value)
{
HAL_StatusTypeDef res;
if (blocking_)
{
if (master_)
{
res = HAL_I2C_Master_Transmit(handle_, address_, reinterpret_cast<uint8_t *>(&value), 2, timeout_);
} else {
res = HAL_I2C_Slave_Transmit(handle_, reinterpret_cast<uint8_t *>(&value), 2, timeout_);
}
} else {
if (master_)
{
res = HAL_I2C_Slave_Transmit_IT(handle_, reinterpret_cast<uint8_t *>(&value), 2);
} else {
res = HAL_I2C_Slave_Transmit_IT(handle_, reinterpret_cast<uint8_t *>(&value), 2);
}
}
STA_ASSERT(res == HAL_OK);
}
void STM32I2C::transfer(const uint8_t * buffer, size_t size)
{
HAL_StatusTypeDef res;
/*
* It's undecided if we want to change the parameter for this function. Since the transmission
* doesn't take a const buffer as an argument, we are using this fix by creating a temporary buffer.
*/
uint8_t * temp_buffer = new uint8_t[size];
memcpy(temp_buffer, buffer, size);
if (blocking_)
{
if (master_)
{
res = HAL_I2C_Master_Transmit(handle_, address_, temp_buffer, size, timeout_);
} else {
res = HAL_I2C_Slave_Transmit(handle_, temp_buffer, size, timeout_);
}
} else {
if (master_) {
res = HAL_I2C_Master_Transmit_IT(handle_, address_, temp_buffer, size);
} else {
res = HAL_I2C_Slave_Transmit_IT(handle_, temp_buffer, size);
}
}
delete [] temp_buffer;
STA_ASSERT(res == HAL_OK);
}
void STM32I2C::receive(uint8_t * buffer, size_t size)
{
HAL_StatusTypeDef res;
if (blocking_) {
if (master_) {
res = HAL_I2C_Master_Receive(handle_, address_, buffer, size, timeout_);
} else {
res = HAL_I2C_Slave_Receive(handle_, buffer, size, timeout_);
}
} else {
if (master_) {
res = HAL_I2C_Master_Receive_IT(handle_, address_, buffer, size);
} else {
res = HAL_I2C_Slave_Receive_IT(handle_, buffer, size);
}
}
STA_ASSERT(res == HAL_OK);
}
void STM32I2C::fill(uint8_t value, size_t count)
{
// Initialize a buffer of size count and fill it with the value.
uint8_t *buffer = new uint8_t[count];
memset(buffer, value, count);
// Transfer the buffer via the bus.
transfer(buffer, count);
delete [] buffer;
}
STM32I2CDevice::STM32I2CDevice(STM32I2C * intf, int address, bool master, bool blocking)
: I2CDevice(intf, address, master, blocking)
{
}
} // namespace sta
#endif // STA_STM32_I2C_ENABLED