cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H5 DMA (GPDMA), why is USART using a "node"? Intent?

MBC
Associate III

 

I'm trying to set up a DMA transfer from UART1 periheral to memory. Using LL drivers. Using STM32Cube for "convenient" setup. It puts the all the USART peripheral init in usart.c. Where for GPDMA it does something like:

 

 

 

 /* GPDMA1_REQUEST_USART1_RX Init */
  NodeConfig.DestAllocatedPort = LL_DMA_DEST_ALLOCATED_PORT0;
  NodeConfig.DestHWordExchange = LL_DMA_DEST_HALFWORD_PRESERVE;
  NodeConfig.DestByteExchange = LL_DMA_DEST_BYTE_PRESERVE;
  NodeConfig.DestBurstLength = 1;
  NodeConfig.DestIncMode = LL_DMA_DEST_INCREMENT;
  NodeConfig.DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE;
  NodeConfig.SrcAllocatedPort = LL_DMA_SRC_ALLOCATED_PORT0;
  NodeConfig.SrcByteExchange = LL_DMA_SRC_BYTE_PRESERVE;
  NodeConfig.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD;
  NodeConfig.SrcBurstLength = 1;
  NodeConfig.SrcIncMode = LL_DMA_SRC_FIXED;
  NodeConfig.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE;
  NodeConfig.TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER;
  NodeConfig.Mode = LL_DMA_NORMAL;
  NodeConfig.TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED;
  NodeConfig.BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST;
  NodeConfig.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  NodeConfig.Request = LL_GPDMA1_REQUEST_USART1_RX;
  NodeConfig.Mode = LL_DMA_NORMAL;
  NodeConfig.UpdateRegisters = (LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CTR3 | LL_DMA_UPDATE_CBR2 | LL_DMA_UPDATE_CLLR);
  NodeConfig.NodeType = LL_DMA_GPDMA_LINEAR_NODE;
  LL_DMA_CreateLinkNode(&NodeConfig, &Node_GPDMA1_Channel0);

  LL_DMA_ConnectLinkNode(&Node_GPDMA1_Channel0, LL_DMA_CLLR_OFFSET5, &Node_GPDMA1_Channel0, LL_DMA_CLLR_OFFSET5);

 

 

 

1. Ok... WHY!? I don't understand why Cube decided to make a node for this. It's not part of the linked list feature in Cube. It seems to me, as a guess, that this peripheral uses a single instance of the same linked list format when receiving to an arbitrary buffer instead of its dedicated FIFO. Is that right?

2. I could accept that, except there seems to be no opportunity or good time to add my source address, destination address, and block size (buffer size). These are members at:

 

 

    DMA_InitStruct.DestAddress = LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_TRANSMIT);
    /* Default settings - updated prior start of transmission */
    DMA_InitStruct.SrcAddress = 0x00000000U;
    DMA_InitStruct.BlkDataLength = 0x00000000U;

 

 

Do not exist in the Cube definition. What is the intent on when/where/how to set these? This is in the non-user section of the generated file. I can set them outside of the linked list with functions like `LL_DMA_SetBlkDataLength()`, but that seems incorrect as it isn't using the node/list item. Am I intended to set these were I need them with something like:

 

 

  LL_DMA_InitNodeTypeDef NodeConfig = {0};


      DMA_InitStruct.DestAddress = LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_TRANSMIT);
    DMA_InitStruct.SrcAddress = 0x00000000U;
    DMA_InitStruct.BlkDataLength = 0x00000000U;

// Only update those three?
  NodeConfig.UpdateRegisters = (LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | LL_DMA_UPDATE_CDAR);

  LL_DMA_CreateLinkNode(&NodeConfig, &Node_GPDMA1_Channel0);

 

 

 

Where I've set the Node once in generated, and partially again later in my code?

3. Once I set the linked list as in #2.. It seems that I do/can use `LL_DMA_SetSrcAddress()` for my memory/buffer. So I guess I could just use those more simple set functions that do not seem to be in the list. It isn't clear when the source/dest/size is going to be pulled from the one-item list, and when it'll be used from the register I set direction. This seems very complicated, I'm sure there is a reason. But any explanation would be helpful.

 

Thanks

0 REPLIES 0