diff --git a/.gitignore b/.gitignore index cfe5f9d..4b5a695 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # IDE settings .settings/ +.vscode/ # Contain local paths .mxproject diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0c03699 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,69 @@ +{ + "files.associations": { + "__bit_reference": "cpp", + "__bits": "cpp", + "__config": "cpp", + "__debug": "cpp", + "__errc": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__mutex_base": "cpp", + "__node_handle": "cpp", + "__nullptr": "cpp", + "__split_buffer": "cpp", + "__string": "cpp", + "__threading_support": "cpp", + "__tuple": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "locale": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "variant": "cpp", + "vector": "cpp", + "__functional_base": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "utility": "cpp" + } +} \ No newline at end of file diff --git a/README.md b/README.md index bb7a761..66e36a8 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ Interfaces for the following resources are provided: * Signal * SPI * UART +* I2C ## HAL implementations @@ -108,6 +109,16 @@ Implementations using the HAL are provided for the following interfaces: To enable these implementations follow the instructions from the individual headers. +## Merge with STM32 Core + +The merge with STM32 Core allows seamless usage of the STM32 implementations for the different Interfaces etc. +Notable inclusions: +* CAN +* I2C +* SPI +* UART + + ## Atomic implementations Implementations using atomic variables are provided for the following interfaces: diff --git a/include/sta/i2c.hpp b/include/sta/i2c.hpp new file mode 100644 index 0000000..db467dd --- /dev/null +++ b/include/sta/i2c.hpp @@ -0,0 +1,27 @@ +#ifndef STA_I2C_HPP +#define STA_I2C_HPP + +#include +#include + +namespace sta { + class I2cDevice { + protected: + uint16_t address; + Mutex* mutex; + bool master; + bool blocking; + public: + I2cDevice(uint16_t address_10bit, Mutex* mutex=nullptr, bool master=false, bool blocking=true); + + virtual bool transmit(uint8_t* data, uint16_t size) = 0; + + virtual bool receive(uint8_t* data, uint16_t size) = 0; + + virtual void acquire(); + + virtual void release(); + }; +} + +#endif // STA_I2C_HPP diff --git a/include/sta/stm32/i2c.hpp b/include/sta/stm32/i2c.hpp new file mode 100644 index 0000000..4804e1a --- /dev/null +++ b/include/sta/stm32/i2c.hpp @@ -0,0 +1,39 @@ +#ifndef STA_STM32_I2C_HPP +#define STA_STM32_I2C_HPP + +#include +#ifdef STA_PLATFORM_STM32 +# include +# ifdef HAL_I2C_MODULE_ENABLED +# define STA_STM32_I2C_ENABLED +# endif // HAL_SPI_MODULE_ENABLED +#endif // STA_PLATFORM_STM32 + +#ifdef STA_STM32_I2C_ENABLED + +#include + +namespace sta { + class STM32I2cDevice : public I2cDevice { + private: + I2C_HandleTypeDef* i2cHandle; + const uint32_t timeout = HAL_MAX_DELAY; + + public: + STM32I2cDevice( + I2C_HandleTypeDef* i2cHandle, + uint16_t address, + Mutex* mutex=nullptr, + bool master=false, + bool blocking=true + ); + + bool transmit(uint8_t* data, uint16_t size) override; + bool receive(uint8_t* data, uint16_t size) override; + + bool deviceReady(); + }; +} + +#endif // STA_STM32_I2C_ENABLED +#endif // STA_STM32_I2C_HPP diff --git a/src/i2c.cpp b/src/i2c.cpp new file mode 100644 index 0000000..0f32c26 --- /dev/null +++ b/src/i2c.cpp @@ -0,0 +1,22 @@ +#include + +namespace sta { + I2cDevice::I2cDevice(uint16_t address_7bit, Mutex* mutex, bool master, bool blocking) { + this->address = address_7bit << 1; + this->mutex = mutex; + this->master = master; + this->blocking = blocking; + } + + void I2cDevice::acquire() { + if (this->mutex != nullptr) { + mutex->acquire(); + } + } + + void I2cDevice::release() { + if (this->mutex != nullptr) { + mutex->release(); + } + } +} diff --git a/src/stm32/i2c.cpp b/src/stm32/i2c.cpp new file mode 100644 index 0000000..289bfc1 --- /dev/null +++ b/src/stm32/i2c.cpp @@ -0,0 +1,53 @@ +#include + +namespace sta { + STM32I2cDevice::STM32I2cDevice(I2C_HandleTypeDef* i2cHandle, uint16_t address, Mutex* mutex, bool master, bool blocking) + : I2cDevice(address, mutex, master, blocking) { + this->master = master; + } + + bool STM32I2cDevice::transmit(uint8_t* data, uint16_t size) { + HAL_StatusTypeDef res; + + if (this->blocking) { + if (!this->master) { + res = HAL_I2C_Master_Transmit(i2cHandle, address, data, size, this->timeout); + } else { + res = HAL_I2C_Slave_Transmit(i2cHandle , data, size, this->timeout); + } + } else { + if (!this->master) { + res = HAL_I2C_Master_Transmit_IT(i2cHandle, address, data, size); + } else { + res = HAL_I2C_Slave_Transmit_IT(i2cHandle , data, size); + } + } + + return res == HAL_OK; + } + + bool STM32I2cDevice::receive(uint8_t* data, uint16_t size) { + HAL_StatusTypeDef res; + + if (this->blocking) { + if (!this->master) { + res = HAL_I2C_Master_Receive(i2cHandle, address, data, size, this->timeout); + } else { + res = HAL_I2C_Slave_Receive(i2cHandle , data, size, this->timeout); + } + } else { + if (!this->master) { + res = HAL_I2C_Master_Receive_IT(i2cHandle, address, data, size); + } else { + res = HAL_I2C_Slave_Receive_IT(i2cHandle , data, size); + } + } + + return res == HAL_OK; + } + + bool STM32I2cDevice::deviceReady() { + HAL_StatusTypeDef res = HAL_I2C_IsDeviceReady(this->i2cHandle, this->address, 8, this->timeout); + return res == HAL_OK; + } +}