Posted on January 09, 2018 at 17:38The original post was too long to process during our migration. Please click on the attachment to read the original post.
This looks to be a blog post rather than a question ?
A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Not sure on this because I couldn't find any place where well documented issues could be easily submitted to the HAL/CUBE development teams. The main issue is getting around incomplete and problematic library implementations of which I've found a few.
Wouldn't it be better if the HAL drivers were evolved to properly handle the modalities needed for everyday work for instance:
a. block transfer IS NOT the expected normal historical use form of a UART/USART async serial port. The standard normal historical form of an aysnc port once configured supports continuous asynchronous stream flow in both directions until disabled. The per character interrupt call back supports this. The supported buffering allows both fifo and block burst transfers without compromising the sleep modes of the processor. My conclusion that this missing functionality should be a normal UART/USART option for the driver with its own predictable call back functionality. Please note that the tweak/fix of this post was implemented only for the L4 processors though it applies to all STM32 versions. A general update would correct the libraries for all STM32 models.
b. On a related missing functionality, the USB CDC driver lacks a transmit complete callback (eg peripheral to host direction). This forces polling of the txStatus which prevents the proper handling of interrupt transfers from a transmit queue. This missing functionality should be added to all relevant STM32 HAL library implementations.
c. I have be unable to locate a callback when USB Charger determination functionality is enabled on the STM32L series processors. The lack of this prevents us from adapting our charging circuitry for normal vs high rate charging.
Perhaps this entire reply should be moved into the forum as a question.
I have to totally agree. The key factor here is the ability the application programmer to implement a specific processing behavior to underlying and correct device drivers and their ISR's by instantiating the appropriate __weak attributed callbacks. This assures that the base driver operates in a predictable manner in the unextended mode. Further the behavior of drivers from the perspective of the application programmer should be consistent (ie transfer completion vs intermediate data ready) .
Overall I cannot fault the theory and base implementation of CubeMX's fundamental approach. The driver faults, as you've noted are basically incomplete implementations based on failure to properly consider the normal use cases. Additional faults are related to the libraries not implementing a clean mutex atomic HAL locking function.at the driver level that can be used with or without the RTOS.
Thanks Kent & Clive. I've run into the same issue trying to get a quick development head start using the sample programs as a starting point. (The I2C sample is the same in that it transfers fixed size blocks back and forth.) Now, I'm starting to work on implementing a serial handler and came upon your post. The sample I've started with is the UART_TwoBoards_ComDMA example for the STM32F722ZE Nucleo board which has the fixed size limitations.
I have a fairly tight main loop in my application and I'm wondering how difficult it would be to manually check the UART handle's RX status every time N times around the loop and simply transfer whatever bytes that are in the RX buffer into my own ring buffer for processing after a full command is received. Simplistically speaking, I'd like to start the UART receive when the system comes up and never terminate or touch it, except to pull received characters from it. The sample code's transmit function works fine for me since I'll have a package of known size to send.
Any thoughts or pointers? Also, your method may work for what I need. I need to study it a bit more before making a decision on what way to proceed.
Could this receive stream to a ring buffer work in together with the TransmitDMA_IT call? The sample UART code calls to reinitialize the UART handle before and after each packet send/receive? My suspicion is that I’d need to handle the TX character by character manually in the main loop as well as the RX taking this approach, right?
I've also run into this as well. The modifications you talk about in your More Stable Tweak are undesirable to me because they'll affect any other projects I create from those reference files. But I just discovered that the stm32f7xx_it.c file generated in my project by STM32CubeMX contains the IRQHandler functions, and in them are user code sections:
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}�?�?�?�?�?�?�?�?�?�?
This opens up the possibility of creating a streaming version of the HAL driver by writing my own ISR functions and completely bypassing the HAL driver's ISR function. If I get any success with that I'll update here.
I think you've forgotten to mention that in HAL_UART_Receive_IT() you need to take out the (Size == 0U) check in the 2nd if statement, as you use RxXferCount to index the buffer, wheras the original function incremented the buffer pointer and decrements RxXferCount. It might also be worth mentioning that when you call HAL_UART_Receive_IT it must be with size=0.
Apart from those things catching me out a bit your implementation worked perfectly!
Thanks for the feedback. Glad that I could help out but it still annoys me when a common modality is not selectable with the generative IDE's. Oh well. My major stm32 tasking at the moment is multiple i2S channels running DMA and fully synchronized with in and out audio streams with some simple DSP processes. on the queued packet buffers internally.
Thanks! Stream UART code looks very useful. Could you please clarify one more thing? If I understood correctly, this approach requires special actions to close receive stream before transmitting data? Like in UART_RxISR_8BIT:
/* Disable the UART Parity Error Interrupt and RXNE interrupts */
The various root libraries for the different mainline processor series have fairly similar standard peripheral silicon. Don't get me wrong, the evolution of processors and their capabilities mandate that changes will occur but within a processor series the changes are much less traumatic relative to the library code. That being said, the need to implement high level api peripheral compatibility makes the underlying libraries similar. This means that you could implement the changes in the current F libraries by following the guidelines that I detailed in the post and attached pdf. In actual fact the changes to the libraries themselves are rather minimal and the rest of the non library dispatch and callback code should remain mostly the same. It would be nicer if ST had implemented streaming interrupt uart drivers as a simple mode option like they have with the other methods of operation but, at this writing they haven't. I hope this helps.