#define NETIF_ADD_ERR -10 /* could be one of previous */
#define DHCP_MEM_ERR -11
+#define DHCP_BIND_TIMEOUT -12
/**
- * ETH module initialization.
+ * ETH module system startup initialization.
*
* Call this method before using this module.
* This method starts autonegotiation and doesn't check for end of autoneg.
- * When eth should be used, you have to check whether link is up or autoneg complete.
+ * When eth module is about to be used, you have to run rpp_eth_init_postInit()
+ * first and you should check whether link is up.
*
* @return SUCCESS if initialization successful.\n
* FAILURE if module already initialized.
*/
int8_t rpp_eth_init();
-int8_t rpp_eth_init_postInit();
+
+/**
+ * ETH module application initialization.
+ *
+ * Call this method before using eth module.
+ * This method blocks on autonegotiation till it's complete and creates tasks
+ * for lwIP (including lwIP init) and for receiving. Sets IP address using
+ * predefined static IP or DHCP. Before calling this method you must call rpp_eth_init() first.
+ *
+ * @param instNum number of EMAC instance
+ * @param macArray address assigned to link layer - when NULL RPP_MAC_ADDR is used
+ *
+ * @return SUCCESS if init successful.
+ * NETIF_ADD_ERR if lwip netif was not succesfully initialized or on low hw init error.
+ * DHCP_MEM_ERR if DHCP unsuccesfull.
+ * DHCP_BIND_TIMEOUT
+ */
+int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray);
//Generic API
/**
+ * Handles too short packets, preserves the integrity of the transmission,
+ * calls rpp_et_send_raw()
*
+ * @param netif lwIP network interface describing struct
+ * @param p buffer for data to be sent
*/
err_t rpp_eth_send(struct netif * netif, struct pbuf *p);
/**
+ * Handles transmission of data buffer p through EMAC to network.
*
+ * @param netif lwIP network interface describing struct
+ * @param p buffer for data to be sent
*/
err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *p);
/**
+ * Receives raw data and sends them upward to lwIP stack.
+ * Handles rx emac descriptors.
*
+ * @param arg netif
*/
void rpp_eth_recv_raw(void *arg);
-void EMACCore0RxIsrHandler(unsigned int instNum);
+/**
+ * Handles receiving by running rpp_eth_recv_raw()
+ *
+ * @param instNum number of EMAC instance
+ */
+void RxIntHandler(u32_t instNum);
-void EMACCore0TxIsrHandler(unsigned int instNum);
+/**
+ * Handles tx emac descriptors.
+ *
+ * @param instNum number of EMAC instance
+ */
+void TxIntHandler(u32_t instNum);
#endif /* __RPP_ETH_H */
/* Number of EMAC Instances */
#define MAX_EMAC_INSTANCE 1
+#define EMAC_CTRL_RAM_BASE_m(x) EMAC_CTRL_RAM_##x##_BASE
+#define EMAC_BASE_m(x) EMAC_##x##_BASE
+#define EMAC_CTRL_BASE_m(x) EMAC_CTRL_##x##_BASE
+#define MDIO_BASE_m(x) MDIO_##x##_BASE
/* -EMAC0- */
#define EMAC_CTRL_RAM_0_BASE EMAC_CTRL_RAM_BASE
#define EMAC_0_BASE EMAC_BASE
/* rpp startup init indicator */
static boolean_t initialized = FALSE;
+
+/******************************************************************************************************/
+
+void rpp_eth_print_macAddr(uint32_t instNum)
+{
+ u32_t temp;
+ struct hdkif *hdkif = &hdkif_data[instNum];
+ rpp_sci_printf((const char *) "MAC address: ");
+ for(temp = 0; temp < (MAC_ADDR_LEN-1); temp++) {
+ rpp_sci_printf((const char *) "%x:", hdkif->mac_addr[(MAC_ADDR_LEN - 1) - temp]);
+ }
+ rpp_sci_printf((const char *) "%x\r\n", hdkif->mac_addr[0]);
+}
+
+void rpp_eth_print_IPAddr(uint32_t instNum)
+{
+ struct netif *netif = &hdkNetIF[instNum];
+ rpp_sci_printf((const char *) "address: %x\r\nnetmask: %x\r\ngateway: %x\r\n",netif->ip_addr,netif->netmask,netif->gw);
+}
+
/******************************************************************************************************/
/* forward declare */
/* set MAC hardware address */
for(temp = 0; temp < MAC_ADDR_LEN; temp++) {
hdkif->mac_addr[temp] = mac_addr[(MAC_ADDR_LEN - 1) - temp];
- rpp_sci_printf((const char *) "%x:", mac_addr[temp]);
}
- rpp_sci_printf((const char *) "\b\r\n");
+#ifdef DEBUG
+ rpp_eth_print_macAddr(inst_num);
+#endif
}
/**
hdkif_inst_config(struct hdkif *hdkif) {
if(hdkif->inst_num == 0)
{
- hdkif->emac_base = EMAC_0_BASE;
- hdkif->emac_ctrl_base = EMAC_CTRL_0_BASE;
- hdkif->emac_ctrl_ram = EMAC_CTRL_RAM_0_BASE;
- hdkif->mdio_base = MDIO_0_BASE;
+ hdkif->emac_base = EMAC_BASE_m(0);
+ hdkif->emac_ctrl_base = EMAC_CTRL_BASE_m(0);
+ hdkif->emac_ctrl_ram = EMAC_CTRL_RAM_BASE_m(0);
+ hdkif->mdio_base = MDIO_BASE_m(0);
hdkif->phy_addr = DEFAULT_PHY_ADDR; /* Default address of PHY on "MDIO bus" (depends on PHY hw configuration) */
hdkif->phy_autoneg = PHY_auto_negotiate;
hdkif->phy_autoneg_start = PHY_start_auto_negotiate;
int8_t rpp_eth_init_postInit(uint32_t instNum, uint8_t *macArray)
{
struct netif *netif = &hdkNetIF[instNum];
- struct hdkif *hdkif;
u8_t mac_addr[MAC_ADDR_LEN] = RPP_MAC_ADDR;
/* ----- lwIP stuff ----- */
#if NO_SYS
lwip_init();
#else /* NO_SYS */
+ struct hdkif *hdkif;
/* this can be called only within post OS init */
tcpip_init(NULL,NULL); /* calls lwip_init() implicitly, starts lwIP task (thread), when started function given to tcpip_init is executed first */
#endif /* NO_SYS */
gw_addr.addr = 0;
#endif /* STATIC_IP_ADDRESS */
- rpp_sci_printf((const char *) ("netif_add\r\n"));
/* init and add new netif */
/* add new network interface to lwIP list of ifaces and initialize netif with specific function */
#if NO_SYS
netif_set_default(netif);
- rpp_sci_printf((const char *) "default netif set\r\n");
-
- rpp_sci_printf((const char *) "creating recv task\r\n");
- hdkif = (struct hdkif *) netif->state;
-
#if !NO_SYS
+ hdkif = (struct hdkif *) netif->state;
/* ----- freeRTOS elements ----- */
/* TODO: rewrite these to functions from sys_arch.* for compatibility with other systems then freeRTOS */
/* semaphore blocking receive task (rpp_eth_recv_raw) from receive operation, till RX interrupt occurs and notify it */
vSemaphoreCreateBinary(hdkif->goRX);
- rpp_sci_printf((const char *) "goRX semaphore created\r\n");
/* run task rpp_eth_recv_raw */
xTaskCreate( rpp_eth_recv_raw, "RXHandler", 500, netif, 1, NULL );
/* ----- end - freeRTOS ----- */
+#endif /* !NO_SYS */
#if STATIC_IP_ADDRESS
netif_set_up(netif);
#elif LWIP_DHCP /* STATIC_IP_ADDRESS-LWIP_DHCP */
if(dhcp_start(netif) != ERR_OK)
{
+#ifdef DEBUG
rpp_sci_printf((const char *) "dhcp mem err\r\n");
+#endif
return DHCP_MEM_ERR;
}
+#ifdef DEBUG
rpp_sci_printf((const char *) "binding DHCP\r");
+#endif
while((netif->dhcp->state != DHCP_BOUND) && (dhcpBindWait--));
+#ifdef DEBUG
if(!dhcpBindWait)
rpp_sci_printf((const char *) "dhcp binding timeout...\r\n");
-#else /* LWIP_DHCP-LWIP_AUTOIP */
+#endif
+#else /* LWIP_DHCP-LWIP_AUTOIP FIXME: there should be some kind of waiting till ip is assigned */
autoip_start(netif);
#endif /* STATIC_IP_ADDRESS-LWIP_DHCP-LWIP_AUTOIP */
- rpp_sci_printf((const char *) "IP address assigned\r\n");
- rpp_sci_printf((const char *) "address: %x\r\nnetmask: %x\r\ngateway: %x\r\n",netif->ip_addr,netif->netmask,netif->gw);
+#ifdef DEBUG
+ rpp_eth_print_IPAddr(instNum);
+#endif
/* ----- end - lwIP stuff ----- */
-#endif /* !NO_SYS */
- rpp_sci_printf((const char *) "postInit finished");
-
return SUCCESS;
}
*/
netif->output = etharp_output;
netif->linkoutput = rpp_eth_send;
- rpp_sci_printf((const char *) "up to finish setting of hw - postInit\r\n");
return rpp_eth_hw_init_postInit(netif);
}
}
if(!physAlive)
{
+#ifdef DEBUG
rpp_sci_printf((const char *) "no phy found, phys: %d\r\n", physAlive);
+#endif
return NO_PHY_ALIVE;
}
#else
+#ifdef DEBUG
rpp_sci_printf((const char *) "default phy not alive\r\n");
+#endif
return DFLT_PHY_NOT_ALIVE;
#endif
}
rxch = &(hdkif->rxch);
txch = &(hdkif->txch);
+#ifdef DEBUG
rpp_sci_printf((const char *) "autoneg started - check on cable if it's connected!\r\n");
+#endif
/*
last_txbd->next = txch->free_head;
/* Initialize the descriptors for the RX channel */
- rxch->active_head = (volatile struct emac_rx_bd*)(curr_txbd); /* FIXED: removed '+ 1' and three lines later '-1' */
+ rxch->active_head = (volatile struct emac_rx_bd*)(curr_txbd);
rxch->free_head = NULL;
rxch->freed_pbuf_len = 0;
num_bd = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(struct emac_rx_bd));
/* wait for autonegotiation to be done - FIXME: add waitTicks type waiting */
while(hdkif->phy_autoneg_is_done(hdkif->mdio_base, hdkif->phy_addr) == FALSE);
- rpp_sci_printf((const char *) "\r\n aneg finished \r\n");
+#ifdef DEBUG
+ rpp_sci_printf((const char *) "aneg finished \r\n");
+#endif
/* check if phy link is up - it is when autoneg was completed succesfully */
/* if(!PHY_link_status_get(hdkif->mdio_base, hdkif->phy_addr, 3))
{
+#ifdef DEBUG
rpp_sci_printf((const char *) "Link is down\r\n");
+#endif
return PHY_LINK_DOWN;
}*/
} else if (regContent & (PHY_100BASETX_m | PHY_10BASET_m)) {
EMACDuplexSet(hdkif->emac_base, EMAC_DUPLEX_HALF);
} else {
+#ifdef DEBUG
rpp_sci_printf((const char *) "Unknown duplex mode\r\n");
+#endif
return UNKN_DUPLEX_MODE;
}
return SUCCESS;
}
-/*
-void rpp_eth_recv(void *arg)
-{
- struct pbuf *p;
- struct netif *inp;
-*/
- /*netif->input(p, inp);*/
-/*
- return SUCCESS;
-}
-*/
-
err_t rpp_eth_send_raw(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
volatile struct emac_tx_bd *curr_bd, *active_head, *bd_end;
+ struct hdkif *hdkif;
struct txch *txch;
- txch = &(((struct hdkif *)netif->state)->txch);
+ hdkif = (struct hdkif *) netif->state;
+ txch = &(hdkif->txch);
/* Get the buffer descriptor which is free to transmit */
/* For the first time, write the HDP with the filled bd */
if(txch->active_tail == NULL) {
- EMACTxHdrDescPtrWrite(EMAC_BASE, (unsigned int)(active_head), CHANNEL);
+ EMACTxHdrDescPtrWrite(hdkif->emac_base, (unsigned int)(active_head), CHANNEL);
}
/*
* Chain the bd's. If the DMA engine, already reached the end of the chain,
if(EMAC_DSC_FLAG_EOQ == (curr_bd->flags_pktlen & EMAC_DSC_FLAG_EOQ))
{
/* Don't write to TX0HDP until it turns to zero - because EOQ was set, it should be zero already */
- while (0 != *((uint32_t *) (EMAC_BASE + EMAC_TXHDP(CHANNEL)) ));
+ while (0 != *((uint32_t *) (hdkif->emac_base + EMAC_TXHDP(CHANNEL)) ));
/* Write the Header Descriptor Pointer and start DMA */
- EMACTxHdrDescPtrWrite(EMAC_BASE, (unsigned int)(active_head), CHANNEL);
+ EMACTxHdrDescPtrWrite(hdkif->emac_base, (unsigned int)(active_head), CHANNEL);
}
}
struct rxch *rxch;
rxch = &(hdkif->rxch);
-
+#if !NO_SYS
for(;;)
{
sys_arch_sem_wait(&(hdkif->goRX), 0);
+#endif
/* Get the bd which contains the earliest filled data */
curr_bd = rxch->active_head;
}
/* Acknowledge that this packet is processed */
- EMACRxCPWrite(EMAC_BASE, CHANNEL, (unsigned int)processed_bd);
+ EMACRxCPWrite(hdkif->emac_base, CHANNEL, (unsigned int)processed_bd);
rxch->active_head = curr_bd;
*/
if(curr_tail->flags_pktlen & EMAC_DSC_FLAG_EOQ)
{
- EMACRxHdrDescPtrWrite(EMAC_BASE, (u32_t)(rxch->free_head), CHANNEL);
+ EMACRxHdrDescPtrWrite(hdkif->emac_base, (u32_t)(rxch->free_head), CHANNEL);
}
rxch->free_head = curr_bd;
}
curr_bd = rxch->active_head;
}
- EMACCoreIntAck(EMAC_BASE, EMAC_INT_CORE0_RX);
+ EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
+#if !NO_SYS
}
+#endif
}
-void EMACCore0RxIsrHandler(unsigned int instNum)
+void RxIntHandler(u32_t instNum)
{
#if !NO_SYS
/*
}
*/
#else
+ rpp_eth_recv_raw((void *) &hdkNetIF[instNum]);
#endif
}
-void EMACCore0TxIsrHandler(unsigned int instNum)
+void TxIntHandler(u32_t instNum)
{
+ struct hdkif *hdkif = &hdkif_data[instNum];
struct txch *txch = &(hdkif_data[instNum].txch);
volatile struct emac_tx_bd *curr_bd, *next_bd_to_process;
}
/* Acknowledge the EMAC and free the corresponding pbuf */
- EMACTxCPWrite(EMAC_BASE, CHANNEL, (uint32_t)curr_bd);
+ EMACTxCPWrite(hdkif->emac_base, CHANNEL, (uint32_t)curr_bd);
pbuf_free((struct pbuf *)curr_bd->pbuf);
curr_bd = next_bd_to_process;
}
- EMACCoreIntAck(EMAC_BASE, EMAC_INT_CORE0_TX);
+ EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
}
#endif /* rppCONFIG_INCLUDE_ETH */