cancel
Showing results for 
Search instead for 
Did you mean: 

STM32-MAT-TARGET: Simultaneous reception on two different UARTs

RomanMH
Associate II

Hello!

I'm experiencing difficulties using STM32-MAT-TARGET to generate code for STM32 controllers from Simulink models using the provided blocks for USART communication.

I'm using this setup:

  • Nucleo-F401RE
  • USART1 and USART6 with interrupt enabled
  • EXTI1 and EXTI13 for use with software interrupt

The following pictures show my Simulink model:

0690X000006BzNRQA0.png0690X000006BzNWQA0.png0690X000006BzNbQAK.png

Unfortunately, the program only does half the job. I observe that only one USART is actually receiving anything. The other just doesn't respond when I send it a byte. Either USART works if I have just one of them in my model. But with both USARTS in my model, one will work, the other won't. It seems to be whichever USART happens to get put into receptin mode first, will be the one that's working.

Can anyone help me with a solution to this problem? Is my setup correct? Does STM32-MAT-TARGET support this kind of operation?

Best regards

Roman

11 REPLIES 11
T J
Lead

there must be a selection for using DMA circular buffer .

that is the most robust method for Uarts Rx.

did you use the cube ?

T J
Lead

I enable the circular Rx

void initUart1RxDMABuffer(void) {
    if (HAL_UART_Receive_DMA(&huart2, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK)
    {
        // Transfer error in reception process 
        //_Error_Handler(__FILE__, __LINE__);
        //char string[32];
        sprintf(string, "initUart1RxDMABuffer Failed\n");
        puts1(string);        
    }
    else
    {
        //char string[32];
        sprintf(string, "initUart1RxDMABuffer OK!\n");
        puts1(string);
    }
}

DMA and the Rx interrupts, in the cube

RomanMH
Associate II

I have to use Cube configuration and then use the code generation from within Simulink. The process is automatic and I cannot edit the code manually.

T J
Lead

in the cube, add the 'circular' DMA function to Rx and enable the Uart Rx Interrupt

I use a 'normal' DMA buffer for Tx.

RomanMH
Associate II

Thank you for the suggestion. I tried it with DMA mode.

0690X000006BzQ1QAK.png

This time I get no response at all.

T J
Lead

not sure if it will help but you don't need high priority interrupts for serial ports.

you did make sure the Uart interrupt was left enabled ?

then I run this code to make it work:

void initUart1RxDMABuffer(void) {
    if (HAL_UART_Receive_DMA(&huart7, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK)
    {
        // Transfer error in reception process 
        //_Error_Handler(__FILE__, __LINE__);
        sprintf(string, "initUart1RxDMABuffer Failed\n");
        puts1(string);        
    }
    else
    {
        //char string[32];
        sprintf(string, "initUart1RxDMABuffer OK!\n");
        puts1(string);
    }
}

did you look in the DMA buffer ?

int U1RxBufferPtrOUT =0;
 
char readableU1(void) {
    U1RxBufferPtrIN =  U1RxBufSize - __HAL_DMA_GET_COUNTER(huart7.hdmarx);       
    return U1RxBufferPtrIN - U1RxBufferPtrOUT;
}

RomanMH
Associate II

I tried it again with low priority for the DMA channels. That didn't make a difference.

I checked and verified that the UART interrupt is enabled.

I'm generating code with Simulink (slbuild) and compile it with gmake. It's an automated process. I don't know how to use the code you show with that. I cannot debug that code.

Should I post the code that Simulink generated?

T J
Lead

If you couldn't run the init code, the DMAs are not running.

So turn off the DMAs, are you getting the interrupts ?

save the U1 byte in a U1 buffer under interrupt.

save the U6 byte in a U6 buffer under interrupt.

I'm not sure if anyone here can support Simulink, do they have a forum ?

can you let us know the fix ?

RomanMH
Associate II

I discovered something new:

I use this minimal example for testing purposes:

0690X000006BzSlQAK.png0690X000006BzSqQAK.png

This generally works. Though it doesn't work anymore when I enable the USART1 (the other USART I enabled in Cube but do not use here) interrupt.

So the issue is having two USART interrupts enabled at the same time.