I'm trying to implement simple echo for UART on stm32f4 discovery board (using freertos). As far as I understand it should be very easy.
First I call HAL_UART_Receive_IT(&huart3, &rx_char,1) in a task. And after receiving an interrupt USART3_IRQHandler should trigger. And then in HAL_UART_RxCpltCallback I'll do HAL_UART_Transmit(&huart3, &rx_char, 1, timeout) and maybe re-enable it with HAL_UART_Receive_IT. Did I get the idea right? Should it work?
But in my case it doesn't. I'm trying to send a char from the terminal, but USART3_IRQHandler is never triggered. Nothing happens.
The code was generated using Stm32CubeMX with Freertos, USART3, NVIC and with USART3 global interrupt enabled.
Also I call __HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE) in main function.
What is wrong? HAL_UART_Transmit works perfectly.
HAL isn't ideal library. You must check registers, if something went wrong.
Your problem is looking like non-working NVIC. Check it, and if it wasn't turning on use something like - NVIC_EnableIRQ(USART3_IRQn);
Or may be wasn't switch on RE register in CR1 in USART3.
Anyway, I'm repeating - check registers.
Related
We want our device (STM32-F446RE running FreeRTOS + Telit ME310G1 modem) to communicate to the AWS cloud. We are trying to follow the Cellular Interface Library Demo, in particular following this- diagram
We are using coreMQTT Agent, MbedTLS libraries, the amazon communication interface implementation for UART and amazon UART API implementation.
UART using 115200 baud rate.
Currently failing on the Cellular_Init function when trying to send the first AT command to the modem, specifically when calling the HAL_UART_TRANSMIT_IT function from the above comm interface send function. While debugging we see that the USART1_IRQHandler is called infinite times and nothing is sent through the UART communication.
We are using the default handler, do we need to implement it in any way?
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
Any help will be appreciated.
Thanks in advance,
Guy
Sounds like the UART line from HW point of view are not in a good state (High).
Did you check and ensure that the Power On sequence is done correctly? (Power On telit pin shall be high).
I expect you have some logic to translate the 1.8v to 3.3v and vice versa.
Can you check by measuring the different voltage that everything is OK?
If you verified all the point above.
Do you perform a reset on the telit side before starting the AT communication?
This ensure that you don't leave the module into a data mode where no AT commande are possible
Yacine
I'm trying to start a DMA transfer on my stm32f412, and I've got everything set up to the point where I'm setting the control registers on the DMA channels/streams for TX and RX. I am able to set the enable (Bit 0) on the TX, but not the RX.
The datasheet has 3 options for the bit being cleared by hardware: 1.) On a DMA end of transfer (stream ready to be configured) 2.) If a transfer error occurs on the AHB master buses 3.) When the FIFO threshold on memory AHB port is not compatible with the size of the burst.
I don't think it could be the first or the third, because the DMA transfer hasn't even started yet, and there isn't a burst configured, it's just a single transfer. I'm not quite certain what the second means, but there aren't transfer errors marked in the error registers.
Any avenues to look into would be appreciated
Edit: Ugh, I was looking at the wrong registers for to find the DMA_LISR and _HISR. There was a transfer error on my RX channel.
From the description of DMA_SxCR_EN bit in the reference manual:
Note: Before setting EN bit to '1' to start a new transfer, the event flags corresponding to the
stream in DMA_LISR or DMA_HISR register must be cleared.
In my experience, these event flags include not only the error flags, but also the regular event flags like Transfer Complete or Half Transfer. In some cases, I also ended up clearing FIFO error flag, although I can't remember the reason behind it.
This problem manifests itself as "DMA works only once". In your case, it doesn't work even once, so there can be other problems. Still, I think it's worth trying to clear all the status flags before enabling the stream.
I am working on STM32L152VB-A controller. I am using FreeRTOS.
I used CubeMX to generate the code and I configured USART1 with global interrupts.
The non interrupt RX and TX (HAL_UART_Receive and HAL_UART_Transmit) is working.
But I am trying to make it work with interrupts.
Only after I called HAL_UART_Receive_IT, I am getting interrupt.
Since I couldn't know the receive data size, I am planning to receive characters one by one.
Since I use RTOS, I am confused about where to write HAL_UART_Receive_IT, as the message can come at any time. can anybody guide me??
PS: I tried calling the HAL_UART_Receive_IT inside ISR, but it is also not working.
I think you're confusing HAL_UART_Receive_IT with a function which actually receives anything. This is not the case. This function merely enables the UART peripheral and its receive interrupt.
If you want to stick with the HAL library you need to pass a struct of type UART_HandleTypeDef as parameter to HAL_UART_Receive_IT which contains
a uint8_t* pointer to a receive buffer
a transfer counter for the number of elements you'd like to receive
As far as I know there is no way for receiving elements indefinitely with this framework because once the transfer counter reaches zero the receive interrupt gets disabled automatically. So if you need this you're probably better of writing the ISR yourself by overwriting the weak function defined by ST (most likely called "UARTx_IRQHandler").
To finally integrate the receive interrupt in FreeRTOS you've got two options:
Receive data inside the ISR into a raw (uint8_t*) buffer like HAL does and use a critical section which temporarily disables the receive interrupt when accessing it.
Receive data inside the ISR into a FreeRTOS queue using the interrupt safe API. The official FreeRTOS book chapter 6 explains this very well.
I created the following task (consider a high priority):
void UARTReceiveTask(void const * argument)
{
/* USER CODE BEGIN UARTReceiveTask */
/* Infinite loop */
for(;;)
{
osSemaphoreWait(BinarySemaphoreUARTHandle, osWaitForever);
HAL_UART_Receive_IT(&huart3, message_received, 2);
}
/* USER CODE END UARTReceiveTask */
}
Then, if you are using HAL, you must know that HAL_UART_RxCpltCallback() is executed on the UART ISR, so I wrote:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
if (huart->Instance == USART3){
osSemaphoreRelease(BinarySemaphoreUARTHandle);
}
}
I only followed the tips on the "Mastering the FreeRTOS" document (Chapter 6) to deferr interrupts to tasks.
I haven´t dug deep into it, but I know this info is important if you are working with FreeRTOS and Arm Cortex systems.
Hope I helped!
I'm working on a project with a STM32L4 micro-controller configured for USB and cannot seem to get the USB interrupt to trigger on disconnect. I set everything up using the STM32Cube utility and have tested a similar implementation on a EVAL board I received with a chip from the same family and that one works fine but for some reason on my actual board I can't seem to replicate the expected behavior. I will trigger the interrupt when I first connect the device, and it has settings to handle when a device is disconnected but that portion never gets triggered.
Has anyone dealt with something similar and may be able to point me in the right direction of what to look into?
I am having trouble running the debugger on a STM32F205ZG using µVision4 and the ULINK2. I keep getting the error message "Could not stop Cortex-M device! Please check the JTAG cable." I am using the SW port. Any help with this would be greatly appreciated.
In my own experience I have usually seen this error when either the ULINK2 is disconnected and reconnected while in the middle of a debug session or if you have some external hardware, outside of the control of the debugger, that is acting on your processor.
If the ULINK2 was disconnected mid-debug, then usually cycling power to your device will fix the problem.
If you have something like a watchdog timer that is trying to reset the processor while you are in the middle of debugging, then you will have to disable the watchdog before you can start a debug session.
I've seen the same problem with my NXP uC.
The problem was that the code loaded in flash was faulty and was placing the CPU into a busy loop branching back to the same address, this prevented the debugger accessing the bus.
the uLink worked if I put the device into ISP mode as it never got to the user code.
it seems that uLink takes too long to halt the device after reset, the spec tells you this somewhere, so by the time uLink tries to halt the CPU it is too late as it cannot access the bus and locks up.
I had this problem on LPC4337. I tried all the solutions people are talking about but the only one that worked for me was using a lower processor clock so that JTAG/SWD interface can match/catch up with the processor before it is gone too far into executing user code. In my case I set JTAG/SWD clock in Keil uVision 5 to 10MHz and the changes the processor clock divisors to give 36MHz. With these settings, it never missed to capture on reset when I begin a debug session.
This happens for ULink2 but ULINK Pro and ULINK Pro-D support a JTAG/SWD <= 50MHz. See this link for more comparisons:
ulink comparisons
Just an other issue with this message:
We have the same error message, but the problem was the wrong state of the RESET line.