Advertisement
Guest User

Untitled

a guest
Jan 18th, 2018
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.33 KB | None | 0 0
  1. #include <stm32f4xx_hal.h>
  2. #include <string.h>
  3. #include "ethernetif.h"
  4.  
  5. #include "NetworkDefaults.h"
  6.  
  7. #include "lwip/init.h"
  8. #include "lwip/netif.h"
  9. #include "lwip/tcpip.h"
  10. #include "lwip/dhcp.h"
  11. #include "lwip/api.h"
  12. #include "lwip/opt.h"
  13. #include "lwip/timeouts.h"
  14. #include "netif/etharp.h"
  15.  
  16. // TLK110 datasheet, page 5
  17. #define PHY_ADDR        0x01
  18.  
  19. // TLK110 Registers
  20. #define PHY_MISR1       0x0012
  21. #define PHY_BMSR        0x0001
  22.  
  23. // TLK110 bits
  24. #define PHY_LINK_STATUS (uint16_t)(1 << 2)
  25.  
  26. static ETH_HandleTypeDef EthHandle;
  27.  
  28. __ALIGN_BEGIN ETH_DMADescTypeDef  DMARxDscrTab[ETH_RXBUFNB] __ALIGN_END; // Ethernet Rx MA Descriptor
  29. __ALIGN_BEGIN ETH_DMADescTypeDef  DMATxDscrTab[ETH_TXBUFNB] __ALIGN_END; // Ethernet Tx DMA Descriptor
  30. __ALIGN_BEGIN uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __ALIGN_END; // Ethernet RX buffer
  31. __ALIGN_BEGIN uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __ALIGN_END; // Ethernet TX buffer
  32.  
  33. static err_t low_level_output(struct netif *netif, struct pbuf *p);
  34. static struct pbuf * low_level_input(struct netif *netif);
  35. static void InitPhyInterrupt(void);
  36. static uint8_t Tlk110EnableInterrupts(void);
  37. static void Tlk110TestRead(void);
  38.  
  39. void low_level_init(struct netif *netif)
  40. {
  41.     GPIO_InitTypeDef GPIO_InitStructure;
  42.     uint8_t macaddress[6] = {MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, MAC_ADDR3, MAC_ADDR4, MAC_ADDR5};
  43.  
  44.     // Enable clocks
  45.     __HAL_RCC_ETH_CLK_ENABLE();
  46.     __HAL_RCC_GPIOA_CLK_ENABLE();
  47.     __HAL_RCC_GPIOB_CLK_ENABLE();
  48.     __HAL_RCC_GPIOC_CLK_ENABLE();
  49.  
  50.     /*
  51.      *  TapBot ETH pins
  52.      *
  53.         RMII_REF_CLK ----------------------> PA1
  54.         RMII_MDIO -------------------------> PA2
  55.         RMII_MDC --------------------------> PC1
  56.         RMII_MII_CRS_DV -------------------> PA7
  57.         RMII_MII_RXD0 ---------------------> PC4
  58.         RMII_MII_RXD1 ---------------------> PC5
  59.         RMII_MII_TX_EN --------------------> PB11
  60.         RMII_MII_TXD0 ---------------------> PB12
  61.         RMII_MII_TXD1 ---------------------> PB13
  62.     */
  63.    
  64.     // Common settings for RMII/MDC lines
  65.     GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  66.     GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
  67.     GPIO_InitStructure.Pull = GPIO_NOPULL;
  68.     GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
  69.    
  70.     // RMII_REF_CLK, RMII_MDIO, RMII_MII_CRS_DV
  71.     GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
  72.     HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
  73.  
  74.     // RMII_MII_TX_EN, RMII_MII_TXD0, RMII_MII_TXD1
  75.     GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
  76.     HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  77.  
  78.     // RMII_MDC, RMII_MII_RXD0, RMII_MII_RXD1
  79.     GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
  80.     HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
  81.  
  82.     // Enable ethernet interrupts
  83.     HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
  84.     HAL_NVIC_EnableIRQ(ETH_IRQn);
  85.    
  86.     // Configure the Eth MAC hardware
  87.     EthHandle.Instance              = ETH;  
  88.     EthHandle.Init.MACAddr          = macaddress;
  89.     EthHandle.Init.AutoNegotiation  = ETH_AUTONEGOTIATION_ENABLE;
  90.     EthHandle.Init.Speed            = ETH_SPEED_100M;
  91.     EthHandle.Init.DuplexMode       = ETH_MODE_FULLDUPLEX;
  92.     EthHandle.Init.MediaInterface   = ETH_MEDIA_INTERFACE_RMII;
  93.     EthHandle.Init.RxMode           = ETH_RXINTERRUPT_MODE;
  94.     EthHandle.Init.ChecksumMode     = ETH_CHECKSUM_BY_HARDWARE;
  95.     EthHandle.Init.PhyAddress       = PHY_ADDR;
  96.    
  97.     // Commit eth config
  98.     if(HAL_ETH_Init(&EthHandle) == HAL_OK)
  99.     {
  100.         printf("Init OK!\r\n");
  101.     }
  102.  
  103.     // Initialize Tx Descriptors list: Chain Mode
  104.     HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
  105.      
  106.     // Initialize Rx Descriptors list: Chain Mode
  107.     HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
  108.  
  109.     // Enable Eth MAC/DMA
  110.     if(HAL_ETH_Start(&EthHandle) == HAL_OK)
  111.     {
  112.         printf("Link up!\r\n");
  113.         netif_set_link_up(netif);
  114.     }
  115. }
  116.  
  117. void ethernetif_check_link_state(struct netif *netif)
  118. {
  119.     uint32_t tmp;
  120.  
  121.     // Read back for verification
  122.     if(HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BMSR, &tmp) != HAL_OK)
  123.     {
  124.         printf("Read fail!\r\n");
  125.         return;
  126.     }
  127.    
  128.     if (tmp & (1 << 2))
  129.     {
  130.         printf("Link up!!!!\r\n");
  131.         netif_set_link_up(netif);
  132.     }
  133.     else
  134.     {
  135.         printf("Link down...\r\n");
  136.         netif_set_link_down(netif);
  137.     }
  138.  
  139. }
  140.  
  141. err_t ethernetif_init(struct netif *netif)
  142. {
  143.     // MAC address length
  144.     netif->hwaddr_len = ETHARP_HWADDR_LEN;
  145.    
  146.     // Copy MAC address
  147.     netif->hwaddr[0] =  MAC_ADDR0;
  148.     netif->hwaddr[1] =  MAC_ADDR1;
  149.     netif->hwaddr[2] =  MAC_ADDR2;
  150.     netif->hwaddr[3] =  MAC_ADDR3;
  151.     netif->hwaddr[4] =  MAC_ADDR4;
  152.     netif->hwaddr[5] =  MAC_ADDR5;
  153.    
  154.     // Interface name
  155.     netif->name[0] = 's';
  156.     netif->name[1] = 't';
  157.    
  158.     // Max transfer unit
  159.     netif->mtu = 1500;
  160.    
  161.     // Accept broadcast address and ARP traffic
  162.     netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
  163.  
  164.     // Link IO callbacks
  165.     netif->output = etharp_output;
  166.     netif->linkoutput = low_level_output;
  167.    
  168.     // Init hardware
  169.     low_level_init(netif);
  170.    
  171.     printf("Low level init done!\r\n");
  172.    
  173.     return ERR_OK;
  174. }
  175.  
  176. err_t ethernetif_input(struct netif *netif)
  177. {
  178.     err_t err;
  179.     struct pbuf *p;
  180.  
  181.     // Move received packet into a new pbuf
  182.     p = low_level_input(netif);
  183.    
  184.     // No packet could be read, silently ignore this
  185.     if (p == NULL)
  186.     {
  187.         return ERR_MEM;
  188.     }
  189.  
  190.     // We do have a packet, give it to LwIP
  191.     err = netif->input(p, netif);
  192.    
  193.     // If LwIP was able to process the packet, free the pbuf
  194.     if (err != ERR_OK)
  195.     {
  196.         pbuf_free(p);
  197.         p = NULL;
  198.     }
  199.  
  200.     return err;
  201. }
  202.  
  203. uint32_t sys_now(void)
  204. {
  205.     return HAL_GetTick();
  206. }
  207.  
  208. // Handle packet TX
  209. static err_t low_level_output(struct netif *netif, struct pbuf *p)
  210. {
  211.     err_t errval;
  212.     struct pbuf *q;
  213.     uint8_t *buffer = (uint8_t *)(EthHandle.TxDesc->Buffer1Addr);
  214.     __IO ETH_DMADescTypeDef *DmaTxDesc;
  215.     uint32_t framelength = 0;
  216.     uint32_t bufferoffset = 0;
  217.     uint32_t byteslefttocopy = 0;
  218.     uint32_t payloadoffset = 0;
  219.  
  220.     DmaTxDesc = EthHandle.TxDesc;
  221.     bufferoffset = 0;
  222.    
  223.     printf("TX\r\n");
  224.  
  225.     /* copy frame from pbufs to driver buffers */
  226.     for (q = p; q != NULL; q = q->next)
  227.     {
  228.         /* Is this buffer available? If not, goto error */
  229.         if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
  230.         {
  231.             errval = ERR_USE;
  232.             goto error;
  233.         }
  234.    
  235.         /* Get bytes in current lwIP buffer */
  236.         byteslefttocopy = q->len;
  237.         payloadoffset = 0;
  238.    
  239.         /* Check if the length of data to copy is bigger than Tx buffer size*/
  240.         while ((byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE)
  241.         {
  242.             /* Copy data to Tx buffer*/
  243.             memcpy((uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset));
  244.      
  245.             /* Point to next descriptor */
  246.             DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
  247.      
  248.             /* Check if the buffer is available */
  249.             if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
  250.             {
  251.                 errval = ERR_USE;
  252.                 goto error;
  253.             }
  254.      
  255.             buffer = (uint8_t *)(DmaTxDesc->Buffer1Addr);
  256.      
  257.             byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
  258.             payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
  259.             framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
  260.             bufferoffset = 0;
  261.         }
  262.    
  263.         /* Copy the remaining bytes */
  264.         memcpy((uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), byteslefttocopy);
  265.         bufferoffset = bufferoffset + byteslefttocopy;
  266.         framelength = framelength + byteslefttocopy;
  267.     }
  268.  
  269.     /* Prepare transmit descriptors to give to DMA */
  270.     HAL_ETH_TransmitFrame(&EthHandle, framelength);
  271.  
  272.     errval = ERR_OK;
  273.  
  274. error:
  275.  
  276.     /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
  277.     if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
  278.     {
  279.         /* Clear TUS ETHERNET DMA flag */
  280.         EthHandle.Instance->DMASR = ETH_DMASR_TUS;
  281.    
  282.         /* Resume DMA transmission*/
  283.         EthHandle.Instance->DMATPDR = 0;
  284.     }
  285.     return errval;
  286. }
  287.  
  288. // Handle packet RX
  289. static struct pbuf* low_level_input(struct netif *netif)
  290. {
  291.     struct pbuf *p = NULL, *q = NULL;
  292.     uint16_t len = 0;
  293.     uint8_t *buffer;
  294.     __IO ETH_DMADescTypeDef *dmarxdesc;
  295.     uint32_t bufferoffset = 0;
  296.     uint32_t payloadoffset = 0;
  297.     uint32_t byteslefttocopy = 0;
  298.     uint32_t i = 0;
  299.  
  300.     /* get received frame */
  301.     if (HAL_ETH_GetReceivedFrame(&EthHandle) != HAL_OK)
  302.     {
  303.         return NULL;
  304.     }
  305.     printf("RX\r\n");
  306.     /* Obtain the size of the packet and put it into the "len" variable. */
  307.     len = EthHandle.RxFrameInfos.length;
  308.     buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer;
  309.  
  310.     if (len > 0)
  311.     {
  312.         /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
  313.         p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
  314.     }
  315.  
  316.     if (p != NULL)
  317.     {
  318.         dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
  319.         bufferoffset = 0;
  320.    
  321.         for (q = p; q != NULL; q = q->next)
  322.         {
  323.             byteslefttocopy = q->len;
  324.             payloadoffset = 0;
  325.      
  326.             /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */
  327.             while ((byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE)
  328.             {
  329.                 /* Copy data to pbuf */
  330.                 memcpy((uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
  331.        
  332.                 /* Point to next descriptor */
  333.                 dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
  334.                 buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);
  335.        
  336.                 byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
  337.                 payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
  338.                 bufferoffset = 0;
  339.             }
  340.      
  341.             /* Copy remaining data in pbuf */
  342.             memcpy((uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy);
  343.             bufferoffset = bufferoffset + byteslefttocopy;
  344.         }
  345.     }
  346.    
  347.     /* Release descriptors to DMA */
  348.     /* Point to first descriptor */
  349.     dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
  350.     /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
  351.     for (i = 0; i < EthHandle.RxFrameInfos.SegCount; i++)
  352.     {  
  353.         dmarxdesc->Status |= ETH_DMARXDESC_OWN;
  354.         dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
  355.     }
  356.    
  357.     /* Clear Segment_Count */
  358.     EthHandle.RxFrameInfos.SegCount = 0;
  359.  
  360.     /* When Rx Buffer unavailable flag is set: clear it and resume reception */
  361.     if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)  
  362.     {
  363.         /* Clear RBUS ETHERNET DMA flag */
  364.         EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
  365.         /* Resume DMA reception */
  366.         EthHandle.Instance->DMARPDR = 0;
  367.     }
  368.     return p;
  369. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement