6 #include "RtosInclude.hpp"
9 #include "LibEndian.hpp"
10 #include "NetDefs.hpp"
11 #include "RtosInterrupt.hpp"
12 #include "NetMacros.hpp"
13 #include "stm32f4xx.h"
20 void NetMac::start(
const NetDefs::MAC_ADDR& addr) {
23 RtosPortable::disableAllInt();
25 RCC ->AHB1ENR |= RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN |
26 RCC_AHB1ENR_ETHMACRXEN;
28 RCC ->AHB1RSTR |= RCC_AHB1RSTR_ETHMACRST;
29 RCC ->AHB1RSTR &= ~RCC_AHB1RSTR_ETHMACRST;
31 RtosPortable::enableAllInt();
33 ETH ->DMABMR |= ETH_DMABMR_SR;
34 while (ETH ->DMABMR & ETH_DMABMR_SR ) {
38 ETH ->MACMIIAR &= ((uint32_t) 0xFFFFFFE3);
39 ETH ->MACMIIAR |= ETH_MACMIIAR_CR_Div102;
45 mPhyId = phyRead(PHY_REG_IDR1) << 16;
46 mPhyId += phyRead(PHY_REG_IDR2);
49 phyWrite(PHY_REG_BMCR, PHY_BMCR_RESET);
52 for (
int i = 500; i; i--) {
53 uint32_t reg = phyRead(PHY_REG_BMCR);
54 if (!((reg) & (PHY_BMCR_RESET | PHY_BMCR_POWERDOWN))) {
61 phyWrite(PHY_REG_BMCR, PHY_BMCR_AN);
63 for (
int i = 500; i; i--) {
64 if (phyRead(PHY_REG_BMSR) & PHY_BMSR_AUTO_DONE) {
71 for (
int i = 500; i; i--) {
72 uint32_t reg = phyRead(PHY_REG_BMSR);
73 if (reg & PHY_BMSR_LINK_ESTABLISHED) {
79 ETH ->MACA0HR = (addr.v[5] << 8) + (addr.v[4]);
80 ETH ->MACA0LR = (addr.v[3] << 24) + (addr.v[2] << 16) + (addr.v[1] << 8) + (addr.v[0]);
83 memset(sTxDesc, 0,
sizeof(sTxDesc));
84 for (
int i = 0; i < EMAC_TX_FRAG_COUNT; i++) {
85 sTxDesc[i].tdes0.value = TX_DESC0_TCH;
86 sTxDesc[i].tdes1.value = 0;
88 sTxDesc[i].tdes3 = (uint32_t) &sTxDesc[(i + 1) % EMAC_TX_FRAG_COUNT];
89 sTxDesc[i].state = TX_FRAG_STATE::TX_FRAG_NO_BUFFER;
93 ETH ->DMATDLAR = (uint32_t) sTxDesc;
96 memset(sRxDesc, 0,
sizeof(sRxDesc));
97 for (
int i = 0; i < EMAC_RX_FRAG_COUNT; i++) {
98 sRxDesc[i].rdes0.value = RX_DESC0_OWN;
99 sRxDesc[i].rdes1.bits.RCH = 1;
100 sRxDesc[i].rdes1.bits.RBS1 = NetDefs::MAX_FRAME_LEN + 2;
101 sRxDesc[i].rdes2 = (uint32_t) &Net::allocFrame(NetDefs::MAX_FRAME_LEN + 4)->types.mac.macHeader.dstAddr;
102 sRxDesc[i].rdes3 = (uint32_t) &sRxDesc[(i + 1) % EMAC_RX_FRAG_COUNT];
104 ETH ->DMARDLAR = (uint32_t) sRxDesc;
107 ETH ->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE;
109 NVIC ->IP[ETH_IRQn] = RTOS_INT_PRI;
110 NVIC_EnableIRQ(ETH_IRQn);
113 ETH ->MACCR |= ETH_MACCR_DM | ETH_MACCR_FES;
115 ETH ->MACFFR = ETH_MACFFR_PCF_BlockAll;
121 ETH ->MACFCR = ETH_MACFCR_ZQPD;
125 ETH ->DMAOMR = ETH_DMAOMR_RSF | ETH_DMAOMR_TSF | ETH_DMAOMR_OSF;
127 ETH ->DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_USP | ETH_DMABMR_PBL_32Beat | ETH_DMABMR_FB | ETH_DMABMR_RDP_32Beat | ETH_DMABMR_RTPR_2_1;
129 ETH ->MACCR |= ETH_MACCR_TE;
131 ETH ->DMAOMR |= ETH_DMAOMR_FTF;
133 ETH ->MACCR |= ETH_MACCR_RE;
135 ETH ->DMAOMR |= ETH_DMAOMR_ST;
137 ETH ->DMAOMR |= ETH_DMAOMR_SR;
140 NetDefs::FRAME* NetMac::getFrame() {
141 if (!sRxDesc[mRxIdx].rdes0.bits.OWN) {
142 if (!sRxDesc[mRxIdx].rdes0.bits.LS) {
143 sRxDesc[mRxIdx].rdes0.value = RX_DESC0_OWN;
145 mRxIdx = (mRxIdx + 1) % EMAC_RX_FRAG_COUNT;
146 if (sRxDesc[mRxIdx].rdes0.bits.OWN) {
149 sRxDesc[mRxIdx].rdes0.value = RX_DESC0_OWN;
150 if (sRxDesc[mRxIdx].rdes0.bits.LS) {
154 return ((NetDefs::FRAME*) 0);
156 if (sRxDesc[mRxIdx].rdes0.bits.ES) {
157 sRxDesc[mRxIdx].rdes0.value = RX_DESC0_OWN;
158 mRxIdx = (mRxIdx + 1) % EMAC_RX_FRAG_COUNT;
159 return ((NetDefs::FRAME*) 0);
161 NetDefs::FRAME* newFrame = Net::allocFrame(NetDefs::MAX_FRAME_LEN + 4);
163 sRxDesc[mRxIdx].rdes0.value = RX_DESC0_OWN;
164 mRxIdx = (mRxIdx + 1) % EMAC_RX_FRAG_COUNT;
165 return ((NetDefs::FRAME*) 0);
167 NetDefs::FRAME* frame = (NetDefs::FRAME*) (sRxDesc[mRxIdx].rdes2 - 2);
168 frame = (NetDefs::FRAME*) Net::resizeFrame(*frame, sRxDesc[mRxIdx].rdes0.bits.FL + 2);
169 sRxDesc[mRxIdx].rdes2 = (uint32_t) &newFrame->types.mac.macHeader.dstAddr;
170 sRxDesc[mRxIdx].rdes0.value = RX_DESC0_OWN;
171 mRxIdx = (mRxIdx + 1) % EMAC_RX_FRAG_COUNT;
172 frame->types.mac.macHeader.type = (NetDefs::MAC_TYPE) LibEndian::beToHw((uint16_t) frame->types.mac.macHeader.type);
175 return ((NetDefs::FRAME*) 0);
178 void NetMac::putHeader(NetDefs::FRAME& frame,
const NetDefs::MAC_ADDR& dst, NetDefs::MAC_TYPE type) {
179 frame.types.mac.macHeader.dstAddr = dst;
180 frame.types.mac.macHeader.srcAddr = sAddr;
181 frame.types.mac.macHeader.type = (NetDefs::MAC_TYPE) LibEndian::hwToBe((uint16_t) type);
184 bool NetMac::flush(NetDefs::FRAME& frame,
size_t len,
bool discardable) {
186 Net::freeFrame(frame);
192 TX_DESC* desc = &sTxDesc[sTxNextToSend];
193 if (desc->state != TX_FRAG_STATE::TX_FRAG_NO_BUFFER) {
195 Net::freeFrame(frame);
201 desc->tdes1.bits.TBS1 =
sizeof(NetDefs::MAC_HEADER) - 2 + len;
202 desc->tdes2 = (uint32_t) &frame.types.mac.macHeader.dstAddr;
205 desc->state = TX_FRAG_STATE::TX_FRAG_DISCARDABLE;
208 desc->state = TX_FRAG_STATE::TX_FRAG_NOT_DISCARDABLE;
211 desc->tdes0.value = TX_DESC0_OWN | TX_DESC0_IC | TX_DESC0_FS | TX_DESC0_LS | TX_DESC0_TCH;
212 sTxNextToSend = (sTxNextToSend + 1) % EMAC_TX_FRAG_COUNT;
214 if (ETH ->DMASR & ETH_DMASR_TBUS ) {
215 ETH ->DMASR = ETH_DMASR_TBUS;
223 void NetMac::freeSentFrames() {
225 TX_DESC* desc = &sTxDesc[sTxNextToCheck];
227 if (desc->state == TX_FRAG_STATE::TX_FRAG_NO_BUFFER) {
230 if (desc->tdes0.bits.OWN) {
233 if (desc->state == TX_FRAG_STATE::TX_FRAG_DISCARDABLE) {
234 Net::freeFrame(*((NetDefs::FRAME*) (desc->tdes2 - 2)));
236 desc->state = TX_FRAG_STATE::TX_FRAG_NO_BUFFER;
237 sTxNextToCheck = (sTxNextToCheck + 1) % EMAC_TX_FRAG_COUNT;
242 #define EMAC_DEF_PHY_REG 0x0001
243 #define EMAC_DEF_CLOCK_RANGE 0x0004
245 bool NetMac::phyWrite(uint16_t reg, uint16_t value) {
246 ETH ->MACMIIDR = value;
247 ETH ->MACMIIAR = (mPhyAddr << 11) | EMAC_DEF_CLOCK_RANGE | reg << 6 | ETH_MACMIIAR_MW | ETH_MACMIIAR_MB;
253 if (!(ETH ->MACMIIAR & ETH_MACMIIAR_MB )) {
260 uint32_t NetMac::phyRead(uint16_t reg) {
261 ETH ->MACMIIAR = (mPhyAddr << 11) | EMAC_DEF_CLOCK_RANGE | reg << 6 | ETH_MACMIIAR_MB;
267 if (!(ETH ->MACMIIAR & ETH_MACMIIAR_MB )) {
268 return ETH ->MACMIIDR;
274 void RtosInterrupt::IRQ_ETH() {
275 uint32_t mask = ETH ->DMASR;
277 if ((mask & ETH_DMASR_TS )|| (mask & ETH_DMASR_RS)){
278 if(!Net::onMacEventInterrupt()) {