Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


UART Character Match Interrupt

Hello the community !

I am developping a GPS driver based on a UART communication. I want to use the Character Match Interrupt to detect the ‘$’ at the beginning of each line sent by the GPS module.

I am using a STM32L4 and the cube version 1.4.

In the file stm32l4xx_hal_uart.h I see that there are the flags and all the stuff to enable / disable / get the IT but even if I do so, where do I have to put the character I want to match ??

I missed something...

In advance, thank you !

Romain

Tunisia
Romain, the character should be placed in USARTx_CR bits 31:24 = ADD as indicated in the reference manual ;)

Thank you Terek! I managed to get the interruption!

However, I still have one problem. When the program handles a first interruption, it doesn’t handle following ones...

I added the following lines :

In main.c before the while(1):

_ _HAL_UART_ENABLE_IT(&huart1, UART_IT_CM);

In stm32l4xx_it.c in USART1_IRQHandler :

if(_ _HAL_UART_GET_IT(&huart1, UART_IT_CM)) {
_ _HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_CMF);
}
HAL_UART_IRQHandler(&huart1);

When I delete the CLEAR_FLAG line, the interrupt is continuously handled, of course.

Sorry I am not that comfortable with the registers and the interruptions...



Hi...i am a new user here. By profession i am a hardware design engineer. I worked on STM32 and as per my experince you should refer to the user manual for your problem. If you can share your code here then share it so that i could review it and try to identify the problem. Also share the your hardware setup and specifications of all components connected.

assembly circuitQuestion

You should refer to the user manual for your problem.



hdi pcbQuestion


I can offer some general suggestions although I don’t have a direct answer or resolution for your specific problem.

Bear in mind that I am not very familiar with the ST-provided HAL (my preference is to access peripheral registers directly using their CMSIS names and symbols); some of what I say here might need to be done a bit differently if you’re going to work through the HAL.

The general requirements to get an interrupt working for any STM32 peripheral are:

Set the interrupt-source-enable bit(s) in the configuration or interrupt-enable register(s) associated with the peripheral you are working with. It looks like you’ve done this.

Call NVIC_SetPriority(irq_number, priority) and NVIC_EnableIRQ(irq_number) to allow the core to process interrupt(s) from the peripheral in question. Figuring out what (irq_number) to use can be a bit difficult; I usually refer the the (startup_stm32xxxx.s) asm source file for this, and the CMSIS header file(s) for the specific target in use to find it. This step may already be getting done somewhere (maybe inside the HAL code) since you stated that you were able to get one character match interrupt.

You need to create a function that will serve as the interrupt handler (ISR) that is appropriately named; you can get some idea of what the name should be by looking at the interrupt vector table declaration in the system_stm32xxxx.s file. The asm .s file declares ‘weak’ stubs all of the STM32’s interrupts; you need to create a function with the same name in your own source to override (replace) the weak definition in the startup code.

Now, what I’d do next - and not sure how much the HAL does for you in this regard - would be to set the character match interrupt enable bit, and inside the ISR, after recognizing that a CM interrupt, I’d turn on the receive-not-empty interrupt enable, and process all data coming in after the match character until end-of-message (whatever that may be) is detected, then turn off the RXNE interrupt and set CME.

Another general rule of thumb for dealing with interrupts with the STM32: All of the peripherals I’ve worked with (which is quite a few, but certainly not all) usually have some sort of interrupt identification or interrupt flag register associated with them - this is the register you look at to determine which peripheral event(s) caused the interrupt to occur. It is absolutely necessary to get the flag(s) associated with the event(s) that are interrupt-enabled cleared before exiting the ISR. Conditions for clearing these flag(s) will vary. Oftentimes (but certainly not always), the flag is cleared by writing 1’s to the interrupt status register or the interrupt clear register (USARTx->ICR = USART_ICR_CMF in this specific case). You’ll have to look at the reference manual for specifics. Failing to clear the interrupt flag will result in the ISR being re-entered immediately after ISR exit.


Thanks MSchultz for the detailed response. That really helped me in getting the line break detection interrupt working properly. I was in the same situation as the original poster and was pulling my hair out.

Below are the interrupt handler and line break detection callback that worked for me. It was a little bit of a pain clearing all the flags plus reading from the ISR register so that the ISR would not re-enter. One thing I was not clear on is that there seems to be a distinction between status flags and interrupt flags. There seem to be a difference between the two.

/**
* Brief This function handles USARTx Instance interrupt request.
* Param None
* Retval None
*/
void USARTx_IRQHandler(void)
{
if ((LL_USART_IsActiveFlag_FE(USARTx_INSTANCE) || LL_USART_IsActiveFlag_LBD(USARTx_INSTANCE))
&& LL_USART_IsEnabledIT_LBD(USARTx_INSTANCE)
&& LL_USART_IsEnabledLIN(USARTx_INSTANCE)) {

/* Toss Receive Data */
LL_USART_ReceiveData8(USARTx_INSTANCE);
/* Clear ORE (Overrun Error) Flag */
LL_USART_ClearFlag_ORE(USARTx_INSTANCE);
/* Clear EOB (End of Block) Flag */
LL_USART_ClearFlag_EOB(USARTx_INSTANCE);
/* Clear FE (Frame Error) Flag */
LL_USART_ClearFlag_FE(USARTx_INSTANCE);

/* LBD flag will be cleared after reading of ISR register (done in call) */
/* Call function in charge of handling Character reception */
USART_LineBreak_Callback();
}

/**
* @brief Function called from USART IRQ Handler when LBD flag is set
* Function is in charge of reading line break received on USART RX line.
* @param None
* @retval None
*/
void USART_LineBreak_Callback(void)
{
__IO uint32_t isr_reg;

isr_reg = LL_USART_ReadReg(USARTx_INSTANCE, ISR);
if (isr_reg & LL_USART_ISR_LBDF) {
/* Toggle LED */
LL_GPIO_TogglePin(LED4_GPIO_PORT, LED4_PIN);

/* Clear LBD Flag */
LL_USART_ClearFlag_LBD(USARTx_INSTANCE);
}
}

All the code was based on this example:
https://github.com/STMicroelectronics/STM32CubeG0/tree/master/Projects/NUCLEO-G071RB/Examples_LL/USART/USART_Communication_Rx_ITQuestion