#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static t_configBlock *config; wiz_NetInfo netInfo; #define DHCP_BUFFER_SIZE 2048 static uint8_t dhcpBuffer[DHCP_BUFFER_SIZE]; #define DNS_BUFFER_SIZE MAX_DNS_BUF_SIZE static uint8_t dnsBuffer[DNS_BUFFER_SIZE]; static uint8_t sntpBuffer[MAX_SNTP_BUF_SIZE]; static t_seconds seconds = { .seconds = 0, .missedUpdates = 0, .valid = false }; const uint64_t UNIX_NTP_EPOCH_DIFF = 2208988800; extern const uint8_t DHCP_SOCK; extern const uint8_t DNS_SOCK; extern const uint8_t SNTP_SOCK; static bool networkAvailable = false; bool isNetworkAvailable() { return networkAvailable; } uint8_t* wizGetIPAddress() { return netInfo.ip; } static void wiz_cs_select(void) { HAL_GPIO_WritePin(ETHER_CS_GPIO_Port, ETHER_CS_Pin, GPIO_PIN_RESET); } static void wiz_cs_deselect(void) { HAL_GPIO_WritePin(ETHER_CS_GPIO_Port, ETHER_CS_Pin, GPIO_PIN_SET); } static uint8_t wiz_spi_readbyte(void) { uint8_t rbuf; HAL_SPI_Receive(ðerSpi, &rbuf, 1, HAL_MAX_DELAY); return rbuf; } static void wiz_spi_writebyte(uint8_t wb) { HAL_SPI_Transmit(ðerSpi, &wb, 1, HAL_MAX_DELAY); } static void wiz_spi_readburst(uint8_t* pBuf, uint16_t len) { HAL_SPI_Receive(ðerSpi, pBuf, len, HAL_MAX_DELAY); } static void wiz_spi_writeburst(uint8_t* pBuf, uint16_t len) { HAL_SPI_Transmit(ðerSpi, pBuf, len, HAL_MAX_DELAY); } static void wizReset(bool b) { HAL_GPIO_WritePin(ETHER_RES_GPIO_Port, ETHER_RES_Pin, b ? GPIO_PIN_RESET : GPIO_PIN_SET); } static void wizDHCPAssign() { coloredMsg(LOG_BLUE, "wizda"); getIPfromDHCP(netInfo.ip); coloredMsg(LOG_BLUE, "wizda, IP: %d.%d.%d.%d", netInfo.ip[0], netInfo.ip[1], netInfo.ip[2], netInfo.ip[3]); getGWfromDHCP(netInfo.gw); coloredMsg(LOG_BLUE, "wizda, GW: %d.%d.%d.%d", netInfo.gw[0], netInfo.gw[1], netInfo.gw[2], netInfo.gw[3]); getSNfromDHCP(netInfo.sn); coloredMsg(LOG_BLUE, "wizda, SN: %d.%d.%d.%d", netInfo.sn[0], netInfo.sn[1], netInfo.sn[2], netInfo.sn[3]); getDNSfromDHCP(netInfo.dns); coloredMsg(LOG_BLUE, "wizda, DNS: %d.%d.%d.%d", netInfo.dns[0], netInfo.dns[1], netInfo.dns[2], netInfo.dns[3]); wizchip_setnetinfo(&netInfo); coloredMsg(LOG_BLUE, "wizda, set netinfo again"); networkAvailable = true; show(LED_GREEN, ON); coloredMsg(LOG_BLUE, "wizda, network is available"); } static void wizDHCPUpdate() { coloredMsg(LOG_BLUE, "wizdu"); getIPfromDHCP(netInfo.ip); coloredMsg(LOG_BLUE, "wizdu, IP: %d.%d.%d.%d", netInfo.ip[0], netInfo.ip[1], netInfo.ip[2], netInfo.ip[3]); getGWfromDHCP(netInfo.gw); coloredMsg(LOG_BLUE, "wizdu, GW: %d.%d.%d.%d", netInfo.gw[0], netInfo.gw[1], netInfo.gw[2], netInfo.gw[3]); getSNfromDHCP(netInfo.sn); coloredMsg(LOG_BLUE, "wizdu, SN: %d.%d.%d.%d", netInfo.sn[0], netInfo.sn[1], netInfo.sn[2], netInfo.sn[3]); getDNSfromDHCP(netInfo.dns); coloredMsg(LOG_BLUE, "wizdu, DNS: %d.%d.%d.%d", netInfo.dns[0], netInfo.dns[1], netInfo.dns[2], netInfo.dns[3]); wizchip_setnetinfo(&netInfo); coloredMsg(LOG_BLUE, "wizdu, netinfo updated"); } static void wizDHCPHandler(void *handle) { static uint8_t lastDhcpRes = 255; uint8_t res = DHCP_run(); if (lastDhcpRes != res) { coloredMsg(LOG_BLUE, "wizdh, dhcp state has changed: %d", res); lastDhcpRes = res; } } bool wizDnsQuery(char *name, uint8_t *ip) { bool retCode = false; coloredMsg(LOG_BLUE, "wizdq, querying for %s", name); int8_t res = DNS_run(netInfo.dns, (uint8_t*) name, ip); coloredMsg(LOG_BLUE, "wizdq, DNS_run returns %d", res); retCode = (res == 1); if (retCode) { coloredMsg(LOG_BLUE, "wizdq, got address %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); } return retCode; } static void wizSNTPHandler(void *handle) { if (networkAvailable) { coloredMsg(LOG_BLUE, "wizsh, about to call SNTP"); uint8_t ntpServer[4]; if (wizDnsQuery(NTP_SERVER, ntpServer)) { SNTP_init(SNTP_SOCK, ntpServer, 0, sntpBuffer); bool updated = false; for (uint8_t i = 0; i < 16; i++) { datetime curTime; int8_t res = SNTP_run(&curTime); uint64_t receivedSeconds = curTime.seconds - UNIX_NTP_EPOCH_DIFF; if (res == 1) { if (seconds.seconds != receivedSeconds) { coloredMsg(LOG_BLUE, "wizsh, time deviation: %lu %lu", seconds.seconds, receivedSeconds); } else { coloredMsg(LOG_BLUE, "wizsh, time still matching"); } seconds.seconds = receivedSeconds; seconds.valid = true; seconds.missedUpdates = 0; updated = true; coloredMsg(LOG_BLUE, "wizsh, curTime: %lu", seconds.seconds); break; } } if (! updated) { coloredMsg(LOG_BLUE, "wizsh, time update failed"); seconds.missedUpdates += 1; } } else { seconds.missedUpdates += 1; coloredMsg(LOG_BLUE, "wizsh, error when querying ntp server name"); } } } static void wizSecondsHandler(void *handle) { seconds.seconds += 1; } t_seconds* wizGetSeconds() { return &seconds; } static void wizPhyLinkHandler(void *handle) { // this handler is anyhow called with a 1s period, so we reuse it for the DNS timer DNS_time_handler(); static uint8_t lastStablePhyLink = 255; static bool dhcpInitialized = false; static bool sntpInitialized = false; uint8_t phyLink = 0; int8_t res = ctlwizchip(CW_GET_PHYLINK, (void*) &phyLink); if (lastStablePhyLink != phyLink) { coloredMsg(LOG_BLUE, "wizplh, ctlwizchip returns %d, phy link changed to %d", res, phyLink); lastStablePhyLink = phyLink; if (phyLink == PHY_LINK_ON) { // start DHCP handler memset(dhcpBuffer, 0, DHCP_BUFFER_SIZE); reg_dhcp_cbfunc(wizDHCPAssign, wizDHCPUpdate, NULL); DHCP_init(DHCP_SOCK, dhcpBuffer); coloredMsg(LOG_BLUE, "wizplh, DHCP initialized"); // run the dhcp handler the first time after 1s and then every 100ms schAdd(wizDHCPHandler, NULL, 1000, 1000); coloredMsg(LOG_BLUE, "wizplh, DHCP handler scheduled"); dhcpInitialized = true; schAdd(wizSNTPHandler, NULL, 0, 60*1000); coloredMsg(LOG_BLUE, "wizplh, SNTP handler scheduled"); sntpInitialized = true; } else { networkAvailable = false; show(LED_GREEN, BLINK); coloredMsg(LOG_BLUE, "wizplh, network is unavailable"); // stop DHCP handler if (dhcpInitialized) { DHCP_stop(); coloredMsg(LOG_BLUE, "wizplh, DHCP stopped"); schDel(wizDHCPHandler, NULL); coloredMsg(LOG_BLUE, "wizplh, DHCP handler unscheduled"); dhcpInitialized = false; } if (sntpInitialized) { schDel(wizSNTPHandler, NULL); coloredMsg(LOG_BLUE, "wizplh, SNTP handler unscheduled"); sntpInitialized = false; } } } } int wizInit() { config = getConfig(); netInfo.dhcp = NETINFO_DHCP; memcpy(netInfo.mac, config->macAddress, 6); coloredMsg(LOG_BLUE, "wizI, resetting Ethernet module"); wizReset(true); activeDelay(2); wizReset(false); activeDelay(50); coloredMsg(LOG_BLUE, "wizI, registering callbacks"); reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect); coloredMsg(LOG_BLUE, "wizI, cs funcs registed"); reg_wizchip_spi_cbfunc(wiz_spi_readbyte, wiz_spi_writebyte); coloredMsg(LOG_BLUE, "wizI, spi funcs registed"); reg_wizchip_spiburst_cbfunc(wiz_spi_readburst, wiz_spi_writeburst); coloredMsg(LOG_BLUE, "wizI, spi burst funcs registed"); coloredMsg(LOG_BLUE, "wizI, initializing Ethernet module"); uint8_t bufSizes[] = { 2, 2, 2, 2, 2, 2, 2, 2 }; int8_t res = wizchip_init(bufSizes, bufSizes); coloredMsg(LOG_BLUE, "wizI, module driver returned %d", res); wizphy_reset(); activeDelay(5); coloredMsg(LOG_BLUE, "wizI, reset phy"); wiz_PhyConf wpc; wpc.mode = PHY_MODE_MANUAL; wpc.speed = PHY_MODE_MANUAL; wpc.duplex = PHY_DUPLEX_FULL; wizphy_setphyconf(&wpc); activeDelay(5); coloredMsg(LOG_BLUE, "wizI, phy config set"); wizchip_setnetinfo(&netInfo); coloredMsg(LOG_BLUE, "wizI, netinfo set to Ethernet module"); res = wizchip_setnetmode(NM_FORCEARP); // and not NM_PINGBLOCK coloredMsg(LOG_BLUE, "wizI, set netmode, result is %d", res); uint8_t buf[6]; res = ctlwizchip(CW_GET_ID, (void*) buf); coloredMsg(LOG_BLUE, "wizI, CW_GET_ID: %d %02x %02x %02x %02x %02x %02x", res, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); DNS_init(DNS_SOCK, dnsBuffer); schAdd(wizPhyLinkHandler, NULL, 0, 1000); coloredMsg(LOG_BLUE, "wizI, PhyLink handler scheduled"); schAdd(wizSecondsHandler, NULL, 0, 1000); coloredMsg(LOG_BLUE, "wizI, Seconds handler scheduled"); return 0; }