Skip to content

Commit

Permalink
add uart driver
Browse files Browse the repository at this point in the history
  • Loading branch information
PonomarevDA committed Nov 17, 2024
1 parent 6e28c6a commit 1f34034
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 5 deletions.
20 changes: 20 additions & 0 deletions Src/peripheral/uart/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (C) 2023-2024 Dmitry Ponomarev <ponomarevda96@gmail.com>
# 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()
53 changes: 48 additions & 5 deletions Src/peripheral/uart/uart.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,50 @@
// Copyright (C) 2023 Dmitry Ponomarev <ponomarevda96@gmail.com>
// 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 <https://www.gnu.org/licenses/> for details.
* Author: Dmitry Ponomarev <ponomarevda96@gmail.com>
*/

#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 <cstdint>
#include <cstddef>

namespace HAL {

class UART {
public:
enum class Instance {
FIRST,
SECOND,
AMOUNT,
};

/**
* @brief Allocate resources, but not initialize yet
*/
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_
89 changes: 89 additions & 0 deletions Src/peripheral/uart/uart_stm32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* This program is free software under the GNU General Public License v3.
* See <https://www.gnu.org/licenses/> for details.
* Author: Dmitry Ponomarev <ponomarevda96@gmail.com>
*/

#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<uint8_t>(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<uint8_t>(instance)];

if (uart_rx_config->huart_ptr == nullptr) {
return 0;
}

uint16_t number_of_remaining_data_units = __HAL_DMA_GET_COUNTER(uart_rx_config->huart_ptr->hdmarx);
if (number_of_remaining_data_units == uart_rx_config->size) {
return uart_rx_config->size - 1;
}
return uart_rx_config->size - number_of_remaining_data_units - 1;
}

} // namespace HAL
26 changes: 26 additions & 0 deletions Src/peripheral/uart/uart_ubuntu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* This program is free software under the GNU General Public License v3.
* See <https://www.gnu.org/licenses/> for details.
* Author: Dmitry Ponomarev <ponomarevda96@gmail.com>
*/

#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
1 change: 1 addition & 0 deletions Src/platform/stm32f103/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Src/platform/stm32g0b1/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ cmake_path(GET SRC_DIR PARENT_PATH ROOT_DIR)
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
Expand Down
1 change: 1 addition & 0 deletions Src/platform/ubuntu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 1f34034

Please # to comment.