我正在尝试在 USART Tx DMA 片段上启用 DCache,这会导致 USART Tx 失败。
我的印象是 MCU 已经写入物理内存并且 DMA 访问写入的内存应该没有问题?
有人可以帮我解决这个问题吗?
马努
附上完整的代码片段。
- #include "STM32h7xx_ll_bus.h"
- #include "stm32h7xx_ll_cortex.h"
- #include "stm32h7xx_ll_dma.h"
- #include "stm32h7xx_ll_gpio.h"
- #include "stm32h7xx_ll_pwr.h"
- #include "stm32h7xx_ll_rcc.h"
- #include "stm32h7xx_ll_system.h"
- #include "stm32h7xx_ll_usart.h"
- #include "stm32h7xx_ll_utils.h"
- #include "string.h"
- #include
- #include
- #define APB_Div 4
- #define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
- __IO uint8_t tx_done = 0, rx_done = 0;
- const uint8_t exstr[] ="test";
- uint8_t rxbuf[80];
- uint8_t rxlen = ARRAY_LEN(exstr);
- void SystemClock_Config(void)
- {
- LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
- if (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4)
- while (1) {}
- LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
- LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
- LL_RCC_HSE_EnableBypass();
- LL_RCC_HSE_Enable();
- while (!LL_RCC_HSE_IsReady()) {}
- LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);
- LL_RCC_PLL1P_Enable();
- LL_RCC_PLL1Q_Enable();
- LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
- LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
- LL_RCC_PLL1_SetM(1);
- LL_RCC_PLL1_SetN(120);
- LL_RCC_PLL1_SetP(2);
- LL_RCC_PLL1_SetQ(20);
- LL_RCC_PLL1_SetR(2);
- LL_RCC_PLL1_Enable();
- while (!LL_RCC_PLL1_IsReady()) {}
- LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
- LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
- LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
- LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
- LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
- LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
- LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_2);
- LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);
- LL_Init1msTick(480000000);
- LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
- LL_SetSystemCoreClock(480000000); /* 480Mhz */
- LL_RCC_SetUSARTClockSource(LL_RCC_USART234578_CLKSOURCE_PCLK1);
- }
- void gpio_init(void)
- {
- LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOD); /* USART GPIO Clk */
- LL_GPIO_SetPinMode(GPIOD, LL_GPIO_PIN_8, LL_GPIO_MODE_ALTERNATE);
- LL_GPIO_SetAFPin_8_15(GPIOD, LL_GPIO_PIN_8, LL_GPIO_AF_7);
- LL_GPIO_SetPinSpeed(GPIOD, LL_GPIO_PIN_8, LL_GPIO_SPEED_FREQ_HIGH);
- LL_GPIO_SetPinOutputType(GPIOD, LL_GPIO_PIN_8, LL_GPIO_OUTPUT_PUSHPULL);
- LL_GPIO_SetPinPull(GPIOD, LL_GPIO_PIN_8, LL_GPIO_PULL_UP);
- LL_GPIO_SetPinMode(GPIOD, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE);
- LL_GPIO_SetAFPin_8_15(GPIOD, LL_GPIO_PIN_9, LL_GPIO_AF_7);
- LL_GPIO_SetPinSpeed(GPIOD, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_HIGH);
- LL_GPIO_SetPinOutputType(GPIOD, LL_GPIO_PIN_9, LL_GPIO_OUTPUT_PUSHPULL);
- LL_GPIO_SetPinPull(GPIOD, LL_GPIO_PIN_9, LL_GPIO_PULL_UP);
- }
- __STATIC_INLINE void LL_DMA_EnablePeriphDMA(DMA_TypeDef *DMAx, uint32_t Stream)
- {
- register uint32_t dma_base_addr = (uint32_t)DMAx;
- SET_BIT(((DMA_Stream_TypeDef *)(dma_base_addr + LL_DMA_STR_OFFSET_TAB[Stream]))->CR, DMA_SxCR_TRBUFF);
- }
- __STATIC_INLINE void LL_DMA_DisablePeriphDMA(DMA_TypeDef *DMAx, uint32_t Stream)
- {
- register uint32_t dma_base_addr = (uint32_t)DMAx;
- CLEAR_BIT(((DMA_Stream_TypeDef *)(dma_base_addr + LL_DMA_STR_OFFSET_TAB[Stream]))->CR, DMA_SxCR_TRBUFF);
- }
- void config_usart(void)
- {
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3); /* USART3 Clk */
- LL_USART_SetTransferDirection(USART3,
- LL_USART_DIRECTION_TX_RX);
- LL_USART_ConfigCharacter(USART3,
- LL_USART_DATAWIDTH_8B,
- LL_USART_PARITY_NONE,
- LL_USART_STOPBITS_1);
- LL_USART_SetBaudRate(USART3,
- (SystemCoreClock / APB_Div),
- LL_USART_PRESCALER_DIV1,
- LL_USART_OVERSAMPLING_16,
- 115200);
- LL_USART_Enable(USART3); /* Enable USART */
- while ((!(LL_USART_IsActiveFlag_TEACK(USART3))) ||
- (!(LL_USART_IsActiveFlag_REACK(USART3)))) { }
- }
- void config_dma(void)
- {
- LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
- LL_DMA_SetPeriphRequest(DMA1,
- LL_DMA_STREAM_0, /* Request DMA Stream 0 */
- LL_DMAMUX1_REQ_USART3_TX); /* for DMAMUX1 USART3 Tx */
- LL_DMA_SetPeriphRequest(DMA1,
- LL_DMA_STREAM_1, /* Request DMA Stream 1 */
- LL_DMAMUX1_REQ_USART3_RX); /* for DMAMUX1 USART3 Rx */
- /* Tx DMA */
- LL_DMA_SetDataTransferDirection(DMA1,
- LL_DMA_STREAM_0,
- LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
- LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_0, LL_DMA_PRIORITY_HIGH);
- LL_DMA_SetMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MODE_NORMAL);
- LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_PERIPH_NOINCREMENT);
- LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MEMORY_INCREMENT);
- LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_BYTE);
- LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_BYTE);
- /* Rx DMA */
- LL_DMA_SetDataTransferDirection(DMA1,
- LL_DMA_STREAM_1,
- LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
- LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_1, LL_DMA_PRIORITY_HIGH);
- LL_DMA_SetMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MODE_CIRCULAR);
- LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_PERIPH_NOINCREMENT);
- LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MEMORY_INCREMENT);
- LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_BYTE);
- LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_BYTE);
- LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_1);
- LL_DMA_EnableIT_TC(DMA1, LL_DMA_STREAM_0); /* Tx Transfer Complete */
- LL_DMA_EnableIT_TE(DMA1, LL_DMA_STREAM_0); /* Tx Transfer Error */
- LL_DMA_EnableIT_HT(DMA1, LL_DMA_STREAM_1); /* Rx Half Transfer Done */
- LL_DMA_EnableIT_TC(DMA1, LL_DMA_STREAM_1); /* Rx Transfer Complete */
- LL_DMA_EnableIT_TE(DMA1, LL_DMA_STREAM_1); /* Tx Transfer Error */
- NVIC_SetPriority(DMA1_Stream0_IRQn, 0); /* Stream Priority */
- NVIC_SetPriority(DMA1_Stream1_IRQn, 0);
- NVIC_EnableIRQ(DMA1_Stream0_IRQn); /* Global IRQ */
- NVIC_EnableIRQ(DMA1_Stream1_IRQn);
- LL_USART_EnableDMAReq_TX(USART3); /* Enable Tx DMARQ */
- LL_USART_EnableDMAReq_RX(USART3); /* Enable Rx DMARQ */
- LL_DMA_ClearFlag_TC1(DMA1); /* Transfer complete */
- LL_DMA_ClearFlag_HT1(DMA1); /* Half Transfer done */
- LL_DMA_ClearFlag_TE1(DMA1); /* Transfer Error */
- LL_DMA_ClearFlag_DME1(DMA1); /* Direct MODE Error */
- LL_DMA_ClearFlag_FE1(DMA1); /* FIFO Error */
- LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, rxlen);
- LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_1, LL_USART_DMA_GetRegAddr(USART3, LL_USART_DMA_REG_DATA_RECEIVE));
- LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_1, (uint32_t)rxbuf);
- LL_DMA_EnablePeriphDMA(DMA1, LL_DMA_STREAM_1); /* Enable USART3 Stream DMA */
- LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1); /* Enable DMA Channel Rx */
- }
- void start_dma(uint8_t *buf, uint8_t txlen)
- {
- tx_done = 0;
- LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0); /* Done: LED OFF */
- LL_DMA_ClearFlag_TC0(DMA1); /* Transfer complete */
- LL_DMA_ClearFlag_HT0(DMA1); /* Half Transfer done */
- LL_DMA_ClearFlag_TE0(DMA1); /* Transfer Error */
- LL_DMA_ClearFlag_DME0(DMA1); /* Direct MODE Error */
- LL_DMA_ClearFlag_FE0(DMA1); /* FIFO Error */
- LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, txlen); /* DMA Stream length */
- LL_DMA_ConfigAddresses(DMA1,
- LL_DMA_STREAM_0, /* USART3 DMA Stream 0 */
- (uint32_t)buf, /* Transmit string */
- LL_USART_DMA_GetRegAddr(USART3, LL_USART_DMA_REG_DATA_TRANSMIT),
- LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_STREAM_0));
- LL_DMA_EnablePeriphDMA(DMA1, LL_DMA_STREAM_0); /* Enable USART3 Stream DMA */
- LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0); /* Enable DMA Channel Tx */
- }
- void stop_dma(void)
- {
- while (!tx_done) {}
- LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_0);
- LL_DMA_DisablePeriphDMA(DMA1, LL_DMA_STREAM_0); /* Disable USART3 Stream DMA */
- LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0); /* Done: LED ON */
- }
- void DMA1_Stream0_IRQHandler(void)
- {
- if (LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_STREAM_0) &&
- LL_DMA_IsActiveFlag_TC0(DMA1)) {
- LL_DMA_ClearFlag_TC0(DMA1);
- LL_GPIO_SetOutputPin(GPIOE, LL_GPIO_PIN_1); /* Done: LED2 ON */
- tx_done = 1;
- }
- if (LL_DMA_IsEnabledIT_TE(DMA1, LL_DMA_STREAM_0) &&
- LL_DMA_IsActiveFlag_TE0(DMA1)) {
- }
- }
- void DMA1_Stream1_IRQHandler(void)
- {
- if (LL_DMA_IsEnabledIT_HT(DMA1, LL_DMA_STREAM_1) &&
- LL_DMA_IsActiveFlag_HT1(DMA1)) {
- LL_DMA_ClearFlag_HT1(DMA1);
- }
- if (LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_STREAM_1) &&
- LL_DMA_IsActiveFlag_TC1(DMA1)) {
- LL_DMA_ClearFlag_TC1(DMA1); /* Clear transfer complete flag */
- LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_14); /* LED3 Toggle */
- rx_done = 1;
- }
- if (LL_DMA_IsEnabledIT_TE(DMA1, LL_DMA_STREAM_1) &&
- LL_DMA_IsActiveFlag_TE1(DMA1)) {
- }
- }
- void printh(const char *fmt, ...)
- {
- uint8_t pb[80];
- uint8_t len;
- va_list argp;
- va_start(argp, fmt);
- vsprintf((char *)&pb[0], fmt, argp);
- va_end(argp);
- len = strlen((char *)pb);
- start_dma(pb, len);
- stop_dma();
- }
- int main(void)
- {
- SystemClock_Config();
- SCB_EnableICache(); /* Enable I-Cache */
- // SCB_EnableDCache(); /* Enable D-Cache */
- gpio_init();
- config_usart();
- config_dma();
- LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0); /* Done: LED ON */
- LL_mDelay(500);
- printh("STM32H743 USART DMA Testrn");
- LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_0); /* Done: LED ON */
- LL_mDelay(500);
- LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0); /* Done: LED ON */
- LL_mDelay(500);
- printh("Hello Againrn");
- LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_0); /* Done: LED ON */
- while (1) { }
- }
0
|
1个回答
|
|
|