From 379b0ec3e5eacdde822966c84062bea41da7ae89 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 Feb 2019 19:47:19 +0000 Subject: Working --- app/ATTIC/debug_eth.c | 105 ++++++++++++++ app/ATTIC/lwip_glue.c | 374 ++++++++++++++++++++++++++++++++++++++++++++++++++ app/Makefile | 3 + app/abs.c | 42 +++--- app/gps.c | 37 ++--- app/lwip_glue.c | 323 +------------------------------------------ app/main.c | 35 ++--- app/msf.c | 4 +- app/ntp.c | 74 +++++++--- app/pll.c | 9 +- app/prototypes.h | 3 + app/steth.c | 77 ++++++----- 12 files changed, 650 insertions(+), 436 deletions(-) create mode 100644 app/ATTIC/debug_eth.c create mode 100644 app/ATTIC/lwip_glue.c diff --git a/app/ATTIC/debug_eth.c b/app/ATTIC/debug_eth.c new file mode 100644 index 0000000..2742eeb --- /dev/null +++ b/app/ATTIC/debug_eth.c @@ -0,0 +1,105 @@ +#include "project.h" + +/*---------------------------------------------------------------------------*/ +/** @brief Process pending SMI transaction and wait to be done. + */ +static void my_eth_smi_transact(void) +{ +TRACE; + /* Begin transaction. */ + ETH_MACMIIAR |= ETH_MACMIIAR_MB; +TRACE; + + /* Wait for not busy. */ + while (ETH_MACMIIAR & ETH_MACMIIAR_MB); +TRACE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Write 16-bit register to the PHY + * + * @param[in] phy uint8_t ID of the PHY (defaults to 1) + * @param[in] reg uint8_t Register address + * @param[in] data uint16_t Data to write + */ +void my_eth_smi_write(uint8_t phy, uint8_t reg, uint16_t data) +{ + /* Write operation MW=1*/ + ETH_MACMIIAR = (ETH_MACMIIAR & ETH_MACMIIAR_CR) | /* save clocks */ + (phy << ETH_MACMIIAR_PA_SHIFT) | + (reg << ETH_MACMIIAR_MR_SHIFT) | + ETH_MACMIIAR_MW; + + ETH_MACMIIDR = data & ETH_MACMIIDR_MD; +TRACE; + + my_eth_smi_transact(); +TRACE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read the 16-bit register from the PHY + * + * @param[in] phy uint8_t ID of the PHY (defaults to 1) + * @param[in] reg uint8_t Register address + * @returns uint16_t Readed data + */ +uint16_t my_eth_smi_read(uint8_t phy, uint8_t reg) +{ + /* Read operation MW=0*/ + ETH_MACMIIAR = (ETH_MACMIIAR & ETH_MACMIIAR_CR) | /* save clocks */ + (phy << ETH_MACMIIAR_PA_SHIFT) | + (reg << ETH_MACMIIAR_MR_SHIFT); + +TRACE; + my_eth_smi_transact(); +TRACE; + + return (uint16_t)(ETH_MACMIIDR & ETH_MACMIIDR_MD); +} + + +void my_phy_reset(uint8_t phy) +{ +unsigned i; +TRACE; + my_eth_smi_write(phy, PHY_REG_BCR, PHY_REG_BCR_RESET); + + +for (i=0;i<0x20;++i){ +printf("%x %x\n",i,my_eth_smi_read(phy,i)); +} + + +TRACE; + + while (my_eth_smi_read(phy, PHY_REG_BCR) & PHY_REG_BCR_RESET); +TRACE; + +delay_ms(100); +} + + +void my_eth_init(uint8_t phy, enum eth_clk clock) +{ + ETH_MACMIIAR = clock; +TRACE; + my_phy_reset(phy); +TRACE; + + ETH_MACCR = ETH_MACCR_CSTF | ETH_MACCR_FES | ETH_MACCR_DM | + ETH_MACCR_APCS | ETH_MACCR_RD; + ETH_MACFFR = ETH_MACFFR_RA | ETH_MACFFR_PM; + ETH_MACHTHR = 0; /* pass all frames */ + ETH_MACHTLR = 0; + ETH_MACFCR = (0x100 << ETH_MACFCR_PT_SHIFT); + ETH_MACVLANTR = 0; + ETH_DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_DFRF | + ETH_DMAOMR_TSF | ETH_DMAOMR_FEF | ETH_DMAOMR_OSF; + ETH_DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_FB | + (32 << ETH_DMABMR_RDP_SHIFT) | (32 << ETH_DMABMR_PBL_SHIFT) | + ETH_DMABMR_PM_2_1 | ETH_DMABMR_USP; +TRACE; +} + + diff --git a/app/ATTIC/lwip_glue.c b/app/ATTIC/lwip_glue.c new file mode 100644 index 0000000..0fb7922 --- /dev/null +++ b/app/ATTIC/lwip_glue.c @@ -0,0 +1,374 @@ +#include + +struct netif if0; + + +uint32_t sys_now (void) +{ + return ticks; +} + +void dispatch_lwip (void) +{ +#if 0 + if (link_lost()) + netif_set_down (&if0); + + if (link_gained()) + netif_set_up (&if0); +#endif + + sys_check_timeouts(); + +#if 0 + + /* Fine DHCP periodic process every 500ms */ + if (localtime - DHCPfineTimer >= DHCP_FINE_TIMER_MSECS) { + DHCPfineTimer = localtime; + dhcp_fine_tmr(); + + if ((DHCP_state != DHCP_ADDRESS_ASSIGNED) && (DHCP_state != DHCP_TIMEOUT)) { + /* toggle LED1 to indicate DHCP on-going process */ + STM_EVAL_LEDToggle (LED1); + + /* process DHCP state machine */ + LwIP_DHCP_Process_Handle(); + } + } + + /* DHCP Coarse periodic process every 60s */ + if (localtime - DHCPcoarseTimer >= DHCP_COARSE_TIMER_MSECS) { + DHCPcoarseTimer = localtime; + dhcp_coarse_tmr(); + } + +#endif +} + + + +void start_lwip (void) +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + // uint8_t macaddress[6]={0,0,0,0,0,1}; + + lwip_init(); + + IP4_ADDR (&ipaddr, 10, 32, 94, 9); + IP4_ADDR (&netmask, 255, 255, 255, 0); + IP4_ADDR (&gw, 10, 32, 94, 1); + + + netif_add (&if0, &ipaddr, &netmask, &gw, NULL, steth_lwip_init , ethernet_input); + + /* Registers the default network interface.*/ + netif_set_default (&if0); + + netif_set_up (&if0); + + +} + + + + + + + + + + + +#if 0 +/** + ****************************************************************************** + * @file netconf.c + * @author MCD Application Team + * @version V1.0.0 + * @date 11/20/2009 + * @brief Network connection configuration + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2009 STMicroelectronics

