From 6b4acfd27b001d455ecfbec41eedb99c84bdaa0d Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 23 Jun 2023 15:50:54 +0100 Subject: [PATCH] Added I2C support for raspi & first rework of debugging --- include/sta/{ => bus}/can/controller.hpp | 6 +- include/sta/{ => bus}/can/filter.hpp | 2 +- include/sta/{ => bus}/can/headers.hpp | 2 +- include/sta/{ => bus}/can/id.hpp | 0 include/sta/{ => bus}/can/iter.hpp | 0 include/sta/{ => bus}/can/subscribable.hpp | 8 +- include/sta/{ => bus}/can/subscribable.tpp | 0 include/sta/{spi => bus}/device.hpp | 63 ++-- include/sta/bus/i2c/device.hpp | 37 +++ include/sta/bus/i2c/i2c.hpp | 33 ++ .../sta/{spi/spi.hpp => bus/interface.hpp} | 48 +-- include/sta/bus/spi/device.hpp | 51 ++++ include/sta/{ => bus}/spi/settings.hpp | 3 - include/sta/bus/spi/spi.hpp | 47 +++ include/sta/bus/uart/settings.hpp | 24 ++ include/sta/bus/uart/uart.hpp | 25 ++ include/sta/config.hpp | 2 +- .../{ => devices}/arduino/not_implemented.hpp | 0 include/sta/devices/raspi/bus/i2c.hpp | 52 ++++ .../sta/{raspi => devices/raspi/bus}/spi.hpp | 4 +- include/sta/devices/raspi/can.hpp | 0 include/sta/{ => devices}/raspi/delay.hpp | 0 include/sta/{ => devices}/raspi/gpio_pin.hpp | 2 +- include/sta/{ => devices}/raspi/hal.hpp | 0 .../sta/{ => devices}/raspi/mcu/common.hpp | 0 include/sta/{ => devices}/stm32/can.hpp | 0 include/sta/{ => devices}/stm32/clocks.hpp | 0 include/sta/{ => devices}/stm32/delay.hpp | 0 include/sta/{ => devices}/stm32/gpio_pin.hpp | 0 include/sta/{ => devices}/stm32/hal.hpp | 0 include/sta/{ => devices}/stm32/i2c.hpp | 0 include/sta/{ => devices}/stm32/init.hpp | 0 .../{ => devices}/stm32/mcu/STM32F411xE.hpp | 0 .../{ => devices}/stm32/mcu/STM32F413xx.hpp | 0 .../sta/{ => devices}/stm32/mcu/common.hpp | 0 include/sta/{ => devices}/stm32/spi.hpp | 0 include/sta/{ => devices}/stm32/uart.hpp | 0 include/sta/devices/template/delay.hpp | 43 +++ include/sta/i2c.hpp | 27 -- include/sta/lang.hpp | 8 + include/sta/printable.hpp | 283 +++++++++--------- include/sta/printable_uart.hpp | 156 +--------- include/sta/uart.hpp | 10 +- src/bus/device.cpp | 77 +++++ src/bus/i2c/device.cpp | 23 ++ src/bus/i2c/i2c.cpp | 11 + src/bus/interface.cpp | 29 ++ src/bus/spi/device.cpp | 29 ++ src/{ => bus}/spi/settings.cpp | 2 +- src/bus/spi/spi.cpp | 17 ++ src/bus/uart/settings.cpp | 0 src/bus/uart/uart.cpp | 15 + src/devices/raspi/bus/i2c/i2c.cpp | 129 ++++++++ src/{raspi => devices/raspi/bus/spi}/spi.cpp | 12 +- src/{ => devices}/raspi/delay.cpp | 4 +- src/{ => devices}/raspi/gpio_pin.cpp | 0 src/{ => devices}/stm32/can.cpp | 0 src/{ => devices}/stm32/delay.cpp | 0 src/{ => devices}/stm32/gpio_pin.cpp | 0 src/{ => devices}/stm32/i2c.cpp | 0 src/{ => devices}/stm32/init.cpp | 0 src/{ => devices}/stm32/spi.cpp | 0 src/{ => devices}/stm32/uart.cpp | 2 +- src/devices/template/delay.cpp | 36 +++ src/i2c.cpp | 22 -- src/printable.cpp | 116 ++++--- src/printable_uart.cpp | 181 +---------- src/spi/device.cpp | 88 ------ src/spi/spi.cpp | 27 -- src/uart.cpp | 1 - 70 files changed, 985 insertions(+), 772 deletions(-) rename include/sta/{ => bus}/can/controller.hpp (96%) rename include/sta/{ => bus}/can/filter.hpp (96%) rename include/sta/{ => bus}/can/headers.hpp (96%) rename include/sta/{ => bus}/can/id.hpp (100%) rename include/sta/{ => bus}/can/iter.hpp (100%) rename include/sta/{ => bus}/can/subscribable.hpp (93%) rename include/sta/{ => bus}/can/subscribable.tpp (100%) rename include/sta/{spi => bus}/device.hpp (69%) create mode 100644 include/sta/bus/i2c/device.hpp create mode 100644 include/sta/bus/i2c/i2c.hpp rename include/sta/{spi/spi.hpp => bus/interface.hpp} (69%) create mode 100644 include/sta/bus/spi/device.hpp rename include/sta/{ => bus}/spi/settings.hpp (99%) create mode 100644 include/sta/bus/spi/spi.hpp create mode 100644 include/sta/bus/uart/settings.hpp create mode 100644 include/sta/bus/uart/uart.hpp rename include/sta/{ => devices}/arduino/not_implemented.hpp (100%) create mode 100644 include/sta/devices/raspi/bus/i2c.hpp rename include/sta/{raspi => devices/raspi/bus}/spi.hpp (95%) create mode 100644 include/sta/devices/raspi/can.hpp rename include/sta/{ => devices}/raspi/delay.hpp (100%) rename include/sta/{ => devices}/raspi/gpio_pin.hpp (96%) rename include/sta/{ => devices}/raspi/hal.hpp (100%) rename include/sta/{ => devices}/raspi/mcu/common.hpp (100%) rename include/sta/{ => devices}/stm32/can.hpp (100%) rename include/sta/{ => devices}/stm32/clocks.hpp (100%) rename include/sta/{ => devices}/stm32/delay.hpp (100%) rename include/sta/{ => devices}/stm32/gpio_pin.hpp (100%) rename include/sta/{ => devices}/stm32/hal.hpp (100%) rename include/sta/{ => devices}/stm32/i2c.hpp (100%) rename include/sta/{ => devices}/stm32/init.hpp (100%) rename include/sta/{ => devices}/stm32/mcu/STM32F411xE.hpp (100%) rename include/sta/{ => devices}/stm32/mcu/STM32F413xx.hpp (100%) rename include/sta/{ => devices}/stm32/mcu/common.hpp (100%) rename include/sta/{ => devices}/stm32/spi.hpp (100%) rename include/sta/{ => devices}/stm32/uart.hpp (100%) create mode 100644 include/sta/devices/template/delay.hpp delete mode 100644 include/sta/i2c.hpp create mode 100644 src/bus/device.cpp create mode 100644 src/bus/i2c/device.cpp create mode 100644 src/bus/i2c/i2c.cpp create mode 100644 src/bus/interface.cpp create mode 100644 src/bus/spi/device.cpp rename src/{ => bus}/spi/settings.cpp (97%) create mode 100644 src/bus/spi/spi.cpp create mode 100644 src/bus/uart/settings.cpp create mode 100644 src/bus/uart/uart.cpp create mode 100644 src/devices/raspi/bus/i2c/i2c.cpp rename src/{raspi => devices/raspi/bus/spi}/spi.cpp (97%) rename src/{ => devices}/raspi/delay.cpp (78%) rename src/{ => devices}/raspi/gpio_pin.cpp (100%) rename src/{ => devices}/stm32/can.cpp (100%) rename src/{ => devices}/stm32/delay.cpp (100%) rename src/{ => devices}/stm32/gpio_pin.cpp (100%) rename src/{ => devices}/stm32/i2c.cpp (100%) rename src/{ => devices}/stm32/init.cpp (100%) rename src/{ => devices}/stm32/spi.cpp (100%) rename src/{ => devices}/stm32/uart.cpp (92%) create mode 100644 src/devices/template/delay.cpp delete mode 100644 src/i2c.cpp delete mode 100644 src/spi/device.cpp delete mode 100644 src/spi/spi.cpp diff --git a/include/sta/can/controller.hpp b/include/sta/bus/can/controller.hpp similarity index 96% rename from include/sta/can/controller.hpp rename to include/sta/bus/can/controller.hpp index fbadb59..0c6f212 100644 --- a/include/sta/can/controller.hpp +++ b/include/sta/bus/can/controller.hpp @@ -12,9 +12,9 @@ */ -#include -#include -#include +#include +#include +#include namespace sta diff --git a/include/sta/can/filter.hpp b/include/sta/bus/can/filter.hpp similarity index 96% rename from include/sta/can/filter.hpp rename to include/sta/bus/can/filter.hpp index 0071139..1499eea 100644 --- a/include/sta/can/filter.hpp +++ b/include/sta/bus/can/filter.hpp @@ -5,7 +5,7 @@ #ifndef STA_CORE_CAN_FILTER_HPP #define STA_CORE_CAN_FILTER_HPP -#include +#include #include diff --git a/include/sta/can/headers.hpp b/include/sta/bus/can/headers.hpp similarity index 96% rename from include/sta/can/headers.hpp rename to include/sta/bus/can/headers.hpp index 24536c5..0214434 100644 --- a/include/sta/can/headers.hpp +++ b/include/sta/bus/can/headers.hpp @@ -5,7 +5,7 @@ #ifndef STA_CORE_CAN_HEADERS_HPP #define STA_CORE_CAN_HEADERS_HPP -#include +#include #include diff --git a/include/sta/can/id.hpp b/include/sta/bus/can/id.hpp similarity index 100% rename from include/sta/can/id.hpp rename to include/sta/bus/can/id.hpp diff --git a/include/sta/can/iter.hpp b/include/sta/bus/can/iter.hpp similarity index 100% rename from include/sta/can/iter.hpp rename to include/sta/bus/can/iter.hpp diff --git a/include/sta/can/subscribable.hpp b/include/sta/bus/can/subscribable.hpp similarity index 93% rename from include/sta/can/subscribable.hpp rename to include/sta/bus/can/subscribable.hpp index 1d84080..2f5d600 100644 --- a/include/sta/can/subscribable.hpp +++ b/include/sta/bus/can/subscribable.hpp @@ -5,8 +5,8 @@ #ifndef STA_CORE_CAN_SUBSCRIBABLE_HPP #define STA_CORE_CAN_SUBSCRIBABLE_HPP -#include -#include +#include +#include namespace sta @@ -96,7 +96,7 @@ namespace sta } // namespace sta -#include +#include -#endif // STA_CORE_CAN_SUBSCRIBABLE_HPP +#endif // STA_CORE_CAN_SUBSCRIBABLE_HPP \ No newline at end of file diff --git a/include/sta/can/subscribable.tpp b/include/sta/bus/can/subscribable.tpp similarity index 100% rename from include/sta/can/subscribable.tpp rename to include/sta/bus/can/subscribable.tpp diff --git a/include/sta/spi/device.hpp b/include/sta/bus/device.hpp similarity index 69% rename from include/sta/spi/device.hpp rename to include/sta/bus/device.hpp index 657b6b1..55ea4a4 100644 --- a/include/sta/spi/device.hpp +++ b/include/sta/bus/device.hpp @@ -1,33 +1,21 @@ -/** - * @file - * @brief SPI bus peripheral device. - */ -#ifndef STA_CORE_SPI_DEVICE_HPP -#define STA_CORE_SPI_DEVICE_HPP - -#include -#include - -#include -#include +#ifndef STA_CORE_BUS_SERIAL_DEVICE_HPP +#define STA_CORE_BUS_SERIAL_DEVICE_HPP +#include namespace sta { /** - * @brief Peripheral device connected via SPI. - * - * @ingroup sta_core_spi - */ - class SPIDevice + * @brief Abstract device for serial communication. + */ + class Device { public: - /** + /** * @param intf %SPI hardware interface * @param csPin Chip select pin */ - SPIDevice(SPI * intf, GpioPin * csPin); - + Device(Interface * intf); /** * @brief Start transmission with device. @@ -35,6 +23,7 @@ namespace sta * Must be called before any I/O operations. */ void beginTransmission(); + /** * @brief End transmission with device. * @@ -42,19 +31,20 @@ namespace sta */ void endTransmission(); - /** * @brief Send single byte of data. * * @param value 8-bit value */ void transfer(uint8_t value); + /** * @brief Send two bytes of data. * * @param value 16-bit value */ void transfer16(uint16_t value); + /** * @brief Send data from buffer. * @@ -62,6 +52,7 @@ namespace sta * @param size Number of bytes to transfer */ void transfer(const uint8_t * buffer, size_t size); + /** * @brief Send and receive data simultaneously. * @@ -70,6 +61,7 @@ namespace sta * @param size Number of bytes to transfer */ void transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size); + /** * @brief Read incoming data to buffer. * @@ -78,7 +70,6 @@ namespace sta */ void receive(uint8_t * buffer, size_t size); - /** * @brief Send byte value repeatedly. * @@ -87,29 +78,21 @@ namespace sta */ void fill(uint8_t value, size_t count); + protected: + /** + * @brief Activate device.. + */ + virtual void select() = 0; /** - * @brief Get %SPI interface settings. - * - * @return SPI settings + * @brief Deactivate device.. */ - const SPISettings & settings() const; - - - /** - * @brief Activate device via CS pin. - */ - void select(); - /** - * @brief Deactivate device via CS pin. - */ - void deselect(); + virtual void deselect() = 0; private: - SPI * intf_; /**< %SPI hardware interface */ - GpioPin * csPin_; /**< Chip select pin */ + Interface * intf_; + bool selected_ = false; }; } // namespace sta - -#endif // STA_CORE_SPI_DEVICE_HPP +#endif // STA_CORE_BUS_SERIAL_DEVICE_HPP \ No newline at end of file diff --git a/include/sta/bus/i2c/device.hpp b/include/sta/bus/i2c/device.hpp new file mode 100644 index 0000000..2a96b4d --- /dev/null +++ b/include/sta/bus/i2c/device.hpp @@ -0,0 +1,37 @@ +#ifndef STA_CORE_I2C_DEVICE_HPP +#define STA_CORE_I2C_DEVICE_HPP + +#include +#include + +namespace sta +{ + /** + * @brief Peripheral device connected via I2c. + * + * @ingroup sta_core_i2c + */ + class I2cDevice : public Device + { + public: + /** + * @param intf %I2C hardware interface + * @param csPin The peripheral's address. + */ + I2cDevice(I2c * intf, int addr); + + protected: + void select() override; + + void deselect() override; + + private: + int addr_; /**< device address */ + }; + +} // namespace sta + + + + +#endif // STA_CORE_I2C_DEVICE_HPP \ No newline at end of file diff --git a/include/sta/bus/i2c/i2c.hpp b/include/sta/bus/i2c/i2c.hpp new file mode 100644 index 0000000..8d3123a --- /dev/null +++ b/include/sta/bus/i2c/i2c.hpp @@ -0,0 +1,33 @@ +#ifndef STA_CORE_I2C_I2C_HPP +#define STA_CORE_I2C_I2C_HPP + +#include +#include + +#include +#include + +namespace sta +{ + /** + * @brief Interface class for %I2C hardware. + * + * Represents a single %I2C bus that can be shared by multiple devices. + * + * @ingroup sta_core_i2c + */ + class I2c : public Interface + { + public: + I2c(Mutex * mutex=nullptr); + + /** + * @brief Address selection for the I2C bus. + * + * @param address The address to select. + */ + virtual void selectAddress(uint16_t address) = 0; + }; +} // namespace sta + +#endif // STA_CORE_I2C_I2C_HPP \ No newline at end of file diff --git a/include/sta/spi/spi.hpp b/include/sta/bus/interface.hpp similarity index 69% rename from include/sta/spi/spi.hpp rename to include/sta/bus/interface.hpp index bb80419..a8581d8 100644 --- a/include/sta/spi/spi.hpp +++ b/include/sta/bus/interface.hpp @@ -1,35 +1,20 @@ -/** - * @file - * @brief SPI bus software interface. - */ -#ifndef STA_CORE_SPI_SPI_HPP -#define STA_CORE_SPI_SPI_HPP +#ifndef STA_CORE_BUS_SERIAL_INTERFACE_HPP +#define STA_CORE_BUS_SERIAL_INTERFACE_HPP #include -#include -#include #include - +#include namespace sta { /** - * @brief Interface class for %SPI hardware. - * - * Represents a single %SPI bus that can be shared by multiple devices. - * - * @ingroup sta_core_spi - */ - class SPI + * @brief Abstract interface for serial communication. + */ + class Interface { public: - /** - * @param settings %SPI bus settings - * @param mutex Mutex object for managing shared access. Pass nullptr for no access control - */ - SPI(const SPISettings & settings, Mutex * mutex = nullptr); - + Interface(Mutex * mutex); /** * @brief Send single byte of data. @@ -66,7 +51,6 @@ namespace sta */ virtual void receive(uint8_t * buffer, size_t size) = 0; - /** * @brief Send byte value repeatedly. * @@ -75,14 +59,6 @@ namespace sta */ virtual void fill(uint8_t value, size_t count) = 0; - - /** - * @brief Get %SPI interface settings. - * - * @return %SPI settings - */ - const SPISettings & settings(); - /** * @brief Acquire usage rights to use the interface. * @@ -96,11 +72,15 @@ namespace sta */ virtual void release(); + /** + * @returns true if the interface has been aquired. + */ + bool isAquired(); private: - SPISettings settings_; /**< %SPI settings */ - Mutex * mutex_; /**< Mutex object */ + Mutex * mutex_; + bool aquired_ = false; }; } // namespace sta -#endif // STA_CORE_SPI_SPI_HPP +#endif // STA_CORE_BUS_SERIAL_INTERFACE_HPP \ No newline at end of file diff --git a/include/sta/bus/spi/device.hpp b/include/sta/bus/spi/device.hpp new file mode 100644 index 0000000..5f22b87 --- /dev/null +++ b/include/sta/bus/spi/device.hpp @@ -0,0 +1,51 @@ +/** + * @file + * @brief SPI bus peripheral device. + */ +#ifndef STA_CORE_SPI_DEVICE_HPP +#define STA_CORE_SPI_DEVICE_HPP + +#include +#include +#include + +#include +#include + + +namespace sta +{ + /** + * @brief Peripheral device connected via SPI. + * + * @ingroup sta_core_spi + */ + class SPIDevice : public Device + { + public: + /** + * @param intf %SPI hardware interface + * @param csPin Chip select pin + */ + SPIDevice(SPI * intf, GpioPin * csPin); + + /** + * @brief Get %SPI interface settings. + * + * @return SPI settings + */ + const SPISettings & settings() const; + + protected: + void select() override; + + void deselect() override; + + private: + SPI * intf_; /**< %SPI hardware interface */ + GpioPin * csPin_; /**< Chip select pin */ + }; +} // namespace sta + + +#endif // STA_CORE_SPI_DEVICE_HPP diff --git a/include/sta/spi/settings.hpp b/include/sta/bus/spi/settings.hpp similarity index 99% rename from include/sta/spi/settings.hpp rename to include/sta/bus/spi/settings.hpp index 35b7433..dea4618 100644 --- a/include/sta/spi/settings.hpp +++ b/include/sta/bus/spi/settings.hpp @@ -5,17 +5,14 @@ #ifndef STA_CORE_SPI_SETTINGS_HPP #define STA_CORE_SPI_SETTINGS_HPP - /** * @defgroup sta_core_spi SPI * @ingroup sta_core * @brief SPI interface. */ - #include - namespace sta { /** diff --git a/include/sta/bus/spi/spi.hpp b/include/sta/bus/spi/spi.hpp new file mode 100644 index 0000000..fdf978f --- /dev/null +++ b/include/sta/bus/spi/spi.hpp @@ -0,0 +1,47 @@ +/** + * @file + * @brief SPI bus software interface. + */ +#ifndef STA_CORE_SPI_SPI_HPP +#define STA_CORE_SPI_SPI_HPP + +#include +#include +#include + +#include +#include + + +namespace sta +{ + /** + * @brief Interface class for %SPI hardware. + * + * Represents a single %SPI bus that can be shared by multiple devices. + * + * @ingroup sta_core_spi + */ + class SPI : public Interface + { + public: + /** + * @param settings %SPI bus settings + * @param mutex Mutex object for managing shared access. Pass nullptr for no access control + */ + SPI(const SPISettings & settings, Mutex * mutex = nullptr); + + /** + * @brief Get %SPI interface settings. + * + * @return %SPI settings + */ + const SPISettings & settings(); + + private: + SPISettings settings_; /**< %SPI settings */ + }; +} // namespace sta + + +#endif // STA_CORE_SPI_SPI_HPP diff --git a/include/sta/bus/uart/settings.hpp b/include/sta/bus/uart/settings.hpp new file mode 100644 index 0000000..c3bbe2b --- /dev/null +++ b/include/sta/bus/uart/settings.hpp @@ -0,0 +1,24 @@ +#ifndef STA_CORE_UART_SETTINGS_HPP +#define STA_CORE_UART_SETTINGS_HPP + +#include + +namespace sta +{ + enum class UARTMode + { + RX, + TX, + RX_TX + }; + + /** + * @brief %UART settings. + */ + struct UARTSettings + { + UARTMode mode; + }; +} // namespace sta + +#endif // STA_CORE_UART_SETTINGS_HPP diff --git a/include/sta/bus/uart/uart.hpp b/include/sta/bus/uart/uart.hpp new file mode 100644 index 0000000..fafd153 --- /dev/null +++ b/include/sta/bus/uart/uart.hpp @@ -0,0 +1,25 @@ +#ifndef STA_CORE_UART_UART_HPP +#define STA_CORE_UART_UART_HPP + +#include +#include + +namespace sta +{ + class UART : public Interface + { + public: + UART(const UARTSettings & settings, Mutex * mutex=nullptr); + + /** + * @brief Get %UART interface settings. + * + * @return %UART settings + */ + const UARTSettings & settings(); + private: + UARTSettings settings_; /**< %UART settings */ + }; +} // namespace sta + +#endif // STA_CORE_UART_UART_HPP \ No newline at end of file diff --git a/include/sta/config.hpp b/include/sta/config.hpp index deed5f1..f2f4489 100644 --- a/include/sta/config.hpp +++ b/include/sta/config.hpp @@ -2,7 +2,7 @@ #define STA_CONFIG // Use the raspberry pi for this project. -#include +#include // #define DEBUG #define STA_PRINTF_USE_STDLIB diff --git a/include/sta/arduino/not_implemented.hpp b/include/sta/devices/arduino/not_implemented.hpp similarity index 100% rename from include/sta/arduino/not_implemented.hpp rename to include/sta/devices/arduino/not_implemented.hpp diff --git a/include/sta/devices/raspi/bus/i2c.hpp b/include/sta/devices/raspi/bus/i2c.hpp new file mode 100644 index 0000000..597b4bd --- /dev/null +++ b/include/sta/devices/raspi/bus/i2c.hpp @@ -0,0 +1,52 @@ +#ifndef STA_RASPI_I2C_HPP +#define STA_RASPI_I2C_HPP + +#include +#ifdef STA_PLATFORM_RASPI + +#include +#include + +#include +#include + +namespace sta +{ + enum class I2cNode { + DEV_1, + DEV_2 + }; + + class RaspiI2c : public I2c + { + public: + RaspiI2c(I2cNode node, Mutex * mutex=nullptr, bool persistent_open=false); + ~RaspiI2c(); + + void transfer(uint8_t value) override; + void transfer16(uint16_t value) override; + void transfer(const uint8_t * buffer, size_t size) override; + void transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size) override; + void receive(uint8_t * buffer, size_t size) override; + + void fill(uint8_t value, size_t count) override; + + void selectAddress(uint16_t address) override; + void acquire() override; + void release() override; + private: + char * i2cdev_; + int i2cfd_; + bool open_ = false; + const bool persistent_open_; + }; + + class RaspiI2cDevice : public I2cDevice + { + RaspiI2cDevice(I2c * intf, uint16_t address_10bit, Mutex* mutex=nullptr, bool master=false, bool blocking=true); + }; +} // namespace sta + +#endif // STA_PLATFORM_RASPI + +#endif // STA_I2C_HPP \ No newline at end of file diff --git a/include/sta/raspi/spi.hpp b/include/sta/devices/raspi/bus/spi.hpp similarity index 95% rename from include/sta/raspi/spi.hpp rename to include/sta/devices/raspi/bus/spi.hpp index 484debc..266a0cc 100644 --- a/include/sta/raspi/spi.hpp +++ b/include/sta/devices/raspi/bus/spi.hpp @@ -4,8 +4,8 @@ #include #ifdef STA_PLATFORM_RASPI -#include -#include +#include +#include namespace sta { diff --git a/include/sta/devices/raspi/can.hpp b/include/sta/devices/raspi/can.hpp new file mode 100644 index 0000000..e69de29 diff --git a/include/sta/raspi/delay.hpp b/include/sta/devices/raspi/delay.hpp similarity index 100% rename from include/sta/raspi/delay.hpp rename to include/sta/devices/raspi/delay.hpp diff --git a/include/sta/raspi/gpio_pin.hpp b/include/sta/devices/raspi/gpio_pin.hpp similarity index 96% rename from include/sta/raspi/gpio_pin.hpp rename to include/sta/devices/raspi/gpio_pin.hpp index 2e5e456..22af920 100644 --- a/include/sta/raspi/gpio_pin.hpp +++ b/include/sta/devices/raspi/gpio_pin.hpp @@ -4,7 +4,7 @@ // Only enable module on Raspi platform w/ HAL GPIO module enabled #include #ifdef STA_PLATFORM_RASPI -# include +# include # define STA_RASPI_GPIO_ENABLED #endif // STA_PLATFORM_RASPI diff --git a/include/sta/raspi/hal.hpp b/include/sta/devices/raspi/hal.hpp similarity index 100% rename from include/sta/raspi/hal.hpp rename to include/sta/devices/raspi/hal.hpp diff --git a/include/sta/raspi/mcu/common.hpp b/include/sta/devices/raspi/mcu/common.hpp similarity index 100% rename from include/sta/raspi/mcu/common.hpp rename to include/sta/devices/raspi/mcu/common.hpp diff --git a/include/sta/stm32/can.hpp b/include/sta/devices/stm32/can.hpp similarity index 100% rename from include/sta/stm32/can.hpp rename to include/sta/devices/stm32/can.hpp diff --git a/include/sta/stm32/clocks.hpp b/include/sta/devices/stm32/clocks.hpp similarity index 100% rename from include/sta/stm32/clocks.hpp rename to include/sta/devices/stm32/clocks.hpp diff --git a/include/sta/stm32/delay.hpp b/include/sta/devices/stm32/delay.hpp similarity index 100% rename from include/sta/stm32/delay.hpp rename to include/sta/devices/stm32/delay.hpp diff --git a/include/sta/stm32/gpio_pin.hpp b/include/sta/devices/stm32/gpio_pin.hpp similarity index 100% rename from include/sta/stm32/gpio_pin.hpp rename to include/sta/devices/stm32/gpio_pin.hpp diff --git a/include/sta/stm32/hal.hpp b/include/sta/devices/stm32/hal.hpp similarity index 100% rename from include/sta/stm32/hal.hpp rename to include/sta/devices/stm32/hal.hpp diff --git a/include/sta/stm32/i2c.hpp b/include/sta/devices/stm32/i2c.hpp similarity index 100% rename from include/sta/stm32/i2c.hpp rename to include/sta/devices/stm32/i2c.hpp diff --git a/include/sta/stm32/init.hpp b/include/sta/devices/stm32/init.hpp similarity index 100% rename from include/sta/stm32/init.hpp rename to include/sta/devices/stm32/init.hpp diff --git a/include/sta/stm32/mcu/STM32F411xE.hpp b/include/sta/devices/stm32/mcu/STM32F411xE.hpp similarity index 100% rename from include/sta/stm32/mcu/STM32F411xE.hpp rename to include/sta/devices/stm32/mcu/STM32F411xE.hpp diff --git a/include/sta/stm32/mcu/STM32F413xx.hpp b/include/sta/devices/stm32/mcu/STM32F413xx.hpp similarity index 100% rename from include/sta/stm32/mcu/STM32F413xx.hpp rename to include/sta/devices/stm32/mcu/STM32F413xx.hpp diff --git a/include/sta/stm32/mcu/common.hpp b/include/sta/devices/stm32/mcu/common.hpp similarity index 100% rename from include/sta/stm32/mcu/common.hpp rename to include/sta/devices/stm32/mcu/common.hpp diff --git a/include/sta/stm32/spi.hpp b/include/sta/devices/stm32/spi.hpp similarity index 100% rename from include/sta/stm32/spi.hpp rename to include/sta/devices/stm32/spi.hpp diff --git a/include/sta/stm32/uart.hpp b/include/sta/devices/stm32/uart.hpp similarity index 100% rename from include/sta/stm32/uart.hpp rename to include/sta/devices/stm32/uart.hpp diff --git a/include/sta/devices/template/delay.hpp b/include/sta/devices/template/delay.hpp new file mode 100644 index 0000000..a87bd66 --- /dev/null +++ b/include/sta/devices/template/delay.hpp @@ -0,0 +1,43 @@ +/** + * @file delay.hpp + * @author (@.com) + * @brief + * @version 0.1 + * @date 2023-06-13 + * + * @copyright Copyright (c) 2023 + * + * How to modify this file: + * - Ctrl + F and replace "YOUR_DEVICE" with the appropriate name. + */ +#ifndef STA_CORE_YOUR_DEVICE_DELAY_HPP +#define STA_CORE_YOUR_DEVICE_DELAY_HPP + +// Only enable module on YOUR_DEVICE platform +#include + + +#if defined(STA_PLATFORM_YOUR_DEVICE) || defined(DOXYGEN) + +#include + +namespace sta +{ + /** + * @brief Millisecond delay. + * + * @param ms Milliseconds + */ + void delayMs(uint32_t ms); + + /** + * @brief Microsecond delay. + * + * @param us Microseconds + */ + void delayUs(uint32_t us); +} // namespace sta + +#endif // STA_PLATFORM_YOUR_DEVICE + +#endif // STA_CORE_YOUR_DEVICE_DELAY_HPP \ No newline at end of file diff --git a/include/sta/i2c.hpp b/include/sta/i2c.hpp deleted file mode 100644 index db467dd..0000000 --- a/include/sta/i2c.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#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/lang.hpp b/include/sta/lang.hpp index 35591b7..0c68348 100644 --- a/include/sta/lang.hpp +++ b/include/sta/lang.hpp @@ -95,6 +95,14 @@ # define STA_UNREACHABLE() __builtin_unreachable() #endif // !STA_UNREACHABLE +/** + * @brief A macro for marking code as not implemented. Causes a program to + * crash with the appropriate error message if the code is executed. + */ +#ifndef STA_NOT_IMPLEMENTED +# define STA_NOT_IMPLEMENTED() throw "myFunction is not implemented yet."; +#endif // !STA_NOT_IMPLEMENTED + /** * @brief Silencing compiler warnings for intended switch case fallthrough. * diff --git a/include/sta/printable.hpp b/include/sta/printable.hpp index 4597a41..7925c8c 100644 --- a/include/sta/printable.hpp +++ b/include/sta/printable.hpp @@ -5,8 +5,6 @@ #ifndef STA_CORE_PRINTABLE_HPP #define STA_CORE_PRINTABLE_HPP -#include - #include #include @@ -25,165 +23,168 @@ namespace sta HEX /**< Hexadecimal */ }; - /** - * @brief Print single character. - * - * @param c Character to print - */ - void print(char c); + class Printable + { + /** + * @brief Print single character. + * + * @param c Character to print + */ + void print(char c); - /** - * @brief Print boolean value. - * - * @param b Boolean value - */ - void print(bool b); + /** + * @brief Print boolean value. + * + * @param b Boolean value + */ + void print(bool b); - /** - * @brief Print floating point value. - * - * @param d Floating point value - */ - void print(double d); + /** + * @brief Print floating point value. + * + * @param d Floating point value + */ + void print(double d); - /** - * @brief Print integer in selected base. - * - * @param num 8-bit unsigned integer - * @param base Integer base - */ - void print(uint8_t num, IntegerBase base = IntegerBase::DEC); + /** + * @brief Print integer in selected base. + * + * @param num 8-bit unsigned integer + * @param base Integer base + */ + void print(uint8_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base. - * - * @param num 16-bit unsigned integer - * @param base Integer base - */ - void print(uint16_t num, IntegerBase base = IntegerBase::DEC); + /** + * @brief Print integer in selected base. + * + * @param num 16-bit unsigned integer + * @param base Integer base + */ + void print(uint16_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base. - * - * @param num 32-bit unsigned integer - * @param base Integer base - */ - void print(uint32_t num, IntegerBase base = IntegerBase::DEC); + /** + * @brief Print integer in selected base. + * + * @param num 32-bit unsigned integer + * @param base Integer base + */ + void print(uint32_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print c-string. - * - * @param str Null terminated string - */ - void print(const char * str); + /** + * @brief Print c-string. + * + * @param str Null terminated string + */ + void print(const char * str); - /** - * @brief Print string. - * - * @param str String buffer - * @param length String length - */ - void print(const char * str, size_t length); + /** + * @brief Print string. + * + * @param str String buffer + * @param length String length + */ + virtual void print(const char * str, size_t length) = 0; - /** - * @brief Print new-line. - */ - void println(); + /** + * @brief Print new-line. + */ + void println(); - /** - * @brief Print single character followed by a new-line. - * - * @param c Character to print - */ - void println(char c); + /** + * @brief Print single character followed by a new-line. + * + * @param c Character to print + */ + void println(char c); - /** - * @brief Print boolean value followed by a new-line. - * - * @param b Boolean value - */ - void println(bool b); + /** + * @brief Print boolean value followed by a new-line. + * + * @param b Boolean value + */ + void println(bool b); - /** - * @brief Print floating point value followed by a new-line. - * - * @param d Floating point value - */ - void println(double d); + /** + * @brief Print floating point value followed by a new-line. + * + * @param d Floating point value + */ + void println(double d); - /** - * @brief Print integer in selected base followed by a new-line. - * - * @param num 8-bit unsigned integer - * @param base Integer base - */ - void println(uint8_t num, IntegerBase base = IntegerBase::DEC); + /** + * @brief Print integer in selected base followed by a new-line. + * + * @param num 8-bit unsigned integer + * @param base Integer base + */ + void println(uint8_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base followed by a new-line. - * - * @param num 16-bit unsigned integer - * @param base Integer base - */ - void println(uint16_t num, IntegerBase base = IntegerBase::DEC); + /** + * @brief Print integer in selected base followed by a new-line. + * + * @param num 16-bit unsigned integer + * @param base Integer base + */ + void println(uint16_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base followed by a new-line. - * - * @param num 32-bit unsigned integer - * @param base Integer base - */ - void println(uint32_t num, IntegerBase base = IntegerBase::DEC); + /** + * @brief Print integer in selected base followed by a new-line. + * + * @param num 32-bit unsigned integer + * @param base Integer base + */ + void println(uint32_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print c-string followed by a new-line. - * - * @param str Null terminated string - */ - void println(const char * str); + /** + * @brief Print c-string followed by a new-line. + * + * @param str Null terminated string + */ + void println(const char * str); - /** - * @brief Print string followed by a new-line. - * - * @param str String buffer - * @param length String length - */ - void println(const char * str, size_t length); + /** + * @brief Print string followed by a new-line. + * + * @param str String buffer + * @param length String length + */ + void println(const char * str, size_t length); - /** - * @brief Print unsigned integer in selected base. - * - * @param value Unsigned integer value - * @param base Integer base - * @param fmt printf format string for base 10 - * @param size Size of value in bytes - */ - void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size); + private: + /** + * @brief Print unsigned integer in selected base. + * + * @param value Unsigned integer value + * @param base Integer base + * @param fmt printf format string for base 10 + * @param size Size of value in bytes + */ + void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size); - /** - * @brief Print unsigned integer in base 10. - * - * @param value Unsigned integer value - * @param fmt printf format string - */ - void printDec(uintmax_t value, const char * fmt); + /** + * @brief Print unsigned integer in base 10. + * + * @param value Unsigned integer value + * @param fmt printf format string + */ + void printDec(uintmax_t value, const char * fmt); - /** - * @brief Print unsigned integer in base 2. - * - * @param value Unsigned integer value - * @param digits Number of digits to print - */ - void printBin(uintmax_t value, size_t digits); - - /** - * @brief Print unsigned integer in base 16. - * - * @param value Unsigned integer value - * @param digits Number of digits to print - */ - void printHex(uintmax_t value, size_t digits); + /** + * @brief Print unsigned integer in base 2. + * + * @param value Unsigned integer value + * @param digits Number of digits to print + */ + void printBin(uintmax_t value, size_t digits); + /** + * @brief Print unsigned integer in base 16. + * + * @param value Unsigned integer value + * @param digits Number of digits to print + */ + void printHex(uintmax_t value, size_t digits); + }; } // namespace sta diff --git a/include/sta/printable_uart.hpp b/include/sta/printable_uart.hpp index 9dfb3ee..7e78b0e 100644 --- a/include/sta/printable_uart.hpp +++ b/include/sta/printable_uart.hpp @@ -5,7 +5,8 @@ #ifndef STA_CORE_PRINTABLE_UART_HPP #define STA_CORE_PRINTABLE_UART_HPP -#include +#include +#include #include #include @@ -13,24 +14,12 @@ namespace sta { - /** - * @brief Integer representation. - * - * @ingroup sta_core - */ - enum class IntegerBase - { - DEC, /**< Decimal */ - BIN, /**< Binary */ - HEX /**< Hexadecimal */ - }; - /** * @brief Printable interface for UART. * * @ingroup sta_core */ - class PrintableUART + class PrintableUART : public Printable { public: /** @@ -38,149 +27,14 @@ namespace sta */ PrintableUART(UART * intf); - /** - * @brief Print single character. - * - * @param c Character to print - */ - void print(char c); - /** - * @brief Print boolean value. - * - * @param b Boolean value - */ - void print(bool b); - /** - * @brief Print floating point value. - * - * @param d Floating point value - */ - void print(double d); - /** - * @brief Print integer in selected base. - * - * @param num 8-bit unsigned integer - * @param base Integer base - */ - void print(uint8_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base. - * - * @param num 16-bit unsigned integer - * @param base Integer base - */ - void print(uint16_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base. - * - * @param num 32-bit unsigned integer - * @param base Integer base - */ - void print(uint32_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print c-string. - * - * @param str Null terminated string - */ - void print(const char * str); /** * @brief Print string. * * @param str String buffer * @param length String length */ - void print(const char * str, size_t length); - - - /** - * @brief Print new-line. - */ - void println(); - /** - * @brief Print single character followed by a new-line. - * - * @param c Character to print - */ - void println(char c); - /** - * @brief Print boolean value followed by a new-line. - * - * @param b Boolean value - */ - void println(bool b); - /** - * @brief Print floating point value followed by a new-line. - * - * @param d Floating point value - */ - void println(double d); - /** - * @brief Print integer in selected base followed by a new-line. - * - * @param num 8-bit unsigned integer - * @param base Integer base - */ - void println(uint8_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base followed by a new-line. - * - * @param num 16-bit unsigned integer - * @param base Integer base - */ - void println(uint16_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print integer in selected base followed by a new-line. - * - * @param num 32-bit unsigned integer - * @param base Integer base - */ - void println(uint32_t num, IntegerBase base = IntegerBase::DEC); - /** - * @brief Print c-string followed by a new-line. - * - * @param str Null terminated string - */ - void println(const char * str); - /** - * @brief Print string followed by a new-line. - * - * @param str String buffer - * @param length String length - */ - void println(const char * str, size_t length); - - private: - /** - * @brief Print unsigned integer in selected base. - * - * @param value Unsigned integer value - * @param base Integer base - * @param fmt printf format string for base 10 - * @param size Size of value in bytes - */ - void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size); - /** - * @brief Print unsigned integer in base 10. - * - * @param value Unsigned integer value - * @param fmt printf format string - */ - void printDec(uintmax_t value, const char * fmt); - /** - * @brief Print unsigned integer in base 2. - * - * @param value Unsigned integer value - * @param digits Number of digits to print - */ - void printBin(uintmax_t value, size_t digits); - /** - * @brief Print unsigned integer in base 16. - * - * @param value Unsigned integer value - * @param digits Number of digits to print - */ - void printHex(uintmax_t value, size_t digits); - + void print(const char * str, size_t length) override; + private: UART * intf_; }; diff --git a/include/sta/uart.hpp b/include/sta/uart.hpp index 9667623..400f871 100644 --- a/include/sta/uart.hpp +++ b/include/sta/uart.hpp @@ -19,10 +19,10 @@ namespace sta { /** - * @brief Interface for %UART. - * - * @ingroup sta_core_uart - */ + * @brief Interface for %UART. + * + * @ingroup sta_core_uart + */ class UART { public: @@ -40,12 +40,14 @@ namespace sta * @param value Unsigned integer value */ void write(uint8_t value); + /** * @brief Write unsigned integer to %UART. * * @param value Unsigned integer value */ void write(uint16_t value); + /** * @brief Write unsigned integer to %UART. * diff --git a/src/bus/device.cpp b/src/bus/device.cpp new file mode 100644 index 0000000..fb2365f --- /dev/null +++ b/src/bus/device.cpp @@ -0,0 +1,77 @@ +#include +#include + +namespace sta +{ + Device::Device(Interface * intf) + : intf_{intf} + { + STA_ASSERT(intf != nullptr); + } + + void Device::beginTransmission() + { + intf_->acquire(); + select(); + selected_ = true; + } + + void Device::endTransmission() + { + deselect(); + selected_ = false; + intf_->release(); + } + + void Device::transfer(uint8_t value) + { + STA_ASSERT(intf_->isAquired()); + STA_ASSERT(selected_); + + intf_->transfer(value); + } + + void Device::transfer16(uint16_t value) + { + STA_ASSERT(intf_->isAquired()); + STA_ASSERT(selected_); + + intf_->transfer16(value); + } + + void Device::transfer(const uint8_t * buffer, size_t size) + { + STA_ASSERT(intf_->isAquired()); + STA_ASSERT(selected_); + STA_ASSERT(buffer != nullptr); + + intf_->transfer(buffer, size); + } + + void Device::transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size) + { + STA_ASSERT(intf_->isAquired()); + STA_ASSERT(selected_); + STA_ASSERT(txBuffer != nullptr); + STA_ASSERT(rxBuffer != nullptr); + + intf_->transfer(txBuffer, rxBuffer, size); + } + + void Device::receive(uint8_t * buffer, size_t size) + { + STA_ASSERT(intf_->isAquired()); + STA_ASSERT(selected_); + STA_ASSERT(buffer != nullptr); + + intf_->receive(buffer, size); + } + + void Device::fill(uint8_t value, size_t count) + { + STA_ASSERT(intf_->isAquired()); + STA_ASSERT(selected_); + + intf_->fill(value, count); + } +} // namespace sta diff --git a/src/bus/i2c/device.cpp b/src/bus/i2c/device.cpp new file mode 100644 index 0000000..dc54795 --- /dev/null +++ b/src/bus/i2c/device.cpp @@ -0,0 +1,23 @@ +#include + +#include + + +namespace sta +{ + I2cDevice::I2cDevice(I2c * intf, int addr) + : Device{intf}, addr_{addr} + { + STA_ASSERT(intf != nullptr); + } + + void I2cDevice::select() + { + // TODO: Implement address selection here? + } + + void I2cDevice::deselect() + { + // TODO: Implement address deselection here? + } +} // namespace sta diff --git a/src/bus/i2c/i2c.cpp b/src/bus/i2c/i2c.cpp new file mode 100644 index 0000000..db7d91f --- /dev/null +++ b/src/bus/i2c/i2c.cpp @@ -0,0 +1,11 @@ +#include + + +namespace sta +{ + I2c::I2c(Mutex * mutex=nullptr) + : Interface{mutex} + { + + } +} // namespace sta \ No newline at end of file diff --git a/src/bus/interface.cpp b/src/bus/interface.cpp new file mode 100644 index 0000000..a727dee --- /dev/null +++ b/src/bus/interface.cpp @@ -0,0 +1,29 @@ +#include + +#include + +namespace sta +{ + Interface::Interface(Mutex * mutex) + : mutex_{mutex} + { + STA_ASSERT(mutex != nullptr); + } + + void Interface::acquire() + { + if (mutex_ != nullptr) + mutex_->acquire(); + } + + void Interface::release() + { + if (mutex_ != nullptr) + mutex_->release(); + } + + bool Interface::isAquired() + { + return aquired_; + } +} // namespace sta diff --git a/src/bus/spi/device.cpp b/src/bus/spi/device.cpp new file mode 100644 index 0000000..29c25b2 --- /dev/null +++ b/src/bus/spi/device.cpp @@ -0,0 +1,29 @@ +#include + +#include + + +namespace sta +{ + SPIDevice::SPIDevice(SPI * intf, GpioPin * csPin) + : Device{intf}, intf_{intf}, csPin_{csPin} + { + STA_ASSERT(intf != nullptr); + STA_ASSERT(csPin != nullptr); + } + + const SPISettings & SPIDevice::settings() const + { + return intf_->settings(); + } + + void SPIDevice::select() + { + csPin_->setState(GpioPinState::GPIO_LOW); + } + + void SPIDevice::deselect() + { + csPin_->setState(GpioPinState::GPIO_HIGH); + } +} // namespace sta diff --git a/src/spi/settings.cpp b/src/bus/spi/settings.cpp similarity index 97% rename from src/spi/settings.cpp rename to src/bus/spi/settings.cpp index 7d76aa0..d0c9246 100644 --- a/src/spi/settings.cpp +++ b/src/bus/spi/settings.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/bus/spi/spi.cpp b/src/bus/spi/spi.cpp new file mode 100644 index 0000000..012bcf3 --- /dev/null +++ b/src/bus/spi/spi.cpp @@ -0,0 +1,17 @@ +#include + +#include + +namespace sta +{ + SPI::SPI(const SPISettings & settings, Mutex * mutex /* = nullptr */) + : Interface{mutex}, settings_{settings} + { + + } + + const SPISettings & SPI::settings() + { + return settings_; + } +} // namespace sta diff --git a/src/bus/uart/settings.cpp b/src/bus/uart/settings.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/bus/uart/uart.cpp b/src/bus/uart/uart.cpp new file mode 100644 index 0000000..6225576 --- /dev/null +++ b/src/bus/uart/uart.cpp @@ -0,0 +1,15 @@ +#include + +namespace sta +{ + UART::UART(const UARTSettings & settings, Mutex * mutex) + : Interface{mutex}, settings_{settings} + { + + } + + const UARTSettings & UART::settings() + { + return settings_; + } +} // namespace sta diff --git a/src/devices/raspi/bus/i2c/i2c.cpp b/src/devices/raspi/bus/i2c/i2c.cpp new file mode 100644 index 0000000..7be071f --- /dev/null +++ b/src/devices/raspi/bus/i2c/i2c.cpp @@ -0,0 +1,129 @@ +#include + +#ifdef STA_PLATFORM_RASPI + +#include + +#include +#include +#include + +#include +#include +#include +#include + + +namespace sta +{ + RaspiI2c::RaspiI2c(I2cNode node, Mutex * mutex, bool persistent_open) + : I2c{mutex}, persistent_open_{persistent_open} + { + // Safer version of malloc + strcpy + i2cdev_ = strdup(node == I2cNode::DEV_1 ? "/dev/i2c-1" : "/dev/i2c-2"); + + STA_ASSERT(i2cdev_ != nullptr); + } + + RaspiI2c::~RaspiI2c() + { + if (i2cdev_ != NULL ) { + free(i2cdev_); + i2cdev_ = NULL; + } + + if (open_) { + close(i2cfd_); + } + } + + void RaspiI2c::transfer(uint8_t value) + { + STA_ASSERT(open_); + + write(i2cfd_, &value, 1); + } + + void RaspiI2c::transfer16(uint16_t value) + { + STA_ASSERT(open_); + + write(i2cfd_, &value, 2); + } + + void RaspiI2c::transfer(const uint8_t * buffer, size_t size) + { + STA_ASSERT(open_); + + write(i2cfd_, buffer, size); + } + + void RaspiI2c::transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size) + { + STA_ASSERT(open_); + + // TODO: Is this even possible in i2c? + } + + void RaspiI2c::receive(uint8_t * buffer, size_t size) + { + STA_ASSERT(open_); + + if (read(i2cfd_, buffer, size) <= 0) + { + printf("Error while reading i2c bus."); + } + } + + void RaspiI2c::fill(uint8_t value, size_t count) + { + STA_ASSERT(open_); + + // Initialize a buffer of size count and fill it with the value. + uint8_t *buffer = new uint8_t[count]; + memset(buffer, value, count); + + write(i2cfd_, buffer, count); + + delete [] buffer; + } + + void RaspiI2c::selectAddress(uint16_t address) + { + if (ioctl(i2cfd_, I2C_SLAVE, address) < 0) + { + printf("Failed to send the slave address."); + } + } + + void RaspiI2c::acquire() + { + I2c::acquire(); + + if (open_) { + return; + } + + i2cfd_ = open(i2cdev_, O_RDWR); + open_ = true; + + STA_ASSERT(i2cfd_ >= 0); + } + + void RaspiI2c::release() + { + if (!persistent_open_ && open_) { + close(i2cfd_); + } + + I2c::release(); + } + + RaspiI2cDevice::RaspiI2cDevice(I2c * intf, uint16_t address_10bit, Mutex* mutex, bool master, bool blocking) + : I2cDevice { intf, address_10bit } + { + + } +} // namespace sta + +#endif // STA_PLATFORM_RASPI \ No newline at end of file diff --git a/src/raspi/spi.cpp b/src/devices/raspi/bus/spi/spi.cpp similarity index 97% rename from src/raspi/spi.cpp rename to src/devices/raspi/bus/spi/spi.cpp index 0d9d92f..74f71f1 100644 --- a/src/raspi/spi.cpp +++ b/src/devices/raspi/bus/spi/spi.cpp @@ -1,9 +1,9 @@ -#include +#include #ifdef STA_PLATFORM_RASPI -#include -#include +#include +#include #include #include #include @@ -94,6 +94,10 @@ namespace sta int result = ioctl(spifd_, SPI_IOC_MESSAGE(1), spi_message); + if (result < 0) { + printf("Sending failed with error '%s'! \n", strerror(errno)); + } + STA_DEBUG_IOCTL_SEND(result); } @@ -293,8 +297,6 @@ namespace sta void RaspiSPI::release() { - STA_ASSERT_MSG(open_, "'release' was called despite the device being closed! This has to be a bug!"); - if (!persistent_open_ && open_) { close(spifd_); } diff --git a/src/raspi/delay.cpp b/src/devices/raspi/delay.cpp similarity index 78% rename from src/raspi/delay.cpp rename to src/devices/raspi/delay.cpp index 0cbb495..3bbc5f1 100644 --- a/src/raspi/delay.cpp +++ b/src/devices/raspi/delay.cpp @@ -1,7 +1,7 @@ -#include +#include #ifdef STA_PLATFORM_RASPI -#include +#include #include #include diff --git a/src/raspi/gpio_pin.cpp b/src/devices/raspi/gpio_pin.cpp similarity index 100% rename from src/raspi/gpio_pin.cpp rename to src/devices/raspi/gpio_pin.cpp diff --git a/src/stm32/can.cpp b/src/devices/stm32/can.cpp similarity index 100% rename from src/stm32/can.cpp rename to src/devices/stm32/can.cpp diff --git a/src/stm32/delay.cpp b/src/devices/stm32/delay.cpp similarity index 100% rename from src/stm32/delay.cpp rename to src/devices/stm32/delay.cpp diff --git a/src/stm32/gpio_pin.cpp b/src/devices/stm32/gpio_pin.cpp similarity index 100% rename from src/stm32/gpio_pin.cpp rename to src/devices/stm32/gpio_pin.cpp diff --git a/src/stm32/i2c.cpp b/src/devices/stm32/i2c.cpp similarity index 100% rename from src/stm32/i2c.cpp rename to src/devices/stm32/i2c.cpp diff --git a/src/stm32/init.cpp b/src/devices/stm32/init.cpp similarity index 100% rename from src/stm32/init.cpp rename to src/devices/stm32/init.cpp diff --git a/src/stm32/spi.cpp b/src/devices/stm32/spi.cpp similarity index 100% rename from src/stm32/spi.cpp rename to src/devices/stm32/spi.cpp diff --git a/src/stm32/uart.cpp b/src/devices/stm32/uart.cpp similarity index 92% rename from src/stm32/uart.cpp rename to src/devices/stm32/uart.cpp index 094b34e..d377cd5 100644 --- a/src/stm32/uart.cpp +++ b/src/devices/stm32/uart.cpp @@ -1,4 +1,4 @@ -#include +#include #ifdef STA_STM32_UART_ENABLED #include diff --git a/src/devices/template/delay.cpp b/src/devices/template/delay.cpp new file mode 100644 index 0000000..18edb34 --- /dev/null +++ b/src/devices/template/delay.cpp @@ -0,0 +1,36 @@ +/** + * @file delay.cpp + * @author (@.com) + * @brief + * @version 0.1 + * @date 2023-06-13 + * + * @copyright Copyright (c) 2023 + * + * How to modify this file: + * - Ctrl + F and replace "YOUR_DEVICE" with the appropriate name. + * - Implement the functions delayMs and delayUs. + * - Remove the import if no longer needed. + */ + +#define STA_PLATFORM_YOUR_DEVICE + +#include +#ifdef STA_PLATFORM_YOUR_DEVICE + +#include + +namespace sta +{ + void delayMs(uint32_t ms) + { + STA_NOT_IMPLEMENTED(); + } + + void delayUs(uint32_t us) + { + STA_NOT_IMPLEMENTED(); + } +} // namespace sta + +#endif // STA_PLATFORM_YOUR_DEVICE \ No newline at end of file diff --git a/src/i2c.cpp b/src/i2c.cpp deleted file mode 100644 index 0f32c26..0000000 --- a/src/i2c.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#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/printable.cpp b/src/printable.cpp index 3bc8325..4031032 100644 --- a/src/printable.cpp +++ b/src/printable.cpp @@ -2,136 +2,184 @@ #include #include +#include + #include #include namespace sta { - void print(char c) + void Printable::print(char c) { print(&c, 1); } - void print(bool b) + void Printable::print(bool b) { print(b ? "true" : "false"); } - void print(double d) + void Printable::print(double d) { char buffer[64]; snprintf(buffer, sizeof(buffer), "%f", d); print(buffer); } - void print(uint8_t num, IntegerBase base) + void Printable::print(uint8_t num, IntegerBase base) { printBase(num, base, "%" PRIu8, sizeof(num)); } - void print(uint16_t num, IntegerBase base) + void Printable::print(uint16_t num, IntegerBase base) { printBase(num, base, "%" PRIu16, sizeof(num)); } - void print(uint32_t num, IntegerBase base) + void Printable::print(uint32_t num, IntegerBase base) { printBase(num, base, "%" PRIu32, sizeof(num)); } - void print(const char * str) + void Printable::print(const char * str) { print(str, strlen(str)); } - - void print(const char * str, size_t length) { - print(str, length); - } - - void println() + + void Printable::println() { print("\r\n", 2); } - void println(char c) + void Printable::println(char c) { print(&c, 1); println(); } - void println(bool b) + void Printable::println(bool b) { print(b); println(); } - void println(double d) + void Printable::println(double d) { print(d); println(); } - void println(uint8_t num, IntegerBase base) + void Printable::println(uint8_t num, IntegerBase base) { print(num, base); println(); } - void println(uint16_t num, IntegerBase base) + void Printable::println(uint16_t num, IntegerBase base) { print(num, base); println(); } - void println(uint32_t num, IntegerBase base) + void Printable::println(uint32_t num, IntegerBase base) { print(num, base); println(); } - void println(const char * str) + void Printable::println(const char * str) { println(str, strlen(str)); } - void println(const char * str, size_t length) + void Printable::println(const char * str, size_t length) { print(str, length); println(); } - void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size) + void Printable::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size) { switch (base) { case IntegerBase::DEC: - printDec(value, fmt); - break; - case IntegerBase::HEX: - printHex(value, size); + printDec(num, fmt); break; + case IntegerBase::BIN: - printBin(value, size); + // Digits in base 2 = size in bytes * 8 + printBin(num, size * 8); break; + + case IntegerBase::HEX: + // Digits in base 16 = size in bytes * 2 + printHex(num, size * 2); + break; + default: - STA_ASSERT_MSG(false, "Case for IntegerBase enum not handled"); - STA_UNREACHABLE(); + print(""); } } - void printDec(uintmax_t value, const char * fmt) + void Printable::printDec(uintmax_t num, const char * fmt) { - printf(fmt, value); + char buffer[64]; + snprintf(buffer, sizeof(buffer), fmt, static_cast(num)); + print(buffer); } - void printBin(uintmax_t value, size_t digits) + void Printable::printBin(uintmax_t value, size_t digits) { + // Need 8 digits for every byte + char buffer[sizeof(value) * 8]; + // Check bounds + if (digits > sizeof(buffer)) + { + print(""); + return; + } + // Nothing to do + if (digits == 0) + return; + + for (size_t i = 0; i < digits; ++i) + { + // Convert bit to '0' or '1' + // First digit in buffer is MSB in value, so shift from high to low + buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1); + } + + print(buffer, digits); } - void printHex(uintmax_t value, size_t digits) + void Printable::printHex(uintmax_t value, size_t digits) { - printf("%x", value); + // Need 2 digits for every byte + char buffer[sizeof(value) * 2]; + + // Check bounds + if (digits > sizeof(buffer)) + { + print(""); + return; + } + // Nothing to do + if (digits == 0) + return; + + for (size_t i = 0; i < digits; ++i) + { + // Convert 4 bits to hex + // First digit in buffer is 4 MSBs in value, so shift from high to low + uint8_t hex = ((value >> ((digits - 1 - i) * 4)) & 0xF); + if (hex > 9) + buffer[i] = 'A' + (hex - 10); + else + buffer[i] = '0' + hex; + } + + print(buffer, digits); } } // namespace sta \ No newline at end of file diff --git a/src/printable_uart.cpp b/src/printable_uart.cpp index fbc48cf..5a6ae2e 100644 --- a/src/printable_uart.cpp +++ b/src/printable_uart.cpp @@ -7,194 +7,19 @@ #include - namespace sta { + PrintableUART::PrintableUART(UART * intf) : intf_{intf} { STA_ASSERT(intf != nullptr); - } - - - void PrintableUART::print(char c) - { - print(&c, 1); - } - - void PrintableUART::print(bool b) - { - print(b ? "true" : "false"); - } - - void PrintableUART::print(double d) - { - char buffer[64]; - snprintf(buffer, sizeof(buffer), "%f", d); - print(buffer); - } - - void PrintableUART::print(uint8_t num, IntegerBase base /* = IntegerBase::DEC */) - { - printBase(num, base, "%" PRIu8, sizeof(num)); - } - - void PrintableUART::print(uint16_t num, IntegerBase base /* = IntegerBase::DEC */) - { - printBase(num, base, "%" PRIu16, sizeof(num)); - } - - void PrintableUART::print(uint32_t num, IntegerBase base /* = IntegerBase::DEC */) - { - printBase(num, base, "%" PRIu32, sizeof(num)); - } - - void PrintableUART::print(const char * str) - { - print(str, strlen(str)); + STA_ASSERT(intf->settings().mode == UARTMode::RX || intf->settings().mode == UARTMode::RX_TX); } void PrintableUART::print(const char * str, size_t length) { - intf_->write(reinterpret_cast(str), length); + intf_->transfer(reinterpret_cast(str), length); } - - void PrintableUART::println() - { - print("\r\n", 2); - } - - void PrintableUART::println(char c) - { - print(&c, 1); - println(); - } - - void PrintableUART::println(bool b) - { - print(b); - println(); - } - - void PrintableUART::println(double d) - { - print(d); - println(); - } - - void PrintableUART::println(uint8_t num, IntegerBase base /* = IntegerBase::DEC */) - { - print(num, base); - println(); - } - - void PrintableUART::println(uint16_t num, IntegerBase base /* = IntegerBase::DEC */) - { - print(num, base); - println(); - } - - void PrintableUART::println(uint32_t num, IntegerBase base /* = IntegerBase::DEC */) - { - print(num, base); - println(); - } - - void PrintableUART::println(const char * str) - { - println(str, strlen(str)); - } - - void PrintableUART::println(const char * str, size_t length) - { - print(str, length); - println(); - } - - - - void PrintableUART::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size) - { - switch (base) - { - case IntegerBase::DEC: - printDec(num, fmt); - break; - - case IntegerBase::BIN: - // Digits in base 2 = size in bytes * 8 - printBin(num, size * 8); - break; - - case IntegerBase::HEX: - // Digits in base 16 = size in bytes * 2 - printHex(num, size * 2); - break; - - default: - print(""); - } - } - - void PrintableUART::printDec(uintmax_t num, const char * fmt) - { - char buffer[64]; - snprintf(buffer, sizeof(buffer), fmt, static_cast(num)); - print(buffer); - } - - void PrintableUART::printBin(uintmax_t value, size_t digits) - { - // Need 8 digits for every byte - char buffer[sizeof(value) * 8]; - - // Check bounds - if (digits > sizeof(buffer)) - { - print(""); - return; - } - // Nothing to do - if (digits == 0) - return; - - for (size_t i = 0; i < digits; ++i) - { - // Convert bit to '0' or '1' - // First digit in buffer is MSB in value, so shift from high to low - buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1); - } - - print(buffer, digits); - } - - void PrintableUART::printHex(uintmax_t value, size_t digits) - { - // Need 2 digits for every byte - char buffer[sizeof(value) * 2]; - - // Check bounds - if (digits > sizeof(buffer)) - { - print(""); - return; - } - // Nothing to do - if (digits == 0) - return; - - for (size_t i = 0; i < digits; ++i) - { - // Convert 4 bits to hex - // First digit in buffer is 4 MSBs in value, so shift from high to low - uint8_t hex = ((value >> ((digits - 1 - i) * 4)) & 0xF); - if (hex > 9) - buffer[i] = 'A' + (hex - 10); - else - buffer[i] = '0' + hex; - } - - print(buffer, digits); - } } // namespace sta diff --git a/src/spi/device.cpp b/src/spi/device.cpp deleted file mode 100644 index 86a5210..0000000 --- a/src/spi/device.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include - -#include - - -namespace sta -{ - SPIDevice::SPIDevice(SPI * intf, GpioPin * csPin) - : intf_{intf}, csPin_{csPin} - { - STA_ASSERT(intf != nullptr); - STA_ASSERT(csPin != nullptr); - } - - void SPIDevice::beginTransmission() - { - // Acquire SPI access and activate device - intf_->acquire(); - select(); - } - - void SPIDevice::endTransmission() - { - // Deactivate device and release SPI access - deselect(); - intf_->release(); - } - - - // Forward I/O operations to SPI interface - - void SPIDevice::transfer(uint8_t data) - { - intf_->transfer(data); - } - - void SPIDevice::transfer16(uint16_t data) - { - intf_->transfer16(data); - } - - void SPIDevice::transfer(const uint8_t * buffer, size_t size) - { - STA_ASSERT(buffer != nullptr); - - intf_->transfer(buffer, size); - } - - void SPIDevice::transfer(const uint8_t * txBuffer, uint8_t * rxBuffer, size_t size) - { - STA_ASSERT(txBuffer != nullptr); - STA_ASSERT(rxBuffer != nullptr); - STA_ASSERT(size != 0); - - intf_->transfer(txBuffer, rxBuffer, size); - } - - void SPIDevice::receive(uint8_t * buffer, size_t size) - { - STA_ASSERT(buffer != nullptr); - - intf_->receive(buffer, size); - } - - void SPIDevice::fill(uint8_t value, size_t count) - { - STA_ASSERT(count != 0); - - intf_->fill(value, count); - } - - - const SPISettings & SPIDevice::settings() const - { - return intf_->settings(); - } - - - void SPIDevice::select() - { - csPin_->setState(GpioPinState::GPIO_LOW); - } - - void SPIDevice::deselect() - { - csPin_->setState(GpioPinState::GPIO_HIGH); - } -} // namespace sta diff --git a/src/spi/spi.cpp b/src/spi/spi.cpp deleted file mode 100644 index 621086f..0000000 --- a/src/spi/spi.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include - -#include - -namespace sta -{ - SPI::SPI(const SPISettings & settings, Mutex * mutex /* = nullptr */) - : settings_{settings}, mutex_{mutex} - {} - - const SPISettings & SPI::settings() - { - return settings_; - } - - void SPI::acquire() - { - if (mutex_ != nullptr) - mutex_->acquire(); - } - - void SPI::release() - { - if (mutex_ != nullptr) - mutex_->release(); - } -} // namespace sta diff --git a/src/uart.cpp b/src/uart.cpp index 87eadef..dd0f69f 100644 --- a/src/uart.cpp +++ b/src/uart.cpp @@ -6,7 +6,6 @@ #include - namespace sta { void UART::write(uint8_t value)