×

Внимание

Форум находится в режиме только для чтения.

Проблема с DMA MAC STM32F4

9 года 11 мес. назад - 9 года 11 мес. назад #5291 от rychkov@tpu.ru
rychkov@tpu.ru создал тему: Проблема с DMA MAC STM32F4
Добрый день!


Столкнулся с такой проблемой: Необходимо принимать Ethernet пакеты. За основу работы с Ethernet взял пример расположенный на сайте. Создал массив дескрипторов, настроил по кольцевому типу т.е. последний указывает на первый. Пакеты принимаются пока не дойдет до последнего дескриптора. В этом случае в регистре DMASR устанавливается бит 7 -
ETH_DMASR_RBUS. В обработчике приема пакетов есть строки


if
{


/* Clear RBUS ETHERNET DMA flag */ ETH->
Dma_SR= ETH->
DMASR = ETH_DMASR_RBUS; DMASR ;

/* Resume DMA reception */
ETH->DMARPDR = 0;
}

однако после выхода из обработчика этот бит снова устанавливается и DMA подвисает.
Как от этого избавиться?

((ETH-> DMASR & ETH_DMASR_RBUS) != ( u32 ) RESET )
9 года 11 мес. назад #5294 от rychkov@tpu.ru
rychkov@tpu.ru ответил в теме Re: Проблема с DMA MAC STM32F4
Вобщем покопался и обнаружил, что дескрипторы не закольцевались. В регистре DMACHRDR где записан адрес текущего дескриптора, после последнего записывается не адрес первого, а текущего + размер дескриптора. Каким образом DMA указать, что он работает с последним дескриптором?
9 года 11 мес. назад #5295 от Денис Ягов
Денис Ягов ответил в теме Re: Проблема с DMA MAC STM32F4
Добрый день.

Если использовать стандартный Ethernet драйвер, то есть такя функция:
void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount);
void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount);

Формирует цепочки дескрипторов.
Применяются указатели на буферы  uint8_t *RxBuff и количество буферов. Результирующая цепочка дескрипторов складывается в *DMARxDescTab.
По структуре ETH_DMADESCTypeDef вытаскиваются параметры дескрипторов, в том числе зацикливание.

сама структура:
typedef struct  {
  __IO uint32_t   Status;                /*!< Status */
  uint32_t   ControlBufferSize;     /*!< Control and Buffer1, Buffer2 lengths */
  uint32_t   Buffer1Addr;           /*!< Buffer1 address pointer */
  uint32_t   Buffer2NextDescAddr;   /*!< Buffer2 or next descriptor address pointer */
/* Enhanced ETHERNET DMA PTP Descriptors */
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
  uint32_t   ExtendedStatus;        /* Extended status for PTP receive descriptor */
  uint32_t   Reserved1;             /* Reserved */
  uint32_t   TimeStampLow;          /* Time Stamp Low value for transmit and receive */
  uint32_t   TimeStampHigh;         /* Time Stamp High value for transmit and receive */
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
} ETH_DMADESCTypeDef;


тело функции (момент, где делается зацикливание выделил):
/**
  * @brief  Initializes the DMA Tx descriptors in chain mode.
  * @param  DMATxDescTab: Pointer on the first Tx desc list
  * @param  TxBuff: Pointer on the first TxBuffer list
  * @param  TxBuffCount: Number of the used Tx desc in the list
  * @retval None
  */
void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount)
{
  uint32_t i = 0;
  ETH_DMADESCTypeDef *DMATxDesc;
 
  /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
  DMATxDescToSet = DMATxDescTab;
  /* Fill each DMATxDesc descriptor with the right values */  
  for(i=0; i < TxBuffCount; i++)
  {
    /* Get the pointer on the ith member of the Tx Desc list */
    DMATxDesc = DMATxDescTab + i;
    /* Set Second Address Chained bit */
    DMATxDesc->Status = ETH_DMATxDesc_TCH; 
      
    /* Set Buffer1 address pointer */
    DMATxDesc->Buffer1Addr = (uint32_t)(&TxBuff[i*ETH_TX_BUF_SIZE]);
   
    /* Initialize the next descriptor with the Next Descriptor Polling Enable */
    if(i < (TxBuffCount-1))
    {
      /* Set next descriptor address register with next descriptor base address */
      DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1);
    }
    else
    {
      /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
      DMATxDesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab; 
    }

  }
  
  /* Set Transmit Desciptor List Address Register */
  ETH->DMATDLAR = (uint32_t) DMATxDescTab;
}
9 года 11 мес. назад #5296 от Денис Ягов
Денис Ягов ответил в теме Re: Проблема с DMA MAC STM32F4
Ну и до кучи ...... когда дескриптор "сделал дело" в нём взводится флаг "Впредь меня не обрабатывать".

Флажок надо опустить перед тем как его в таком виде обнаружит DMA.

Если DMA MAC обнаружит поднятый данный флаг - надо ещё будет запустить процесс работы DMA MAC заново. (альтернативой может быть опускание флагов дескрипторов ядром до обнаружения их DMA)

8)
9 года 11 мес. назад #5297 от rychkov@tpu.ru
rychkov@tpu.ru ответил в теме Re: Проблема с DMA MAC STM32F4
Спасибо за ответ, вроде заработало. А еще вопрос: бывают два типа дескриптора, как DMA указать что это цепочный или кольцевой тип, ведь во втором случае во втором буфере дескриптора будет не адрес следующего, и как при кольцевом типе DMA узнает что это последний дескриптор
9 года 11 мес. назад #5299 от Денис Ягов
Денис Ягов ответил в теме Re: Проблема с DMA MAC STM32F4
первое слово дескриптора (из 4-х), бит 21. Кусок мануала ниже отсканен
Время создания страницы: 0.114 секунд
Работает на Kunena форум