123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- /* Includes ------------------------------------------------------------------*/
- #include "ethernetif_dm9k.h"
- #include "dm9k.h"
- #include "lwip/tcpip.h"
- #include "lwip/timeouts.h"
- #include "lwip_dm9k.h"
- #include "memory_manager.h"
- #include "netif/etharp.h"
- #include "netif/ethernet.h"
- // #include "snmp.h"
- #include "lwip_init.h"
- #include "string.h"
- #define DM9K_RX_TASK_PRIO 4
- #define DM9K_RX_TASK_STK_SIZE 2048
- CPU_STK dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE];
- /* Define those to better describe your network interface. */
- #define IFNAME0 'D'
- #define IFNAME1 '2'
- #define DM9K_RX_DESC_CNT 4
- #define DM9K_RX_Lenth 1536UL
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- static uint8_t *Rx_Buff[DM9K_RX_DESC_CNT] = {0}; /* Ethernet Rx Buffer */
- uint8_t current_pbuf_idx = 0; /* Zero-copy RX PBUF pool */
- static struct pbuf_custom *custom_pbuf[DM9K_RX_DESC_CNT] = {0};
- /* Private function prototypes -----------------------------------------------*/
- static void pbuf_free_custom(struct pbuf *p);
- static void ethernetif_input(void *pvParameters);
- // static void ethernet_link_check_state(struct netif *netif);
- static OS_EVENT *g_dm9k_rx_sem = NULL;
- static OS_EVENT *dm9k_mutex = NULL;
- static struct netif *low_netif = NULL;
- /*
- *********************************************************************************************************
- * 函 数 名: VariableMemInit
- * 功能说明: 申请串口相关的变量内存
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void VariableMemInit(void)
- {
- uint16_t idx = 0;
- for (idx = 0; idx < DM9K_RX_DESC_CNT; idx++)
- {
- if (Rx_Buff[idx] == 0)
- Rx_Buff[idx] = pMemoryMalloc(&SRAM0, DM9K_RX_Lenth); // 因为不释放,避免重复申请
- if (custom_pbuf[idx] == 0)
- custom_pbuf[idx] = pMemoryMalloc(&SRAM0, sizeof(struct pbuf_custom)); // 因为不释放,避免重复申请
- }
- }
- static void low_level_init(struct netif *netif)
- {
- INT32U idx = 0;
- VariableMemInit();
- INT8U err;
- /* set MAC hardware address length */
- netif->hwaddr_len = ETHARP_HWADDR_LEN;
- /* set MAC hardware address */ /* 网卡的 MAC 修改2 */
- netif->hwaddr[0] = dm9kdev.mac[0];
- netif->hwaddr[1] = dm9kdev.mac[1];
- netif->hwaddr[2] = dm9kdev.mac[2];
- netif->hwaddr[3] = dm9kdev.mac[3];
- netif->hwaddr[4] = dm9kdev.mac[4];
- netif->hwaddr[5] = dm9kdev.mac[5];
- /* maximum transfer unit */
- netif->mtu = 1500;
- /* device capabilities */
- /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
- netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
- low_netif = netif;
- for (idx = 0; idx < DM9K_RX_DESC_CNT; idx++)
- {
- custom_pbuf[idx]->custom_free_function = pbuf_free_custom;
- }
- if (NULL == dm9k_mutex)
- {
- dm9k_mutex = OSMutexCreate(1, &err);
- }
- /* create binary semaphore used for informing ethernetif of frame reception */
- if (NULL == g_dm9k_rx_sem)
- {
- g_dm9k_rx_sem = OSSemCreate(0);
- }
- OSTaskCreateExt((void (*)(void *))ethernetif_input,
- (void *)0,
- (OS_STK *)&dm9k_rx_task_stk[DM9K_RX_TASK_STK_SIZE - 1],
- (INT8U)DM9K_RX_TASK_PRIO,
- (INT16U)DM9K_RX_TASK_PRIO,
- (OS_STK *)&dm9k_rx_task_stk[0],
- (INT32U)DM9K_RX_TASK_STK_SIZE,
- (void *)0,
- (INT16U)OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR | OS_TASK_OPT_SAVE_FP);
- // ethernet_link_check_state(netif);
- }
- /**
- * @brief This function should do the actual transmission of the packet. The packet is
- * contained in the pbuf that is passed to the function. This pbuf
- * might be chained.
- *
- * @param netif the lwip network interface structure for this ethernetif
- * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
- * @return ERR_OK if the packet could be sent
- * an err_t value if the packet couldn't be sent
- *
- * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
- * strange results. You might consider waiting for space in the DMA queue
- * to become available since the stack doesn't retry to send a packet
- * dropped because of memory failure (except for the TCP timers).
- */
- static err_t low_level_output(struct netif *netif, struct pbuf *p)
- {
- INT8U err;
- err_t errval = ERR_OK;
- uint32_t i = 0, framelen = 0, calc_len = 0;
- struct pbuf *q;
- SYS_ARCH_DECL_PROTECT(sr);
- OSMutexPend(dm9k_mutex, 1000, &err);
- SYS_ARCH_PROTECT(sr);
- dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 dm9kA 中断 */
- NET_REG_ADDR = DM9K_REG_MWCMD;
- for (q = p; q != NULL; q = q->next)
- {
- framelen = framelen + q->len;
- calc_len = (q->len + 1) >> 1;
- for (i = 0; i < calc_len; i++)
- {
- NET_REG_DATA = ((uint16_t *)q->payload)[i];
- }
- }
- dm9k_WriteReg(DM9K_REG_TXPLH, (framelen >> 8) & 0xff); /* 设置传送封包的长度 */
- dm9k_WriteReg(DM9K_REG_TXPLL, framelen & 0xff);
- dm9k_WriteReg(DM9K_REG_TCR, DM9K_TCR_SET); /* 进行传送 */
- while ((dm9k_ReadReg(DM9K_REG_ISR) & 0x02) == 0)
- ; /* 等待发送完成 */
- dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 dm9kA 中断 */
- SYS_ARCH_UNPROTECT(sr);
- OSMutexPost(dm9k_mutex);
- return errval;
- }
- static struct pbuf *low_level_input(struct netif *netif)
- {
- struct pbuf *p = NULL;
- uint32_t framelen = 0;
- dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9000A 中断 */
- framelen = etherdev_read(Rx_Buff[current_pbuf_idx]);
- dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9000A 中断 */
- if (framelen)
- {
- // p = pbuf_alloc(PBUF_RAW, framelen, PBUF_POOL);
- p = pbuf_alloced_custom(PBUF_RAW, framelen, PBUF_REF, custom_pbuf[current_pbuf_idx], Rx_Buff[current_pbuf_idx], Max_Ethernet_Lenth);
- if (current_pbuf_idx < (DM9K_RX_DESC_CNT - 1))
- {
- current_pbuf_idx++;
- }
- else
- {
- current_pbuf_idx = 0;
- }
- }
- return p;
- }
- #if 1
- void ethernetif_input(void *pvParameters)
- {
- struct pbuf *p;
- INT8U err;
- SYS_ARCH_DECL_PROTECT(sr);
- for (;;)
- {
- OSSemPend(g_dm9k_rx_sem, 100, &err);
- TRY_GET_NEXT_FRAME:
- SYS_ARCH_PROTECT(sr);
- p = low_level_input(low_netif);
- SYS_ARCH_UNPROTECT(sr);
- if (p != NULL)
- {
- if (ERR_OK != low_netif->input(p, low_netif))
- {
- pbuf_free(p);
- }
- else
- {
- goto TRY_GET_NEXT_FRAME;
- }
- }
- }
- }
- #else
- void ethernetif_input(void *argument)
- {
- struct pbuf *p;
- // struct netif *netif = (struct netif *)argument;
- INT8U err;
- for (;;)
- {
- OSSemPend(g_dm9k_rx_sem, 0, &err);
- // if (err == OS)
- // {
- if (err == ERR_OK)
- {
- do
- {
- LOCK_TCPIP_CORE();
- p = low_level_input(low_netif);
- if (p != NULL)
- {
- err = low_netif->input(p, low_netif);
- if (err != ERR_OK)
- {
- LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
- pbuf_free(p);
- }
- }
- UNLOCK_TCPIP_CORE();
- } while (p != NULL);
- }
- // }
- }
- }
- #endif
- err_t ethernetif_dm9k_init(struct netif *netif)
- {
- LWIP_ASSERT("netif != NULL", (netif != NULL));
- #if LWIP_NETIF_HOSTNAME
- /* Initialize interface hostname */
- netif->hostname = "DM9000";
- #endif /* LWIP_NETIF_HOSTNAME */
- /*
- * Initialize the snmp variables and counters inside the struct netif.
- * The last argument should be replaced with your link speed, in units
- * of bits per second.
- */
- // MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
- netif->name[0] = IFNAME0;
- netif->name[1] = IFNAME1;
- /* We directly use etharp_output() here to save a function call.
- * You can instead declare your own function an call etharp_output()
- * from it if you have to do some checks before sending (e.g. if link
- * is available...) */
- netif->output = etharp_output;
- netif->linkoutput = low_level_output;
- /* initialize the hardware */
- low_level_init(netif);
- return ERR_OK;
- }
- /**
- * @brief Custom Rx pbuf free callback
- * @param pbuf: pbuf to be freed
- * @retval None
- */
- static void pbuf_free_custom(struct pbuf *p)
- {
- if (p != NULL)
- {
- memset(p, 0, sizeof(struct pbuf));
- }
- }
- void dm9k_interrupt(void)
- {
- uint8_t save_reg;
- uint16_t isr_status;
- save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
- dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_OFF); /* 关闭 DM9KA 中断 */
- isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
- // isr_status = isr_status & DM9K_RX_INTR;
- if (isr_status & DM9K_RX_INTR)
- { /* 检查是否为接收中断 */
- OSSemPost(g_dm9k_rx_sem);
- // dm9k_receive_packet(); /* 执行接收处理程序 */
- }
- dm9k_WriteReg(DM9K_REG_IMR, DM9K_IMR_SET); /* 开启 DM9KA 中断 */
- NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
- }
- /**
- * @brief Ethernet Rx Transfer completed callback
- * @param heth: ETH handle
- * @retval None
- */
- void BSP_GPIO15_EXTI_Callback(void)
- {
- uint8_t save_reg;
- uint8_t isr_status;
- save_reg = NET_REG_ADDR; /* 暂存所使用的位置 */
- isr_status = dm9k_ReadReg(DM9K_REG_ISR); /* 取得中断产生值 */
- dm9k_WriteReg(DM9K_REG_ISR, isr_status); /* 清除中断产生值 */
- // isr_status = isr_status & DM9K_RX_INTR;
- if (isr_status & DM9K_RX_INTR) /* 检查是否为接收中断 */
- {
- OSSemPost(g_dm9k_rx_sem); /* 执行接收处理程序 */
- }
- NET_REG_ADDR = save_reg; /* 回复所使用的位置 */
- }
- //中断处理函数,注意不是中断服函数,需要在中断服务函数中调用
- void DMA9K_ISRHandler(void)
- {
- u16 int_status;
- u16 last_io;
- last_io = NET_REG_ADDR;
- int_status = dm9k_ReadReg(DM9K_REG_ISR);
- dm9k_WriteReg(DM9K_REG_ISR, int_status); //清除中断标志位
- if (int_status & DM9K_RX_INTR) //接收中断
- {
- OSSemPost(g_dm9k_rx_sem);
- //接收完成中断,用户自己添加代码
- }
- if (int_status & DM9K_TX_INTR) //发送中断
- {
- // OSSemPost(g_dm9k_tx_sem);
- //发送完成中断,用户自己添加代码
- }
- NET_REG_ADDR = last_io;
- }
- void EXTI15_10_IRQHandler(void)
- {
- OSIntEnter();
- EXTI_ClearITPendingBit(EXTI_Line15); /* 清除中断标志位 */
- if (EXTI_GetITStatus(EXTI_Line15) != RESET)
- {
- BSP_GPIO15_EXTI_Callback();
- }
- OSIntExit();
- }
- void ethernet_link_check_state(struct netif *netif)
- {
- uint8_t linkchanged = 0;
- linkchanged = dm9k_linkstat();
- if (netif_is_link_up(netif) && (linkchanged == 0))
- {
- netif_set_down(netif);
- netif_set_link_down(netif);
- }
- else if (!netif_is_link_up(netif) && (linkchanged == 1))
- {
- netif_set_up(netif);
- netif_set_link_up(netif);
- }
- }
|