2017-09-14 02:35 AM
Hello,
I try to use Usart Tx with DMA on a STM32L052K6, in order to send a string
without needing to send each character independently.
I don't use ISR. The Usart TX works well without DMA using HAL functions.
The problem : when I call my function UsartTxData, there is only 2 bytes that are transferred, whereas my string is 13 characters. I've checked with debugger that CNDTR is correctly loaded to the value 13.
As soon as TCIF = 1, there is only 2 bytes transferred instead of 13, I've check Tx signal with oscilloscope.
I can not find out the problem, can you please help me ?
Thanks !
Thomas
Main :
char msg[20] = 'page keybd ';
#define BUFFER_SIZE 50
char TxBuffer[BUFFER_SIZE];
while(1)
{
UsartTxData(msg);
for(i=0;i<1000000;i++) RestartWdt(); // Delay}
void UsartInit(void)
{ GPIO_InitTypeDef GPIO_InitStruct; // Peripheral clock enable __USART1_CLK_ENABLE(); // USART1 GPIO Configuration // PB6 ------> USART1_TX // PB7 ------> USART1_RX GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF0_USART1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // DMA controller clock enable RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Remap DMA channel2 on USART TX DMA1_CSELR->CSELR |= 0x011 << DMA_CSELR_C2S_Pos; // Configure the peripheral data register address DMA1_Channel2->CPAR = (uint32_t) (&(USART1->TDR)); // Configure the memory address DMA1_Channel2->CMAR = (uint32_t)(TxBuffer); // Memory to memory transfer DMA1_Channel2->CCR |= DMA_CCR_MEM2MEM; // Memory increment mode enabled DMA1_Channel2->CCR |= DMA_CCR_MINC; // Data transfer direction, Read from memory DMA1_Channel2->CCR |= DMA_CCR_DIR; huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&huart1); // DMA USART TX Enable USART1->CR3 |= USART_CR3_DMAT;}void UsartTxData(char *data)
{// Check if Tx DMA is busy
if(UsartTxBusy() == 1) return;// Clear status / interrupt flags
DMA1->IFCR |= DMA_IFCR_CGIF2 | DMA_IFCR_CTCIF2 | DMA_IFCR_CHTIF2 | DMA_IFCR_CTEIF2;// Set transfer data size
DMA1_Channel2->CNDTR = strlen(data);// Copy data to buffer
strcpy(TxBuffer, data);// Set busy flag (used in UsartTxBusy())
TxBusyFlag = 1;// Channel Enable - start transfer
DMA1_Channel2->CCR |= DMA_CCR_EN;}uint8_t UsartTxBusy(void)
{ if((DMA1->ISR & DMA_ISR_TCIF2) != 0) { TxBusyFlag = 0; DMA1_Channel2->CCR &= ~DMA_CCR_EN;// Clear status / interrupt flags
DMA1->IFCR |= DMA_IFCR_CGIF2 | DMA_IFCR_CTCIF2 | DMA_IFCR_CHTIF2 | DMA_IFCR_CTEIF2; } return(TxBusyFlag);}Solved! Go to Solution.
2017-09-14 07:30 AM
// DMA USART TX Enable
USART1->CR3 |= USART_CR3_DMAT;This is your peripheral trigger.
JW
2017-09-14 07:43 AM
Without setting M2M, read out and post content of relevant DMA registers (including status).
JW