diff --git a/CMakeLists.txt b/CMakeLists.txt index ed74b0e..dcce0ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ if(USE_PLATFORM_UBUNTU) set(CAN_PLATFORM socketcan) set(APP_PLATFORM ubuntu) set(PLATFORM_NAME sitl) - elseif(USE_PLATFORM_NODE_V2) +elseif(USE_PLATFORM_NODE_V2) set(LIBPARAMS_PLATFORM stm32f103) set(CAN_PLATFORM bxcan) set(APP_PLATFORM stm32f103) diff --git a/Libs/Dronecan b/Libs/Dronecan index 8cf4a58..663ca38 160000 --- a/Libs/Dronecan +++ b/Libs/Dronecan @@ -1 +1 @@ -Subproject commit 8cf4a5807276951edf2a67e152c7360c2bdeb278 +Subproject commit 663ca3885a4db03894c21d896a1224462cac3f68 diff --git a/Src/modules/system/CMakeLists.txt b/Src/modules/system/CMakeLists.txt index 3ecac9b..8e2ff3c 100644 --- a/Src/modules/system/CMakeLists.txt +++ b/Src/modules/system/CMakeLists.txt @@ -18,3 +18,5 @@ list(APPEND APPLICATION_SOURCES list(APPEND LIBPARAMS_PARAMS ${CMAKE_CURRENT_LIST_DIR}/params.yaml ) + +include(${ROOT_DIR}/Src/peripheral/led/CMakeLists.txt) diff --git a/Src/peripheral/led/CMakeLists.txt b/Src/peripheral/led/CMakeLists.txt new file mode 100644 index 0000000..e7540d7 --- /dev/null +++ b/Src/peripheral/led/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2023-2024 Dmitry Ponomarev +# Distributed under the terms of the GPL v3 license, available in the file LICENSE. + +# Include guard +if(PERIPHERAL_LED_CMAKE) + return() +endif() +set(PERIPHERAL_LED_CMAKE ${CMAKE_CURRENT_LIST_DIR}) + +if(NOT APP_PLATFORM) + message(SEND_ERROR "APP_PLATFORM is not specified or unsupported! Options: stm32f103, stm32g0b1, ubuntu.") +endif() + +if(APP_PLATFORM STREQUAL "stm32f103" OR APP_PLATFORM STREQUAL "stm32g0b1") + list(APPEND PERIPHERAL_SOURCES ${CMAKE_CURRENT_LIST_DIR}/led_stm32.cpp) +elseif(APP_PLATFORM STREQUAL "ubuntu") + list(APPEND PERIPHERAL_SOURCES ${CMAKE_CURRENT_LIST_DIR}/led_ubuntu.cpp) +else() + message(SEND_ERROR "APP_PLATFORM is unknown.") +endif() diff --git a/Src/platform/stm32f103/led.cpp b/Src/peripheral/led/led_stm32.cpp similarity index 83% rename from Src/platform/stm32f103/led.cpp rename to Src/peripheral/led/led_stm32.cpp index 99c2371..377ad25 100644 --- a/Src/platform/stm32f103/led.cpp +++ b/Src/peripheral/led/led_stm32.cpp @@ -4,7 +4,7 @@ * Author: Dmitry Ponomarev */ -#include "peripheral/led/led.hpp" +#include "led.hpp" #include #include "main.h" @@ -22,14 +22,26 @@ namespace Board { static void write_red(bool enabled) { GPIO_PinState state = enabled ? GPIO_PIN_RESET : GPIO_PIN_SET; HAL_GPIO_WritePin(INTERNAL_LED_RED_GPIO_Port, INTERNAL_LED_RED_Pin, state); + +#ifdef EXT_RGB_LED_RED_GPIO_Port + HAL_GPIO_WritePin(EXT_RGB_LED_RED_GPIO_Port, EXT_RGB_LED_RED_Pin, state); +#endif } static void write_green(bool enabled) { GPIO_PinState state = enabled ? GPIO_PIN_RESET : GPIO_PIN_SET; HAL_GPIO_WritePin(INTERNAL_LED_GREEN_GPIO_Port, INTERNAL_LED_GREEN_Pin, state); + +#ifdef EXT_RGB_LED_GREEN_GPIO_Port + HAL_GPIO_WritePin(EXT_RGB_LED_GREEN_GPIO_Port, EXT_RGB_LED_GREEN_Pin, state); +#endif } static void write_blue(bool enabled) { GPIO_PinState state = enabled ? GPIO_PIN_RESET : GPIO_PIN_SET; HAL_GPIO_WritePin(INTERNAL_LED_BLUE_GPIO_Port, INTERNAL_LED_BLUE_Pin, state); + +#ifdef EXT_RGB_LED_BLUE_GPIO_Port + HAL_GPIO_WritePin(EXT_RGB_LED_BLUE_GPIO_Port, EXT_RGB_LED_BLUE_Pin, state); +#endif } void Led::set(Color color) { diff --git a/Src/platform/ubuntu/led.cpp b/Src/peripheral/led/led_ubuntu.cpp similarity index 92% rename from Src/platform/ubuntu/led.cpp rename to Src/peripheral/led/led_ubuntu.cpp index 5c40733..4b67116 100644 --- a/Src/platform/ubuntu/led.cpp +++ b/Src/peripheral/led/led_ubuntu.cpp @@ -4,7 +4,7 @@ * Author: Dmitry Ponomarev */ -#include "peripheral/led/led.hpp" +#include "led.hpp" namespace Board { diff --git a/Src/peripheral/spi/CMakeLists.txt b/Src/peripheral/spi/CMakeLists.txt new file mode 100644 index 0000000..e0fd577 --- /dev/null +++ b/Src/peripheral/spi/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2023-2024 Dmitry Ponomarev +# Distributed under the terms of the GPL v3 license, available in the file LICENSE. + +# Include guard +if(PERIPHERAL_SPI_CMAKE) + return() +endif() +set(PERIPHERAL_SPI_CMAKE ${CMAKE_CURRENT_LIST_DIR}) + +if(NOT APP_PLATFORM) + message(SEND_ERROR "APP_PLATFORM is not specified or unsupported! Options: stm32f103, stm32g0b1, ubuntu.") +endif() + +if(APP_PLATFORM STREQUAL "stm32f103" OR APP_PLATFORM STREQUAL "stm32g0b1") + list(APPEND PERIPHERAL_SOURCES ${CMAKE_CURRENT_LIST_DIR}/spi_stm32.cpp) +elseif(APP_PLATFORM STREQUAL "ubuntu") + list(APPEND PERIPHERAL_SOURCES ${CMAKE_CURRENT_LIST_DIR}/spi_ubuntu.cpp) +else() + message(SEND_ERROR "APP_PLATFORM is unknown.") +endif() diff --git a/Src/platform/stm32g0b1/spi.cpp b/Src/peripheral/spi/spi_stm32.cpp similarity index 93% rename from Src/platform/stm32g0b1/spi.cpp rename to Src/peripheral/spi/spi_stm32.cpp index 8e286e5..9a1b91f 100644 --- a/Src/platform/stm32g0b1/spi.cpp +++ b/Src/peripheral/spi/spi_stm32.cpp @@ -21,6 +21,9 @@ static void spi_set_nss(bool nss_state) { #ifdef SPI2_NSS_GPIO_Port auto state = nss_state ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port, SPI2_NSS_Pin, state); +#elif defined(SPI_SS_GPIO_Port) + auto state = nss_state ? GPIO_PIN_SET : GPIO_PIN_RESET; + HAL_GPIO_WritePin(SPI_SS_GPIO_Port, SPI_SS_Pin, state); #endif } diff --git a/Src/platform/ubuntu/spi.cpp b/Src/peripheral/spi/spi_ununtu.cpp similarity index 100% rename from Src/platform/ubuntu/spi.cpp rename to Src/peripheral/spi/spi_ununtu.cpp diff --git a/Src/peripheral/uart/CMakeLists.txt b/Src/peripheral/uart/CMakeLists.txt new file mode 100644 index 0000000..c937d9a --- /dev/null +++ b/Src/peripheral/uart/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2023-2024 Dmitry Ponomarev +# Distributed under the terms of the GPL v3 license, available in the file LICENSE. + +# Include guard +if(PERIPHERAL_UART_CMAKE) + return() +endif() +set(PERIPHERAL_UART_CMAKE ${CMAKE_CURRENT_LIST_DIR}) + +if(NOT APP_PLATFORM) + message(SEND_ERROR "APP_PLATFORM is not specified or unsupported! Options: stm32f103, stm32g0b1, ubuntu.") +endif() + +if(APP_PLATFORM STREQUAL "stm32f103" OR APP_PLATFORM STREQUAL "stm32g0b1") + list(APPEND PERIPHERAL_SOURCES ${CMAKE_CURRENT_LIST_DIR}/uart_stm32.cpp) +elseif(APP_PLATFORM STREQUAL "ubuntu") + list(APPEND PERIPHERAL_SOURCES ${CMAKE_CURRENT_LIST_DIR}/uart_ubuntu.cpp) +else() + message(SEND_ERROR "APP_PLATFORM is unknown.") +endif() diff --git a/Src/peripheral/uart/uart.hpp b/Src/peripheral/uart/uart.hpp index ac4863b..59af9e7 100644 --- a/Src/peripheral/uart/uart.hpp +++ b/Src/peripheral/uart/uart.hpp @@ -1,7 +1,50 @@ -// Copyright (C) 2023 Dmitry Ponomarev -// Distributed under the terms of the GPL v3 license, available in the file LICENSE. +/** + * This program is free software under the GNU General Public License v3. + * See for details. + * Author: Dmitry Ponomarev + */ -#ifndef SRC_PERIPHERY_UART_UART_HPP_ -#define SRC_PERIPHERY_UART_UART_HPP_ +#ifndef SRC_PERIPHERAL_UART_UART_HPP_ +#define SRC_PERIPHERAL_UART_UART_HPP_ -#endif // SRC_PERIPHERY_UART_UART_HPP_ +#include +#include + +namespace HAL { + +class UART { +public: + enum class Instance { + FIRST, + SECOND, + AMOUNT, + }; + + /** + * @brief Allocate resources, but not initialize yet + */ + explicit UART(UART::Instance instance_) : instance(instance_) {} + + /** + * @brief After updating the baudrate, you typically want to reinialize the driver + */ + void set_baudrate(uint32_t rate); + + /** + * @brief RX DMA mode + * @return 0 on success, -1 on failure + */ + int8_t init_rx_dma(uint8_t buffer[], uint16_t size); + + /** + * @return a value in range [0, RX_DMA_BUFFER_SIZE - 1] + */ + size_t get_last_received_index(); + +private: + Instance instance; +}; + +} // namespace HAL + +#endif // SRC_PERIPHERAL_UART_UART_HPP_ diff --git a/Src/peripheral/uart/uart_stm32.cpp b/Src/peripheral/uart/uart_stm32.cpp new file mode 100644 index 0000000..4a2b39b --- /dev/null +++ b/Src/peripheral/uart/uart_stm32.cpp @@ -0,0 +1,103 @@ +/** + * This program is free software under the GNU General Public License v3. + * See for details. + * Author: Dmitry Ponomarev + */ + +#include "peripheral/uart/uart.hpp" +#include "main.h" + +extern UART_HandleTypeDef huart1; +#define UART_1_PTR &huart1 + +#if defined(SECOND_UART) + extern UART_HandleTypeDef huart2; + #define UART_2_PTR &huart2 +#else + #define UART_2_PTR NULL +#endif + +typedef enum { + NO_FLAGS = 0, + HALF_RECEIVED_FLAG, + FULL_RECEIVED_FLAG, + BOTH_FLAGS, +} UartRxStatus_t; + +typedef struct { + UART_HandleTypeDef* huart_ptr; + uint8_t* buffer; + uint16_t size; + UartRxStatus_t status; + void (*rx_callback)(); + uint32_t rx_counter; +} UartRxConfig_t; + +static UartRxConfig_t uart_rx[2] = { + { + .huart_ptr = UART_1_PTR, + .buffer = nullptr, + .size = 0, + .status = NO_FLAGS, + .rx_callback = nullptr, + .rx_counter = 0 + }, + { + .huart_ptr = UART_2_PTR, + .buffer = nullptr, + .size = 0, + .status = NO_FLAGS, + .rx_callback = nullptr, + .rx_counter = 0 + }, +}; + +namespace HAL { + +void UART::set_baudrate(uint32_t rate) { + if (instance == Instance::FIRST) { + huart1.Init.BaudRate = rate; + HAL_UART_Init(&huart1); + } else if (instance == Instance::SECOND) { +#if defined(SECOND_UART) + huart2.Init.BaudRate = rate; + HAL_HalfDuplex_Init(&huart2); +#endif + } +} + + +int8_t UART::init_rx_dma(uint8_t buffer[], uint16_t size) { + if (instance >= Instance::AMOUNT) { + return -1; + } + + auto& uart_rx_config = uart_rx[static_cast(instance)]; + + uart_rx_config.buffer = buffer; + uart_rx_config.size = size; + uart_rx_config.rx_counter = 0; + HAL_StatusTypeDef status = HAL_UART_Receive_DMA(uart_rx_config.huart_ptr, buffer, size); + return status == HAL_OK ? 0 : -1; +} + + +size_t UART:: get_last_received_index() { + if (instance >= Instance::AMOUNT) { + return 0; + } + + auto uart_rx_config = &uart_rx[static_cast(instance)]; + + if (uart_rx_config->huart_ptr == nullptr) { + return 0; + } + + uint16_t remaining_data_units = __HAL_DMA_GET_COUNTER(uart_rx_config->huart_ptr->hdmarx); + if (remaining_data_units == uart_rx_config->size) { + return uart_rx_config->size - 1; + } + return uart_rx_config->size - remaining_data_units - 1; +} + +} // namespace HAL diff --git a/Src/peripheral/uart/uart_ubuntu.cpp b/Src/peripheral/uart/uart_ubuntu.cpp new file mode 100644 index 0000000..45e9990 --- /dev/null +++ b/Src/peripheral/uart/uart_ubuntu.cpp @@ -0,0 +1,26 @@ +/** + * This program is free software under the GNU General Public License v3. + * See for details. + * Author: Dmitry Ponomarev + */ + +#include "peripheral/uart/uart.hpp" +#include "main.h" + +namespace HAL { + +void UART::set_baudrate(uint32_t rate) { + (void)rate; +} + +int8_t UART::init_rx_dma(uint8_t buffer[], uint16_t size) { + (void)buffer; + (void)size; + return 0; +} + +size_t UART:: get_last_received_index() { + return 0; +} + +} // namespace HAL diff --git a/Src/platform/stm32f103/CMakeLists.txt b/Src/platform/stm32f103/CMakeLists.txt index 466f5fe..8c9b2bf 100644 --- a/Src/platform/stm32f103/CMakeLists.txt +++ b/Src/platform/stm32f103/CMakeLists.txt @@ -4,6 +4,7 @@ set(EXECUTABLE ${PROJECT_NAME}.out) add_executable(${EXECUTABLE} ${APPLICATION_SOURCES} + ${PERIPHERAL_SOURCES} ${BUILD_SRC_DIR}/params.cpp ${ROOT_DIR}/Src/common/algorithms.cpp ${ROOT_DIR}/Src/common/logging.cpp @@ -15,7 +16,6 @@ add_executable(${EXECUTABLE} ${ROOT_DIR}/Src/platform/stm32/pwm/pwm.cpp ${CMAKE_CURRENT_LIST_DIR}/pwm.cpp ${ROOT_DIR}/Src/platform/stm32/iwdg/iwdg.cpp - ${CMAKE_CURRENT_LIST_DIR}/led.cpp ${CMAKE_CURRENT_LIST_DIR}/temperature_sensor.cpp ${ROOT_DIR}/Src/platform/stm32/platform_specific.cpp diff --git a/Src/platform/stm32g0b1/CMakeLists.txt b/Src/platform/stm32g0b1/CMakeLists.txt index c6f5c3f..0a2b64f 100644 --- a/Src/platform/stm32g0b1/CMakeLists.txt +++ b/Src/platform/stm32g0b1/CMakeLists.txt @@ -6,9 +6,12 @@ cmake_path(GET CMAKE_CURRENT_LIST_DIR PARENT_PATH PLATFORM_DIR) cmake_path(GET PLATFORM_DIR PARENT_PATH SRC_DIR) cmake_path(GET SRC_DIR PARENT_PATH ROOT_DIR) +include(${ROOT_DIR}/Src/peripheral/spi/CMakeLists.txt) + set(EXECUTABLE ${PROJECT_NAME}.out) add_executable(${EXECUTABLE} ${APPLICATION_SOURCES} + ${PERIPHERAL_SOURCES} ${BUILD_SRC_DIR}/params.cpp ${ROOT_DIR}/Src/common/algorithms.cpp ${ROOT_DIR}/Src/common/logging.cpp @@ -20,9 +23,7 @@ add_executable(${EXECUTABLE} ${PLATFORM_DIR}/stm32f103/adc.cpp ${CMAKE_CURRENT_LIST_DIR}/gpio.cpp ${PLATFORM_DIR}/stm32g0b1/pwm.cpp - ${PLATFORM_DIR}/stm32g0b1/spi.cpp ${ROOT_DIR}/Src/platform/stm32/iwdg/iwdg.cpp - ${PLATFORM_DIR}/stm32f103/led.cpp ${PLATFORM_DIR}/stm32f103/temperature_sensor.cpp ${ROOT_DIR}/Src/platform/stm32/platform_specific.cpp diff --git a/Src/platform/stm32g0b1/gpio.cpp b/Src/platform/stm32g0b1/gpio.cpp index b108ce0..7d28928 100644 --- a/Src/platform/stm32g0b1/gpio.cpp +++ b/Src/platform/stm32g0b1/gpio.cpp @@ -9,6 +9,7 @@ #include "main.h" void GPIOPeriphery::set(GPIOPin gpio_pin) { +#ifdef CAN1_TERMINATOR_GPIO_Port switch (gpio_pin) { case GPIOPin::CAN_TERMINATOR1: HAL_GPIO_WritePin(CAN1_TERMINATOR_GPIO_Port, CAN1_TERMINATOR_Pin, GPIO_PIN_SET); @@ -20,9 +21,13 @@ void GPIOPeriphery::set(GPIOPin gpio_pin) { default: break; } +#else + (void)gpio_pin; +#endif } bool GPIOPeriphery::get(GPIOPin gpio_pin) { +#ifdef CAN1_TERMINATOR_GPIO_Port switch (gpio_pin) { case GPIOPin::CAN_TERMINATOR1: return HAL_GPIO_ReadPin(CAN1_TERMINATOR_GPIO_Port, CAN1_TERMINATOR_Pin); @@ -33,14 +38,21 @@ bool GPIOPeriphery::get(GPIOPin gpio_pin) { default: return GPIO_PIN_SET; } +#else + (void)gpio_pin; + return GPIO_PIN_RESET; +#endif } void GPIOPeriphery::reset() { +#ifdef CAN1_TERMINATOR_GPIO_Port HAL_GPIO_WritePin(CAN1_TERMINATOR_GPIO_Port, CAN1_TERMINATOR_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(CAN2_TERMINATOR_GPIO_Port, CAN2_TERMINATOR_Pin, GPIO_PIN_RESET); +#endif } void GPIOPeriphery::reset(GPIOPin gpio_pin) { +#ifdef CAN1_TERMINATOR_GPIO_Port switch (gpio_pin) { case GPIOPin::CAN_TERMINATOR1: HAL_GPIO_WritePin(CAN1_TERMINATOR_GPIO_Port, CAN1_TERMINATOR_Pin, GPIO_PIN_RESET); @@ -51,4 +63,7 @@ void GPIOPeriphery::reset(GPIOPin gpio_pin) { default: break; } +#else + (void)gpio_pin; +#endif } diff --git a/Src/platform/ubuntu/CMakeLists.txt b/Src/platform/ubuntu/CMakeLists.txt index 2e8578e..72a0b68 100644 --- a/Src/platform/ubuntu/CMakeLists.txt +++ b/Src/platform/ubuntu/CMakeLists.txt @@ -4,6 +4,7 @@ set(EXECUTABLE ${PROJECT_NAME}.out) add_executable(${EXECUTABLE} ${APPLICATION_SOURCES} + ${PERIPHERAL_SOURCES} ${BUILD_SRC_DIR}/params.cpp ${ROOT_DIR}/Src/common/algorithms.cpp ${ROOT_DIR}/Src/common/logging.cpp @@ -15,7 +16,6 @@ add_executable(${EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/gpio.cpp ${CMAKE_CURRENT_LIST_DIR}/pwm.cpp ${CMAKE_CURRENT_LIST_DIR}/iwdg.cpp - ${CMAKE_CURRENT_LIST_DIR}/led.cpp ${CMAKE_CURRENT_LIST_DIR}/temperature_sensor.cpp ${CMAKE_CURRENT_LIST_DIR}/platform_specific.cpp ) diff --git a/Src/platform/ubuntu/uart.cpp b/Src/platform/ubuntu/uart.cpp deleted file mode 100644 index f5f1a1e..0000000 --- a/Src/platform/ubuntu/uart.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/** - * This program is free software under the GNU General Public License v3. - * See for details. - * Author: Dmitry Ponomarev - */ - -#include "peripheral/uart/uart.hpp" -#include "main.h"