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