/** * \brief Register/Clear RX callback. Callback will be invoked after the next received * frame. * * When gmac_dev_read() returns GMAC_RX_NULL, the application task calls * gmac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state. * The callback is in charge to resume the task once a new frame has been * received. The next time gmac_dev_read() is called, it will be successful. * * This function is usually invoked from the RX callback itself with NULL * callback, to unregister. Once the callback has resumed the application task, * there is no need to invoke the callback again. * * \param p_gmac_dev Pointer to the GMAC device instance. * \param func_tx_cb Receive callback function. */ void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev, gmac_dev_tx_cb_t func_rx_cb) { Gmac *p_hw = p_gmac_dev->p_hw; if (func_rx_cb == NULL) { gmac_disable_interrupt(p_hw, GMAC_IDR_RCOMP); p_gmac_dev->func_rx_cb = NULL; } else { p_gmac_dev->func_rx_cb = func_rx_cb; gmac_enable_interrupt(p_hw, GMAC_IER_RCOMP); } }
/** * \brief Initialize the GMAC driver. * * \param p_gmac Pointer to the GMAC instance. * \param p_gmac_dev Pointer to the GMAC device instance. * \param p_opt GMAC configure options. */ void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev, gmac_options_t* p_opt) { gmac_dev_mem_t gmac_dev_mm; /* Disable TX & RX and more */ gmac_network_control(p_gmac, 0); gmac_disable_interrupt(p_gmac, ~0u); gmac_clear_statistics(p_gmac); /* Clear all status bits in the receive status register. */ gmac_clear_rx_status(p_gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA); /* Clear all status bits in the transmit status register */ gmac_clear_tx_status(p_gmac, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE | GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_UND); /* Clear interrupts */ gmac_get_interrupt_status(p_gmac); /* Enable the copy of data into the buffers ignore broadcasts, and not copy FCS. */ gmac_set_configure(p_gmac, gmac_get_configure(p_gmac) | GMAC_NCFGR_RFCS| GMAC_NCFGR_PEN); gmac_enable_copy_all(p_gmac, p_opt->uc_copy_all_frame); gmac_disable_broadcast(p_gmac, p_opt->uc_no_boardcast); /* Fill in GMAC device memory management */ gmac_dev_mm.p_rx_buffer = gs_uc_rx_buffer; gmac_dev_mm.p_rx_dscr = gs_rx_desc; gmac_dev_mm.us_rx_size = GMAC_RX_BUFFERS; gmac_dev_mm.p_tx_buffer = gs_uc_tx_buffer; gmac_dev_mm.p_tx_dscr = gs_tx_desc; gmac_dev_mm.us_tx_size = GMAC_TX_BUFFERS; gmac_init_mem(p_gmac, p_gmac_dev, &gmac_dev_mm, gs_tx_callback); gmac_set_address(p_gmac, 0, p_opt->uc_mac_addr); }
/** * \brief Register/Clear RX callback. Callback will be invoked after the next received * frame. * * When gmac_dev_read() returns GMAC_RX_NULL, the application task calls * gmac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state. * The callback is in charge to resume the task once a new frame has been * received. The next time gmac_dev_read() is called, it will be successful. * * This function is usually invoked from the RX callback itself with NULL * callback, to unregister. Once the callback has resumed the application task, * there is no need to invoke the callback again. * * \param p_gmac_dev Pointer to the GMAC device instance. * \param func_tx_cb Receive callback function. */ void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev, gmac_quelist_t queue_idx, gmac_dev_tx_cb_t func_rx_cb) { Gmac *p_hw = p_gmac_dev->p_hw; if (func_rx_cb == NULL) { if(queue_idx == GMAC_QUE_0) { gmac_disable_interrupt(p_hw, GMAC_IDR_RCOMP); } else { gmac_disable_priority_interrupt(p_hw, GMAC_IER_RCOMP, queue_idx); } p_gmac_dev->gmac_queue_list[queue_idx].func_rx_cb = NULL; } else { p_gmac_dev->gmac_queue_list[queue_idx].func_rx_cb = func_rx_cb; if(queue_idx == GMAC_QUE_0) { gmac_enable_interrupt(p_hw, GMAC_IER_RCOMP); } else { gmac_enable_priority_interrupt(p_hw, GMAC_IER_RCOMP, queue_idx); } } }
/** * \brief Initialize the GMAC driver. * * \param p_gmac Pointer to the GMAC instance. * \param p_gmac_dev Pointer to the GMAC device instance. * \param p_opt GMAC configure options. */ void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev, gmac_options_t* p_opt) { /* Disable TX & RX and more */ gmac_network_control(p_gmac, 0); gmac_disable_interrupt(p_gmac, ~0u); gmac_clear_statistics(p_gmac); /* Clear all status bits in the receive status register. */ gmac_clear_rx_status(p_gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA | GMAC_RSR_HNO); /* Clear all status bits in the transmit status register */ gmac_clear_tx_status(p_gmac, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE | GMAC_TSR_TXGO | GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_HRESP ); /* Enable the copy of data into the buffers ignore broadcasts, and not copy FCS. */ gmac_set_config(p_gmac, gmac_get_config(p_gmac) | GMAC_NCFGR_FD | GMAC_NCFGR_DBW(0) | GMAC_NCFGR_MAXFS | GMAC_NCFGR_RFCS | GMAC_NCFGR_PEN); gmac_enable_copy_all(p_gmac, p_opt->uc_copy_all_frame); gmac_disable_broadcast(p_gmac, p_opt->uc_no_boardcast); gmac_init_queue(p_gmac, p_gmac_dev); gmac_set_address(p_gmac, 0, p_opt->uc_mac_addr); #ifdef FREERTOS_USED /* Asynchronous operation requires a notification semaphore. First, * create the semaphore. */ vSemaphoreCreateBinary(netif_notification_semaphore); vQueueAddToRegistry(netif_notification_semaphore, "GMAC Sem"); /* Then set the semaphore into the correct initial state. */ xSemaphoreTake(netif_notification_semaphore, 0); #endif }