+ */ + +#include "lwip/memp.h" +#include "lwip/tcp.h" +#include "lwip/udp.h" +#include "netif/etharp.h" +//include "lwip/dhcp.h" +#include "ethernetif.h" +#include +#include "stm32f4x7_eth.h" +#include +#include "netconf.h" + +struct netif netif; +uint32_t TCPTimer = 0; +uint32_t ARPTimer = 0; + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Driver Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Driver Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Put ethernet related stuff in struct so it causes less namespace pollution + * and is easier to access from debugger */ +struct { + uint8_t connected_; + uint16_t lost_links_; + uint32_t last_link_up_time_; +} ethernet_state; + +void send_raw_packet() +{ + //ETH_TxPkt_ChainMode(l); +} + +/** + * @brief Initializes the lwIP stack + * @param None + * @retval None + * + * Should only be called once at start-up. Ethernet interface does not + * need to have link for this to be called. + */ +/** \brief Checks PHY's link status + * \returns true if there is a link, false if there is an error, or no link + */ +uint8_t checkEthernetLink() +{ + // PHY_BSR -- defined in stm32f4x7_eth.h + // The basic status register number for the Micrel KSZ8051MLL PHY is 0x1 + // If MDIO read times out, ETH_ReadPHYRegister returns ETH_ERROR (0) which make link look down + uint8_t has_link = (ETH_ReadPHYRegister (PHY_ADDRESS, PHY_BSR) & PHY_Linked_Status) ? 1 : 0; + return has_link; +} + +/** + * @brief Called when a frame is received + * @param None + * @retval None + */ +void LwIP_Pkt_Handle (void) +{ + /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */ + ethernetif_input (&if0); +} + +/** + * @brief LwIP periodic tasks + * @param localtime the current LocalTime value + * @retval None + */ +#ifdef USE_DHCP +/** + * @brief LwIP_DHCP_Process_Handle + * @param None + * @retval None + */ +void LwIP_DHCP_Process_Handle() +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + uint8_t iptab[4]; + uint8_t iptxt[20]; + + switch (DHCP_state) { + case DHCP_START: { + dhcp_start (&if0); + IPaddress = 0; + DHCP_state = DHCP_WAIT_ADDRESS; + } + break; + + case DHCP_WAIT_ADDRESS: { + /* Read the new IP address */ + IPaddress = netif.ip_addr.addr; + + if (IPaddress != 0) { + DHCP_state = DHCP_ADDRESS_ASSIGNED; + + /* Stop DHCP */ + dhcp_stop (&if0); + } else { + /* DHCP timeout */ + if (netif.dhcp->tries > MAX_DHCP_TRIES) { + DHCP_state = DHCP_TIMEOUT; + + /* Stop DHCP */ + dhcp_stop (&if0); + + /* Static address used */ + IP4_ADDR (&ipaddr, IP_ADDR0 , IP_ADDR1 , IP_ADDR2 , IP_ADDR3); + IP4_ADDR (&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR (&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr (&if0, &ipaddr , &netmask, &gw); + } + } + } + break; + + default: + break; + } +} +#endif + +/*void ETH_IRQHandler(void) +{ + while(ETH_GetRxPktSize() != 0) + { + LwIP_Pkt_Handle(); + } + + ETH_DMAClearITPendingBit(ETH_DMA_IT_R); + ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS); +}*/ + +/** + * @brief Configures the Ethernet Interface + * @param None + * @retval ETH_ERROR on failure, ETH_SUCCESS on success + * + * Should be called everytime PHY gets a new link (in case link speed or duplex is differnet) + * Before being called, ethernet link should be set to "down" with netif_set_down() + * This prevents LwIP from attempt to send packets on link + */ +uint32_t Ethernet_Init (void) +{ + /* Enable SYSCFG clock */ + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + + /* Enable ETHERNET clock */ + //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx | + // RCC_AHBPeriph_ETH_MAC_Rx, ENABLE); + //RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; + + ETH_InitTypeDef ETH_InitStructure; + + /* Configure MII_RMII selection bit */ + SYSCFG_ETH_MediaInterfaceConfig (SYSCFG_ETH_MediaInterface_RMII); + + /* Reset ETHERNET on AHB Bus */ + ETH_DeInit(); + + /* Software reset */ + ETH_SoftwareReset(); + //RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + + /* Wait for software reset */ + while (ETH_GetSoftwareResetStatus() == SET); + + RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; + + /* ETHERNET Configuration ------------------------------------------------------*/ + /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */ + ETH_StructInit (Ð_InitStructure); + + /* Fill ETH_InitStructure parametrs */ + /*------------------------ MAC -----------------------------------*/ + ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable ; + ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable; + ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable; + ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; + ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable; + ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable; + ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; + ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect; + ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; +#ifdef CHECKSUM_BY_HARDWARE + ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable; +#endif + + /*------------------------ DMA -----------------------------------*/ + + /* When we use the Checksum offload feature, we need to enable the Store and Forward mode: + the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum, + if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */ + ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable; + ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable; + ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable; + + ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable; + ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable; + ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable; + ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; + ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable; + ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; + ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat; + ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1; + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig (ETH_MAC_Address0, netif.hwaddr); + + /* Configure Ethernet */ + if (ETH_Init (Ð_InitStructure, PHY_ADDRESS) == ETH_ERROR) + return ETH_ERROR; + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit (DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit (DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + +#ifdef CHECKSUM_BY_HARDWARE + + /* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */ + for (int i = 0; i < ETH_TXBUFNB; i++) + ETH_DMATxDescChecksumInsertionConfig (&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull); + +#endif + + /* Note: TCP, UDP, ICMP checksum checking for received frame are enabled in DMA config */ + + /* Enable MAC and DMA transmission and reception */ + ETH_Start(); + + /* Enable the Ethernet Rx Interrupt */ + // ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE); + + // NVIC_InitTypeDef NVIC_InitStructure; + + /* MACCR has an errata where writes that occur next to each other can be ignored. + * Have MACCR writen after a delay to guarentee that the register write goes through. + */ + { + uint32_t i = 28 * 4; // delay about 4 us + + while (i-- > 0) + __asm__ ("nop"); + } + ETH_MACReceptionCmd (ENABLE); + + /* Enable the Ethernet global Interrupt + NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); */ + // NVIC_SetPriority(ETH_IRQn, 3); + // NVIC_EnableIRQ(ETH_IRQn); + + return ETH_SUCCESS; +} +#endif diff --git a/app/Makefile b/app/Makefile index 7a0f1a9..c325681 100644 --- a/app/Makefile +++ b/app/Makefile @@ -107,3 +107,6 @@ EXTRA_CLEAN=${OBJS} ${LWIP_OBJS:%.o=%.d} almanac.c tidy: astyle -A3 -s2 --attach-extern-c -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} + +slog: + sympathy -d /dev/ttyUSB5 -b 38400 -L ../log -w 132x59 -s diff --git a/app/abs.c b/app/abs.c index a91787c..2ed8dd4 100644 --- a/app/abs.c +++ b/app/abs.c @@ -15,40 +15,40 @@ uint64_t abs_extend (uint32_t now) if (!m) { - ret = high_tick; - ret <<= 32; - ret |= now; + ret = high_tick; + ret <<= 32; + ret |= now; - if ((now>THREE_QUARTERS) &&( now<=ONE)) { - high_tick++; - m=1; - } + if ((now > THREE_QUARTERS) && (now <= ONE)) { + high_tick++; + m = 1; + } } else { - if (nowQUARTER) &&( now QUARTER) && (now < HALF)) + m = 0; + } - return ret; + return ret; } -void abs_meh(void) +void abs_meh (void) { -printf("HT %d\n",(int) high_tick); + printf ("HT %d\n", (int) high_tick); } diff --git a/app/gps.c b/app/gps.c index b0bc433..7e2fd1b 100644 --- a/app/gps.c +++ b/app/gps.c @@ -185,25 +185,30 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) ptr += ubx_get_u8 (ptr, &min); ptr += ubx_get_u8 (ptr, &sec); -// printf ("gps %02d:%02d:%02d %09d\r\n", (int) hour, (int) min, (int) sec, (int) nano); + // printf ("gps %02d:%02d:%02d %09d\r\n", (int) hour, (int) min, (int) sec, (int) nano); -{ - UTC u; - EPOCH gps_time; + { + UTC u; + EPOCH gps_time; + uint32_t now; + uint64_t abs; - u.jday = 0; - u.year = year; - u.month = month; - u.mday = day; - u.hour = hour; - u.minute = min; - u.second = sec; - u.nanosecond = 0; + u.jday = 0; + u.year = year; + u.month = month; + u.mday = day; + u.hour = hour; + u.minute = min; + u.second = sec; + u.nanosecond = 0; - gps_time = time_utc_to_epoch (u); + gps_time = time_utc_to_epoch (u); - pll_set_offset (gps_time, abs); -} + + now = SCS_DWT_CYCCNT; + abs = abs_extend (now); + pll_set_offset (gps_time, abs); + } #if 0 @@ -437,7 +442,7 @@ static void gps_pps_dispatch (void) if (!v) return; - abs=abs_extend(now); + abs = abs_extend (now); diff --git a/app/lwip_glue.c b/app/lwip_glue.c index 3771c38..556fa0e 100644 --- a/app/lwip_glue.c +++ b/app/lwip_glue.c @@ -10,14 +10,6 @@ uint32_t sys_now (void) void dispatch_lwip (void) { -#if 0 - - /* check if any packet received */ - if (ETH_CheckFrameReceived()) - ethernetif_input (&if0); - -#endif - #if 0 if (link_lost()) @@ -67,34 +59,16 @@ void start_lwip (void) lwip_init(); - IP4_ADDR (&ipaddr, 10, 32, 48, 98); + IP4_ADDR (&ipaddr, 10, 32, 94, 9); IP4_ADDR (&netmask, 255, 255, 255, 0); - IP4_ADDR (&gw, 10, 32, 48, 1); - - - //Set_MAC_Address(macaddress); - - /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, - struct ip_addr *netmask, struct ip_addr *gw, - void *state, err_t (* init)(struct netif *netif), - err_t (* input)(struct pbuf *p, struct netif *netif)) + IP4_ADDR (&gw, 10, 32, 94, 1); - Adds your network interface to the netif_list. Allocate a struct - netif and pass a pointer to this structure as the first argument. - Give pointers to cleared ip_addr structures when using DHCP, - or fill them with sane numbers otherwise. The state pointer may be NULL. - The init function pointer must point to a initialization function for - your ethernet netif interface. The following code illustrates it's use.*/ - - - //netif_add(&if0, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernetif_input); netif_add (&if0, &ipaddr, &netmask, &gw, NULL, steth_lwip_init , ethernet_input); /* Registers the default network interface.*/ netif_set_default (&if0); - netif_set_up (&if0); @@ -107,296 +81,3 @@ void start_lwip (void) - - - -#if 0 -/** - ****************************************************************************** - * @file netconf.c - * @author MCD Application Team - * @version V1.0.0 - * @date 11/20/2009 - * @brief Network connection configuration - ****************************************************************************** - * @copy - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - *

