diff --git a/Firmware/F407V-PWMServoTester/Core/Inc/stm32f4xx_it.h b/Firmware/F407V-PWMServoTester/Core/Inc/stm32f4xx_it.h index fa257fb..89e229f 100644 --- a/Firmware/F407V-PWMServoTester/Core/Inc/stm32f4xx_it.h +++ b/Firmware/F407V-PWMServoTester/Core/Inc/stm32f4xx_it.h @@ -56,7 +56,10 @@ void EXTI0_IRQHandler(void); void EXTI4_IRQHandler(void); void DMA1_Stream3_IRQHandler(void); void DMA1_Stream4_IRQHandler(void); +void DMA1_Stream5_IRQHandler(void); +void DMA1_Stream6_IRQHandler(void); void EXTI9_5_IRQHandler(void); +void USART2_IRQHandler(void); void EXTI15_10_IRQHandler(void); void TIM7_IRQHandler(void); void DMA2_Stream0_IRQHandler(void); diff --git a/Firmware/F407V-PWMServoTester/Core/Src/Components/SharedResource.cpp b/Firmware/F407V-PWMServoTester/Core/Src/Components/SharedResource.cpp new file mode 100644 index 0000000..71e3b54 --- /dev/null +++ b/Firmware/F407V-PWMServoTester/Core/Src/Components/SharedResource.cpp @@ -0,0 +1,47 @@ +/* + * SharedResource.cpp + * + * Created on: Aug 17, 2024 + * Author: Gabriel + */ + +#include "SharedResource.hpp" + +SharedResource::SharedResource() { + +} + +SharedResource::~SharedResource() { + +} + +int32_t SharedResource::init() { + hMutex = xSemaphoreCreateMutexStatic(&hMutexBuffer); + vQueueAddToRegistry(hMutex, resourceName); + return 0; +} + +int32_t SharedResource::take(uint32_t timeout) { + if(xSemaphoreTake(hMutex, timeout)){ + // Took + taskLocking = xTaskGetCurrentTaskHandle(); + return 0; + }else{ + // Timeout + return -1; + } +} + +int32_t SharedResource::give() { + taskLocking = nullptr; + xSemaphoreGive(hMutex); + return 0; +} + +int32_t SharedResource::taken() { + if (taskLocking == xTaskGetCurrentTaskHandle()){ + return 1; + }else{ + return 0; + } +} diff --git a/Firmware/F407V-PWMServoTester/Core/Src/Components/SharedResource.hpp b/Firmware/F407V-PWMServoTester/Core/Src/Components/SharedResource.hpp new file mode 100644 index 0000000..33f88b7 --- /dev/null +++ b/Firmware/F407V-PWMServoTester/Core/Src/Components/SharedResource.hpp @@ -0,0 +1,30 @@ +/* + * SharedResource.hpp + * + * Created on: Aug 17, 2024 + * Author: Gabriel + */ + +#ifndef SRC_COMPONENTS_SHAREDRESOURCE_HPP_ +#define SRC_COMPONENTS_SHAREDRESOURCE_HPP_ + +#include +#include +#include + +class SharedResource { +public: + SharedResource(); + virtual ~SharedResource(); + virtual int32_t init(); + virtual int32_t take(uint32_t timeout); + virtual int32_t give(); +protected: + virtual int32_t taken(); + const char* resourceName = "SharedResource"; + SemaphoreHandle_t hMutex; + StaticSemaphore_t hMutexBuffer; + TaskHandle_t taskLocking = nullptr; +}; + +#endif /* SRC_COMPONENTS_SHAREDRESOURCE_HPP_ */ diff --git a/Firmware/F407V-PWMServoTester/Core/Src/Components/UART.hpp b/Firmware/F407V-PWMServoTester/Core/Src/Components/UART.hpp new file mode 100644 index 0000000..b0f160b --- /dev/null +++ b/Firmware/F407V-PWMServoTester/Core/Src/Components/UART.hpp @@ -0,0 +1,20 @@ +/* + * UART.hpp + * + * Created on: Aug 17, 2024 + * Author: Gabriel + */ + +#ifndef SRC_COMPONENTS_UART_HPP_ +#define SRC_COMPONENTS_UART_HPP_ + +#include "SharedResource.hpp" + +class UART : public SharedResource { +public: + int32_t init() = 0; + virtual int32_t transmit(uint8_t* buffer, uint32_t size) = 0; + virtual int32_t receiveUntilLineIdle(uint8_t* buffer, uint32_t maxSize) = 0; +}; + +#endif /* SRC_COMPONENTS_UART_HPP_ */ diff --git a/Firmware/F407V-PWMServoTester/Core/Src/Components/UART_STM32.cpp b/Firmware/F407V-PWMServoTester/Core/Src/Components/UART_STM32.cpp new file mode 100644 index 0000000..867fa44 --- /dev/null +++ b/Firmware/F407V-PWMServoTester/Core/Src/Components/UART_STM32.cpp @@ -0,0 +1,424 @@ +/* + * UART_STM32.cpp + * + * Created on: Aug 17, 2024 + * Author: Gabriel + */ + +#include "UART_STM32.hpp" +#include + +UART_STM32::UART_STM32(UART_HandleTypeDef* huart) : huart(huart){ + +} + +UART_STM32::~UART_STM32() { + +} + +int32_t UART_STM32::init() { + int32_t errors = 0; +#ifdef UART1 + if(huart->Instance == UART1){ + objects[0] = this; + } +#endif +#ifdef UART2 + if(huart->Instance == UART2){ + objects[1] = this; + } +#endif +#ifdef UART3 + if(huart->Instance == UART3){ + objects[2] = this; + } +#endif +#ifdef UART4 + if(huart->Instance == UART4){ + objects[3] = this; + } +#endif +#ifdef UART5 + if(huart->Instance == UART5){ + objects[4] = this; + } +#endif +#ifdef UART6 + if(huart->Instance == UART6){ + objects[5] = this; + } +#endif +#ifdef UART7 + if(huart->Instance == UART7){ + objects[6] = this; + } +#endif +#ifdef UART8 + if(huart->Instance == UART8){ + objects[7] = this; + } +#endif +#ifdef UART9 + if(huart->Instance == UART9){ + objects[8] = this; + } +#endif +#ifdef UART10 + if(huart->Instance == UART10){ + objects[9] = this; + } +#endif +#ifdef USART1 + if(huart->Instance == USART1){ + objects[0] = this; + } +#endif +#ifdef USART2 + if(huart->Instance == USART2){ + objects[1] = this; + } +#endif +#ifdef USART3 + if(huart->Instance == USART3){ + objects[2] = this; + } +#endif +#ifdef USART4 + if(huart->Instance == USART4){ + objects[3] = this; + } +#endif +#ifdef USART5 + if(huart->Instance == USART5){ + objects[4] = this; + } +#endif +#ifdef USART6 + if(huart->Instance == USART6){ + objects[5] = this; + } +#endif +#ifdef USART7 + if(huart->Instance == USART7){ + objects[6] = this; + } +#endif +#ifdef USART8 + if(huart->Instance == USART8){ + objects[7] = this; + } +#endif +#ifdef USART9 + if(huart->Instance == USART9){ + objects[8] = this; + } +#endif +#ifdef USART10 + if(huart->Instance == USART10){ + objects[9] = this; + } +#endif + errors += SharedResource::init(); + eventGroupHandle = xEventGroupCreateStatic(&eventGroupBuffer); + errors -= HAL_UART_RegisterCallback(huart, HAL_UART_TX_COMPLETE_CB_ID, txCpltCallbackStatic); + errors -= HAL_UART_RegisterCallback(huart, HAL_UART_RX_COMPLETE_CB_ID, rxCpltCallbackStatic); + errors -= HAL_UART_RegisterCallback(huart, HAL_UART_ERROR_CB_ID, errorCallbackStatic); + errors -= HAL_UART_RegisterRxEventCallback(huart, rxEventCallbackStatic); + return errors; +} + +int32_t UART_STM32::transmit(uint8_t* buffer, uint32_t size) { + if(!taken()){ + // Mutex not locked + return -1; + } + if(HAL_UART_Transmit_DMA(huart, buffer, size)){ + return -1; + } + Event bits = (Event)xEventGroupWaitBits(eventGroupHandle, (uint32_t)Event::TX_CPLT | (uint32_t)Event::ERROR, true, false, portMAX_DELAY); + // Only one event can happen + switch(bits){ + case Event::TX_CPLT: + return 0; + case Event::ERROR: + default: + return -1; + } +} + +int32_t UART_STM32::receiveUntilLineIdle(uint8_t* buffer, uint32_t maxSize) { + if(!taken()){ + // Mutex not locked + return -1; + } + if(HAL_UARTEx_ReceiveToIdle_DMA(huart, buffer, maxSize)){ + return -1; + } + Event bits = (Event)xEventGroupWaitBits(eventGroupHandle, (uint32_t)Event::RX_CPLT | (uint32_t)Event::IDLE | (uint32_t)Event::ERROR, true, false, portMAX_DELAY); + // Only one event can happen + switch(bits){ + case Event::RX_CPLT: + case Event::IDLE: + return rxToIdleRecvBytes; + case Event::ERROR: + default: + return -1; + } +} + +void UART_STM32::txCpltCallbackStatic(UART_HandleTypeDef *_huart) { + dispatchStaticToCallback(_huart, &UART_STM32::txCpltCallback); +} + +void UART_STM32::rxCpltCallbackStatic(UART_HandleTypeDef *_huart) { + dispatchStaticToCallback(_huart, &UART_STM32::rxCpltCallback); +} + +void UART_STM32::errorCallbackStatic(UART_HandleTypeDef *_huart) { + dispatchStaticToCallback(_huart, &UART_STM32::errorCallback); +} + +void UART_STM32::rxEventCallbackStatic(UART_HandleTypeDef *_huart, uint16_t pos) { + dispatchStaticToCallback(_huart, &UART_STM32::rxEventCallback); +} + +void UART_STM32::dispatchStaticToCallback(UART_HandleTypeDef* _huart, void (UART_STM32::*callback)(void)) { +#ifdef UART1 + if(_huart->Instance == UART1){ + if(objects[0]){ + (objects[0]->*callback)(); + return; + } + printf("IRQ called for UART1 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART2 + if(_huart->Instance == UART2){ + if(objects[1]){ + (objects[1]->*callback)(); + return; + } + printf("IRQ called for UART2 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART3 + if(_huart->Instance == UART3){ + if(objects[2]){ + (objects[2]->*callback)(); + return; + } + printf("IRQ called for UART3 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART4 + if(_huart->Instance == UART4){ + if(objects[3]){ + (objects[3]->*callback)(); + return; + } + printf("IRQ called for UART4 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART5 + if(_huart->Instance == UART5){ + if(objects[4]){ + (objects[4]->*callback)(); + return; + } + printf("IRQ called for UART5 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART6 + if(_huart->Instance == UART6){ + if(objects[5]){ + (objects[5]->*callback)(); + return; + } + printf("IRQ called for UART6 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART7 + if(_huart->Instance == UART7){ + if(objects[6]){ + (objects[6]->*callback)(); + return; + } + printf("IRQ called for UART7 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART8 + if(_huart->Instance == UART8){ + if(objects[7]){ + (objects[7]->*callback)(); + return; + } + printf("IRQ called for UART8 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART9 + if(_huart->Instance == UART9){ + if(objects[8]){ + (objects[8]->*callback)(); + return; + } + printf("IRQ called for UART9 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef UART10 + if(_huart->Instance == UART10){ + if(objects[9]){ + (objects[9]->*callback)(); + return; + } + printf("IRQ called for UART10 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART1 + if(_huart->Instance == USART1){ + if(objects[0]){ + (objects[0]->*callback)(); + return; + } + printf("IRQ called for USART1 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART2 + if(_huart->Instance == USART2){ + if(objects[1]){ + (objects[1]->*callback)(); + return; + } + printf("IRQ called for USART2 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART3 + if(_huart->Instance == USART3){ + if(objects[2]){ + (objects[2]->*callback)(); + return; + } + printf("IRQ called for USART3 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART4 + if(_huart->Instance == USART4){ + if(objects[3]){ + (objects[3]->*callback)(); + return; + } + printf("IRQ called for USART4 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART5 + if(_huart->Instance == USART5){ + if(objects[4]){ + (objects[4]->*callback)(); + return; + } + printf("IRQ called for USART5 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART6 + if(_huart->Instance == USART6){ + if(objects[5]){ + (objects[5]->*callback)(); + return; + } + printf("IRQ called for USART6 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART7 + if(_huart->Instance == USART7){ + if(objects[6]){ + (objects[6]->*callback)(); + return; + } + printf("IRQ called for USART7 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART8 + if(_huart->Instance == USART8){ + if(objects[7]){ + (objects[7]->*callback)(); + return; + } + printf("IRQ called for USART8 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART9 + if(_huart->Instance == USART9){ + if(objects[8]){ + (objects[8]->*callback)(); + return; + } + printf("IRQ called for USART9 with uninitialized object\n"); + Error_Handler(); + } +#endif +#ifdef USART10 + if(_huart->Instance == USART10){ + if(objects[9]){ + (objects[9]->*callback)(); + return; + } + printf("IRQ called for USART10 with uninitialized object\n"); + Error_Handler(); + } +#endif + printf("Unknown UART instance %p\n", _huart); + Error_Handler(); +} + +void UART_STM32::txCpltCallback() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xEventGroupSetBitsFromISR(eventGroupHandle, (EventBits_t)Event::TX_CPLT, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void UART_STM32::rxCpltCallback() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xEventGroupSetBitsFromISR(eventGroupHandle, (EventBits_t)Event::RX_CPLT, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void UART_STM32::errorCallback() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xEventGroupSetBitsFromISR(eventGroupHandle, (EventBits_t)Event::ERROR, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void UART_STM32::rxEventCallback() { + // According to stm32f4xx_hal_uart.c, TC and HT events are handled here if reception is to be until idle. + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + rxToIdleRecvBytes = huart->RxXferSize - huart->RxXferCount; + switch(HAL_UARTEx_GetRxEventType(huart)){ + case HAL_UART_RXEVENT_TC: + xEventGroupSetBitsFromISR(eventGroupHandle, (EventBits_t)Event::RX_CPLT, &xHigherPriorityTaskWoken); + break; + case HAL_UART_RXEVENT_HT: + // Handling not implemented yet + break; + case HAL_UART_RXEVENT_IDLE: + xEventGroupSetBitsFromISR(eventGroupHandle, (EventBits_t)Event::IDLE, &xHigherPriorityTaskWoken); + break; + } + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} diff --git a/Firmware/F407V-PWMServoTester/Core/Src/Components/UART_STM32.hpp b/Firmware/F407V-PWMServoTester/Core/Src/Components/UART_STM32.hpp new file mode 100644 index 0000000..0df0b38 --- /dev/null +++ b/Firmware/F407V-PWMServoTester/Core/Src/Components/UART_STM32.hpp @@ -0,0 +1,47 @@ +/* + * UART_STM32.hpp + * + * Created on: Aug 17, 2024 + * Author: Gabriel + */ + +#ifndef SRC_COMPONENTS_UART_STM32_HPP_ +#define SRC_COMPONENTS_UART_STM32_HPP_ + +#include "main.h" +#include "UART.hpp" +#include +#include + +class UART_STM32 : public UART { +public: + UART_STM32(UART_HandleTypeDef* huart); + virtual ~UART_STM32(); + int32_t init(); + int32_t transmit(uint8_t* buffer, uint32_t size); + int32_t receiveUntilLineIdle(uint8_t* buffer, uint32_t maxSize); +private: + enum class Event : uint32_t{ + TIMEOUT = 0, + TX_CPLT = 1<<0, + RX_CPLT = 1<<1, + IDLE = 1<<2, + ERROR = 1<<3, + }; + static void txCpltCallbackStatic(UART_HandleTypeDef* _huart); + static void rxCpltCallbackStatic(UART_HandleTypeDef* _huart); + static void errorCallbackStatic(UART_HandleTypeDef* _huart); + static void rxEventCallbackStatic(UART_HandleTypeDef* _huart, uint16_t pos); + static void dispatchStaticToCallback(UART_HandleTypeDef* _huart, void (UART_STM32::*callback)(void)); + void txCpltCallback(); + void rxCpltCallback(); + void errorCallback(); + void rxEventCallback(); + inline static UART_STM32* objects[10]; + UART_HandleTypeDef* huart; + EventGroupHandle_t eventGroupHandle; + StaticEventGroup_t eventGroupBuffer; + uint32_t rxToIdleRecvBytes; +}; + +#endif /* SRC_COMPONENTS_UART_STM32_HPP_ */ diff --git a/Firmware/F407V-PWMServoTester/Core/Src/Components/start.cpp b/Firmware/F407V-PWMServoTester/Core/Src/Components/start.cpp index 62da222..8f0df9e 100644 --- a/Firmware/F407V-PWMServoTester/Core/Src/Components/start.cpp +++ b/Firmware/F407V-PWMServoTester/Core/Src/Components/start.cpp @@ -13,6 +13,7 @@ #include "LogDriver.hpp" #include "PWMServo.hpp" #include "PWM_Pin_STM32.hpp" +#include "UART_STM32.hpp" GPIO_Pin_STM32 ledOrange(GPIOD, GPIO_PIN_13); GPIO_Pin_STM32 ledGreen(GPIOD, GPIO_PIN_12); @@ -24,6 +25,11 @@ extern TIM_HandleTypeDef htim8; PWM_Pin_STM32 escPin(&htim8, TIM_CHANNEL_3); PWMServo esc(&escPin, 1000, 2000); +extern UART_HandleTypeDef huart2; +UART_STM32 uart2(&huart2); +uint8_t uartTransmitBuffer[] = "Hello back\r\n"; +uint8_t uartRecvBuffer[16]; + void executableDispatch(void* _executable){ Executable* executable = static_cast(_executable); executable->execute(); @@ -47,6 +53,11 @@ void start(){ LogDriver::getInstance()->init(); TaskHandle_t hTaskLogDriver; xTaskCreate(executableDispatch, "LogDriver", 256, LogDriver::getInstance(), 20, &hTaskLogDriver); + uart2.init(); + uart2.take(100); + uart2.receiveUntilLineIdle(uartRecvBuffer, 16); + uart2.transmit(uartTransmitBuffer, 12); + uart2.give(); esc.init(); esc.setPosition(0); vTaskDelay(10000); diff --git a/Firmware/F407V-PWMServoTester/Core/Src/dma.c b/Firmware/F407V-PWMServoTester/Core/Src/dma.c index 2f40ef7..d98fa6d 100644 --- a/Firmware/F407V-PWMServoTester/Core/Src/dma.c +++ b/Firmware/F407V-PWMServoTester/Core/Src/dma.c @@ -50,6 +50,12 @@ void MX_DMA_Init(void) /* DMA1_Stream4_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); + /* DMA1_Stream5_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); + /* DMA1_Stream6_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn); /* DMA2_Stream0_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); diff --git a/Firmware/F407V-PWMServoTester/Core/Src/stm32f4xx_it.c b/Firmware/F407V-PWMServoTester/Core/Src/stm32f4xx_it.c index bb08927..810822e 100644 --- a/Firmware/F407V-PWMServoTester/Core/Src/stm32f4xx_it.c +++ b/Firmware/F407V-PWMServoTester/Core/Src/stm32f4xx_it.c @@ -59,6 +59,9 @@ extern DMA_HandleTypeDef hdma_spi1_rx; extern DMA_HandleTypeDef hdma_spi1_tx; extern DMA_HandleTypeDef hdma_spi2_rx; extern DMA_HandleTypeDef hdma_spi2_tx; +extern DMA_HandleTypeDef hdma_usart2_rx; +extern DMA_HandleTypeDef hdma_usart2_tx; +extern UART_HandleTypeDef huart2; extern TIM_HandleTypeDef htim7; /* USER CODE BEGIN EV */ @@ -219,6 +222,34 @@ void DMA1_Stream4_IRQHandler(void) /* USER CODE END DMA1_Stream4_IRQn 1 */ } +/** + * @brief This function handles DMA1 stream5 global interrupt. + */ +void DMA1_Stream5_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Stream5_IRQn 0 */ + + /* USER CODE END DMA1_Stream5_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart2_rx); + /* USER CODE BEGIN DMA1_Stream5_IRQn 1 */ + + /* USER CODE END DMA1_Stream5_IRQn 1 */ +} + +/** + * @brief This function handles DMA1 stream6 global interrupt. + */ +void DMA1_Stream6_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Stream6_IRQn 0 */ + + /* USER CODE END DMA1_Stream6_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart2_tx); + /* USER CODE BEGIN DMA1_Stream6_IRQn 1 */ + + /* USER CODE END DMA1_Stream6_IRQn 1 */ +} + /** * @brief This function handles EXTI line[9:5] interrupts. */ @@ -237,6 +268,20 @@ void EXTI9_5_IRQHandler(void) /* USER CODE END EXTI9_5_IRQn 1 */ } +/** + * @brief This function handles USART2 global interrupt. + */ +void USART2_IRQHandler(void) +{ + /* USER CODE BEGIN USART2_IRQn 0 */ + + /* USER CODE END USART2_IRQn 0 */ + HAL_UART_IRQHandler(&huart2); + /* USER CODE BEGIN USART2_IRQn 1 */ + + /* USER CODE END USART2_IRQn 1 */ +} + /** * @brief This function handles EXTI line[15:10] interrupts. */ diff --git a/Firmware/F407V-PWMServoTester/Core/Src/usart.c b/Firmware/F407V-PWMServoTester/Core/Src/usart.c index e0628bc..f9a81b2 100644 --- a/Firmware/F407V-PWMServoTester/Core/Src/usart.c +++ b/Firmware/F407V-PWMServoTester/Core/Src/usart.c @@ -25,6 +25,8 @@ /* USER CODE END 0 */ UART_HandleTypeDef huart2; +DMA_HandleTypeDef hdma_usart2_rx; +DMA_HandleTypeDef hdma_usart2_tx; /* USART2 init function */ @@ -39,7 +41,7 @@ void MX_USART2_UART_Init(void) /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; - huart2.Init.BaudRate = 115200; + huart2.Init.BaudRate = 921600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; @@ -80,6 +82,46 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + /* USART2 DMA Init */ + /* USART2_RX Init */ + hdma_usart2_rx.Instance = DMA1_Stream5; + hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4; + hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart2_rx.Init.Mode = DMA_NORMAL; + hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx); + + /* USART2_TX Init */ + hdma_usart2_tx.Instance = DMA1_Stream6; + hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4; + hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart2_tx.Init.Mode = DMA_NORMAL; + hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW; + hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx); + + /* USART2 interrupt Init */ + HAL_NVIC_SetPriority(USART2_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspInit 1 */ /* USER CODE END USART2_MspInit 1 */ @@ -103,6 +145,12 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) */ HAL_GPIO_DeInit(GPIOA, USART2_TX_Pin|USART2_RX_Pin); + /* USART2 DMA DeInit */ + HAL_DMA_DeInit(uartHandle->hdmarx); + HAL_DMA_DeInit(uartHandle->hdmatx); + + /* USART2 interrupt Deinit */ + HAL_NVIC_DisableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspDeInit 1 */ /* USER CODE END USART2_MspDeInit 1 */ diff --git a/Firmware/F407V-PWMServoTester/F407V-PWMServoTester.ioc b/Firmware/F407V-PWMServoTester/F407V-PWMServoTester.ioc index ece324b..d64e5ff 100644 --- a/Firmware/F407V-PWMServoTester/F407V-PWMServoTester.ioc +++ b/Firmware/F407V-PWMServoTester/F407V-PWMServoTester.ioc @@ -6,7 +6,9 @@ Dma.Request0=SPI2_RX Dma.Request1=SPI2_TX Dma.Request2=SPI1_RX Dma.Request3=SPI1_TX -Dma.RequestsNb=4 +Dma.Request4=USART2_RX +Dma.Request5=USART2_TX +Dma.RequestsNb=6 Dma.SPI1_RX.2.Direction=DMA_PERIPH_TO_MEMORY Dma.SPI1_RX.2.FIFOMode=DMA_FIFOMODE_DISABLE Dma.SPI1_RX.2.Instance=DMA2_Stream0 @@ -47,6 +49,26 @@ Dma.SPI2_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.SPI2_TX.1.PeriphInc=DMA_PINC_DISABLE Dma.SPI2_TX.1.Priority=DMA_PRIORITY_LOW Dma.SPI2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode +Dma.USART2_RX.4.Direction=DMA_PERIPH_TO_MEMORY +Dma.USART2_RX.4.FIFOMode=DMA_FIFOMODE_DISABLE +Dma.USART2_RX.4.Instance=DMA1_Stream5 +Dma.USART2_RX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.USART2_RX.4.MemInc=DMA_MINC_ENABLE +Dma.USART2_RX.4.Mode=DMA_NORMAL +Dma.USART2_RX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.USART2_RX.4.PeriphInc=DMA_PINC_DISABLE +Dma.USART2_RX.4.Priority=DMA_PRIORITY_LOW +Dma.USART2_RX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode +Dma.USART2_TX.5.Direction=DMA_MEMORY_TO_PERIPH +Dma.USART2_TX.5.FIFOMode=DMA_FIFOMODE_DISABLE +Dma.USART2_TX.5.Instance=DMA1_Stream6 +Dma.USART2_TX.5.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.USART2_TX.5.MemInc=DMA_MINC_ENABLE +Dma.USART2_TX.5.Mode=DMA_NORMAL +Dma.USART2_TX.5.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.USART2_TX.5.PeriphInc=DMA_PINC_DISABLE +Dma.USART2_TX.5.Priority=DMA_PRIORITY_LOW +Dma.USART2_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode FREERTOS.IPParameters=Tasks01,configUSE_NEWLIB_REENTRANT FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL FREERTOS.configUSE_NEWLIB_REENTRANT=1 @@ -159,6 +181,8 @@ MxDb.Version=DB.6.0.120 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DMA1_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true +NVIC.DMA1_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true +NVIC.DMA1_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DMA2_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DMA2_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false @@ -180,6 +204,7 @@ NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:true\:true\:false NVIC.TIM7_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true NVIC.TimeBase=TIM7_IRQn NVIC.TimeBaseIP=TIM7 +NVIC.USART2_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false PA0-WKUP.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI PA0-WKUP.GPIO_Label=B1 [Blue PushButton] @@ -576,7 +601,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_I2C1_Init-I2C1-false-HAL-true,5-MX_I2S3_Init-I2S3-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_TIM10_Init-TIM10-false-HAL-true,9-MX_USART2_UART_Init-USART2-false-HAL-true,10-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_I2C1_Init-I2C1-false-HAL-true,5-MX_I2S3_Init-I2S3-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_TIM10_Init-TIM10-false-HAL-true,9-MX_USART2_UART_Init-USART2-false-HAL-true,10-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,11-MX_TIM8_Init-TIM8-false-HAL-true RCC.48MHZClocksFreq_Value=48000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -654,7 +679,8 @@ TIM8.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE TIM8.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 TIM8.IPParameters=Channel-PWM Generation3 CH3,Prescaler,AutoReloadPreload TIM8.Prescaler=50 -USART2.IPParameters=VirtualMode +USART2.BaudRate=921600 +USART2.IPParameters=VirtualMode,BaudRate USART2.VirtualMode=VM_ASYNC USB_OTG_FS.IPParameters=VirtualMode USB_OTG_FS.VirtualMode=Device_Only