Closed ghost closed 6 months ago
Hello @hayar2,
Thank you for this report. We will get back to you as soon as we analyze it further. This may take some time. Thank you for your comprehension.
With regards,
Hi @hayar2,
If I understand well, your point is that by the end of the transfer HAL_UARTEx_GetRxEventType()
does not return HAL_UART_RXEVENT_IDLE
and it returns only HAL_UART_RXEVENT_TC
.
The HAL_UART_RXEVENT_IDLE
should be returned when an Idle event occurs before the reception has been completed as mentioned in the function description
And as per the description of the HAL_UARTEx_ReceiveToIdle_DMA()
function, UART will receive an amount of data in DMA mode till either the expected number of data is received or an IDLE line event occurs.
Actually, the IDLE line event is triggered if UART RX line is inactive for one frame. The frame time depends on your baudrate. Higher baudrate, lower frame.
In your case, the IDLE line event has been detected since all expected data are not received yet. Indeed, if at least one data has already been received, IDLE event is to be notified to user for.
Using the same code, when transferring a data size equal to 8, as the number of received data is exactly equal to the amount of data expected to be received, no idle line event will be generated. The HAL_UARTEx_GetRxEventType()
function will return only half transfer and transfer complete events. The HAL_UART_RXEVENT_HT
is generated when the fourth character is received and HAL_UART_RXEVENT_TC
is generated by the end of transfer.
Size = 4, RxEventType = HT
Size = 8, RxEventType = TC
I hope I've been able to answer your question.
With regards,
okay, how to detect the end of a package in a cyclic mode when HAL_UARTEx_ReceiveToIdle_DMA Size equal to 8 bytes. if received 16 bytes, 24 bytes, 32 bytes?
sorry for my English. If something is unclear, let me know.
Hi @hayar2,
The HAL_UART_RXEVENT_TC
event could notify you the end of transfer it is trigged once the reception has been completed and the expected number of data has been received.
With regards,
Changed the HAL_UARTEx_RxEventCallback() function. Added the output of the received bytes to another uart(printf):
when I send 24 bytes, the following happens:
It turns out I received 3 packages? But in fact I only accepted 1 package.
Hi @hayar2,
I didn't get your question precisely. Would you please give me more details ?
With regards,
of course. how to detect the end of a package in this case?
ST Internal Reference: 178447
Fixed in : 273007f20a5c7bca2698668905a71515cf2116fd
Describe the set-up
Describe the bug I use the HAL_UARTEx_ReceiveToIdle_DMA() function. DMA in ring mode. When the HAL_UARTEx_RxEventCallback() interrupt is called, the HAL_UARTEx_GetRxEventType() function does not return the HAL_UART_RXEVENT_IDLE status if the index of the last received byte is equal to the size of the HAL_UARTEx_ReceiveToIdle_DMA.
How To Reproduce
.io configuration:
``` #MicroXplorer Configuration settings - do not modify CAD.formats= CAD.pinconfig= CAD.provider= Dma.LPUART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY Dma.LPUART1_RX.0.EventEnable=DISABLE Dma.LPUART1_RX.0.Instance=DMA1_Channel3 Dma.LPUART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.LPUART1_RX.0.MemInc=DMA_MINC_ENABLE Dma.LPUART1_RX.0.Mode=DMA_NORMAL Dma.LPUART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.LPUART1_RX.0.PeriphInc=DMA_PINC_DISABLE Dma.LPUART1_RX.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING Dma.LPUART1_RX.0.Priority=DMA_PRIORITY_LOW Dma.LPUART1_RX.0.RequestNumber=1 Dma.LPUART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.LPUART1_RX.0.SignalID=NONE Dma.LPUART1_RX.0.SyncEnable=DISABLE Dma.LPUART1_RX.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT Dma.LPUART1_RX.0.SyncRequestNumber=1 Dma.LPUART1_RX.0.SyncSignalID=NONE Dma.LPUART1_TX.1.Direction=DMA_MEMORY_TO_PERIPH Dma.LPUART1_TX.1.EventEnable=DISABLE Dma.LPUART1_TX.1.Instance=DMA1_Channel4 Dma.LPUART1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.LPUART1_TX.1.MemInc=DMA_MINC_ENABLE Dma.LPUART1_TX.1.Mode=DMA_NORMAL Dma.LPUART1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.LPUART1_TX.1.PeriphInc=DMA_PINC_DISABLE Dma.LPUART1_TX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING Dma.LPUART1_TX.1.Priority=DMA_PRIORITY_LOW Dma.LPUART1_TX.1.RequestNumber=1 Dma.LPUART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.LPUART1_TX.1.SignalID=NONE Dma.LPUART1_TX.1.SyncEnable=DISABLE Dma.LPUART1_TX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT Dma.LPUART1_TX.1.SyncRequestNumber=1 Dma.LPUART1_TX.1.SyncSignalID=NONE Dma.Request0=LPUART1_RX Dma.Request1=LPUART1_TX Dma.Request2=USART1_RX Dma.Request3=USART1_TX Dma.RequestsNb=4 Dma.USART1_RX.2.Direction=DMA_PERIPH_TO_MEMORY Dma.USART1_RX.2.EventEnable=DISABLE Dma.USART1_RX.2.Instance=DMA1_Channel1 Dma.USART1_RX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.USART1_RX.2.MemInc=DMA_MINC_ENABLE Dma.USART1_RX.2.Mode=DMA_CIRCULAR Dma.USART1_RX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.USART1_RX.2.PeriphInc=DMA_PINC_DISABLE Dma.USART1_RX.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING Dma.USART1_RX.2.Priority=DMA_PRIORITY_LOW Dma.USART1_RX.2.RequestNumber=1 Dma.USART1_RX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.USART1_RX.2.SignalID=NONE Dma.USART1_RX.2.SyncEnable=DISABLE Dma.USART1_RX.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT Dma.USART1_RX.2.SyncRequestNumber=1 Dma.USART1_RX.2.SyncSignalID=NONE Dma.USART1_TX.3.Direction=DMA_MEMORY_TO_PERIPH Dma.USART1_TX.3.EventEnable=DISABLE Dma.USART1_TX.3.Instance=DMA1_Channel2 Dma.USART1_TX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.USART1_TX.3.MemInc=DMA_MINC_ENABLE Dma.USART1_TX.3.Mode=DMA_NORMAL Dma.USART1_TX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE Dma.USART1_TX.3.PeriphInc=DMA_PINC_DISABLE Dma.USART1_TX.3.Polarity=HAL_DMAMUX_REQ_GEN_RISING Dma.USART1_TX.3.Priority=DMA_PRIORITY_LOW Dma.USART1_TX.3.RequestNumber=1 Dma.USART1_TX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.USART1_TX.3.SignalID=NONE Dma.USART1_TX.3.SyncEnable=DISABLE Dma.USART1_TX.3.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT Dma.USART1_TX.3.SyncRequestNumber=1 Dma.USART1_TX.3.SyncSignalID=NONE File.Version=6 KeepUserPlacement=false LPUART1.BaudRate=115200 LPUART1.IPParameters=BaudRate Mcu.CPN=STM32WB55CCU6 Mcu.Family=STM32WB Mcu.IP0=DMA Mcu.IP1=LPUART1 Mcu.IP2=NVIC Mcu.IP3=RCC Mcu.IP4=SYS Mcu.IP5=USART1 Mcu.IPNb=6 Mcu.Name=STM32WB55CCUx Mcu.Package=UFQFPN48 Mcu.Pin0=PA2 Mcu.Pin1=PA3 Mcu.Pin2=PA8 Mcu.Pin3=PA9 Mcu.Pin4=PA10 Mcu.Pin5=PA13 Mcu.Pin6=PA14 Mcu.PinsNb=7 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32WB55CCUx MxCube.Version=6.8.0 MxDb.Version=DB.6.0.80 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.DMA1_Channel1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DMA1_Channel2_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DMA1_Channel3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DMA1_Channel4_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.LPUART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false PA10.GPIOParameters=GPIO_Label PA10.GPIO_Label=USART1_RX PA10.Mode=Asynchronous PA10.Signal=USART1_RX PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO PA14.Mode=Serial_Wire PA14.Signal=SYS_JTCK-SWCLK PA2.GPIOParameters=GPIO_Label PA2.GPIO_Label=LPUART1_TX_DEBUG PA2.Mode=Asynchronous PA2.Signal=LPUART1_TX PA3.GPIOParameters=GPIO_Label PA3.GPIO_Label=LPUART1_RX_DEBUG PA3.Mode=Asynchronous PA3.Signal=LPUART1_RX PA8.GPIOParameters=GPIO_Label PA8.GPIO_Label=PIN_DEBUG PA8.Locked=true PA8.Signal=GPIO_Output PA9.GPIOParameters=GPIO_Label PA9.GPIO_Label=USART1_TX PA9.Mode=Asynchronous PA9.Signal=USART1_TX PCC.Ble.ConnectionInterval=1000.0 PCC.Ble.DataLength=6 PCC.Ble.IsUsed=false PCC.Ble.Mode=NOT_SELECTED PCC.Ble.PowerLevel=Min PCC.Zigbee.IsUsed=false PCC.Zigbee.Mode=Sleepy End Device PCC.Zigbee.Payload=15 PCC.Zigbee.PoolPeriodicity=480.0 PCC.Zigbee.PowerLevel=Min PCC.Zigbee.RequestPeriodicity=1500.0 PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=true ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32WB55CCUx ProjectManager.FirmwarePackage=STM32Cube FW_WB V1.16.0 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true ProjectManager.LastFirmware=true ProjectManager.LibraryCopy=1 ProjectManager.MainLocation=Core/Src ProjectManager.NoMain=false ProjectManager.PreviousToolchain=STM32CubeIDE ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=UART_problem_project.ioc ProjectManager.ProjectName=UART_problem_project ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=STM32CubeIDE ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_LPUART1_UART_Init-LPUART1-false-HAL-false RCC.ADCFreq_Value=128000000 RCC.AHBFreq_Value=32000000 RCC.APB1Freq_Value=32000000 RCC.APB1TimFreq_Value=32000000 RCC.APB2Freq_Value=32000000 RCC.APB2TimFreq_Value=32000000 RCC.APB3Freq_Value=16000000 RCC.Cortex2Freq_Value=32000000 RCC.CortexFreq_Value=32000000 RCC.FCLKCortexFreq_Value=32000000 RCC.FamilyName=M RCC.HCLK3Freq_Value=32000000 RCC.HCLKFreq_Value=32000000 RCC.HCLKRFFreq_Value=16000000 RCC.HSE_VALUE=32000000 RCC.HSI48_VALUE=48000000 RCC.HSI_VALUE=16000000 RCC.I2C1Freq_Value=32000000 RCC.I2C3Freq_Value=32000000 RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,Cortex2Freq_Value,CortexFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLK3Freq_Value,HCLKFreq_Value,HCLKRFFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MSIClockRange,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PWRFreq_Value,RFWKPFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SMPS1Freq_Value,SMPSCLockSelectionVirtual,SMPSFreq_Value,SYSCLKFreq_VALUE,USART1Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value RCC.LCDFreq_Value=32768 RCC.LPTIM1Freq_Value=32000000 RCC.LPTIM2Freq_Value=32000000 RCC.LPUART1Freq_Value=32000000 RCC.LSCOPinFreq_Value=32000 RCC.LSI_VALUE=32000 RCC.MCO1PinFreq_Value=32000000 RCC.MSIClockRange=RCC_MSIRANGE_10 RCC.PLLPoutputFreq_Value=128000000 RCC.PLLQoutputFreq_Value=128000000 RCC.PLLRCLKFreq_Value=128000000 RCC.PLLSAI1PoutputFreq_Value=128000000 RCC.PLLSAI1QoutputFreq_Value=128000000 RCC.PLLSAI1RoutputFreq_Value=128000000 RCC.PWRFreq_Value=32000000 RCC.RFWKPFreq_Value=31250 RCC.RNGFreq_Value=32000 RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE RCC.RTCFreq_Value=32768 RCC.SAI1Freq_Value=128000000 RCC.SMPS1Freq_Value=16000000 RCC.SMPSCLockSelectionVirtual=RCC_SMPSCLKSOURCE_MSI RCC.SMPSFreq_Value=8000000 RCC.SYSCLKFreq_VALUE=32000000 RCC.USART1Freq_Value=32000000 RCC.USBFreq_Value=128000000 RCC.VCOInputFreq_Value=32000000 RCC.VCOOutputFreq_Value=256000000 RCC.VCOSAI1OutputFreq_Value=256000000 USART1.BaudRate=38400 USART1.IPParameters=BaudRate,WordLength,Parity,VirtualMode-Asynchronous USART1.Parity=PARITY_EVEN USART1.VirtualMode-Asynchronous=VM_ASYNC USART1.WordLength=WORDLENGTH_9B board=custom isbadioc=false ```in main:
USER CODE 0
``` c /* USER CODE BEGIN 0 */ void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { // debug_pin_toggle(1); // printf( "Size= %i, rxEventType = %i\n\r", Size, (int)rxEventType); printf("Size= %i, RxEventType = ", Size); HAL_UART_RxEventTypeTypeDef rxEventType; rxEventType = HAL_UARTEx_GetRxEventType(huart); switch (rxEventType) { case HAL_UART_RXEVENT_IDLE: printf( "IDLE\n\r" ); printf( "\n\r" ); break; case HAL_UART_RXEVENT_HT: printf( "HT\n\r" ); break; case HAL_UART_RXEVENT_TC: printf( "TC\n\r" ); break; default: printf( "???\n\r" ); break; } } /* USER CODE END 0 */ ```USER CODE 2
``` c /* USER CODE BEGIN 2 */ #define RX_BUFFER_SIZE 8 static uint8_t rx_buffer[RX_BUFFER_SIZE]; HAL_StatusTypeDef halStatus = HAL_OK; halStatus = HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buffer, RX_BUFFER_SIZE); if ( halStatus != HAL_OK ) printf("ReceiveToIdle_error\n\r"); /* USER CODE END 2 */ ```How we can reproduce the problem:
There is no mistake. The HAL_UARTEx_RxEventCallback function is called 2 times: 1 time when filled 1/2 rx_buffer. HAL_UART_RXEVENT_HT 2 times that the package is finished. HAL_UART_RXEVENT_IDLE
There's a mistake. The HAL_UARTEx_RxEventCallback function is called 1 time. With the status HAL_UART_RXEVENT_TC.
Additional context perhaps this is not a bug, but a feature. But in the current code it is impossible to determine the end of reception if HAL_UART_RXEVENT_IDLE == HAL_UART_RXEVENT_TC.
the bug occurs around in this place. If you add to the condition
then everything will work in cyclic DMA mode. But the normal DMA mode will break.
Screenshots
half complete:
![half](https://github.com/STMicroelectronics/STM32CubeWB/assets/97605426/91cdace9-e27f-4b9f-9942-ccb26d82e8ee)full complete:
![full](https://github.com/STMicroelectronics/STM32CubeWB/assets/97605426/a46aaa55-cac0-45d7-816a-05a13e385bf8)