© COPYRIGHT 2009 STMicroelectronics

- */ - -#include "lwip/memp.h" -#include "lwip/tcp.h" -#include "lwip/udp.h" -#include "netif/etharp.h" -//include "lwip/dhcp.h" -#include "ethernetif.h" -#include -#include "stm32f4x7_eth.h" -#include -#include "netconf.h" - -struct netif netif; -uint32_t TCPTimer = 0; -uint32_t ARPTimer = 0; - -/* Ethernet Rx & Tx DMA Descriptors */ -extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; - -/* Ethernet Driver Receive buffers */ -extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; - -/* Ethernet Driver Transmit buffers */ -extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; - -/* Global pointers to track current transmit and receive descriptors */ -extern ETH_DMADESCTypeDef *DMATxDescToSet; -extern ETH_DMADESCTypeDef *DMARxDescToGet; - -/* Put ethernet related stuff in struct so it causes less namespace pollution - * and is easier to access from debugger */ -struct { - uint8_t connected_; - uint16_t lost_links_; - uint32_t last_link_up_time_; -} ethernet_state; - -void send_raw_packet() -{ - //ETH_TxPkt_ChainMode(l); -} - -/** - * @brief Initializes the lwIP stack - * @param None - * @retval None - * - * Should only be called once at start-up. Ethernet interface does not - * need to have link for this to be called. - */ -/** \brief Checks PHY's link status - * \returns true if there is a link, false if there is an error, or no link - */ -uint8_t checkEthernetLink() -{ - // PHY_BSR -- defined in stm32f4x7_eth.h - // The basic status register number for the Micrel KSZ8051MLL PHY is 0x1 - // If MDIO read times out, ETH_ReadPHYRegister returns ETH_ERROR (0) which make link look down - uint8_t has_link = (ETH_ReadPHYRegister (PHY_ADDRESS, PHY_BSR) & PHY_Linked_Status) ? 1 : 0; - return has_link; -} - -/** - * @brief Called when a frame is received - * @param None - * @retval None - */ -void LwIP_Pkt_Handle (void) -{ - /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */ - ethernetif_input (&if0); -} - -/** - * @brief LwIP periodic tasks - * @param localtime the current LocalTime value - * @retval None - */ -#ifdef USE_DHCP -/** - * @brief LwIP_DHCP_Process_Handle - * @param None - * @retval None - */ -void LwIP_DHCP_Process_Handle() -{ - struct ip_addr ipaddr; - struct ip_addr netmask; - struct ip_addr gw; - uint8_t iptab[4]; - uint8_t iptxt[20]; - - switch (DHCP_state) { - case DHCP_START: { - dhcp_start (&if0); - IPaddress = 0; - DHCP_state = DHCP_WAIT_ADDRESS; - } - break; - - case DHCP_WAIT_ADDRESS: { - /* Read the new IP address */ - IPaddress = netif.ip_addr.addr; - - if (IPaddress != 0) { - DHCP_state = DHCP_ADDRESS_ASSIGNED; - - /* Stop DHCP */ - dhcp_stop (&if0); - } else { - /* DHCP timeout */ - if (netif.dhcp->tries > MAX_DHCP_TRIES) { - DHCP_state = DHCP_TIMEOUT; - - /* Stop DHCP */ - dhcp_stop (&if0); - - /* Static address used */ - IP4_ADDR (&ipaddr, IP_ADDR0 , IP_ADDR1 , IP_ADDR2 , IP_ADDR3); - IP4_ADDR (&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); - IP4_ADDR (&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); - netif_set_addr (&if0, &ipaddr , &netmask, &gw); - } - } - } - break; - - default: - break; - } -} -#endif - -/*void ETH_IRQHandler(void) -{ - while(ETH_GetRxPktSize() != 0) - { - LwIP_Pkt_Handle(); - } - - ETH_DMAClearITPendingBit(ETH_DMA_IT_R); - ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS); -}*/ - -/** - * @brief Configures the Ethernet Interface - * @param None - * @retval ETH_ERROR on failure, ETH_SUCCESS on success - * - * Should be called everytime PHY gets a new link (in case link speed or duplex is differnet) - * Before being called, ethernet link should be set to "down" with netif_set_down() - * This prevents LwIP from attempt to send packets on link - */ -uint32_t Ethernet_Init (void) -{ - /* Enable SYSCFG clock */ - RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; - - /* Enable ETHERNET clock */ - //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx | - // RCC_AHBPeriph_ETH_MAC_Rx, ENABLE); - //RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; - - ETH_InitTypeDef ETH_InitStructure; - - /* Configure MII_RMII selection bit */ - SYSCFG_ETH_MediaInterfaceConfig (SYSCFG_ETH_MediaInterface_RMII); - - /* Reset ETHERNET on AHB Bus */ - ETH_DeInit(); - - /* Software reset */ - ETH_SoftwareReset(); - //RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; - - /* Wait for software reset */ - while (ETH_GetSoftwareResetStatus() == SET); - - RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; - - /* ETHERNET Configuration ------------------------------------------------------*/ - /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */ - ETH_StructInit (Ð_InitStructure); - - /* Fill ETH_InitStructure parametrs */ - /*------------------------ MAC -----------------------------------*/ - ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable ; - ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable; - ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable; - ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; - ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable; - ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable; - ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; - ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect; - ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; -#ifdef CHECKSUM_BY_HARDWARE - ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable; -#endif - - /*------------------------ DMA -----------------------------------*/ - - /* When we use the Checksum offload feature, we need to enable the Store and Forward mode: - the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum, - if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */ - ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable; - ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable; - ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable; - - ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable; - ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable; - ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable; - ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; - ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable; - ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; - ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat; - ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1; - - /* initialize MAC address in ethernet MAC */ - ETH_MACAddressConfig (ETH_MAC_Address0, netif.hwaddr); - - /* Configure Ethernet */ - if (ETH_Init (Ð_InitStructure, PHY_ADDRESS) == ETH_ERROR) - return ETH_ERROR; - - /* Initialize Tx Descriptors list: Chain Mode */ - ETH_DMATxDescChainInit (DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); - /* Initialize Rx Descriptors list: Chain Mode */ - ETH_DMARxDescChainInit (DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); - -#ifdef CHECKSUM_BY_HARDWARE - - /* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */ - for (int i = 0; i < ETH_TXBUFNB; i++) - ETH_DMATxDescChecksumInsertionConfig (&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull); - -#endif - - /* Note: TCP, UDP, ICMP checksum checking for received frame are enabled in DMA config */ - - /* Enable MAC and DMA transmission and reception */ - ETH_Start(); - - /* Enable the Ethernet Rx Interrupt */ - // ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE); - - // NVIC_InitTypeDef NVIC_InitStructure; - - /* MACCR has an errata where writes that occur next to each other can be ignored. - * Have MACCR writen after a delay to guarentee that the register write goes through. - */ - { - uint32_t i = 28 * 4; // delay about 4 us - - while (i-- > 0) - __asm__ ("nop"); - } - ETH_MACReceptionCmd (ENABLE); - - /* Enable the Ethernet global Interrupt - NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); */ - // NVIC_SetPriority(ETH_IRQn, 3); - // NVIC_EnableIRQ(ETH_IRQn); - - return ETH_SUCCESS; -} -#endif diff --git a/app/main.c b/app/main.c index 984e74b..229674e 100644 --- a/app/main.c +++ b/app/main.c @@ -13,7 +13,7 @@ static void cmd_dispatch() switch (c) { case 'R': - scb_reset_system(); + scb_reset_system(); break; @@ -78,6 +78,7 @@ system_init (void) steth_init(); gps_init(); + ntp_init(); } @@ -91,32 +92,34 @@ main (void) printf ("Boot\r\n"); #if 0 + while (1) { - uint32_t now = SCS_DWT_CYCCNT; - uint64_t abs= abs_extend (now); - EPOCH e = pll_decompose (abs); - time_print_epoch ("TEST: ", e); - delay_ms(100); -} + uint32_t now = SCS_DWT_CYCCNT; + uint64_t abs = abs_extend (now); + EPOCH e = pll_decompose (abs); + time_print_epoch ("TEST: ", e); + delay_ms (100); + } + #endif - + while (1) { #if 0 - { - uint32_t now = SCS_DWT_CYCCNT; - uint64_t abs= abs_extend (now); - EPOCH e = pll_decompose (abs); - time_print_epoch ("TEST: ", e); - delay_ms(100); - } + { + uint32_t now = SCS_DWT_CYCCNT; + uint64_t abs = abs_extend (now); + EPOCH e = pll_decompose (abs); + time_print_epoch ("TEST: ", e); + delay_ms (100); + } - abs_meh(); + abs_meh(); #endif msf_dispatch(); diff --git a/app/msf.c b/app/msf.c index 72ad024..69790ff 100644 --- a/app/msf.c +++ b/app/msf.c @@ -90,7 +90,7 @@ static void process_bits (uint64_t abs) msf_time = time_utc_to_epoch (u); msf_time.s -= 59; -// pll_set_offset (msf_time, abs); + // pll_set_offset (msf_time, abs); stats_stamp (u, abs); dump_bits ("msfa", bitsa); @@ -183,7 +183,7 @@ void msf_dispatch (void) if (time_known) report_time (abs); -// stats(); + // stats(); } diff --git a/app/ntp.c b/app/ntp.c index 44002cc..2aa33e4 100644 --- a/app/ntp.c +++ b/app/ntp.c @@ -4,12 +4,12 @@ typedef struct { union { struct { - uint32_t li: 2; - uint32_t vn: 3; - uint32_t mode: 3; - uint32_t stratum: 8; - uint32_t poll: 8; uint32_t precision: 8; + uint32_t poll: 8; + uint32_t stratum: 8; + uint32_t mode: 3; + uint32_t vn: 3; + uint32_t li: 2; }; uint32_t word_0; }; @@ -49,36 +49,74 @@ packet (uint8_t *_p) +} +#endif +static uint64_t ntp_ts (uint64_t v) +{ + uint64_t ret; + EPOCH e = pll_decompose (v); + ret = e.ns; + ret <<= 32; + ret = ret / 1000000000; + ret = htonl (ret); + ret <<= 32; + ret |= htonl (2208988800UL + e.s); + return ret; +} +static void ntp_rx (void *arg, struct udp_pcb *s, struct pbuf *p, struct ip_addr *src_addr, u16_t port) +{ + uint32_t now = SCS_DWT_CYCCNT; + struct ip_addr dst_addr = *src_addr; + ntp_packet_t pkt; + do { + if (p->type != PBUF_POOL) break; + if (p->len < sizeof (ntp_packet_t)) break; + memcpy (&pkt, p->payload, sizeof (ntp_packet_t)); + pbuf_realloc (p, sizeof (ntp_packet_t)); + pkt.li = 0; + pkt.vn = 4; + pkt.mode = 4; + pkt.stratum = 1; + pkt.poll = 3; + pkt.precision = 0xec; + pkt.word_0 = htonl (pkt.word_0); + pkt.root_delay = htonl (0x0); + pkt.root_dispersion = htonl (0x825); + pkt.reference_id = htonl (0x47505300); + pkt.origin_ts = pkt.transmit_ts; + pkt.receive_ts = ntp_ts (abs_extend (now)); + pkt.reference_ts = ntp_ts (pll_last_update); + now = SCS_DWT_CYCCNT; + pkt.transmit_ts = ntp_ts (abs_extend (now)); + memcpy (p->payload, &pkt, sizeof (ntp_packet_t)); + udp_sendto (s, p, &dst_addr, port); + } while (0); + /* Free the p buffer */ + pbuf_free (p); +} +void ntp_init (void) +{ + struct udp_pcb *s; + s = udp_new(); + udp_bind (s, IP_ADDR_ANY, 123); - - - - - - - -} -#endif - - -void ntp_init(void) -{ + udp_recv (s, ntp_rx, NULL); } diff --git a/app/pll.c b/app/pll.c index 56e8e21..0c9ed80 100644 --- a/app/pll.c +++ b/app/pll.c @@ -19,10 +19,10 @@ int pll_valid = 0; static int warming_up = WARM_UP; -void pll_meh(void) +void pll_meh (void) { - printf (" %"PRId64" %"PRId64" %" PRId64 "\r\n", - pll_freq,offset,phase); + printf (" %"PRId64" %"PRId64" %" PRId64 "\r\n", + pll_freq, offset, phase); } @@ -96,7 +96,6 @@ void pll_dispatch (uint64_t edge) f *= (double) pll_freq; modify_pll_freq (edge, (int) f); - } pll_last_update = edge; @@ -114,7 +113,7 @@ void pll_set_offset (EPOCH epoch, uint64_t abs) offset = epoch.s - abs; pll_valid = 1; -time_known=1; + time_known = 1; } diff --git a/app/prototypes.h b/app/prototypes.h index a7d2bae..22a7334 100644 --- a/app/prototypes.h +++ b/app/prototypes.h @@ -59,12 +59,14 @@ extern void msf_dispatch(void); extern void msf_init(void); /* abs.c */ extern uint64_t abs_extend(uint32_t now); +extern void abs_meh(void); extern uint64_t abs_get(void); extern void abs_slow_tick(void); /* pll.c */ extern int64_t pll_freq; extern uint64_t pll_last_update; extern int pll_valid; +extern void pll_meh(void); extern void pll_dispatch(uint64_t edge); extern void pll_set_offset(EPOCH epoch, uint64_t abs); extern EPOCH _pll_decompose(uint64_t abs); @@ -79,6 +81,7 @@ extern EPOCH time_utc_to_epoch(UTC u); extern void time_print_utc(const char *p, UTC u); extern void time_print_epoch(const char *p, EPOCH e); /* ntp.c */ +extern void ntp_init(void); /* dcf77.c */ extern uint64_t dcf77_last_second; extern void exti15_10_isr(void); diff --git a/app/steth.c b/app/steth.c index afd68ed..5ed11c7 100644 --- a/app/steth.c +++ b/app/steth.c @@ -200,40 +200,41 @@ steth_lwip_init (struct netif *netif) #ifdef FUCKED -static void fucked_phy_reset(uint8_t phy) +static void fucked_phy_reset (uint8_t phy) { -unsigned i; - eth_smi_write(phy, PHY_REG_BCR, PHY_REG_BCR_RESET); - for (i=0;(eth_smi_read(phy, PHY_REG_BCR) & PHY_REG_BCR_RESET) && (i<1000);++i) delay_us(1000); + unsigned i; + eth_smi_write (phy, PHY_REG_BCR, PHY_REG_BCR_RESET); + + for (i = 0; (eth_smi_read (phy, PHY_REG_BCR) & PHY_REG_BCR_RESET) && (i < 1000); ++i) delay_us (1000); } -static void fucked_eth_init(uint8_t phy, enum eth_clk clock) +static void fucked_eth_init (uint8_t phy, enum eth_clk clock) { - ETH_MACMIIAR = clock; - fucked_phy_reset(phy); - - ETH_MACCR = ETH_MACCR_CSTF | ETH_MACCR_FES | ETH_MACCR_DM | - ETH_MACCR_APCS | ETH_MACCR_RD; - ETH_MACFFR = ETH_MACFFR_RA | ETH_MACFFR_PM; - ETH_MACHTHR = 0; /* pass all frames */ - ETH_MACHTLR = 0; - ETH_MACFCR = (0x100 << ETH_MACFCR_PT_SHIFT); - ETH_MACVLANTR = 0; - ETH_DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_DFRF | - ETH_DMAOMR_TSF | ETH_DMAOMR_FEF | ETH_DMAOMR_OSF; - ETH_DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_FB | - (32 << ETH_DMABMR_RDP_SHIFT) | (32 << ETH_DMABMR_PBL_SHIFT) | - ETH_DMABMR_PM_2_1 | ETH_DMABMR_USP; + ETH_MACMIIAR = clock; + fucked_phy_reset (phy); + + ETH_MACCR = ETH_MACCR_CSTF | ETH_MACCR_FES | ETH_MACCR_DM | + ETH_MACCR_APCS | ETH_MACCR_RD; + ETH_MACFFR = ETH_MACFFR_RA | ETH_MACFFR_PM; + ETH_MACHTHR = 0; /* pass all frames */ + ETH_MACHTLR = 0; + ETH_MACFCR = (0x100 << ETH_MACFCR_PT_SHIFT); + ETH_MACVLANTR = 0; + ETH_DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_DFRF | + ETH_DMAOMR_TSF | ETH_DMAOMR_FEF | ETH_DMAOMR_OSF; + ETH_DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_FB | + (32 << ETH_DMABMR_RDP_SHIFT) | (32 << ETH_DMABMR_PBL_SHIFT) | + ETH_DMABMR_PM_2_1 | ETH_DMABMR_USP; } #endif void eth_reset (void) { -unsigned i; + unsigned i; - printf("Eth_reset()\r\n"); + printf ("Eth_reset()\r\n"); rcc_periph_reset_hold (RST_ETHMAC); delay_ms (1); @@ -246,7 +247,7 @@ unsigned i; rcc_periph_reset_release (RST_ETHMAC); - delay_ms (1); + delay_ms (1); CLEAR (NRST); delay_us (1); SET (NRST); @@ -255,16 +256,17 @@ unsigned i; TRACE; ETH_DMABMR |= ETH_DMABMR_SR; - i=0; + i = 0; + while (ETH_DMABMR & ETH_DMABMR_SR) { - delay_ms(1); - i++; + delay_ms (1); + i++; - if (i>1000) { - printf("No 50MHz clock to ethernet MAC\n"); - return; - } - } + if (i > 1000) { + printf ("No 50MHz clock to ethernet MAC\n"); + return; + } + } /*MDC = HCLK / 102 (0b100) => 1.6MHz */ TRACE; @@ -274,10 +276,10 @@ unsigned i; eth_init (PHY, ETH_CLK_150_168MHZ); #endif - if (eth_smi_read (PHY, 0)==0xffff) { - fucked=1; - printf("WARNING: PHY is AWOL\r\n"); - } + if (eth_smi_read (PHY, 0) == 0xffff) { + fucked = 1; + printf ("WARNING: PHY is AWOL\r\n"); + } TRACE; phy_stat(); @@ -370,7 +372,8 @@ steth_init (void) #endif eth_start_an(); - if (fucked) delay_ms(1000); + + if (fucked) delay_ms (1000); @@ -404,7 +407,7 @@ void steth_slow_tick (void) an_happy = phy_link_an_done (PHY); - if ((!phy_link_isup (PHY) || !an_happy) && running) { + if ((!phy_link_isup (PHY) || !an_happy) && running) { printf ("stopping nic\r\n"); eth_reset(); -- cgit v1.2.3