初级会员
- 积分
- 61
- 金钱
- 61
- 注册时间
- 2016-1-18
- 在线时间
- 26 小时
|
楼主 |
发表于 2022-5-24 03:03:25
|
显示全部楼层
删除了不相关方法完整代码
==========================================================
#include "dmauart.h"
#include "main.h"
#include "semphr.h"
#include "stm32f7xx_hal.h"
#include "stm32f7xx_nucleo_144.h"
#include "stream_buffer.h"
#include "string.h"
#include <queue.h>
#include <stdarg.h>
#include <stdio.h>
#include <stm32f7xx_hal_uart.h>
typedef struct {
uint32_t len;
uint8_t free_after_use;
void *pdata;
} binary_t;
void MX_USART3_UART_Init();
static QueueHandle_t dmaTxBusy = NULL;
static QueueHandle_t sendFunBusy = NULL;
static QueueHandle_t rcvFunBusy = NULL;
static QueueHandle_t dmaTxQueue = NULL;
TaskHandle_t dmaTxTaskHandle;
_Noreturn void dmaTxTask(void *argument);
StreamBufferHandle_t dmaRxStream;
void dmauart_init(void) {
// send and dma Mutex
dmaTxBusy = xSemaphoreCreateCounting(1, 1);
sendFunBusy = xSemaphoreCreateBinary();
xSemaphoreGive(sendFunBusy);
rcvFunBusy = xSemaphoreCreateBinary();
xSemaphoreGive(rcvFunBusy);
dmaTxQueue = xQueueCreate(16, sizeof(binary_t));
dmaRxStream = xStreamBufferCreate(128, 0);
MX_USART3_UART_Init();
xTaskCreate((TaskFunction_t) dmaTxTask, "dmaTxTask", 128 * 4, NULL, 40,
&dmaTxTaskHandle);
}
// hdma_usart3_rx
void DMA1_Stream1_IRQHandler(void) {
if (READ_BIT(DMA1->LISR, DMA_LISR_TCIF1)) {
DMA1->LIFCR = DMA_LIFCR_CTCIF1;
// rx dma complete
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
uint32_t size = RECEIVE_BUFF_SIZE - DMA_RX_Stream->NDTR;
if (size == 0) {
return;
}
if (READ_BIT(DMA_RX_Stream->CR, DMA_SxCR_CT)) {
xStreamBufferSendFromISR(dmaRxStream, (const void *) DMA_RX_Stream->M1AR,
size, &xHigherPriorityTaskWoken);
} else {
xStreamBufferSendFromISR(dmaRxStream, (const void *) DMA_RX_Stream->M0AR,
size, &xHigherPriorityTaskWoken);
}
}
}
void DMA1_Stream3_IRQHandler(void) {
if (READ_BIT(DMA1->LISR, DMA_LISR_TCIF3)) {
DMA1->LIFCR = DMA_LIFCR_CTCIF3;
// tx dma complete
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(dmaTxBusy, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
if (READ_BIT(DMA1->LISR, DMA_LISR_FEIF3)) {
// tx dma harf complete
DMA1->LIFCR = DMA_LIFCR_CFEIF3;
}
}
void USART3_IRQHandler(void) {
if ((USART3->ISR & USART_ISR_ORE) == USART_ISR_ORE) {
USART3->ICR = USART_ICR_ORECF;
}
if (READ_BIT(USART3->ISR, USART_ISR_RTOF)) {
USART3->ICR = USART_ICR_RTOCF;
BSP_LED_Toggle(LED_GREEN);
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
CLEAR_BIT(DMA_RX_Stream->CR, DMA_SxCR_EN);
uint32_t size = RECEIVE_BUFF_SIZE - DMA_RX_Stream->NDTR;
if (size == 0)
goto end;
if (READ_BIT(DMA_RX_Stream->CR, DMA_SxCR_CT)) {
xStreamBufferSendFromISR(dmaRxStream, (const void *) DMA_RX_Stream->M1AR,
size, &xHigherPriorityTaskWoken);
} else {
xStreamBufferSendFromISR(dmaRxStream, (const void *) DMA_RX_Stream->M0AR,
size, &xHigherPriorityTaskWoken);
}
SET_BIT(DMA_RX_Stream->CR, DMA_SxCR_EN);
end:
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
return;
}
if (READ_BIT(USART3->ISR, USART_ISR_TC)) {
USART3->ICR = USART_ICR_TCCF;
}
}
_Noreturn void dmaTxTask(void *argument) {
binary_t msg = {0, 0, NULL};
// disable dma
CLEAR_BIT(DMA_TX_Stream->CR, DMA_SxCR_EN);
MODIFY_REG(DMA_TX_Stream->CR, DMA_SxCR_CHSEL_Msk, 4 << DMA_SxCR_CHSEL_Pos);
SET_BIT(DMA_TX_Stream->CR, DMA_SxCR_MINC);
// set 01 to memory to p
SET_BIT(DMA_TX_Stream->CR, DMA_SxCR_DIR_0);
CLEAR_BIT(DMA_TX_Stream->CR, DMA_SxCR_DIR_1);
// set uart tx
DMA_TX_Stream->PAR = (uint32_t) &(USART3->TDR);
// en TC IE
SET_BIT(DMA_TX_Stream->CR, DMA_SxCR_TCIE);
for (;;) {
if (xQueueReceive(dmaTxQueue, &msg, portMAX_DELAY)) {
CLEAR_BIT(DMA_TX_Stream->CR, DMA_SxCR_EN);
DMA_TX_Stream->NDTR = msg.len;
DMA_TX_Stream->M0AR = (uint32_t) msg.pdata;
SET_BIT(DMA_TX_Stream->CR, DMA_SxCR_EN);
SET_BIT(USART3->CR3, USART_CR3_DMAT);
xSemaphoreTake(dmaTxBusy, portMAX_DELAY);
if (msg.pdata != NULL && msg.free_after_use)
vPortFree(msg.pdata);
msg.pdata = 0;
msg.free_after_use = 0;
msg.len = 0;
} else {
taskYIELD();
}
}
}
void dma_print(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int len = vsnprintf(NULL, 0, fmt, args);
va_end(args);
char *name = pcTaskGetName(NULL);
int name_len = strlen(name);
char *buffer = pvPortMalloc(len + name_len + 4);
if (buffer == NULL) return;
int index = 0;
for (; index < name_len; ++index) {
buffer[index] = name[index];
}
buffer[index++] = ':';
buffer[index++] = ' ';
int n = vsprintf(buffer + index, fmt, args);
if (n > 0) {
dmauart_send(buffer, index + n);
} else {
vPortFree(buffer);
}
}
void dmauart_send(void *pdata, uint32_t len) {
if (len == 0)
return;
if (pdata == NULL)
return;
xSemaphoreTake(sendFunBusy, portMAX_DELAY);
void *buf = pvPortMalloc(len);
memcpy(buf, pdata, len);
binary_t msg;
msg.len = len;
msg.free_after_use = 1;
msg.pdata = buf;
xQueueSend(dmaTxQueue, (void *) &msg, (TickType_t) portMAX_DELAY);
xSemaphoreGive(sendFunBusy);
}
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart3_rx;
DMA_HandleTypeDef hdma_usart3_tx;
static uint8_t receive_buf0[RECEIVE_BUFF_SIZE];
static uint8_t receive_buf1[RECEIVE_BUFF_SIZE];
void MX_USART3_UART_Init(void) {
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart3) != HAL_OK) {
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (uartHandle->Instance == USART3) {
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**USART3 GPIO Configuration
PD8 ------> USART3_TX
PD9 ------> USART3_RX
*/
GPIO_InitStruct.Pin = STLK_RX_Pin | STLK_TX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USART3 DMA Init */
/* USART3_RX Init */
hdma_usart3_rx.Instance = DMA1_Stream1;
hdma_usart3_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_NORMAL;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK) {
Error_Handler();
}
__HAL_LINKDMA(uartHandle, hdmarx, hdma_usart3_rx);
/* USART3_TX Init */
hdma_usart3_tx.Instance = DMA1_Stream3;
hdma_usart3_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK) {
Error_Handler();
}
__HAL_LINKDMA(uartHandle, hdmatx, hdma_usart3_tx);
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
MODIFY_REG(USART3->RTOR, USART_RTOR_RTO, 1400);
SET_BIT(USART3->CR2, USART_CR2_RTOEN);
// disable dma
CLEAR_BIT(DMA_RX_Stream->CR, DMA_SxCR_EN);
MODIFY_REG(DMA_RX_Stream->CR, DMA_SxCR_CHSEL_Msk, 4 << DMA_SxCR_CHSEL_Pos);
// set 00 to Peripheral-to-memory
CLEAR_BIT(DMA_RX_Stream->CR, DMA_SxCR_DIR_0);
CLEAR_BIT(DMA_RX_Stream->CR, DMA_SxCR_DIR_1);
// set uart rx
DMA_RX_Stream->PAR = (uint32_t) &(USART3->RDR);
DMA_RX_Stream->M0AR = (uint32_t) &receive_buf0;
DMA_RX_Stream->M1AR = (uint32_t) &receive_buf1;
DMA_RX_Stream->NDTR = RECEIVE_BUFF_SIZE;
SET_BIT(DMA_RX_Stream->CR, DMA_SxCR_MINC);
SET_BIT(DMA_RX_Stream->CR, DMA_SxCR_DBM);
// en TC IE
SET_BIT(DMA_RX_Stream->CR, DMA_SxCR_TCIE);
SET_BIT(DMA_RX_Stream->CR, DMA_SxCR_EN);
CLEAR_BIT(USART3->CR1, USART_CR1_UE);
SET_BIT(USART3->CR3, USART_CR3_DMAR);
SET_BIT(USART3->CR1, USART_CR1_RTOIE);
SET_BIT(USART3->CR1, USART_CR1_UE);
}
}
|
|