|
@@ -19,7 +19,8 @@ struct lpc17xx_emac
|
|
|
rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
|
|
|
};
|
|
|
static struct lpc17xx_emac lpc17xx_emac_device;
|
|
|
-static struct rt_semaphore sem_slot, sem_lock;
|
|
|
+static struct rt_semaphore sem_lock;
|
|
|
+static struct rt_event tx_event;
|
|
|
|
|
|
/* Local Function Prototypes */
|
|
|
static void write_PHY (rt_uint32_t PhyReg, rt_uint32_t Value);
|
|
@@ -32,11 +33,8 @@ void ENET_IRQHandler(void)
|
|
|
/* enter interrupt */
|
|
|
rt_interrupt_enter();
|
|
|
|
|
|
- status = LPC_EMAC->IntStatus & LPC_EMAC->IntEnable;
|
|
|
+ status = LPC_EMAC->IntStatus;
|
|
|
|
|
|
- /* Clear the interrupt. */
|
|
|
- LPC_EMAC->IntClear = status;
|
|
|
-
|
|
|
if (status & INT_RX_DONE)
|
|
|
{
|
|
|
/* Disable EMAC RxDone interrupts. */
|
|
@@ -47,10 +45,23 @@ void ENET_IRQHandler(void)
|
|
|
}
|
|
|
else if (status & INT_TX_DONE)
|
|
|
{
|
|
|
- /* release one slot */
|
|
|
- rt_sem_release(&sem_slot);
|
|
|
+ /* set event */
|
|
|
+ rt_event_send(&tx_event, 0x01);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (status & INT_RX_OVERRUN)
|
|
|
+ {
|
|
|
+ rt_kprintf("rx overrun\n");
|
|
|
}
|
|
|
|
|
|
+ if (status & INT_TX_UNDERRUN)
|
|
|
+ {
|
|
|
+ rt_kprintf("tx underrun\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Clear the interrupt. */
|
|
|
+ LPC_EMAC->IntClear = status;
|
|
|
+
|
|
|
/* leave interrupt */
|
|
|
rt_interrupt_leave();
|
|
|
}
|
|
@@ -344,8 +355,22 @@ rt_err_t lpc17xx_emac_tx( rt_device_t dev, struct pbuf* p)
|
|
|
struct pbuf *q;
|
|
|
rt_uint8_t *ptr;
|
|
|
|
|
|
- /* take a slot */
|
|
|
- rt_sem_take(&sem_slot, RT_WAITING_FOREVER);
|
|
|
+ /* calculate next index */
|
|
|
+ IndexNext = LPC_EMAC->TxProduceIndex + 1;
|
|
|
+ if(IndexNext > LPC_EMAC->TxDescriptorNumber) IndexNext = 0;
|
|
|
+
|
|
|
+ /* check whether block is full */
|
|
|
+ while (IndexNext == LPC_EMAC->TxConsumeIndex)
|
|
|
+ {
|
|
|
+ rt_err_t result;
|
|
|
+ rt_uint32_t recved;
|
|
|
+
|
|
|
+ /* there is no block yet, wait a flag */
|
|
|
+ result = rt_event_recv(&tx_event, 0x01,
|
|
|
+ RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);
|
|
|
+
|
|
|
+ RT_ASSERT(result == RT_EOK);
|
|
|
+ }
|
|
|
|
|
|
/* lock EMAC device */
|
|
|
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
|
|
@@ -435,19 +460,20 @@ struct pbuf *lpc17xx_emac_rx(rt_device_t dev)
|
|
|
|
|
|
void lpc17xx_emac_hw_init(void)
|
|
|
{
|
|
|
- rt_sem_init(&sem_slot, "tx_slot", NUM_TX_FRAG, RT_IPC_FLAG_FIFO);
|
|
|
+ rt_event_init(&tx_event, "tx_event", RT_IPC_FLAG_FIFO);
|
|
|
rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
|
|
|
|
|
|
/* set autonegotiation mode */
|
|
|
lpc17xx_emac_device.phy_mode = EMAC_PHY_AUTO;
|
|
|
|
|
|
+ // OUI 00-60-37 NXP Semiconductors
|
|
|
+ lpc17xx_emac_device.dev_addr[0] = 0x00;
|
|
|
+ lpc17xx_emac_device.dev_addr[1] = 0x60;
|
|
|
+ lpc17xx_emac_device.dev_addr[2] = 0x37;
|
|
|
/* set mac address: (only for test) */
|
|
|
- lpc17xx_emac_device.dev_addr[0] = 0x1E;
|
|
|
- lpc17xx_emac_device.dev_addr[1] = 0x30;
|
|
|
- lpc17xx_emac_device.dev_addr[2] = 0x6C;
|
|
|
- lpc17xx_emac_device.dev_addr[3] = 0xA2;
|
|
|
- lpc17xx_emac_device.dev_addr[4] = 0x45;
|
|
|
- lpc17xx_emac_device.dev_addr[5] = 0x5E;
|
|
|
+ lpc17xx_emac_device.dev_addr[3] = 0x12;
|
|
|
+ lpc17xx_emac_device.dev_addr[4] = 0x34;
|
|
|
+ lpc17xx_emac_device.dev_addr[5] = 0x56;
|
|
|
|
|
|
lpc17xx_emac_device.parent.parent.init = lpc17xx_emac_init;
|
|
|
lpc17xx_emac_device.parent.parent.open = lpc17xx_emac_open;
|