реклама на сайте
подробности

 
 
> LPC1788 Ethernet DMA драйвер - прерывания, Не работают прерывания от EMAC
Cosmojam
сообщение Jul 17 2012, 10:44
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182



Помогите осилить эзернет на LPC1788
За основу взят пример с FreeRTOS+LwIP для LPC1768 вместе с драйвером эзернет (судя по даташиту модули emac идентичны за исключением поддерки MII, но у меня всё равно используется RMII).
Проблема следующая: инициализация MAC и PHY проходит успешно, линк поднимается на 100мбит полный дуплекс, зелёный диод мыргает при получении широковещательного трафика, на выводах PHY RXD[0:1] присутствуют данные при приёме. Но не генерируется прерывание от EMAC ни на приём ни на передачу.
Инициализация EMAC:
CODE
Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
{
/* Initialize the EMAC Ethernet controller. */
int32_t regv,tout, tmp;

/* Set up clock and power for Ethernet module */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);

/* Reset all EMAC internal modules */
LPC_EMAC->MAC1 = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX |
EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES;

LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES |
EMAC_CR_PASS_RUNT_FRM;

/* A short delay after reset. */
vTaskDelay( 2 );

/* Initialize MAC control registers. */
LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN;
LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;

/*
* Find the clock that close to desired target clock
*/
tmp = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) / EMAC_MCFG_MII_MAXCLK;
for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++){
if (EMAC_clkdiv[tout] >= tmp) break;
}
tout++;

// Write to MAC configuration register and reset
LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII;

// release reset
LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII);
LPC_EMAC->CLRT = EMAC_CLRT_DEF;
LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF;

/* Enable Reduced MII interface. */
LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM;

/* A short delay after reset. */
vTaskDelay( 2 );

LPC_EMAC->SUPP = 0;

/* Put the DP83848C in reset mode */
write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_RESET);

/* Wait for hardware reset to end. */
for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
regv = read_PHY (EMAC_PHY_REG_BMCR);
if (!(regv & (EMAC_PHY_BMCR_RESET | EMAC_PHY_BMCR_POWERDOWN))) {
/* Reset complete, device not Power Down. */
break;
}
if (tout == 0){
// Time out, return ERROR
return (ERROR);
}
vTaskDelay( 2 );
}

// Set PHY mode
if (EMAC_SetPHYMode(EMAC_ConfigStruct->Mode) < 0){
return (ERROR);
}

// Set EMAC address
setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr);

/* Initialize Tx and Rx DMA Descriptors */
rx_descr_init ();
tx_descr_init ();

// Set Receive Filter register: enable broadcast and multicast
LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;

/* Enable Rx Done and Tx Done interrupt for EMAC */
LPC_EMAC->IntEnable = EMAC_INT_RX_DONE | EMAC_INT_TX_DONE;

/* Reset all interrupts */
LPC_EMAC->IntClear = 0xFFFF;

/* Enable receive and transmit mode of MAC Ethernet core */
LPC_EMAC->Command |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;

return SUCCESS;
}

Инициализация дескрипторов DMA
CODE
/** Rx Descriptor data array */
static volatile RX_Desc Rx_Desc[EMAC_NUM_RX_FRAG];

/** Rx Status data array - Must be 8-Byte aligned */
static volatile __attribute__ ((aligned (8))) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];

/** Tx Descriptor data array */
static volatile TX_Desc Tx_Desc[EMAC_NUM_TX_FRAG];
/** Tx Status data array */
static volatile TX_Stat Tx_Stat[EMAC_NUM_TX_FRAG];

#define EMAC_ETH_MAX_FLEN 1536

typedef uint32_t xEMACRxBuffer_t[ EMAC_NUM_RX_FRAG ][ EMAC_ETH_MAX_FLEN >> 2 ];
typedef uint32_t xEMACTxBuffer_t[ EMAC_NUM_TX_FRAG ][ EMAC_ETH_MAX_FLEN >> 2 ];

static void rx_descr_init (void)
{
/* Initialize Receive Descriptor and Status array. */
uint32_t i;
extern void *pvApplicationGetEMACRxBufferAddress( void );
xEMACRxBuffer_t *rx_buf;

rx_buf = ( xEMACRxBuffer_t * ) pvApplicationGetEMACRxBufferAddress();
for (i = 0; i < EMAC_NUM_RX_FRAG; i++) {
Rx_Desc[i].Packet = (uint32_t)&(*rx_buf)[i];
Rx_Desc[i].Ctrl = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN - 1);
Rx_Stat[i].Info = 0xFFFFFFFF;
Rx_Stat[i].HashCRC = 0xFFFFFFFF;
}

/* Set EMAC Receive Descriptor Registers. */
LPC_EMAC->RxDescriptor = (uint32_t)&Rx_Desc[0];
LPC_EMAC->RxStatus = (uint32_t)&Rx_Stat[0];
LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG - 1;

/* Rx Descriptors Point to 0 */
LPC_EMAC->RxConsumeIndex = 0;
}

