Przykładowy kod źródłowy implementujący wszystkie wymienione wyżej punkty przedstawiono w listingu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
/* Buffer Descriptor Format */ #ifdef ENHANCED_BD typedef struct { uint16_t status; /* control and status */ uint16_t length; /* transfer length */ uint8_t *data; /* buffer address */ uint32_t ebd_status; uint16_t length_proto_type; uint16_t payload_checksum; uint32_t bdu; uint32_t timestamp; uint32_t reserverd_word1; uint32_t reserverd_word2; } NBUF; #else typedef struct { uint16_t status; /* control and status */ uint16_t length; /* transfer length */ uint8_t *data; /* buffer address */ } NBUF; #endif /* ENHANCED_BD */ static void enet_init() { int usData; const unsigned portCHAR ucMACAddress[6] = { configMAC_ADDR0, configMAC_ADDR1,configMAC_ADDR2,configMAC_ADDR3,configMAC_ADDR4,configMAC_ADDR5 }; /* Enable the ENET clock. */ SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; /*FSL: allow concurrent access to MPU controller. Example: ENET uDMA to SRAM, otherwise bus error*/ MPU_CESR = 0; prvInitialiseENETBuffers(); /* Set the Reset bit and clear the Enable bit */ ENET_ECR = ENET_ECR_RESET_MASK; /* Wait at least 8 clock cycles */ for( usData = 0; usData < 10; usData++ ) { asm( "NOP" ); } /*FSL: start MII interface*/ mii_init(0, periph_clk_khz/1000/*MHz*/); //enet_interrupt_routine set_irq_priority (76, 6); enable_irq(76);//ENET xmit interrupt //enet_interrupt_routine set_irq_priority (77, 6); enable_irq(77);//ENET rx interrupt //enet_interrupt_routine set_irq_priority (78, 6); enable_irq(78);//ENET error and misc interrupts /* * Make sure the external interface signals are enabled */ PORTB_PCR0 = PORT_PCR_MUX(4);//GPIO;//RMII0_MDIO/MII0_MDIO PORTB_PCR1 = PORT_PCR_MUX(4);//GPIO;//RMII0_MDC/MII0_MDC #if configUSE_MII_MODE PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV PORTA_PCR5 = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER PORTA_PCR12 = PORT_PCR_MUX(4);//RMII0_RXD1/MII0_RXD1 PORTA_PCR13 = PORT_PCR_MUX(4);//RMII0_RXD0/MII0_RXD0 PORTA_PCR15 = PORT_PCR_MUX(4);//RMII0_TXEN/MII0_TXEN PORTA_PCR16 = PORT_PCR_MUX(4);//RMII0_TXD0/MII0_TXD0 PORTA_PCR17 = PORT_PCR_MUX(4);//RMII0_TXD1/MII0_TXD1 PORTA_PCR11 = PORT_PCR_MUX(4);//MII0_RXCLK PORTA_PCR25 = PORT_PCR_MUX(4);//MII0_TXCLK PORTA_PCR9 = PORT_PCR_MUX(4);//MII0_RXD3 PORTA_PCR10 = PORT_PCR_MUX(4);//MII0_RXD2 PORTA_PCR28 = PORT_PCR_MUX(4);//MII0_TXER PORTA_PCR24 = PORT_PCR_MUX(4);//MII0_TXD2 PORTA_PCR26 = PORT_PCR_MUX(4);//MII0_TXD3 PORTA_PCR27 = PORT_PCR_MUX(4);//MII0_CRS PORTA_PCR29 = PORT_PCR_MUX(4);//MII0_COL #else PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV PORTA_PCR5 = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER PORTA_PCR12 = PORT_PCR_MUX(4);//RMII0_RXD1/MII0_RXD1 PORTA_PCR13 = PORT_PCR_MUX(4);//RMII0_RXD0/MII0_RXD0 PORTA_PCR15 = PORT_PCR_MUX(4);//RMII0_TXEN/MII0_TXEN PORTA_PCR16 = PORT_PCR_MUX(4);//RMII0_TXD0/MII0_TXD0 PORTA_PCR17 = PORT_PCR_MUX(4);//RMII0_TXD1/MII0_TXD1 #endif /* Can we talk to the PHY? */ do { RTOS_DELAY( netifLINK_DELAY ); usData = 0xffff; mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &usData ); } while( usData == 0xffff ); /* Start auto negotiate. */ mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) ); /* Wait for auto negotiate to complete. */ do { RTOS_DELAY( netifLINK_DELAY ); mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &usData ); } while( !( usData & PHY_BMSR_AN_COMPLETE ) ); /* When we get here we have a link - find out what has been negotiated. */ usData = 0; mii_read( 0, configPHY_ADDRESS, PHY_STATUS, &usData ); /* Clear the Individual and Group Address Hash registers */ ENET_IALR = 0; ENET_IAUR = 0; ENET_GALR = 0; ENET_GAUR = 0; /* Set the Physical Address for the selected ENET */ enet_set_address( 0, ucMACAddress ); #if configUSE_MII_MODE /* Various mode/status setup. */ ENET_RCR = ENET_RCR_MAX_FL(configENET_RX_BUFFER_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK; #else ENET_RCR = ENET_RCR_MAX_FL(configENET_RX_BUFFER_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK; #endif /*FSL: clear rx/tx control registers*/ ENET_TCR = 0; /* Setup half or full duplex. */ if( usData & PHY_DUPLEX_STATUS ) { /*Full duplex*/ ENET_RCR &= (unsigned portLONG)~ENET_RCR_DRT_MASK; ENET_TCR |= ENET_TCR_FDEN_MASK; } else { /*half duplex*/ ENET_RCR |= ENET_RCR_DRT_MASK; ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK; } /* Setup speed */ if( usData & PHY_SPEED_STATUS ) { /*10Mbps*/ ENET_RCR |= ENET_RCR_RMII_10T_MASK; } #if( configUSE_PROMISCUOUS_MODE == 1 ) { ENET_RCR |= ENET_RCR_PROM_MASK; } #endif #ifdef ENHANCED_BD ENET_ECR = ENET_ECR_EN1588_MASK; #else ENET_ECR = 0; #endif /* Set Rx Buffer Size */ ENET_MRBR = (unsigned portSHORT) configENET_RX_BUFFER_SIZE; /* Point to the start of the circular Rx buffer descriptor queue */ ENET_RDSR = ( unsigned portLONG ) &( xENETRxDescriptors[ 0 ] ); /* Point to the start of the circular Tx buffer descriptor queue */ ENET_TDSR = ( unsigned portLONG ) xENETTxDescriptors; /* Clear all ENET interrupt events */ ENET_EIR = ( unsigned portLONG ) -1; /* Enable interrupts */ ENET_EIMR = ENET_EIR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_RXB_MASK | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK; /* Create the task that handles the MAC ENET RX */ /* RTOS + TCP/IP stack dependent */ /* Enable the MAC itself. */ ENET_ECR |= ENET_ECR_ETHEREN_MASK; /* Indicate that there have been empty receive buffers produced */ ENET_RDAR = ENET_RDAR_RDAR_MASK; } static void prvInitialiseENETBuffers( void ) { unsigned portBASE_TYPE ux; unsigned char *pcBufPointer; pcBufPointer = &( xENETTxDescriptors_unaligned[ 0 ] ); while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 ) { pcBufPointer++; } xENETTxDescriptors = ( NBUF * ) pcBufPointer; pcBufPointer = &( xENETRxDescriptors_unaligned[ 0 ] ); while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 ) { pcBufPointer++; } xENETRxDescriptors = ( NBUF * ) pcBufPointer; /* Setup the buffers and descriptors. */ pcBufPointer = &( ucENETTxBuffers[ 0 ] ); while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 ) { pcBufPointer++; } for( ux = 0; ux < configNUM_ENET_TX_BUFFERS; ux++ ) { xENETTxDescriptors[ ux ].status = TX_BD_TC; #ifdef NBUF_LITTLE_ENDIAN xENETTxDescriptors[ ux ].data = (uint8_t *)__REV((uint32_t)pcBufPointer); #else xENETTxDescriptors[ ux ].data = pcBufPointer; #endif pcBufPointer += configENET_TX_BUFFER_SIZE; xENETTxDescriptors[ ux ].length = 0; #ifdef ENHANCED_BD xENETTxDescriptors[ ux ].ebd_status = TX_BD_IINS | TX_BD_PINS; #endif } pcBufPointer = &( ucENETRxBuffers[ 0 ] ); while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 ) { pcBufPointer++; } for( ux = 0; ux < configNUM_ENET_RX_BUFFERS; ux++ ) { xENETRxDescriptors[ ux ].status = RX_BD_E; xENETRxDescriptors[ ux ].length = 0; #ifdef NBUF_LITTLE_ENDIAN xENETRxDescriptors[ ux ].data = (uint8_t *)__REV((uint32_t)pcBufPointer); #else xENETRxDescriptors[ ux ].data = pcBufPointer; #endif pcBufPointer += configENET_RX_BUFFER_SIZE; #ifdef ENHANCED_BD xENETRxDescriptors[ ux ].bdu = 0x00000000; xENETRxDescriptors[ ux ].ebd_status = RX_BD_INT; #endif } /* Set the wrap bit in the last descriptors to form a ring. */ xENETTxDescriptors[ configNUM_ENET_TX_BUFFERS - 1 ].status |= TX_BD_W; xENETRxDescriptors[ configNUM_ENET_RX_BUFFERS - 1 ].status |= RX_BD_W; uxNextRxBuffer = 0; uxNextTxBuffer = 0; } |