1 /*
2 * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
3 *
4 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
5 * You may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.st.com/software_license_agreement_liberty_v2
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "lan8720.h"
18 #include "stm32f4x7_eth.h"
19 #include "usart.h"
20 #include "prt_module.h"
21
22 uint8_t *Rx_Buff;
23 uint8_t *Tx_Buff;
24 ETH_DMADESCTypeDef *DMARxDscrTab;
25 ETH_DMADESCTypeDef *DMATxDscrTab;
26
27 static void EthernetNvicConf(void);
28 extern void LwipPktHandle(void);
29
LAN8720Init(void)30 u8 LAN8720Init(void)
31 {
32 u8 ret = 0;
33 GPIO_InitTypeDef gpioInitStruct;
34
35 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
36 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC |
37 RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOD, ENABLE);
38 SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
39
40 gpioInitStruct.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_2|GPIO_Pin_1;
41 gpioInitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
42 gpioInitStruct.GPIO_Speed = GPIO_Speed_100MHz;
43 gpioInitStruct.GPIO_OType = GPIO_OType_PP;
44 gpioInitStruct.GPIO_Mode = GPIO_Mode_AF;
45 GPIO_Init(GPIOA, &gpioInitStruct);
46
47 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
48 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
49 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
50
51 gpioInitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_1;
52 GPIO_Init(GPIOC, &gpioInitStruct);
53 GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
54 GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
55 GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
56
57 gpioInitStruct.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_11;
58 GPIO_Init(GPIOG, &gpioInitStruct);
59 GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH);
60 GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH);
61 GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH);
62
63 gpioInitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
64 gpioInitStruct.GPIO_Mode = GPIO_Mode_OUT;
65 gpioInitStruct.GPIO_OType = GPIO_OType_PP;
66
67 gpioInitStruct.GPIO_Speed = GPIO_Speed_100MHz;
68 gpioInitStruct.GPIO_Pin = GPIO_Pin_3;
69
70 GPIO_Init(GPIOD, &gpioInitStruct);
71
72 LAN8720_RST = 0; /* 0, register status */
73 for (int i = 0; i < 2000; i++); /* 2000, delay */
74 LAN8720_RST = 1; /* 1, register status */
75 EthernetNvicConf();
76 ret = EthMacdmaConf();
77 return !ret;
78 }
79
EthernetNvicConf(void)80 static void EthernetNvicConf(void)
81 {
82 NVIC_InitTypeDef nvicInitStruct;
83
84 nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
85 nvicInitStruct.NVIC_IRQChannelSubPriority = 0X00;
86 nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0X00;
87 nvicInitStruct.NVIC_IRQChannel = ETH_IRQn;
88
89 NVIC_Init(&nvicInitStruct);
90 }
91
LAN8720GetSpeed(void)92 u8 LAN8720GetSpeed(void)
93 {
94 return (u8)((ETH_ReadPHYRegister(0x00,31) & 0x1C) >> 2);
95 }
96
EthMacdmaConf(void)97 u8 EthMacdmaConf(void)
98 {
99 u8 ret;
100 ETH_InitTypeDef ethInitStruct;
101
102 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
103 RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
104 ETH_DeInit();
105 ETH_SoftwareReset();
106 while (ETH_GetSoftwareResetStatus() == SET);
107 ETH_StructInit(ðInitStruct);
108
109 ethInitStruct.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
110 ethInitStruct.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
111 ethInitStruct.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
112 ethInitStruct.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
113 ethInitStruct.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
114 ethInitStruct.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
115 ethInitStruct.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
116 ethInitStruct.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
117 ethInitStruct.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
118
119 #ifdef CHECKSUM_BY_HARDWARE
120 ethInitStruct.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
121 #endif
122 ethInitStruct.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
123 ethInitStruct.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
124 ethInitStruct.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
125
126 ethInitStruct.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
127 ethInitStruct.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
128 ethInitStruct.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
129 ethInitStruct.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
130 ethInitStruct.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
131 ethInitStruct.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
132 ethInitStruct.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
133 ethInitStruct.ETH_FixedBurst = ETH_FixedBurst_Enable;
134
135 ret = ETH_Init(ðInitStruct, LAN8720_PHY_ADDRESS);
136 if (ret == ETH_SUCCESS) {
137 ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);
138 }
139 return ret;
140 }
141
EthIrqHandler(void)142 void EthIrqHandler(void)
143 {
144 uint32_t lenght = 0; /* 0, lenght */
145 while ((lenght = ETH_GetRxPktSize(DMARxDescToGet)) != 0) { /* 0, lenght */
146 LwipPktHandle();
147 }
148 ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
149 ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
150 }
151
EthRxPacket(void)152 FrameTypeDef EthRxPacket(void)
153 {
154 u32 framlength = 0; /* 0, framlength */
155 FrameTypeDef fram = {0, 0}; /* 0, initial value */
156
157 if((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (u32)RESET) {
158 fram.length = ETH_ERROR;
159 if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) {
160 ETH->DMASR = ETH_DMASR_RBUS;
161 ETH->DMARPDR = 0; /* register satus */
162 }
163 return fram;
164 }
165
166 if (((DMARxDescToGet->Status & ETH_DMARxDesc_LS)!=(u32)RESET) &&
167 ((DMARxDescToGet->Status & ETH_DMARxDesc_FS)!=(u32)RESET) &&
168 ((DMARxDescToGet->StatusÐ_DMARxDesc_ES)==(u32)RESET)) {
169 framlength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
170 fram.buffer = DMARxDescToGet->Buffer1Addr;
171 } else {
172 framlength = ETH_ERROR;
173 }
174
175 fram.descriptor = DMARxDescToGet;
176 fram.length = framlength;
177 DMARxDescToGet = (ETH_DMADESCTypeDef*)(DMARxDescToGet->Buffer2NextDescAddr);
178 return fram;
179 }
180
EthTxPacket(u16 frameLength)181 u8 EthTxPacket(u16 frameLength)
182 {
183 if ((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (u32)RESET) {
184 return ETH_ERROR;
185 }
186
187 DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS | ETH_DMATxDesc_OWN;
188 DMATxDescToSet->ControlBufferSize = (frameLength & ETH_DMATxDesc_TBS1);
189
190 if((ETH->DMASR & ETH_DMASR_TBUS) != (u32)RESET) {
191 ETH->DMATPDR = 0; /* 0, register status */
192 ETH->DMASR = ETH_DMASR_TBUS;
193 }
194 DMATxDescToSet = (ETH_DMADESCTypeDef*)(DMATxDescToSet->Buffer2NextDescAddr);
195 return ETH_SUCCESS;
196 }
197
EthGetCurrentTxBuffer(void)198 u32 EthGetCurrentTxBuffer(void)
199 {
200 return DMATxDescToSet->Buffer1Addr;
201 }
202
EthMemMalloc(void)203 u8 EthMemMalloc(void)
204 {
205 Tx_Buff = PRT_MemAlloc(OS_MID_MEM, 0, ETH_TX_BUF_SIZE * ETH_TXBUFNB);
206 Rx_Buff = PRT_MemAlloc(OS_MID_MEM, 0, ETH_RX_BUF_SIZE * ETH_RXBUFNB);
207 DMATxDscrTab = PRT_MemAlloc(OS_MID_MEM, 0, ETH_TXBUFNB * sizeof(ETH_DMADESCTypeDef));
208 DMARxDscrTab = PRT_MemAlloc(OS_MID_MEM, 0, ETH_RXBUFNB * sizeof(ETH_DMADESCTypeDef));
209 if(!Tx_Buff || !Rx_Buff || !DMATxDscrTab || !DMARxDscrTab) {
210 EthMemFree();
211 return 1; /* 1, PRT_MemAlloc error */
212 }
213 return 0; /* 0, PRT_MemAlloc ok */
214 }
215
EthMemFree(void)216 void EthMemFree(void)
217 {
218 PRT_MemFree(OS_MID_MEM, DMARxDscrTab);
219 PRT_MemFree(OS_MID_MEM, DMATxDscrTab);
220 PRT_MemFree(OS_MID_MEM, Rx_Buff);
221 PRT_MemFree(OS_MID_MEM, Tx_Buff);
222 }
223