Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC1778 + KSZ8041NL
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Vitaliy_ARM
Всем доброго времени.

Сегодня выявил следующий баг.
Цитата
DWORD EmacTxData(DWORD *Buf, DWORD Len)
{
pEMACDATA pEthData = &Data;
DWORD idx;
DWORD produce, consume;
if(Len>0)
{
do
{
produce = LPC_EMAC->TxProduceIndex;
consume = LPC_EMAC->TxConsumeIndex;
}
while(produce != consume); //////-------------- индексы равны даже, когда пакет еще отправляется!!!!!!!!
// опеределяем номер текущего дескриптора
idx = LPC_EMAC->TxProduceIndex;
pEthData->DmaTx[idx].addr = Buf;
pEthData->DmaTx[idx].ctrl = (Len-1) | 0xF4000000; //(1<<30) | (1<<31) | (1<<29) | (1<<28) | (1<<26); // прерывание включено (бит 31)
if (++idx == ENET_DMA_TXDESC_NUMB)
idx = 0;
if(idx > LPC_EMAC->TxDescriptorNumber) return (FALSE);
LPC_EMAC->TxProduceIndex = idx;
}
return(TRUE);
}


Когда запускаю эту функцию в цикле, например из 15 пакетов, то половина пакетов не отправляется, это хорошо видно при помощи WireShark. Стоит между отправкой поставить задержку в 100 мкс, то после этого все пакеты отправляются исправно. Т.е. похоже происходит "нахлест" между пакетами. Подскажите, в чем может быть дело? Ошибка процессора или PHY?
Rst7
QUOTE
do
{
produce = LPC_EMAC->TxProduceIndex;
consume = LPC_EMAC->TxConsumeIndex;
}
while(produce != consume); //////-------------- индексы равны даже, когда пакет еще отправляется!!!!!!!!


Эээ, пардон, так вроде правильно сравнивать consume с (produce+1)%(TXDESCRIPTORNUMBER-1). Т.е. пока равны - ждать.

Типа вот у меня:
CODE
      L_SENDETH:
    if (len<60) len=60;
    {
      UREG i,j;
      j=(i=TXPRODUCEINDEX)+1;
      if (j>TXDESCRIPTORNUMBER) j=0;
      while(j==TXCONSUMEINDEX); //Ждем освобождения передатчика - хотя бы один буфер
      FreeTXbufs();
      EnetDmaTx[i].pBuffer=(EnetBuffer *)(ep->hdr.dst_mac);
      EnetDmaTx[i].EnetTxCtrl.Size = len-1;
      TXPRODUCEINDEX=j; //Стартуем посылку
Vitaliy_ARM
Цитата(Rst7 @ Oct 6 2012, 18:58) *
Эээ, пардон, так вроде правильно сравнивать consume с (produce+1)%(TXDESCRIPTORNUMBER-1). Т.е. пока равны - ждать.

Типа вот у меня:
Код
      L_SENDETH:
    if (len<60) len=60;
    {
      UREG i,j;
      j=(i=TXPRODUCEINDEX)+1;
      if (j>TXDESCRIPTORNUMBER) j=0;
      while(j==TXCONSUMEINDEX); //Ждем освобождения передатчика - хотя бы один буфер
      FreeTXbufs();
      EnetDmaTx[i].pBuffer=(EnetBuffer *)(ep->hdr.dst_mac);
      EnetDmaTx[i].EnetTxCtrl.Size = len-1;
      TXPRODUCEINDEX=j; //Стартуем посылку

К сожалению не совсем так, PRODUCE убегающий индекс, а CONSUME - догоняющий. Инкрементом PRODUCE мы запускаем DMA, который начинает отправлять пакет. По завершению отправки этого пакета DMA инкрементирует CONSUME индекс. Т.е. DMA будет передавать пакеты до тех пор, пока индексы не равны.

Цитата
If the TxConsumeIndex equals TxProduceIndex the descriptor array is
empty and the transmit channel will stop transmitting until software produces new
descriptors.


В Вашем случае дается разрешение заполнить TXDESCRIPTORNUMBER дескрипторов, пока DMA отправляет один пакет. В моем случае я следующий покет не отправлю, пока не отправился предыдущий. Проблема осталась. Начинаю думать, что это PHY не отдает команды процессору об успешной отправке, в то время, как он отправить данные не успел. Разбираюсь дальше...
Rst7
QUOTE
Начинаю думать, что это PHY не отдает команды процессору об успешной отправке, в то время, как он отправить данные не успел. Разбираюсь дальше...


А причем тут PHY? Он, вообще-то, ничего никому не сообщает. И решение о конце отправки принимает MAC, о чем сигнализирует в PHY снятием сигнала TXEN.

А вообще я бы на Вашем месте проверил правильность настроек RX/TX flow controll и Half/Full Duplex.
Vitaliy_ARM
Цитата(Rst7 @ Oct 7 2012, 00:15) *
А причем тут PHY? Он, вообще-то, ничего никому не сообщает. И решение о конце отправки принимает MAC, о чем сигнализирует в PHY снятием сигнала TXEN.

А вообще я бы на Вашем месте проверил правильность настроек RX/TX flow controll и Half/Full Duplex.


Спасибо за наводку. В общем ошибка была в том, что неправильно инициализировался процессор. В режиме 100 Мбит FULL Duplex процессор у меня инициализировался в HALF Duplex. После исправления кода все заработало как надо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.