static void tx_descr_init (void) {
/* Initialize Transmit Descriptor and Status array. */
uint32_t i;
extern void *pvApplicationGetEMACTxBufferAddress( void );
xEMACTxBuffer_t *tx_buf;

tx_buf = ( xEMACTxBuffer_t * ) pvApplicationGetEMACTxBufferAddress();
for (i = 0; i < EMAC_NUM_TX_FRAG; i++) {
Tx_Desc[i].Packet = (uint32_t)&(*tx_buf)[i];
Tx_Desc[i].Ctrl = 0xFFFFFFFF;
Tx_Stat[i].Info = 0xFFFFFFFF;
}

/* Set EMAC Transmit Descriptor Registers. */
LPC_EMAC->TxDescriptor = (uint32_t)&Tx_Desc[0];
LPC_EMAC->TxStatus = (uint32_t)&Tx_Stat[0];
LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG - 1;

/* Tx Descriptors Point to 0 */
LPC_EMAC->TxProduceIndex = 0;
}


void *pvApplicationGetEMACTxBufferAddress(void)
{
static volatile xEMACTxBuffer_t txb __attribute__ ((aligned (4)));
return (void *)txb;
}

void *pvApplicationGetEMACRxBufferAddress(void)
{

static volatile xEMACRxBuffer_t rxb __attribute__ ((aligned (4)));
return (void *)rxb;
}

Инициализация дескрипторов тоже вроде как проходит успешно, отладчиком вижу правильные адреса буферов приёма/передачи в регистрах EMAC. Прерывания RxDoneInt и TxDoneInt включены. Прерывание от EMAC в NVIC разрешено. Всё выглядит верно настроенным, но прерываний от EMAC нет вообще. Тот же самый код работает на LPC1768 с такой же PHY (KS8721B), прерывание бегают, LwIP работает. А тут вообще глухо, будто прерывания запрещены или он просто не принимает/не передаёт ничего, но на выводах RXD[0:1] чётко видны импульсы при приёме ARP пакетов. Пробовал подбирать чатсоту RMII от 2.5 до 15 МГц. Пробовал менять частоту проца от 80 до 120МГц. Никаких результатов.
Готовый порт http://www.lpcware.com/content/project/lig...etworking-stack тоже запустить не удалось, но по-правде говоря не сильно углублялся в него - слишком наворочено. Внимательно посмотрел как там инициализация EMAC сделана, сравнил со своей - вроде всё так же. Кто сталкивался с эзернетом на этом проце подскажите что-нибудь вроде рабочиего кода инициалицации EMAC sm.gif

Сообщение отредактировал IgorKossak - Jul 17 2012, 19:53
Причина редактирования: [codebox] для длинного кода!!!


--------------------
typedef enum { no, yes, maybe } bool; | блог тут
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Cosmojam
сообщение Jul 18 2012, 08:39
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182



Поллинг не поможет - проблема с самими дескрипторами, похоже, а не с прерываниями. В статусные дескрипторы ничего не записывается при приёме/передаче. Они как инициализируются в 0 так и остаются, НО RxProduceIndex инкрементируется будто всё ОК. Это не соответствует инфе из даташита:
Цитата
After receiving a fragment, the Rx DMA manager writes status information back to the StatusInfo and StatusHashCRC words of the status. The Ethernet block writes the size in bytes of a descriptor’s fragment buffer in the RxSize field of the Status word. The value of the RxProduceIndex is only updated after the fragment data and the fragment status information has been committed to memory, which is checked by an internal tag protocol in the memory interface.

Т.е. RxProduceIndex инкрементируется только после успешной записи и проверки данных записанных в буфер и статусный дескриптор. Но у меня ничего не пишется ни в буфер ни в статус, а RxProduceIndex инкрементиуется пока не достигнет количество фрагментов-1 и выставляет прерывание RxFinishedInt. На этом всё останавливается.


--------------------
typedef enum { no, yes, maybe } bool; | блог тут
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Cosmojam   LPC1788 Ethernet DMA драйвер - прерывания   Jul 17 2012, 10:44
- - DmitryM   Цитата(Cosmojam @ Jul 17 2012, 14:44) Про...   Jul 17 2012, 12:43
|- - Cosmojam   Цитата(DmitryM @ Jul 17 2012, 15:43) А ра...   Jul 17 2012, 13:08
- - Cosmojam   С дескрипторами вот что происходит: RxProduceIndex...   Jul 17 2012, 15:53
- - andrewlekar   У меня на LPC1768 была какая-то загвоздка с прерыв...   Jul 18 2012, 05:17
- - andrewlekar   Ну тогда проверяйте память, адреса, указатели.   Jul 18 2012, 09:53
- - Cosmojam   [CENSORED] Нашёл причину, разместив буферы и дескр...   Jul 18 2012, 10:26
- - ReAl   Detailed block diagram (Fig.2 LPC178x/177x block d...   Jul 18 2012, 16:53
- - Cosmojam   Спасибо пребольшое! Кстати, нашёл где написано...   Jul 18 2012, 18:44
|- - romas2010   Цитата(Cosmojam @ Jul 18 2012, 22:44) Спа...   Oct 1 2012, 07:26
|- - theBMV   Цитата(romas2010 @ Oct 1 2012, 11:26) Тут...   Oct 3 2012, 05:55
- - Kevlar   Немного не из этой темы, но связано с ней. Я нович...   Dec 5 2012, 20:40
- - romas2010   Цитата(Kevlar @ Dec 5 2012, 23:40) Немног...   Dec 6 2012, 18:04
- - Cosmojam   Цитата(Kevlar @ Dec 5 2012, 23:40) Немног...   Dec 6 2012, 18:31
- - SyncLair   Цитата(Kevlar @ Dec 6 2012, 00:40) Немног...   Dec 6 2012, 20:33


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 11:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01442 секунд с 7
ELECTRONIX ©2004-2016