Add working dma example
This commit is contained in:
parent
a1ee35dca3
commit
3bf5ed37c8
@ -194,6 +194,11 @@ static void MX_USART1_UART_Init(void)
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
// Enable USART1 interrupt
|
||||
// It must higher or equal than 5
|
||||
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(USART1_IRQn);
|
||||
|
||||
// USART1 Pin configuration: TX (PA9), RX (PA10)
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
@ -207,6 +212,8 @@ static void MX_USART1_UART_Init(void)
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void MX_SPI1_Init(void)
|
||||
@ -321,12 +328,15 @@ static void MX_DMA_Init(void)
|
||||
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
|
||||
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
|
||||
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
|
||||
{
|
||||
// Initialization error handling
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);
|
||||
|
||||
// DMA2_Stream3 (SPI1_TX) Interrupt Configuration
|
||||
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
||||
@ -369,3 +379,8 @@ void DMA2_Stream2_IRQHandler(void)
|
||||
{
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_rx);
|
||||
}
|
||||
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
HAL_UART_IRQHandler(&huart1);
|
||||
}
|
||||
|
||||
@ -9,6 +9,13 @@ static int32_t write_socket(const uint8_t* buf, uint16_t count, int32_t byte_tim
|
||||
#ifdef NMBS_RTU
|
||||
static int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg);
|
||||
static int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg);
|
||||
|
||||
#if MB_UART_DMA
|
||||
#include "queue.h"
|
||||
xQueueHandle rtu_rx_q;
|
||||
uint8_t rtu_rx_b[MB_RX_BUF_SIZE];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static nmbs_server_t* server;
|
||||
@ -47,6 +54,11 @@ nmbs_error nmbs_server_init(nmbs_t* nmbs, nmbs_server_t* _server)
|
||||
cb.write_single_register = server_write_single_register;
|
||||
cb.write_multiple_registers = server_write_multiple_registers;
|
||||
|
||||
#if MB_UART_DMA
|
||||
rtu_rx_q = xQueueCreate(MB_RX_BUF_SIZE, sizeof(uint8_t));
|
||||
HAL_UARTEx_ReceiveToIdle_DMA(&MB_UART, rtu_rx_b, MB_RX_BUF_SIZE);
|
||||
#endif
|
||||
|
||||
nmbs_error status = nmbs_server_create(nmbs, server->id, &conf, &cb);
|
||||
if(status != NMBS_ERROR_NONE)
|
||||
{
|
||||
@ -202,6 +214,21 @@ int32_t write_socket(const uint8_t *buf, uint16_t count, int32_t byte_timeout_ms
|
||||
#ifdef NMBS_RTU
|
||||
static int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg)
|
||||
{
|
||||
#if MB_UART_DMA
|
||||
uint32_t tick_start = HAL_GetTick();
|
||||
while(uxQueueMessagesWaiting(rtu_rx_q) < count)
|
||||
{
|
||||
if(HAL_GetTick() - tick_start >= (uint32_t)byte_timeout_ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
xQueueReceive(rtu_rx_q, buf + i, 1);
|
||||
}
|
||||
return count;
|
||||
#else
|
||||
HAL_StatusTypeDef status = HAL_UART_Receive(&MB_UART, buf, count, byte_timeout_ms);
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
@ -211,9 +238,13 @@ static int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
static int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg)
|
||||
{
|
||||
#if MB_UART_DMA
|
||||
HAL_UART_Transmit_DMA(&MB_UART, buf, count);
|
||||
#else
|
||||
HAL_StatusTypeDef status = HAL_UART_Transmit(&MB_UART, buf, count, byte_timeout_ms);
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
@ -223,5 +254,25 @@ static int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_tim
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if MB_UART_DMA
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if(huart == &MB_UART)
|
||||
{
|
||||
for(int i = 0; i < Size; i++)
|
||||
{
|
||||
xQueueSendFromISR(rtu_rx_q, rtu_rx_b + i, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
HAL_UARTEx_ReceiveToIdle_DMA(huart, rtu_rx_b, MB_RX_BUF_SIZE);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
// You may add your additional uart handler below
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -21,8 +21,9 @@ extern "C" {
|
||||
|
||||
#ifdef NMBS_RTU
|
||||
// modbus rtu
|
||||
#define MB_UART huart1
|
||||
#define RX_BUF_SIZE 256
|
||||
#define MB_UART huart1
|
||||
#define MB_UART_DMA 1
|
||||
#define MB_RX_BUF_SIZE 256
|
||||
extern UART_HandleTypeDef MB_UART;
|
||||
#endif
|
||||
|
||||
|
||||
@ -6,15 +6,19 @@
|
||||
|
||||
- Blackpill board
|
||||
- STM32F401CCUx
|
||||
- USART1 with DMA
|
||||
- USART1 (with/without) DMA
|
||||
- PA9 : TX1
|
||||
- PA10 : RX1
|
||||
- SPI1 with DMA (connected to W5500)
|
||||
- PB3 : SCK1
|
||||
- PB4 : MISO1
|
||||
- PB5 : MOSI1
|
||||
- PA15 : NSS (Software select)
|
||||
|
||||
## Toolchain and environment
|
||||
|
||||
Tested on Mac OS Sonoma(Apple Silicon M1) but other os having same toolchain should have no problem.
|
||||
Tested on Mac OS Sonoma(Apple Silicon) & Windows 10 but other os having same toolchain should have no problem.
|
||||
|
||||
- STM32CubeMX 6.11.1
|
||||
- arm-none-eabi-gcc
|
||||
- cmake
|
||||
- ninja
|
||||
@ -23,8 +27,3 @@ Tested on Mac OS Sonoma(Apple Silicon M1) but other os having same toolchain sho
|
||||
- CMake
|
||||
- cortex-debug
|
||||
|
||||
## How to run
|
||||
|
||||
1. Generate driver code from stm32f401ccux.ioc using STM32CubeMX
|
||||
2. Configure with CMake
|
||||
3. Launch with elf file or flash it
|
||||
|
||||
Loading…
Reference in New Issue
Block a user