cancel
Showing results for 
Search instead for 
Did you mean: 

SMTM32F767XXX - USART3 and UART7 share the same DMA streams, but different Chanell, ¿How can I change the DMA Stream Chanell on run time?

J80.1
Associate II

Hi,

I'm using STM32F767NGHXX for a project. It is mandatory for me to use USART3 and UART7. I want to use both uarts with DMA transmissions but this 2 uarts use the same DMA Streams. Other option could be use one with DMA and the other use normal UART Functions. The problem is that one of the requirements for this project is to use as less blocking functions as possible, so DMA functions are better in this case as long as they use less the micro.

Therefore I'm trying to deInit both UARTs + DMA and reInit them with or without DMA config (depending on which UART needs to transmit, it will be using the DMA that time), but I'm not able to make it working. Once I link one Uart to the DMA at the beginning of my code, it would be the only one that I could use with DMA. (Once the Chanell is selected for a DMA Stream, it seems to not be possible to Change)

Know anyone how to make this change in the Selected Chanell in the DMA Stream)?

Or Is it impossible and have I to use one UART with DMA and the other one with normal (IT) UART Functions)?

1 ACCEPTED SOLUTION

Accepted Solutions

I don't use Cube and I am not even trying to understand problems which may stem from Cube usage.

I also recommend you not to use Cube whenever you try to do something other than what CubeMX enables to click. Cube is designed to support "usual" usage cases, if you do anything out of "ordinary" Cube may or may not get into your way.

Using USART and DMA directly through registers is not that complicated.

> I mean, i have test that the DMA registers are being written correctly but it seems to be not possible to change.

As I've said above, changing channel is possible if given stream is not active, i.e. when DMAx_SxCR.EN=0, and you should know from context that this is the case - re-read my post above, and read the DMA chapter in RM.

JW

View solution in original post

7 REPLIES 7

Do you use only Tx for given UARTs, or both Rx and Tx? Do you use both Rx and Tx of an UART at the same time (full-duplex), or first you Tx and then Rx (half-duplex)? I am asking, because while both UARTs use the same two DMA streams (although USART3_Tx is present on an additional channel, too), they are swapped, i.e. on one stream one UART has Tx but the other Rx:

0693W00000Uo3yYQAR.png 

It is of course possible to change DMA channel in a stream, i.e. to rewrite DMAx_SxCR.CHSEL field. The precondition is, that this stream is disabled, i.e. DMAx_SxCR.EN=0 (which is either by "normal" Transfer Complete in a non-circular stream, or after performing the procedure described in DMA transfer suspension subchapter).

Your problem may be, that you are probably using Cube/HAL, and its functions may not support changing channel of a stream straightforwardly, as it is not something which is usually done or clicked in CubeMX. I don't use Cube/HAL so can't help with that part, but using DMA through registers is not that complicated.

JW

J80.1
Associate II

Hi,

I use both, Tx and Rx. The problem with the USART3_TX on Stream 4, is that this stream is also busy with another peripheral.

The process I'm following is the next one:

1) First at all i Init UART7 with DMA (the FLAG condition is set to 0 at beginning so it go through the dma initialization) and UART3 without it (DMA will only initialized if a FLAG is set).

2) When I achieve a certain condition I set a FLAG to 1. Then these steps:

  • DeInit both UARTs including the DMA. (Calling the HAL functions of DeInit_UART (.....))
  • Init both UARTS (MX_UART_INIT) with the FLAG set to 1, so UART 7 would not initialized with DMA but USART3 will do it.

As long i understood in the RM of the STM32F767XXXX and I can see in the different functions, all the registers modifications are made in this func. Despite the fact, when I made the Swap (FLAG = 1), UART 3 doesn't work (during this time UART 7 is working without DMA properly). After a while, i make another swap (FLAG = 0) to work in the normal situation, and the UART 7 works properly with DMA.

