Ethernet for Nucleo and Disco board STM32F746 works with gcc and arm. IAC is untested
Fork of F7_Ethernet by
lwip-eth/arch/TARGET_STM/stm32f7_emac.c@0:d26c1b55cfca, 2016-06-19 (annotated)
- Committer:
- DieterGraef
- Date:
- Sun Jun 19 16:23:40 2016 +0000
- Revision:
- 0:d26c1b55cfca
- Child:
- 1:28ba13dd96f7
Ethernet Library for Nucleo stm32f746ZG and Disco stm32f746NG works under arm and gcc environment
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DieterGraef | 0:d26c1b55cfca | 1 | |
DieterGraef | 0:d26c1b55cfca | 2 | #include "stm32f7xx_hal.h" |
DieterGraef | 0:d26c1b55cfca | 3 | #include "lwipopts.h" |
DieterGraef | 0:d26c1b55cfca | 4 | #include "lwip/opt.h" |
DieterGraef | 0:d26c1b55cfca | 5 | #include "wait_api.h" |
DieterGraef | 0:d26c1b55cfca | 6 | //#include "lwip/timers.h" |
DieterGraef | 0:d26c1b55cfca | 7 | #include "netif/etharp.h" |
DieterGraef | 0:d26c1b55cfca | 8 | #include "lwip/tcpip.h" |
DieterGraef | 0:d26c1b55cfca | 9 | #include <string.h> |
DieterGraef | 0:d26c1b55cfca | 10 | #include "cmsis_os.h" |
DieterGraef | 0:d26c1b55cfca | 11 | #include "mbed_interface.h" |
DieterGraef | 0:d26c1b55cfca | 12 | |
DieterGraef | 0:d26c1b55cfca | 13 | |
DieterGraef | 0:d26c1b55cfca | 14 | /** @defgroup lwipstm32f7xx_emac_DRIVER stm32f7 EMAC driver for LWIP |
DieterGraef | 0:d26c1b55cfca | 15 | * @ingroup lwip_emac |
DieterGraef | 0:d26c1b55cfca | 16 | * |
DieterGraef | 0:d26c1b55cfca | 17 | * @{ |
DieterGraef | 0:d26c1b55cfca | 18 | */ |
DieterGraef | 0:d26c1b55cfca | 19 | |
DieterGraef | 0:d26c1b55cfca | 20 | #define RECV_TASK_PRI (osPriorityHigh) |
DieterGraef | 0:d26c1b55cfca | 21 | #define PHY_TASK_PRI (osPriorityLow) |
DieterGraef | 0:d26c1b55cfca | 22 | #define PHY_TASK_WAIT (200) |
DieterGraef | 0:d26c1b55cfca | 23 | |
DieterGraef | 0:d26c1b55cfca | 24 | //#define EMAC_RECIVE_WAIT |
DieterGraef | 0:d26c1b55cfca | 25 | #define EMAC_R_WAIT 200 |
DieterGraef | 0:d26c1b55cfca | 26 | //#define EMAC_TRANSMIT_WAIT |
DieterGraef | 0:d26c1b55cfca | 27 | #define EMAC_T_WAIT 200 |
DieterGraef | 0:d26c1b55cfca | 28 | |
DieterGraef | 0:d26c1b55cfca | 29 | #define MAC_ADDR_0 MBED_MAC_ADDR_0 |
DieterGraef | 0:d26c1b55cfca | 30 | #define MAC_ADDR_1 MBED_MAC_ADDR_1 |
DieterGraef | 0:d26c1b55cfca | 31 | #define MAC_ADDR_2 MBED_MAC_ADDR_2 |
DieterGraef | 0:d26c1b55cfca | 32 | #define MAC_ADDR_3 MBED_MAC_ADDR_3 |
DieterGraef | 0:d26c1b55cfca | 33 | #define MAC_ADDR_4 MBED_MAC_ADDR_4 |
DieterGraef | 0:d26c1b55cfca | 34 | #define MAC_ADDR_5 MBED_MAC_ADDR_5 |
DieterGraef | 0:d26c1b55cfca | 35 | |
DieterGraef | 0:d26c1b55cfca | 36 | /* LAN8742A PHY Address*/ |
DieterGraef | 0:d26c1b55cfca | 37 | #define LAN8742A_PHY_ADDRESS 0x00U |
DieterGraef | 0:d26c1b55cfca | 38 | |
DieterGraef | 0:d26c1b55cfca | 39 | |
DieterGraef | 0:d26c1b55cfca | 40 | __ALIGN_BEGIN ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __ALIGN_END; /* Ethernet Rx MA Descriptor */ |
DieterGraef | 0:d26c1b55cfca | 41 | |
DieterGraef | 0:d26c1b55cfca | 42 | |
DieterGraef | 0:d26c1b55cfca | 43 | __ALIGN_BEGIN uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __ALIGN_END; /* Ethernet Receive Buffer */ |
DieterGraef | 0:d26c1b55cfca | 44 | |
DieterGraef | 0:d26c1b55cfca | 45 | |
DieterGraef | 0:d26c1b55cfca | 46 | __ALIGN_BEGIN ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __ALIGN_END; /* Ethernet Tx DMA Descriptor */ |
DieterGraef | 0:d26c1b55cfca | 47 | |
DieterGraef | 0:d26c1b55cfca | 48 | |
DieterGraef | 0:d26c1b55cfca | 49 | __ALIGN_BEGIN uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __ALIGN_END; /* Ethernet Transmit Buffer */ |
DieterGraef | 0:d26c1b55cfca | 50 | |
DieterGraef | 0:d26c1b55cfca | 51 | |
DieterGraef | 0:d26c1b55cfca | 52 | ETH_HandleTypeDef heth; |
DieterGraef | 0:d26c1b55cfca | 53 | uint32_t phy_status = 0; |
DieterGraef | 0:d26c1b55cfca | 54 | uint32_t systickval; |
DieterGraef | 0:d26c1b55cfca | 55 | uint32_t sysflag=0; |
DieterGraef | 0:d26c1b55cfca | 56 | static sys_sem_t rx_ready_sem; /* receive ready semaphore */ |
DieterGraef | 0:d26c1b55cfca | 57 | static sys_mutex_t tx_lock_mutex; |
DieterGraef | 0:d26c1b55cfca | 58 | |
DieterGraef | 0:d26c1b55cfca | 59 | /* function */ |
DieterGraef | 0:d26c1b55cfca | 60 | static void stm32f7_rx_task(void *arg); |
DieterGraef | 0:d26c1b55cfca | 61 | static void stm32f7_phy_task(void *arg); |
DieterGraef | 0:d26c1b55cfca | 62 | static err_t stm32f7_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); |
DieterGraef | 0:d26c1b55cfca | 63 | static err_t stm32f7_low_level_output(struct netif *netif, struct pbuf *p); |
DieterGraef | 0:d26c1b55cfca | 64 | |
DieterGraef | 0:d26c1b55cfca | 65 | /** |
DieterGraef | 0:d26c1b55cfca | 66 | * Override HAL Eth Init function |
DieterGraef | 0:d26c1b55cfca | 67 | */ |
DieterGraef | 0:d26c1b55cfca | 68 | void HAL_ETH_MspInit(ETH_HandleTypeDef* heth) |
DieterGraef | 0:d26c1b55cfca | 69 | { |
DieterGraef | 0:d26c1b55cfca | 70 | GPIO_InitTypeDef GPIO_InitStructure; |
DieterGraef | 0:d26c1b55cfca | 71 | if (heth->Instance == ETH) { |
DieterGraef | 0:d26c1b55cfca | 72 | #if defined(TARGET_STM32F746ZG) |
DieterGraef | 0:d26c1b55cfca | 73 | // Nucleo STM32F746 Board |
DieterGraef | 0:d26c1b55cfca | 74 | /* Enable GPIOs clocks */ |
DieterGraef | 0:d26c1b55cfca | 75 | __HAL_RCC_GPIOA_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 76 | __HAL_RCC_GPIOB_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 77 | __HAL_RCC_GPIOC_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 78 | __HAL_RCC_GPIOG_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 79 | |
DieterGraef | 0:d26c1b55cfca | 80 | /* Ethernet pins configuration ************************************************/ |
DieterGraef | 0:d26c1b55cfca | 81 | /* |
DieterGraef | 0:d26c1b55cfca | 82 | RMII_REF_CLK ----------------------> PA1 |
DieterGraef | 0:d26c1b55cfca | 83 | RMII_MDIO -------------------------> PA2 |
DieterGraef | 0:d26c1b55cfca | 84 | RMII_MDC --------------------------> PC1 |
DieterGraef | 0:d26c1b55cfca | 85 | RMII_MII_CRS_DV -------------------> PA7 |
DieterGraef | 0:d26c1b55cfca | 86 | RMII_MII_RXD0 ---------------------> PC4 |
DieterGraef | 0:d26c1b55cfca | 87 | RMII_MII_RXD1 ---------------------> PC5 |
DieterGraef | 0:d26c1b55cfca | 88 | RMII_MII_RXER ---------------------> PG2 |
DieterGraef | 0:d26c1b55cfca | 89 | RMII_MII_TX_EN --------------------> PG11 |
DieterGraef | 0:d26c1b55cfca | 90 | RMII_MII_TXD0 ---------------------> PG13 |
DieterGraef | 0:d26c1b55cfca | 91 | RMII_MII_TXD1 ---------------------> PB13 |
DieterGraef | 0:d26c1b55cfca | 92 | */ |
DieterGraef | 0:d26c1b55cfca | 93 | |
DieterGraef | 0:d26c1b55cfca | 94 | /* Configure PA1, PA2 and PA7 */ |
DieterGraef | 0:d26c1b55cfca | 95 | GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; |
DieterGraef | 0:d26c1b55cfca | 96 | GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; |
DieterGraef | 0:d26c1b55cfca | 97 | GPIO_InitStructure.Pull = GPIO_NOPULL; |
DieterGraef | 0:d26c1b55cfca | 98 | GPIO_InitStructure.Alternate = GPIO_AF11_ETH; |
DieterGraef | 0:d26c1b55cfca | 99 | GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; |
DieterGraef | 0:d26c1b55cfca | 100 | HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); |
DieterGraef | 0:d26c1b55cfca | 101 | |
DieterGraef | 0:d26c1b55cfca | 102 | /* Configure PB13 */ |
DieterGraef | 0:d26c1b55cfca | 103 | GPIO_InitStructure.Pin = GPIO_PIN_13; |
DieterGraef | 0:d26c1b55cfca | 104 | HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); |
DieterGraef | 0:d26c1b55cfca | 105 | |
DieterGraef | 0:d26c1b55cfca | 106 | /* Configure PC1, PC4 and PC5 */ |
DieterGraef | 0:d26c1b55cfca | 107 | GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; |
DieterGraef | 0:d26c1b55cfca | 108 | HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); |
DieterGraef | 0:d26c1b55cfca | 109 | |
DieterGraef | 0:d26c1b55cfca | 110 | /* Configure PG2, PG11, PG13 and PG14 */ |
DieterGraef | 0:d26c1b55cfca | 111 | GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13; |
DieterGraef | 0:d26c1b55cfca | 112 | HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); |
DieterGraef | 0:d26c1b55cfca | 113 | |
DieterGraef | 0:d26c1b55cfca | 114 | /* Enable the Ethernet global Interrupt */ |
DieterGraef | 0:d26c1b55cfca | 115 | HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); |
DieterGraef | 0:d26c1b55cfca | 116 | HAL_NVIC_EnableIRQ(ETH_IRQn); |
DieterGraef | 0:d26c1b55cfca | 117 | |
DieterGraef | 0:d26c1b55cfca | 118 | /* Enable ETHERNET clock */ |
DieterGraef | 0:d26c1b55cfca | 119 | __HAL_RCC_ETH_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 120 | #endif |
DieterGraef | 0:d26c1b55cfca | 121 | #if defined(TARGET_STM32F746NG) |
DieterGraef | 0:d26c1b55cfca | 122 | //Discovery STM32F746 Board |
DieterGraef | 0:d26c1b55cfca | 123 | /* Enable GPIOs clocks */ |
DieterGraef | 0:d26c1b55cfca | 124 | __HAL_RCC_GPIOA_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 125 | __HAL_RCC_GPIOC_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 126 | __HAL_RCC_GPIOG_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 127 | __HAL_RCC_ETH_CLK_ENABLE(); |
DieterGraef | 0:d26c1b55cfca | 128 | /* Ethernet pins configuration ************************************************/ |
DieterGraef | 0:d26c1b55cfca | 129 | /* |
DieterGraef | 0:d26c1b55cfca | 130 | RMII_REF_CLK ----------------------> PA1 |
DieterGraef | 0:d26c1b55cfca | 131 | RMII_MDIO -------------------------> PA2 HAL_Init(); |
DieterGraef | 0:d26c1b55cfca | 132 | RMII_MDC --------------------------> PC1 |
DieterGraef | 0:d26c1b55cfca | 133 | RMII_MII_CRS_DV -------------------> PA7 |
DieterGraef | 0:d26c1b55cfca | 134 | RMII_MII_RXD0 ---------------------> PC4 |
DieterGraef | 0:d26c1b55cfca | 135 | RMII_MII_RXD1 ---------------------> PC5 |
DieterGraef | 0:d26c1b55cfca | 136 | RMII_MII_RXER ---------------------> PG2 |
DieterGraef | 0:d26c1b55cfca | 137 | RMII_MII_TX_EN --------------------> PG11 |
DieterGraef | 0:d26c1b55cfca | 138 | RMII_MII_TXD0 ---------------------> PG13 |
DieterGraef | 0:d26c1b55cfca | 139 | RMII_MII_TXD1 ---------------------> PG14 |
DieterGraef | 0:d26c1b55cfca | 140 | */ |
DieterGraef | 0:d26c1b55cfca | 141 | |
DieterGraef | 0:d26c1b55cfca | 142 | /* Configure PA1, PA2 and PA7 */ |
DieterGraef | 0:d26c1b55cfca | 143 | GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; |
DieterGraef | 0:d26c1b55cfca | 144 | GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; |
DieterGraef | 0:d26c1b55cfca | 145 | GPIO_InitStructure.Pull = GPIO_NOPULL; |
DieterGraef | 0:d26c1b55cfca | 146 | GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; |
DieterGraef | 0:d26c1b55cfca | 147 | GPIO_InitStructure.Alternate = GPIO_AF11_ETH; |
DieterGraef | 0:d26c1b55cfca | 148 | GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; |
DieterGraef | 0:d26c1b55cfca | 149 | HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); |
DieterGraef | 0:d26c1b55cfca | 150 | |
DieterGraef | 0:d26c1b55cfca | 151 | /* Configure PC1, PC4 and PC5 */ |
DieterGraef | 0:d26c1b55cfca | 152 | GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; |
DieterGraef | 0:d26c1b55cfca | 153 | HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); |
DieterGraef | 0:d26c1b55cfca | 154 | |
DieterGraef | 0:d26c1b55cfca | 155 | /* Configure PG2, PG11, PG13 and PG14 */ |
DieterGraef | 0:d26c1b55cfca | 156 | GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; |
DieterGraef | 0:d26c1b55cfca | 157 | HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); |
DieterGraef | 0:d26c1b55cfca | 158 | HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); |
DieterGraef | 0:d26c1b55cfca | 159 | HAL_NVIC_EnableIRQ(ETH_IRQn); |
DieterGraef | 0:d26c1b55cfca | 160 | #endif |
DieterGraef | 0:d26c1b55cfca | 161 | } |
DieterGraef | 0:d26c1b55cfca | 162 | |
DieterGraef | 0:d26c1b55cfca | 163 | } |
DieterGraef | 0:d26c1b55cfca | 164 | |
DieterGraef | 0:d26c1b55cfca | 165 | /** |
DieterGraef | 0:d26c1b55cfca | 166 | * Override HAL Eth DeInit function |
DieterGraef | 0:d26c1b55cfca | 167 | */ |
DieterGraef | 0:d26c1b55cfca | 168 | void HAL_ETH_MspDeInit(ETH_HandleTypeDef* heth) |
DieterGraef | 0:d26c1b55cfca | 169 | { |
DieterGraef | 0:d26c1b55cfca | 170 | if (heth->Instance == ETH) { |
DieterGraef | 0:d26c1b55cfca | 171 | #if defined(TARGET_STM32F746ZG) |
DieterGraef | 0:d26c1b55cfca | 172 | //Nucleo STM32F746 Board |
DieterGraef | 0:d26c1b55cfca | 173 | __ETH_CLK_DISABLE(); |
DieterGraef | 0:d26c1b55cfca | 174 | /* Ethernet pins configuration ************************************************/ |
DieterGraef | 0:d26c1b55cfca | 175 | /* |
DieterGraef | 0:d26c1b55cfca | 176 | RMII_REF_CLK ----------------------> PA1 |
DieterGraef | 0:d26c1b55cfca | 177 | RMII_MDIO -------------------------> PA2 |
DieterGraef | 0:d26c1b55cfca | 178 | RMII_MDC --------------------------> PC1 |
DieterGraef | 0:d26c1b55cfca | 179 | RMII_MII_CRS_DV -------------------> PA7 |
DieterGraef | 0:d26c1b55cfca | 180 | RMII_MII_RXD0 ---------------------> PC4 |
DieterGraef | 0:d26c1b55cfca | 181 | RMII_MII_RXD1 ---------------------> PC5 |
DieterGraef | 0:d26c1b55cfca | 182 | RMII_MII_RXER ---------------------> PG2 |
DieterGraef | 0:d26c1b55cfca | 183 | RMII_MII_TX_EN --------------------> PG11 |
DieterGraef | 0:d26c1b55cfca | 184 | RMII_MII_TXD0 ---------------------> PG13 |
DieterGraef | 0:d26c1b55cfca | 185 | RMII_MII_TXD1 ---------------------> PB13 |
DieterGraef | 0:d26c1b55cfca | 186 | */ |
DieterGraef | 0:d26c1b55cfca | 187 | HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5); |
DieterGraef | 0:d26c1b55cfca | 188 | |
DieterGraef | 0:d26c1b55cfca | 189 | HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13); |
DieterGraef | 0:d26c1b55cfca | 190 | |
DieterGraef | 0:d26c1b55cfca | 191 | HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7); |
DieterGraef | 0:d26c1b55cfca | 192 | |
DieterGraef | 0:d26c1b55cfca | 193 | HAL_GPIO_DeInit(GPIOG, GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13); |
DieterGraef | 0:d26c1b55cfca | 194 | |
DieterGraef | 0:d26c1b55cfca | 195 | /* Peripheral interrupt Deinit*/ |
DieterGraef | 0:d26c1b55cfca | 196 | HAL_NVIC_DisableIRQ(ETH_IRQn); |
DieterGraef | 0:d26c1b55cfca | 197 | |
DieterGraef | 0:d26c1b55cfca | 198 | #endif |
DieterGraef | 0:d26c1b55cfca | 199 | #if defined(TARGET_STM32F746NG) |
DieterGraef | 0:d26c1b55cfca | 200 | //Discovery STM32F746 Board |
DieterGraef | 0:d26c1b55cfca | 201 | __ETH_CLK_DISABLE(); |
DieterGraef | 0:d26c1b55cfca | 202 | /**ETH GPIO Configuration |
DieterGraef | 0:d26c1b55cfca | 203 | PC1 ------> ETH_MDC |
DieterGraef | 0:d26c1b55cfca | 204 | PA1 ------> ETH_REF_CLK |
DieterGraef | 0:d26c1b55cfca | 205 | PA2 ------> ETH_MDIO |
DieterGraef | 0:d26c1b55cfca | 206 | PA7 ------> ETH_CRS_DV |
DieterGraef | 0:d26c1b55cfca | 207 | PC4 ------> ETH_RXD0 |
DieterGraef | 0:d26c1b55cfca | 208 | PC5 ------> ETH_RXD1 |
DieterGraef | 0:d26c1b55cfca | 209 | PB11 ------> ETH_TX_EN |
DieterGraef | 0:d26c1b55cfca | 210 | PB12 ------> ETH_TXD0 |
DieterGraef | 0:d26c1b55cfca | 211 | PB13 ------> ETH_TXD1 |
DieterGraef | 0:d26c1b55cfca | 212 | */ |
DieterGraef | 0:d26c1b55cfca | 213 | HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5); |
DieterGraef | 0:d26c1b55cfca | 214 | |
DieterGraef | 0:d26c1b55cfca | 215 | HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7); |
DieterGraef | 0:d26c1b55cfca | 216 | |
DieterGraef | 0:d26c1b55cfca | 217 | HAL_GPIO_DeInit(GPIOG, GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14); |
DieterGraef | 0:d26c1b55cfca | 218 | |
DieterGraef | 0:d26c1b55cfca | 219 | /* Peripheral interrupt Deinit*/ |
DieterGraef | 0:d26c1b55cfca | 220 | HAL_NVIC_DisableIRQ(ETH_IRQn); |
DieterGraef | 0:d26c1b55cfca | 221 | #endif |
DieterGraef | 0:d26c1b55cfca | 222 | } |
DieterGraef | 0:d26c1b55cfca | 223 | } |
DieterGraef | 0:d26c1b55cfca | 224 | /** |
DieterGraef | 0:d26c1b55cfca | 225 | * Ethernet Rx Transfer completed callback |
DieterGraef | 0:d26c1b55cfca | 226 | * |
DieterGraef | 0:d26c1b55cfca | 227 | * @param heth: ETH handle |
DieterGraef | 0:d26c1b55cfca | 228 | * @retval None |
DieterGraef | 0:d26c1b55cfca | 229 | */ |
DieterGraef | 0:d26c1b55cfca | 230 | void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) |
DieterGraef | 0:d26c1b55cfca | 231 | { |
DieterGraef | 0:d26c1b55cfca | 232 | sys_sem_signal(&rx_ready_sem); |
DieterGraef | 0:d26c1b55cfca | 233 | } |
DieterGraef | 0:d26c1b55cfca | 234 | |
DieterGraef | 0:d26c1b55cfca | 235 | |
DieterGraef | 0:d26c1b55cfca | 236 | /** |
DieterGraef | 0:d26c1b55cfca | 237 | * Ethernet IRQ Handler |
DieterGraef | 0:d26c1b55cfca | 238 | * |
DieterGraef | 0:d26c1b55cfca | 239 | * @param None |
DieterGraef | 0:d26c1b55cfca | 240 | * @retval None |
DieterGraef | 0:d26c1b55cfca | 241 | */ |
DieterGraef | 0:d26c1b55cfca | 242 | void ETH_IRQHandler(void) |
DieterGraef | 0:d26c1b55cfca | 243 | { |
DieterGraef | 0:d26c1b55cfca | 244 | HAL_ETH_IRQHandler(&heth); |
DieterGraef | 0:d26c1b55cfca | 245 | } |
DieterGraef | 0:d26c1b55cfca | 246 | |
DieterGraef | 0:d26c1b55cfca | 247 | |
DieterGraef | 0:d26c1b55cfca | 248 | |
DieterGraef | 0:d26c1b55cfca | 249 | /** |
DieterGraef | 0:d26c1b55cfca | 250 | * In this function, the hardware should be initialized. |
DieterGraef | 0:d26c1b55cfca | 251 | * Called from eth_arch_enetif_init(). |
DieterGraef | 0:d26c1b55cfca | 252 | * |
DieterGraef | 0:d26c1b55cfca | 253 | * @param netif the already initialized lwip network interface structure |
DieterGraef | 0:d26c1b55cfca | 254 | * for this ethernetif |
DieterGraef | 0:d26c1b55cfca | 255 | */ |
DieterGraef | 0:d26c1b55cfca | 256 | static void stm32f7_low_level_init(struct netif *netif) |
DieterGraef | 0:d26c1b55cfca | 257 | { |
DieterGraef | 0:d26c1b55cfca | 258 | uint8_t macaddress[6]= { MAC_ADDR_0, MAC_ADDR_1, MAC_ADDR_2, MAC_ADDR_3, MAC_ADDR_4, MAC_ADDR_5 }; |
DieterGraef | 0:d26c1b55cfca | 259 | |
DieterGraef | 0:d26c1b55cfca | 260 | HAL_StatusTypeDef hal_eth_init_status; |
DieterGraef | 0:d26c1b55cfca | 261 | |
DieterGraef | 0:d26c1b55cfca | 262 | /* Init ETH */ |
DieterGraef | 0:d26c1b55cfca | 263 | |
DieterGraef | 0:d26c1b55cfca | 264 | heth.Instance = ETH; |
DieterGraef | 0:d26c1b55cfca | 265 | heth.Init.MACAddr = &macaddress[0]; |
DieterGraef | 0:d26c1b55cfca | 266 | heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; |
DieterGraef | 0:d26c1b55cfca | 267 | heth.Init.Speed = ETH_SPEED_100M; |
DieterGraef | 0:d26c1b55cfca | 268 | heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX; |
DieterGraef | 0:d26c1b55cfca | 269 | heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; |
DieterGraef | 0:d26c1b55cfca | 270 | heth.Init.RxMode = ETH_RXINTERRUPT_MODE; |
DieterGraef | 0:d26c1b55cfca | 271 | heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; |
DieterGraef | 0:d26c1b55cfca | 272 | heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS; |
DieterGraef | 0:d26c1b55cfca | 273 | hal_eth_init_status = HAL_ETH_Init(&heth); |
DieterGraef | 0:d26c1b55cfca | 274 | |
DieterGraef | 0:d26c1b55cfca | 275 | //Configure the receive filter |
DieterGraef | 0:d26c1b55cfca | 276 | heth.Instance->MACFFR = ETH_MACFFR_HPF | ETH_MACFFR_HM; |
DieterGraef | 0:d26c1b55cfca | 277 | //Disable flow control |
DieterGraef | 0:d26c1b55cfca | 278 | heth.Instance->MACFCR = 0; |
DieterGraef | 0:d26c1b55cfca | 279 | //Enable store and forward mode |
DieterGraef | 0:d26c1b55cfca | 280 | heth.Instance->DMAOMR = ETH_DMAOMR_RSF | ETH_DMAOMR_TSF; |
DieterGraef | 0:d26c1b55cfca | 281 | if (hal_eth_init_status == HAL_OK) { |
DieterGraef | 0:d26c1b55cfca | 282 | /* Set netif link flag */ |
DieterGraef | 0:d26c1b55cfca | 283 | netif->flags |= NETIF_FLAG_LINK_UP; |
DieterGraef | 0:d26c1b55cfca | 284 | } |
DieterGraef | 0:d26c1b55cfca | 285 | |
DieterGraef | 0:d26c1b55cfca | 286 | SCB_DisableDCache(); |
DieterGraef | 0:d26c1b55cfca | 287 | |
DieterGraef | 0:d26c1b55cfca | 288 | |
DieterGraef | 0:d26c1b55cfca | 289 | /* Initialize Tx Descriptors list: Chain Mode */ |
DieterGraef | 0:d26c1b55cfca | 290 | HAL_ETH_DMATxDescListInit(&heth, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); |
DieterGraef | 0:d26c1b55cfca | 291 | |
DieterGraef | 0:d26c1b55cfca | 292 | /* Initialize Rx Descriptors list: Chain Mode */ |
DieterGraef | 0:d26c1b55cfca | 293 | HAL_ETH_DMARxDescListInit(&heth, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); |
DieterGraef | 0:d26c1b55cfca | 294 | |
DieterGraef | 0:d26c1b55cfca | 295 | /* set MAC hardware address length */ |
DieterGraef | 0:d26c1b55cfca | 296 | netif->hwaddr_len = ETHARP_HWADDR_LEN; |
DieterGraef | 0:d26c1b55cfca | 297 | |
DieterGraef | 0:d26c1b55cfca | 298 | /* set MAC hardware address */ |
DieterGraef | 0:d26c1b55cfca | 299 | netif->hwaddr[0] = heth.Init.MACAddr[0]; |
DieterGraef | 0:d26c1b55cfca | 300 | netif->hwaddr[1] = heth.Init.MACAddr[1]; |
DieterGraef | 0:d26c1b55cfca | 301 | netif->hwaddr[2] = heth.Init.MACAddr[2]; |
DieterGraef | 0:d26c1b55cfca | 302 | netif->hwaddr[3] = heth.Init.MACAddr[3]; |
DieterGraef | 0:d26c1b55cfca | 303 | netif->hwaddr[4] = heth.Init.MACAddr[4]; |
DieterGraef | 0:d26c1b55cfca | 304 | netif->hwaddr[5] = heth.Init.MACAddr[5]; |
DieterGraef | 0:d26c1b55cfca | 305 | |
DieterGraef | 0:d26c1b55cfca | 306 | /* maximum transfer unit */ |
DieterGraef | 0:d26c1b55cfca | 307 | netif->mtu = 1500; |
DieterGraef | 0:d26c1b55cfca | 308 | |
DieterGraef | 0:d26c1b55cfca | 309 | /* device capabilities */ |
DieterGraef | 0:d26c1b55cfca | 310 | /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ |
DieterGraef | 0:d26c1b55cfca | 311 | netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; |
DieterGraef | 0:d26c1b55cfca | 312 | |
DieterGraef | 0:d26c1b55cfca | 313 | /* Enable MAC and DMA transmission and reception */ |
DieterGraef | 0:d26c1b55cfca | 314 | HAL_ETH_Start(&heth); |
DieterGraef | 0:d26c1b55cfca | 315 | |
DieterGraef | 0:d26c1b55cfca | 316 | } |
DieterGraef | 0:d26c1b55cfca | 317 | |
DieterGraef | 0:d26c1b55cfca | 318 | /** |
DieterGraef | 0:d26c1b55cfca | 319 | * This function should do the actual transmission of the packet. The packet is |
DieterGraef | 0:d26c1b55cfca | 320 | * contained in the pbuf that is passed to the function. This pbuf |
DieterGraef | 0:d26c1b55cfca | 321 | * might be chained. |
DieterGraef | 0:d26c1b55cfca | 322 | * |
DieterGraef | 0:d26c1b55cfca | 323 | * @param netif the lwip network interface structure for this ethernetif |
DieterGraef | 0:d26c1b55cfca | 324 | * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) |
DieterGraef | 0:d26c1b55cfca | 325 | * @return ERR_OK if the packet could be sent |
DieterGraef | 0:d26c1b55cfca | 326 | * an err_t value if the packet couldn't be sent |
DieterGraef | 0:d26c1b55cfca | 327 | * |
DieterGraef | 0:d26c1b55cfca | 328 | * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to |
DieterGraef | 0:d26c1b55cfca | 329 | * strange results. You might consider waiting for space in the DMA queue |
DieterGraef | 0:d26c1b55cfca | 330 | * to become availale since the stack doesn't retry to send a packet |
DieterGraef | 0:d26c1b55cfca | 331 | * dropped because of memory failure (except for the TCP timers). |
DieterGraef | 0:d26c1b55cfca | 332 | */ |
DieterGraef | 0:d26c1b55cfca | 333 | |
DieterGraef | 0:d26c1b55cfca | 334 | static err_t stm32f7_low_level_output(struct netif *netif, struct pbuf *p) |
DieterGraef | 0:d26c1b55cfca | 335 | { |
DieterGraef | 0:d26c1b55cfca | 336 | err_t errval; |
DieterGraef | 0:d26c1b55cfca | 337 | struct pbuf *q; |
DieterGraef | 0:d26c1b55cfca | 338 | uint8_t *buffer = (uint8_t*)(heth.TxDesc->Buffer1Addr); |
DieterGraef | 0:d26c1b55cfca | 339 | __IO ETH_DMADescTypeDef *DmaTxDesc; |
DieterGraef | 0:d26c1b55cfca | 340 | uint32_t framelength = 0; |
DieterGraef | 0:d26c1b55cfca | 341 | uint32_t bufferoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 342 | uint32_t byteslefttocopy = 0; |
DieterGraef | 0:d26c1b55cfca | 343 | uint32_t payloadoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 344 | DmaTxDesc = heth.TxDesc; |
DieterGraef | 0:d26c1b55cfca | 345 | bufferoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 346 | |
DieterGraef | 0:d26c1b55cfca | 347 | |
DieterGraef | 0:d26c1b55cfca | 348 | sys_mutex_lock(&tx_lock_mutex); |
DieterGraef | 0:d26c1b55cfca | 349 | |
DieterGraef | 0:d26c1b55cfca | 350 | /* copy frame from pbufs to driver buffers */ |
DieterGraef | 0:d26c1b55cfca | 351 | for (q = p; q != NULL; q = q->next) { |
DieterGraef | 0:d26c1b55cfca | 352 | /* Is this buffer available? If not, goto error */ |
DieterGraef | 0:d26c1b55cfca | 353 | if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) { |
DieterGraef | 0:d26c1b55cfca | 354 | errval = ERR_USE; |
DieterGraef | 0:d26c1b55cfca | 355 | goto error; |
DieterGraef | 0:d26c1b55cfca | 356 | } |
DieterGraef | 0:d26c1b55cfca | 357 | |
DieterGraef | 0:d26c1b55cfca | 358 | /* Get bytes in current lwIP buffer */ |
DieterGraef | 0:d26c1b55cfca | 359 | byteslefttocopy = q->len; |
DieterGraef | 0:d26c1b55cfca | 360 | payloadoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 361 | |
DieterGraef | 0:d26c1b55cfca | 362 | /* Check if the length of data to copy is bigger than Tx buffer size*/ |
DieterGraef | 0:d26c1b55cfca | 363 | while ((byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE) { |
DieterGraef | 0:d26c1b55cfca | 364 | /* Copy data to Tx buffer*/ |
DieterGraef | 0:d26c1b55cfca | 365 | memcpy((uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset)); |
DieterGraef | 0:d26c1b55cfca | 366 | |
DieterGraef | 0:d26c1b55cfca | 367 | /* Point to next descriptor */ |
DieterGraef | 0:d26c1b55cfca | 368 | DmaTxDesc = (ETH_DMADescTypeDef*)(DmaTxDesc->Buffer2NextDescAddr); |
DieterGraef | 0:d26c1b55cfca | 369 | |
DieterGraef | 0:d26c1b55cfca | 370 | /* Check if the buffer is available */ |
DieterGraef | 0:d26c1b55cfca | 371 | if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) { |
DieterGraef | 0:d26c1b55cfca | 372 | errval = ERR_USE; |
DieterGraef | 0:d26c1b55cfca | 373 | goto error; |
DieterGraef | 0:d26c1b55cfca | 374 | } |
DieterGraef | 0:d26c1b55cfca | 375 | |
DieterGraef | 0:d26c1b55cfca | 376 | buffer = (uint8_t*)(DmaTxDesc->Buffer1Addr); |
DieterGraef | 0:d26c1b55cfca | 377 | |
DieterGraef | 0:d26c1b55cfca | 378 | byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset); |
DieterGraef | 0:d26c1b55cfca | 379 | payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset); |
DieterGraef | 0:d26c1b55cfca | 380 | framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset); |
DieterGraef | 0:d26c1b55cfca | 381 | bufferoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 382 | } |
DieterGraef | 0:d26c1b55cfca | 383 | |
DieterGraef | 0:d26c1b55cfca | 384 | /* Copy the remaining bytes */ |
DieterGraef | 0:d26c1b55cfca | 385 | memcpy((uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), byteslefttocopy); |
DieterGraef | 0:d26c1b55cfca | 386 | bufferoffset = bufferoffset + byteslefttocopy; |
DieterGraef | 0:d26c1b55cfca | 387 | framelength = framelength + byteslefttocopy; |
DieterGraef | 0:d26c1b55cfca | 388 | } |
DieterGraef | 0:d26c1b55cfca | 389 | |
DieterGraef | 0:d26c1b55cfca | 390 | /* Prepare transmit descriptors to give to DMA */ |
DieterGraef | 0:d26c1b55cfca | 391 | HAL_ETH_TransmitFrame(&heth, framelength); |
DieterGraef | 0:d26c1b55cfca | 392 | LWIP_DEBUGF(NETIF_DEBUG,("(SYS_Tick=0x%x)STM_low_level_output: %d bytes \r\n",HAL_GetTick() ,framelength)); |
DieterGraef | 0:d26c1b55cfca | 393 | errval = ERR_OK; |
DieterGraef | 0:d26c1b55cfca | 394 | |
DieterGraef | 0:d26c1b55cfca | 395 | error: |
DieterGraef | 0:d26c1b55cfca | 396 | |
DieterGraef | 0:d26c1b55cfca | 397 | /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */ |
DieterGraef | 0:d26c1b55cfca | 398 | if ((heth.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET) { |
DieterGraef | 0:d26c1b55cfca | 399 | /* Clear TUS ETHERNET DMA flag */ |
DieterGraef | 0:d26c1b55cfca | 400 | heth.Instance->DMASR = ETH_DMASR_TUS; |
DieterGraef | 0:d26c1b55cfca | 401 | |
DieterGraef | 0:d26c1b55cfca | 402 | /* Resume DMA transmission*/ |
DieterGraef | 0:d26c1b55cfca | 403 | heth.Instance->DMATPDR = 0; |
DieterGraef | 0:d26c1b55cfca | 404 | } |
DieterGraef | 0:d26c1b55cfca | 405 | |
DieterGraef | 0:d26c1b55cfca | 406 | sys_mutex_unlock(&tx_lock_mutex); |
DieterGraef | 0:d26c1b55cfca | 407 | #ifdef EMAC_TRANSMIT_WAIT |
DieterGraef | 0:d26c1b55cfca | 408 | wait_us(EMAC_T_WAIT); |
DieterGraef | 0:d26c1b55cfca | 409 | #endif |
DieterGraef | 0:d26c1b55cfca | 410 | return errval; |
DieterGraef | 0:d26c1b55cfca | 411 | } |
DieterGraef | 0:d26c1b55cfca | 412 | |
DieterGraef | 0:d26c1b55cfca | 413 | |
DieterGraef | 0:d26c1b55cfca | 414 | /** |
DieterGraef | 0:d26c1b55cfca | 415 | * Should allocate a pbuf and transfer the bytes of the incoming |
DieterGraef | 0:d26c1b55cfca | 416 | * packet from the interface into the pbuf. |
DieterGraef | 0:d26c1b55cfca | 417 | * |
DieterGraef | 0:d26c1b55cfca | 418 | * @param netif the lwip network interface structure for this ethernetif |
DieterGraef | 0:d26c1b55cfca | 419 | * @return a pbuf filled with the received packet (including MAC header) |
DieterGraef | 0:d26c1b55cfca | 420 | * NULL on memory error |
DieterGraef | 0:d26c1b55cfca | 421 | */ |
DieterGraef | 0:d26c1b55cfca | 422 | static struct pbuf * stm32f7_low_level_input(struct netif *netif) |
DieterGraef | 0:d26c1b55cfca | 423 | { |
DieterGraef | 0:d26c1b55cfca | 424 | struct pbuf *p = NULL; |
DieterGraef | 0:d26c1b55cfca | 425 | struct pbuf *q = NULL; |
DieterGraef | 0:d26c1b55cfca | 426 | uint16_t len = 0; |
DieterGraef | 0:d26c1b55cfca | 427 | uint8_t *buffer; |
DieterGraef | 0:d26c1b55cfca | 428 | __IO ETH_DMADescTypeDef *dmarxdesc; |
DieterGraef | 0:d26c1b55cfca | 429 | uint32_t bufferoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 430 | uint32_t payloadoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 431 | uint32_t byteslefttocopy = 0; |
DieterGraef | 0:d26c1b55cfca | 432 | uint32_t i = 0; |
DieterGraef | 0:d26c1b55cfca | 433 | |
DieterGraef | 0:d26c1b55cfca | 434 | /* get received frame */ |
DieterGraef | 0:d26c1b55cfca | 435 | if (HAL_ETH_GetReceivedFrame_IT(&heth) != HAL_OK) |
DieterGraef | 0:d26c1b55cfca | 436 | return NULL; |
DieterGraef | 0:d26c1b55cfca | 437 | |
DieterGraef | 0:d26c1b55cfca | 438 | /* Obtain the size of the packet and put it into the "len" variable. */ |
DieterGraef | 0:d26c1b55cfca | 439 | len = heth.RxFrameInfos.length; |
DieterGraef | 0:d26c1b55cfca | 440 | buffer = (uint8_t*)heth.RxFrameInfos.buffer; |
DieterGraef | 0:d26c1b55cfca | 441 | |
DieterGraef | 0:d26c1b55cfca | 442 | if (len > 0) { |
DieterGraef | 0:d26c1b55cfca | 443 | /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ |
DieterGraef | 0:d26c1b55cfca | 444 | p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); |
DieterGraef | 0:d26c1b55cfca | 445 | |
DieterGraef | 0:d26c1b55cfca | 446 | } |
DieterGraef | 0:d26c1b55cfca | 447 | |
DieterGraef | 0:d26c1b55cfca | 448 | if (p != NULL) { |
DieterGraef | 0:d26c1b55cfca | 449 | dmarxdesc = heth.RxFrameInfos.FSRxDesc; |
DieterGraef | 0:d26c1b55cfca | 450 | bufferoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 451 | for (q = p; q != NULL; q = q->next) { |
DieterGraef | 0:d26c1b55cfca | 452 | byteslefttocopy = q->len; |
DieterGraef | 0:d26c1b55cfca | 453 | payloadoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 454 | |
DieterGraef | 0:d26c1b55cfca | 455 | /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ |
DieterGraef | 0:d26c1b55cfca | 456 | while ((byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE) { |
DieterGraef | 0:d26c1b55cfca | 457 | /* Copy data to pbuf */ |
DieterGraef | 0:d26c1b55cfca | 458 | memcpy((uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset)); |
DieterGraef | 0:d26c1b55cfca | 459 | /* Point to next descriptor */ |
DieterGraef | 0:d26c1b55cfca | 460 | dmarxdesc = (ETH_DMADescTypeDef*)(dmarxdesc->Buffer2NextDescAddr); |
DieterGraef | 0:d26c1b55cfca | 461 | buffer = (uint8_t*)(dmarxdesc->Buffer1Addr); |
DieterGraef | 0:d26c1b55cfca | 462 | |
DieterGraef | 0:d26c1b55cfca | 463 | byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset); |
DieterGraef | 0:d26c1b55cfca | 464 | payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset); |
DieterGraef | 0:d26c1b55cfca | 465 | bufferoffset = 0; |
DieterGraef | 0:d26c1b55cfca | 466 | } |
DieterGraef | 0:d26c1b55cfca | 467 | /* Copy remaining data in pbuf */ |
DieterGraef | 0:d26c1b55cfca | 468 | memcpy((uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy); |
DieterGraef | 0:d26c1b55cfca | 469 | bufferoffset = bufferoffset + byteslefttocopy; |
DieterGraef | 0:d26c1b55cfca | 470 | } |
DieterGraef | 0:d26c1b55cfca | 471 | /* Release descriptors to DMA */ |
DieterGraef | 0:d26c1b55cfca | 472 | /* Point to first descriptor */ |
DieterGraef | 0:d26c1b55cfca | 473 | dmarxdesc = heth.RxFrameInfos.FSRxDesc; |
DieterGraef | 0:d26c1b55cfca | 474 | /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ |
DieterGraef | 0:d26c1b55cfca | 475 | for (i = 0; i < heth.RxFrameInfos.SegCount; i++) { |
DieterGraef | 0:d26c1b55cfca | 476 | dmarxdesc->Status |= ETH_DMARXDESC_OWN; |
DieterGraef | 0:d26c1b55cfca | 477 | dmarxdesc = (ETH_DMADescTypeDef*)(dmarxdesc->Buffer2NextDescAddr); |
DieterGraef | 0:d26c1b55cfca | 478 | } |
DieterGraef | 0:d26c1b55cfca | 479 | |
DieterGraef | 0:d26c1b55cfca | 480 | /* Clear Segment_Count */ |
DieterGraef | 0:d26c1b55cfca | 481 | heth.RxFrameInfos.SegCount = 0; |
DieterGraef | 0:d26c1b55cfca | 482 | LWIP_DEBUGF(NETIF_DEBUG,("(SYS_Tick=0x%x)STM_low_level_input: Packet received: %p, len %d \r\n",HAL_GetTick(),p, p->len)); |
DieterGraef | 0:d26c1b55cfca | 483 | } |
DieterGraef | 0:d26c1b55cfca | 484 | else |
DieterGraef | 0:d26c1b55cfca | 485 | { |
DieterGraef | 0:d26c1b55cfca | 486 | LWIP_DEBUGF(NETIF_DEBUG,("STM_low_level_input: Packet dropped \r\n")); |
DieterGraef | 0:d26c1b55cfca | 487 | } |
DieterGraef | 0:d26c1b55cfca | 488 | |
DieterGraef | 0:d26c1b55cfca | 489 | /* When Rx Buffer unavailable flag is set: clear it and resume reception */ |
DieterGraef | 0:d26c1b55cfca | 490 | if ((heth.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET) { |
DieterGraef | 0:d26c1b55cfca | 491 | /* Clear RBUS ETHERNET DMA flag */ |
DieterGraef | 0:d26c1b55cfca | 492 | heth.Instance->DMASR = ETH_DMASR_RBUS; |
DieterGraef | 0:d26c1b55cfca | 493 | /* Resume DMA reception */ |
DieterGraef | 0:d26c1b55cfca | 494 | heth.Instance->DMARPDR = 0; |
DieterGraef | 0:d26c1b55cfca | 495 | } |
DieterGraef | 0:d26c1b55cfca | 496 | #ifdef EMAC_RECIVE_WAIT |
DieterGraef | 0:d26c1b55cfca | 497 | wait_us(EMAC_R_WAIT); |
DieterGraef | 0:d26c1b55cfca | 498 | #endif |
DieterGraef | 0:d26c1b55cfca | 499 | return p; |
DieterGraef | 0:d26c1b55cfca | 500 | } |
DieterGraef | 0:d26c1b55cfca | 501 | |
DieterGraef | 0:d26c1b55cfca | 502 | /** |
DieterGraef | 0:d26c1b55cfca | 503 | * This task receives input data |
DieterGraef | 0:d26c1b55cfca | 504 | * |
DieterGraef | 0:d26c1b55cfca | 505 | * \param[in] netif the lwip network interface structure |
DieterGraef | 0:d26c1b55cfca | 506 | */ |
DieterGraef | 0:d26c1b55cfca | 507 | static void stm32f7_rx_task(void *arg) |
DieterGraef | 0:d26c1b55cfca | 508 | { |
DieterGraef | 0:d26c1b55cfca | 509 | struct netif *netif = (struct netif*)arg; |
DieterGraef | 0:d26c1b55cfca | 510 | struct pbuf *p; |
DieterGraef | 0:d26c1b55cfca | 511 | struct eth_hdr *ethhdr; |
DieterGraef | 0:d26c1b55cfca | 512 | while (1) { |
DieterGraef | 0:d26c1b55cfca | 513 | sys_arch_sem_wait(&rx_ready_sem, 0); |
DieterGraef | 0:d26c1b55cfca | 514 | #ifdef LOCK_RX_THREAD |
DieterGraef | 0:d26c1b55cfca | 515 | sys_mutex_lock(&tx_lock_mutex); |
DieterGraef | 0:d26c1b55cfca | 516 | #endif |
DieterGraef | 0:d26c1b55cfca | 517 | sysflag=0x0000; |
DieterGraef | 0:d26c1b55cfca | 518 | p = stm32f7_low_level_input(netif); |
DieterGraef | 0:d26c1b55cfca | 519 | if (p != NULL) { |
DieterGraef | 0:d26c1b55cfca | 520 | ethhdr = p->payload; |
DieterGraef | 0:d26c1b55cfca | 521 | switch (htons(ethhdr->type)) |
DieterGraef | 0:d26c1b55cfca | 522 | { |
DieterGraef | 0:d26c1b55cfca | 523 | /* IP or ARP packet? */ |
DieterGraef | 0:d26c1b55cfca | 524 | case ETHTYPE_IP: |
DieterGraef | 0:d26c1b55cfca | 525 | case ETHTYPE_ARP: |
DieterGraef | 0:d26c1b55cfca | 526 | if (netif->input(p, netif) != ERR_OK) { |
DieterGraef | 0:d26c1b55cfca | 527 | LWIP_DEBUGF(NETIF_DEBUG, ("STM_enetif_input: IP input error\n")); |
DieterGraef | 0:d26c1b55cfca | 528 | pbuf_free(p); |
DieterGraef | 0:d26c1b55cfca | 529 | p = NULL; |
DieterGraef | 0:d26c1b55cfca | 530 | } |
DieterGraef | 0:d26c1b55cfca | 531 | break; |
DieterGraef | 0:d26c1b55cfca | 532 | default: |
DieterGraef | 0:d26c1b55cfca | 533 | LWIP_DEBUGF(NETIF_DEBUG, ("STM_enetif_input: Payload not IP or ARP %d \r\n", p->payload)); |
DieterGraef | 0:d26c1b55cfca | 534 | pbuf_free(p); |
DieterGraef | 0:d26c1b55cfca | 535 | p = NULL; |
DieterGraef | 0:d26c1b55cfca | 536 | break; |
DieterGraef | 0:d26c1b55cfca | 537 | } |
DieterGraef | 0:d26c1b55cfca | 538 | |
DieterGraef | 0:d26c1b55cfca | 539 | } |
DieterGraef | 0:d26c1b55cfca | 540 | #ifdef LOCK_RX_THREAD |
DieterGraef | 0:d26c1b55cfca | 541 | sys_mutex_unlock(&tx_lock_mutex); |
DieterGraef | 0:d26c1b55cfca | 542 | #endif |
DieterGraef | 0:d26c1b55cfca | 543 | } |
DieterGraef | 0:d26c1b55cfca | 544 | } |
DieterGraef | 0:d26c1b55cfca | 545 | |
DieterGraef | 0:d26c1b55cfca | 546 | /** |
DieterGraef | 0:d26c1b55cfca | 547 | * This task checks phy link status and updates net status |
DieterGraef | 0:d26c1b55cfca | 548 | * |
DieterGraef | 0:d26c1b55cfca | 549 | * \param[in] netif the lwip network interface structure |
DieterGraef | 0:d26c1b55cfca | 550 | */ |
DieterGraef | 0:d26c1b55cfca | 551 | static void stm32f7_phy_task(void *arg) |
DieterGraef | 0:d26c1b55cfca | 552 | { |
DieterGraef | 0:d26c1b55cfca | 553 | struct netif *netif = (struct netif*)arg; |
DieterGraef | 0:d26c1b55cfca | 554 | |
DieterGraef | 0:d26c1b55cfca | 555 | |
DieterGraef | 0:d26c1b55cfca | 556 | while (1) { |
DieterGraef | 0:d26c1b55cfca | 557 | uint32_t status; |
DieterGraef | 0:d26c1b55cfca | 558 | if (HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &status) == HAL_OK) |
DieterGraef | 0:d26c1b55cfca | 559 | { |
DieterGraef | 0:d26c1b55cfca | 560 | if (phy_status != status) |
DieterGraef | 0:d26c1b55cfca | 561 | { |
DieterGraef | 0:d26c1b55cfca | 562 | if (status & PHY_LINKED_STATUS ) |
DieterGraef | 0:d26c1b55cfca | 563 | { |
DieterGraef | 0:d26c1b55cfca | 564 | tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1); |
DieterGraef | 0:d26c1b55cfca | 565 | } |
DieterGraef | 0:d26c1b55cfca | 566 | else |
DieterGraef | 0:d26c1b55cfca | 567 | { |
DieterGraef | 0:d26c1b55cfca | 568 | tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1); |
DieterGraef | 0:d26c1b55cfca | 569 | } |
DieterGraef | 0:d26c1b55cfca | 570 | } |
DieterGraef | 0:d26c1b55cfca | 571 | } |
DieterGraef | 0:d26c1b55cfca | 572 | phy_status = status; |
DieterGraef | 0:d26c1b55cfca | 573 | } |
DieterGraef | 0:d26c1b55cfca | 574 | |
DieterGraef | 0:d26c1b55cfca | 575 | osDelay(PHY_TASK_WAIT); |
DieterGraef | 0:d26c1b55cfca | 576 | |
DieterGraef | 0:d26c1b55cfca | 577 | } |
DieterGraef | 0:d26c1b55cfca | 578 | |
DieterGraef | 0:d26c1b55cfca | 579 | /** |
DieterGraef | 0:d26c1b55cfca | 580 | * This function is the ethernet packet send function. It calls |
DieterGraef | 0:d26c1b55cfca | 581 | * etharp_output after checking link status. |
DieterGraef | 0:d26c1b55cfca | 582 | * |
DieterGraef | 0:d26c1b55cfca | 583 | * \param[in] netif the lwip network interface structure for this lpc_enetif |
DieterGraef | 0:d26c1b55cfca | 584 | * \param[in] q Pointer to pbug to send |
DieterGraef | 0:d26c1b55cfca | 585 | * \param[in] ipaddr IP address |
DieterGraef | 0:d26c1b55cfca | 586 | * \return ERR_OK or error code |
DieterGraef | 0:d26c1b55cfca | 587 | */ |
DieterGraef | 0:d26c1b55cfca | 588 | static err_t stm32f7_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) |
DieterGraef | 0:d26c1b55cfca | 589 | { |
DieterGraef | 0:d26c1b55cfca | 590 | /* Only send packet is link is up */ |
DieterGraef | 0:d26c1b55cfca | 591 | if (netif->flags & NETIF_FLAG_LINK_UP) { |
DieterGraef | 0:d26c1b55cfca | 592 | return etharp_output(netif, q, ipaddr); |
DieterGraef | 0:d26c1b55cfca | 593 | } |
DieterGraef | 0:d26c1b55cfca | 594 | |
DieterGraef | 0:d26c1b55cfca | 595 | return ERR_CONN; |
DieterGraef | 0:d26c1b55cfca | 596 | } |
DieterGraef | 0:d26c1b55cfca | 597 | |
DieterGraef | 0:d26c1b55cfca | 598 | /** |
DieterGraef | 0:d26c1b55cfca | 599 | * Should be called at the beginning of the program to set up the |
DieterGraef | 0:d26c1b55cfca | 600 | * network interface. |
DieterGraef | 0:d26c1b55cfca | 601 | * |
DieterGraef | 0:d26c1b55cfca | 602 | * This function should be passed as a parameter to netif_add(). |
DieterGraef | 0:d26c1b55cfca | 603 | * |
DieterGraef | 0:d26c1b55cfca | 604 | * @param[in] netif the lwip network interface structure for this lpc_enetif |
DieterGraef | 0:d26c1b55cfca | 605 | * @return ERR_OK if the loopif is initialized |
DieterGraef | 0:d26c1b55cfca | 606 | * ERR_MEM if private data couldn't be allocated |
DieterGraef | 0:d26c1b55cfca | 607 | * any other err_t on error |
DieterGraef | 0:d26c1b55cfca | 608 | */ |
DieterGraef | 0:d26c1b55cfca | 609 | err_t eth_arch_enetif_init(struct netif *netif) |
DieterGraef | 0:d26c1b55cfca | 610 | { |
DieterGraef | 0:d26c1b55cfca | 611 | /* set MAC hardware address */ |
DieterGraef | 0:d26c1b55cfca | 612 | netif->hwaddr_len = ETHARP_HWADDR_LEN; |
DieterGraef | 0:d26c1b55cfca | 613 | |
DieterGraef | 0:d26c1b55cfca | 614 | |
DieterGraef | 0:d26c1b55cfca | 615 | /* set netif MAC hardware address */ |
DieterGraef | 0:d26c1b55cfca | 616 | netif->hwaddr[0] = MAC_ADDR_0; |
DieterGraef | 0:d26c1b55cfca | 617 | netif->hwaddr[1] = MAC_ADDR_1; |
DieterGraef | 0:d26c1b55cfca | 618 | netif->hwaddr[2] = MAC_ADDR_2; |
DieterGraef | 0:d26c1b55cfca | 619 | netif->hwaddr[3] = MAC_ADDR_3; |
DieterGraef | 0:d26c1b55cfca | 620 | netif->hwaddr[4] = MAC_ADDR_4; |
DieterGraef | 0:d26c1b55cfca | 621 | netif->hwaddr[5] = MAC_ADDR_5; |
DieterGraef | 0:d26c1b55cfca | 622 | |
DieterGraef | 0:d26c1b55cfca | 623 | /* maximum transfer unit */ |
DieterGraef | 0:d26c1b55cfca | 624 | netif->mtu = 1500; |
DieterGraef | 0:d26c1b55cfca | 625 | |
DieterGraef | 0:d26c1b55cfca | 626 | /* device capabilities */ |
DieterGraef | 0:d26c1b55cfca | 627 | //netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; |
DieterGraef | 0:d26c1b55cfca | 628 | |
DieterGraef | 0:d26c1b55cfca | 629 | netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; |
DieterGraef | 0:d26c1b55cfca | 630 | |
DieterGraef | 0:d26c1b55cfca | 631 | #if LWIP_NETIF_HOSTNAME |
DieterGraef | 0:d26c1b55cfca | 632 | /* Initialize interface hostname */ |
DieterGraef | 0:d26c1b55cfca | 633 | netif->hostname = NETIF_HOSTNAME; |
DieterGraef | 0:d26c1b55cfca | 634 | #endif /* LWIP_NETIF_HOSTNAME */ |
DieterGraef | 0:d26c1b55cfca | 635 | |
DieterGraef | 0:d26c1b55cfca | 636 | netif->name[0] = 'e'; |
DieterGraef | 0:d26c1b55cfca | 637 | netif->name[1] = 'n'; |
DieterGraef | 0:d26c1b55cfca | 638 | |
DieterGraef | 0:d26c1b55cfca | 639 | netif->output = stm32f7_etharp_output; |
DieterGraef | 0:d26c1b55cfca | 640 | netif->linkoutput = stm32f7_low_level_output; |
DieterGraef | 0:d26c1b55cfca | 641 | |
DieterGraef | 0:d26c1b55cfca | 642 | /* semaphore */ |
DieterGraef | 0:d26c1b55cfca | 643 | sys_sem_new(&rx_ready_sem, 0); |
DieterGraef | 0:d26c1b55cfca | 644 | |
DieterGraef | 0:d26c1b55cfca | 645 | sys_mutex_new(&tx_lock_mutex); |
DieterGraef | 0:d26c1b55cfca | 646 | |
DieterGraef | 0:d26c1b55cfca | 647 | /* task */ |
DieterGraef | 0:d26c1b55cfca | 648 | sys_thread_new("recv_task", stm32f7_rx_task, netif, EMAC_RECIVE_THREAD_STACKSIZE, RECV_TASK_PRI); |
DieterGraef | 0:d26c1b55cfca | 649 | sys_thread_new("phy_task", stm32f7_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI); |
DieterGraef | 0:d26c1b55cfca | 650 | |
DieterGraef | 0:d26c1b55cfca | 651 | /* initialize the hardware */ |
DieterGraef | 0:d26c1b55cfca | 652 | stm32f7_low_level_init(netif); |
DieterGraef | 0:d26c1b55cfca | 653 | netif_set_link_down(netif); |
DieterGraef | 0:d26c1b55cfca | 654 | HAL_Delay(100); |
DieterGraef | 0:d26c1b55cfca | 655 | phy_status=0; |
DieterGraef | 0:d26c1b55cfca | 656 | return ERR_OK; |
DieterGraef | 0:d26c1b55cfca | 657 | } |
DieterGraef | 0:d26c1b55cfca | 658 | |
DieterGraef | 0:d26c1b55cfca | 659 | void eth_arch_enable_interrupts(void) |
DieterGraef | 0:d26c1b55cfca | 660 | { |
DieterGraef | 0:d26c1b55cfca | 661 | /* Enable the Ethernet global Interrupt */ |
DieterGraef | 0:d26c1b55cfca | 662 | HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); |
DieterGraef | 0:d26c1b55cfca | 663 | HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); |
DieterGraef | 0:d26c1b55cfca | 664 | HAL_NVIC_EnableIRQ(ETH_IRQn); |
DieterGraef | 0:d26c1b55cfca | 665 | } |
DieterGraef | 0:d26c1b55cfca | 666 | |
DieterGraef | 0:d26c1b55cfca | 667 | void eth_arch_disable_interrupts(void) |
DieterGraef | 0:d26c1b55cfca | 668 | { |
DieterGraef | 0:d26c1b55cfca | 669 | NVIC_DisableIRQ(ETH_IRQn); |
DieterGraef | 0:d26c1b55cfca | 670 | } |
DieterGraef | 0:d26c1b55cfca | 671 | |
DieterGraef | 0:d26c1b55cfca | 672 | /** |
DieterGraef | 0:d26c1b55cfca | 673 | * @} |
DieterGraef | 0:d26c1b55cfca | 674 | */ |
DieterGraef | 0:d26c1b55cfca | 675 | |
DieterGraef | 0:d26c1b55cfca | 676 | /* --------------------------------- End Of File ------------------------------ */ |