Перейти к содержанию
    

LPC1778 + KSZ8041NL

Всем доброго времени.

 

Сегодня выявил следующий баг.

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?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

do

{

produce = LPC_EMAC->TxProduceIndex;

consume = LPC_EMAC->TxConsumeIndex;

}

while(produce != consume); //////-------------- индексы равны даже, когда пакет еще отправляется!!!!!!!!

 

Эээ, пардон, так вроде правильно сравнивать 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; //Стартуем посылку

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эээ, пардон, так вроде правильно сравнивать 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 не отдает команды процессору об успешной отправке, в то время, как он отправить данные не успел. Разбираюсь дальше...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Спасибо за наводку. В общем ошибка была в том, что неправильно инициализировался процессор. В режиме 100 Мбит FULL Duplex процессор у меня инициализировался в HALF Duplex. После исправления кода все заработало как надо.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...