I know that the "best" solution would use the USART3 using IT functions, due not to have many processor use (I have already tested it in this way) but when FLAG is set to 1, the quantity of messages is very high, so the Interruptions disturb sometimes another criticals operations. Due to this fact, i wanna try make a dinamical change of the Stream Chanell.

Did I explain the problem / process i need to solve?

Hi,

I use both, Tx and Rx. The problem with the USART3_TX on Stream 4, is that this stream is also busy with another peripheral.

The process I'm following is the next one:

1) First at all i Init UART7 with DMA (the FLAG condition is set to 0 at beginning so it go through the dma initialization) and UART3 without it (DMA will only initialized if a FLAG is set).

2) When I achieve a certain condition I set a FLAG to 1. Then these steps:

  • DeInit both UARTs including the DMA. (Calling the HAL functions of DeInit_UART (.....))
  • Init both UARTS (MX_UART_INIT) with the FLAG set to 1, so UART 7 would not initialized with DMA but USART3 will do it.

As long i understood in the RM of the STM32F767XXXX and I can see in the different functions, all the registers modifications are made in this func. Despite the fact, when I made the Swap (FLAG = 1), UART 3 doesn't work (during this time UART 7 is working without DMA properly). After a while, i make another swap (FLAG = 0) to work in the normal situation, and the UART 7 works properly with DMA.

I know that the "best" solution would use the USART3 using IT functions, due not to have many processor use (I have already tested it in this way) but when FLAG is set to 1, the quantity of messages is very high, so the Interruptions disturb sometimes another criticals operations. Due to this fact, i wanna try make a dinamical change of the Stream Chanell.

Did I explain the problem / process i need to solve?

>... UART 7 would not initialized with DMA but USART3 will do it ... UART 3 doesn't work

Try starting application in this state, i.e. with USART3 using DMA. Does it work? If yes, read out the USART3 and relevant DMA registers content (note, that reading out USART registers (namely the Rx data register and partially also the status register), either in debugger or in program, while in operation will disturb its operation, but for an experiment it does not matter), and compare them to content of UART and DMA registers in the original case, when it does not work.

JW

Hello,

Before I had to start using also UART7, USART3 was working with DMA in a properly way. As soon as i needed UART7 (already defined but not used until then), i had to change the .ioc to set the DMA to the UART7 as the main UART with the DMA in a normal operation.

I have been debugging during normal operation de registers of hdma_uart7_tx (& rx) and the same for usart3 dma. Theese are the "conclussions" i made:

  • UART7 init ok with DMA and USART3 without DMA init ok (all the registers ok, if set, they were set and if null, they were set to null)

  • When FLAG is set to 1 the registers of the DMA in the DMA of USART3 are modify correctly but the parameters hdma_uart7_tx/rx are changed to the same values of the DMA of USART3. It seems to that this DMA variables are not deslinked. USART3 does not work with DMA.

  • Last case, FLAG is set to 0 the parameters of the UART7 DMA are changed correctly, but the USART3 has the same problem as the UART7 before, its values are the same as the UART7 instead of being null (remember than when FLAG is 0, it is to returning to a normal operation with the DMA streams for the UART7). --> here UART7 work with DMA in a proper way.

These problems in the operation mode change are normal? As long as I understand, USART3 should work with DMA due to the fact all the register are changed correctly.

J80.1
Associate II

Other doubt, This swap in the DMA Channel is possible? Or it can be that the DMA system is not prepared to be changed?

I mean, i have test that the DMA registers are being written correctly but it seems to be not possible to change.

I don't use Cube and I am not even trying to understand problems which may stem from Cube usage.

I also recommend you not to use Cube whenever you try to do something other than what CubeMX enables to click. Cube is designed to support "usual" usage cases, if you do anything out of "ordinary" Cube may or may not get into your way.

Using USART and DMA directly through registers is not that complicated.

> I mean, i have test that the DMA registers are being written correctly but it seems to be not possible to change.

As I've said above, changing channel is possible if given stream is not active, i.e. when DMAx_SxCR.EN=0, and you should know from context that this is the case - re-read my post above, and read the DMA chapter in RM.

JW