AT91 ARM EMAC вопрос с опросом - PullRequest
0 голосов
/ 20 ноября 2018

Я использую пример atmel lwip.Взаимодействие с PHY в порядке.Это может связать и даже автоматически договориться.Нетиф идет вверх.Но когда я начинаю опросить, ничего не происходит.Я сузил задачу до EMAC_Poll

unsigned char EMAC_Poll(unsigned char *pFrame, unsigned int frameSize, unsigned int *pRcvSize)
{
    unsigned short bufferLength;
    unsigned int   tmpFrameSize=0;
    unsigned char  *pTmpFrame=0;
    unsigned int   tmpIdx = rxTd.idx;
    volatile EmacRxTDescriptor *pRxTd = rxTd.td + rxTd.idx;

    ASSERT(pFrame, "F: EMAC_Poll\n\r");

    char isFrame = 0;
    // Set the default return value
    *pRcvSize = 0;

    // Process received RxTd
    while ((pRxTd->addr & EMAC_RX_OWNERSHIP_BIT) == EMAC_RX_OWNERSHIP_BIT) {
        // Never got there.
        ...
    }
    return EMAC_RX_NO_DATA;
}


typedef struct {
   volatile EmacRxTDescriptor td[RX_BUFFERS];
   EMAC_RxCallback rxCb; /// Callback function to be invoked once a frame has been received
   unsigned short idx;
} RxTd;

/// Describes the type and attribute of Receive Transfer descriptor.
typedef struct _EmacRxTDescriptor {
    unsigned int addr;
    unsigned int status;
} __attribute__((packed, aligned(8))) EmacRxTDescriptor, *PEmacRxTDescriptor;

Есть цикл while, но условие никогда не сбывается.У меня очень смутное представление о том, что такое RxTd и что именно означает это условие.Однако я не могу видеть, как этот RxTd изменится, чтобы передать условие.Все ссылки на RxTd ведут к одному и тому же модулю emac.c.Большинство из них в этой функции опроса и покоятся в функции EMAC_ResetRx.

static void EMAC_ResetRx(void)
{
    unsigned int Index;
    unsigned int Address;

    // Disable RX
    AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_RE;
    // Setup the RX descriptors.
    rxTd.idx = 0;
    for(Index = 0; Index < RX_BUFFERS; Index++) {

        Address = (unsigned int)(&(pRxBuffer[Index * EMAC_RX_UNITSIZE]));
        // Remove EMAC_RX_OWNERSHIP_BIT and EMAC_RX_WRAP_BIT
        rxTd.td[Index].addr = Address & EMAC_ADDRESS_MASK;
        rxTd.td[Index].status = 0;
    }
    rxTd.td[RX_BUFFERS - 1].addr |= EMAC_RX_WRAP_BIT;
    // Receive Buffer Queue Pointer Register
    AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int) (rxTd.td);
}

Я не совсем понимаю последнюю строку, но похоже, что rxTd автоматически заполняется самим AT91.Если это так, может быть проблема с упаковкой / выравниванием, но Atmel добавил __attribute__ ((packed, aligned(8))) в определение структуры RxTd.В любом случае, кто-то может описать механизм ввода данных или сказать, где может быть проблема?Кстати, я использую GCC, если это имеет значение. UPD : Я проверил RSR и заметил, что он начинается с 0, а затем переходит к 2 через секунду.2 - означает, что были получены новые данные. UPD : Итак, я прочитал о функции emac в таблице данных для моего чипа.Я был прав.Этот регистр RBQP должен указывать на массив дескрипторов.Каждый дескриптор состоит из адреса и поля состояния.Лист данных утверждает, что «нулевой бит поля адреса записывается в единицу, чтобы показать, что буфер был использован».Затем ARM использует другой дескриптор rx из этого массива.Я предполагаю, что под "был использован" они означают, что этот буфер заполнен данными кадра и готов к обработке.Это должно означать, что данные просто не попадают в этот буфер.Но это должно быть там, потому что REC идет высоко.Кроме того, я проверил, что RE в NCR включен и MI включен.Понятия не имею, что не так.

1 Ответ

0 голосов
/ 23 ноября 2018

Я потратил целую неделю, чтобы решить это.Самое смешное, что если я сбросил память и посмотрел все эти адреса - данные были там все время!Поэтому ключом было отключить I и D кеширование и сам MMU .Надеюсь, это кому-нибудь поможет.

...