alex1985 0 6 мая, 2015 Опубликовано 6 мая, 2015 · Жалоба Доброго всем времени суток! Контроллер stm32f107, проект собран в Cube, пытаюсь сделать отправку по USART с DMA. Инициализация: void MX_UART4_Init(void) { huart4.Instance = UART4; huart4.Init.BaudRate = 9600; huart4.Init.WordLength = UART_WORDLENGTH_8B; huart4.Init.StopBits = UART_STOPBITS_1; huart4.Init.Parity = UART_PARITY_NONE; huart4.Init.Mode = UART_MODE_TX; huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart4.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart4); } void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); /* DMA interrupt init */ HAL_NVIC_SetPriority(DMA2_Channel5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Channel5_IRQn); } Связка USART<->DMA: void HAL_UART_MspInit(UART_HandleTypeDef* huart) { GPIO_InitTypeDef GPIO_InitStruct; if(huart->Instance==UART4) { /* USER CODE BEGIN UART4_MspInit 0 */ /* USER CODE END UART4_MspInit 0 */ /* Peripheral clock enable */ __UART4_CLK_ENABLE(); /**UART4 GPIO Configuration PC10 ------> UART4_TX PC11 ------> UART4_RX */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* Peripheral DMA init*/ hdma_uart4_tx.Instance = DMA2_Channel5; hdma_uart4_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_uart4_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_uart4_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_uart4_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_uart4_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_uart4_tx.Init.Mode = DMA_NORMAL; hdma_uart4_tx.Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_Init(&hdma_uart4_tx); __HAL_LINKDMA(huart,hdmatx,hdma_uart4_tx); /* USER CODE BEGIN UART4_MspInit 1 */ /* USER CODE END UART4_MspInit 1 */ } } Посылка данных: uint8_t data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; while (1) { HAL_UART_Transmit_DMA(&huart4, data, 8); HAL_Delay(500); } Но отправляется только первая посылка. Далее huart4.State переходит в состояние HAL_UART_STATE_BUSY_TX. Пробовал делать отправку без HAL (регистрами) - все работает. Хочется разобраться с hal и понять что делаю не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tanya 4 6 мая, 2015 Опубликовано 6 мая, 2015 · Жалоба Но отправляется только первая посылка. Далее huart4.State переходит в состояние HAL_UART_STATE_BUSY_TX. Пробовал делать отправку без HAL (регистрами) - все работает. Хочется разобраться с hal и понять что делаю не так. Первая посылка - это сколько байт? А что у Вас делает обработчик прерываний? И зачем тут прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 6 мая, 2015 Опубликовано 6 мая, 2015 · Жалоба Первая посылка - это сколько байт? А что у Вас делает обработчик прерываний? И зачем тут прерывания? Первая посылка - это все 8 байт (data[8]). Про прерывания был мой второй вопрос ;) Дело в том, что при конфигурации DMA в Cube галка "DMA channel 5 global interrupt" не снимается. Мне прерывания не нужны. Контроль отправки посылки можно делать опросом бита TCIF5 регистра DMA2->ISR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tanya 4 6 мая, 2015 Опубликовано 6 мая, 2015 · Жалоба Первая посылка - это все 8 байт (data[8]). Про прерывания был мой второй вопрос ;) Дело в том, что при конфигурации DMA в Cube галка "DMA channel 5 global interrupt" не снимается. Мне прерывания не нужны. Контроль отправки посылки можно делать опросом бита TCIF5 регистра DMA2->ISR. Да, это у меня тоже после обновления КУБа возникло с галками... Пришлось откатиться на старую версию. Или писать callback, что мне не нужно было совсем... но работало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 6 мая, 2015 Опубликовано 6 мая, 2015 · Жалоба Да, это у меня тоже после обновления КУБа возникло с галками... Пришлось откатиться на старую версию. Или писать callback, что мне не нужно было совсем... но работало. А причем здесь прерывания? У меня обработчик прерывания пустой, но huart4.State переходит в состояние HAL_UART_STATE_BUSY_TX. Мне нужно State менять на Ready в обработчике прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 13 мая, 2015 Опубликовано 13 мая, 2015 · Жалоба Вчера CMSIS, сегодня HAL, завтра еще что-нибудь придумают.. в итоге сделал все через регистры - быстро, красиво и универсально. Все работает, тему можно считать закрытой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sR_ 0 21 ноября, 2015 Опубликовано 21 ноября, 2015 · Жалоба Вдруг кто еще столкнется с этим. Вот на форуме stm нашли в чем причина Если в кратце, то обработчик прерывания по завершению передачи от DMA (UART_DMATransmitCplt) не восстанавливает состояние уарта (huart->State). что бы все работало без правки исходников HAL надо определить штатный обработчик прерывания UART который и вернет состояние в HAL_UART_STATE_READY. void USARTx_IRQHandler(void) { HAL_UART_IRQHandler(&UartHandle); } Альтернативно, если прерывания от UART не нужны, то можно изменить саму UART_DMATransmitCplt Вот как это предложили на форуме st. static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode*/ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) { huart->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the UART CR3 register */ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); /* Enable the UART Transmit Complete Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_TC); huart->State=HAL_UART_STATE_READY; //<--- i add this line to solve the //problem } /* DMA Circular mode */ else { HAL_UART_TxCpltCallback(huart); } } В описании на драйверы HAL (я смотрел Description of STM32F0xx HAL drivers rev 1) про это ничего нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 27 ноября, 2015 Опубликовано 27 ноября, 2015 · Жалоба В соседней теме, где нас обозвали теоретиками мы как раз обсуждали этот вопрос. Дело в том, что DMA начинает слать следующий байт по сигналу инициириванному флагом буфер пуст, но по логике статус должен стать равным HAL_UART_STATE_READY после пересылки байта. В предыдущей версии куба внутри обработчика прерывания DMA в цикле крутились все время пока передается последний байт. В более новой версии поступили иначе. Разрешили прерывание по UART_IT_TC и перенесли код в соответствующий обработчик прерывания. Вот обработчик для 429го процессора, а все детали вы можете посмотерть в соседней теме. /** * @brief Wraps up transmission in non blocking mode. * @param huart: pointer to a UART_HandleTypeDef structure that contains * the configuration information for the specified UART module. * @retval HAL status */ static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) { /* Disable the UART Transmit Complete Interrupt */ __HAL_UART_DISABLE_IT(huart, UART_IT_TC); /* Check if a receive process is ongoing or not */ if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { huart->State = HAL_UART_STATE_BUSY_RX; } else { /* Disable the UART Parity Error Interrupt */ __HAL_UART_DISABLE_IT(huart, UART_IT_PE); /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); huart->State = HAL_UART_STATE_READY; } HAL_UART_TxCpltCallback(huart); return HAL_OK; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eu1cc 0 14 октября, 2016 Опубликовано 14 октября, 2016 · Жалоба Привет всем. Аналогичная проблемма. Советы выше не помогают. Не выходит из while... Как такое может быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться