- Главная
- Форум
- Микроконтроллеры и Системы на Модуле (SOM)
- Микроконтроллеры
- Проблема с DMA MAC STM32F4
Проблема с DMA MAC STM32F4
- rychkov@tpu.ru
- Автор темы
- Посетитель
10 года 7 мес. назад - 10 года 7 мес. назад #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 )
Столкнулся с такой проблемой: Необходимо принимать 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 )
Последнее редактирование: 10 года 7 мес. назад пользователем .
- rychkov@tpu.ru
- Автор темы
- Посетитель
10 года 7 мес. назад #5294
от rychkov@tpu.ru
rychkov@tpu.ru ответил в теме Re: Проблема с DMA MAC STM32F4
Вобщем покопался и обнаружил, что дескрипторы не закольцевались. В регистре DMACHRDR где записан адрес текущего дескриптора, после последнего записывается не адрес первого, а текущего + размер дескриптора. Каким образом DMA указать, что он работает с последним дескриптором?
- Денис Ягов
- Посетитель
10 года 7 мес. назад #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;
}
Если использовать стандартный 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;
}
- Денис Ягов
- Посетитель
10 года 7 мес. назад #5296
от Денис Ягов
Денис Ягов ответил в теме Re: Проблема с DMA MAC STM32F4
Ну и до кучи ...... когда дескриптор "сделал дело" в нём взводится флаг "Впредь меня не обрабатывать".
Флажок надо опустить перед тем как его в таком виде обнаружит DMA.
Если DMA MAC обнаружит поднятый данный флаг - надо ещё будет запустить процесс работы DMA MAC заново. (альтернативой может быть опускание флагов дескрипторов ядром до обнаружения их DMA)
Флажок надо опустить перед тем как его в таком виде обнаружит DMA.
Если DMA MAC обнаружит поднятый данный флаг - надо ещё будет запустить процесс работы DMA MAC заново. (альтернативой может быть опускание флагов дескрипторов ядром до обнаружения их DMA)
- rychkov@tpu.ru
- Автор темы
- Посетитель
10 года 6 мес. назад #5297
от rychkov@tpu.ru
rychkov@tpu.ru ответил в теме Re: Проблема с DMA MAC STM32F4
Спасибо за ответ, вроде заработало. А еще вопрос: бывают два типа дескриптора, как DMA указать что это цепочный или кольцевой тип, ведь во втором случае во втором буфере дескриптора будет не адрес следующего, и как при кольцевом типе DMA узнает что это последний дескриптор
- Денис Ягов
- Посетитель
10 года 6 мес. назад #5299
от Денис Ягов
Денис Ягов ответил в теме Re: Проблема с DMA MAC STM32F4
первое слово дескриптора (из 4-х), бит 21. Кусок мануала ниже отсканен
Время создания страницы: 0.078 секунд