关于这个循环里面模式,要特别注意一点
他不是从节点0开始循环的,是从节点1开始循环的,如节点1,节点2,节点3组成一个循环
而节点0是初始配置,在用户调用了HAL_MDMA_Start_IT后仅执行一次。
/**
* @brief Connect a node to the linked list.
* @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
* the configuration information for the specified MDMA Channel.
* @param pNewNode : Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node
* to be add to the list.
* @param pPrevNode : Pointer to the new node position in the linked list or zero to insert the new node
* at the end of the list
*
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MDMA_LinkedList_AddNode(MDMA_HandleTypeDef *hmdma, MDMA_LinkNodeTypeDef *pNewNode, MDMA_LinkNodeTypeDef *pPrevNode)
{
MDMA_LinkNodeTypeDef *pNode = 0;
uint32_t counter = 0, nodeInserted = 0;
HAL_StatusTypeDef hal_status = HAL_OK;
/* Check the MDMA peripheral handle */
if((hmdma == NULL) || (pNewNode == NULL))
{
return HAL_ERROR;
}
/* Process locked */
__HAL_LOCK(hmdma);
if(HAL_MDMA_STATE_READY == hmdma->State)
{
/* Change MDMA peripheral state */
hmdma->State = HAL_MDMA_STATE_BUSY;
/* Check if this is the first node (after the Inititlization node) */
if((uint32_t)hmdma->FirstLinkedListNodeAddress == 0)
{
if(pPrevNode == NULL)
{
/* if this is the first node after the initialization
connect this node to the node 0 by updating
the MDMA channel CLAR register to this node address */
hmdma->Instance->CLAR = (uint32_t)pNewNode;
/* Set the MDMA handle First linked List node*/
hmdma->FirstLinkedListNodeAddress = pNewNode;
/*reset New node link */
pNewNode->CLAR = 0;
/* Update the Handle last node address */
hmdma->LastLinkedListNodeAddress = pNewNode;
hmdma->LinkedListNodeCounter = 1;
}
else
{
hal_status = HAL_ERROR;
}
}
else if(hmdma->FirstLinkedListNodeAddress != pNewNode)
{
/* Check if the node to insert already exists*/
pNode = hmdma->FirstLinkedListNodeAddress;
while((counter < hmdma->LinkedListNodeCounter) && (hal_status == HAL_OK))
{
if(pNode->CLAR == (uint32_t)pNewNode)
{
hal_status = HAL_ERROR; /* error this node already exist in the linked list and it is not first node */
}
pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR;
counter++;
}
if(hal_status == HAL_OK)
{
/* Check if the previous node is the last one in the current list or zero */
if((pPrevNode == hmdma->LastLinkedListNodeAddress) || (pPrevNode == 0))
{
/* insert the new node at the end of the list. */
pNewNode->CLAR = hmdma->LastLinkedListNodeAddress->CLAR;
hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)pNewNode;
/* Update the Handle last node address */
hmdma->LastLinkedListNodeAddress = pNewNode;
/* Increment the linked list node counter */
hmdma->LinkedListNodeCounter++;
}
else
{
/*insert the new node after the pPreviousNode node */
pNode = hmdma->FirstLinkedListNodeAddress;
counter = 0;
while((counter < hmdma->LinkedListNodeCounter) && (nodeInserted == 0))
{
counter++;
if(pNode == pPrevNode)
{
/*Insert the new node after the previous one */
pNewNode->CLAR = pNode->CLAR;
pNode->CLAR = (uint32_t)pNewNode;
/* Increment the linked list node counter */
hmdma->LinkedListNodeCounter++;
nodeInserted = 1;
}
else
{
pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR;
}
}
if(nodeInserted == 0)
{
hal_status = HAL_ERROR;
}
}
}
}
else
{
hal_status = HAL_ERROR;
}
/* Process unlocked */
__HAL_UNLOCK(hmdma);
hmdma->State = HAL_MDMA_STATE_READY;
return hal_status;
}
else
{
/* Process unlocked */
__HAL_UNLOCK(hmdma);
/* Return error status */
return HAL_BUSY;
}
}
复制代码
/**
* @brief Make the linked list circular by connecting the last node to the first.
* @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
* the configuration information for the specified MDMA Channel.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MDMA_LinkedList_EnableCircularMode(MDMA_HandleTypeDef *hmdma)
{
HAL_StatusTypeDef hal_status = HAL_OK;
/* Check the MDMA peripheral handle */
if(hmdma == NULL)
{
return HAL_ERROR;
}
/* Process locked */
__HAL_LOCK(hmdma);
if(HAL_MDMA_STATE_READY == hmdma->State)
{
/* Change MDMA peripheral state */
hmdma->State = HAL_MDMA_STATE_BUSY;
/* If first and last node are null (no nodes in the list) : return error*/
if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0) || (hmdma->LinkedListNodeCounter == 0))
{
hal_status = HAL_ERROR;
}
else
{
/* to enable circular mode Last Node should be connected to first node */
hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)hmdma->FirstLinkedListNodeAddress;
}
}
/* Process unlocked */
__HAL_UNLOCK(hmdma);
hmdma->State = HAL_MDMA_STATE_READY;
return hal_status;
}复制代码 |