This file defines a useful set of functions for the MACB interface on AVR32 devices.
Definition in file macb.h.
#include <avr32/io.h>
#include "compiler.h"
#include "conf_eth.h"
Go to the source code of this file.
Data Structures | |
struct | _AVR32_RxTdDescriptor |
struct | _AVR32_TxTdDescriptor |
struct | macb_packet_t |
Defines | |
#define | ADVERTISE_ALL |
#define | ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | ADVERTISE_CSMA) |
#define | AVR32_OWNERSHIP_BIT 0x00000001 |
#define | RBR_RMII 0x0020 |
RMII Mode. | |
Advertisement control register. | |
#define | ADVERTISE_1000XFULL 0x0020 |
Try for 1000BASE-X full-duplex. | |
#define | ADVERTISE_1000XHALF 0x0040 |
Try for 1000BASE-X half-duplex. | |
#define | ADVERTISE_1000XPAUSE 0x0080 |
Try for 1000BASE-X pause. | |
#define | ADVERTISE_1000XPSE_ASYM 0x0100 |
Try for 1000BASE-X asym pause. | |
#define | ADVERTISE_100BASE4 0x0200 |
Try for 100mbps 4k packets. | |
#define | ADVERTISE_100FULL 0x0100 |
Try for 100mbps full-duplex. | |
#define | ADVERTISE_100HALF 0x0080 |
Try for 100mbps half-duplex. | |
#define | ADVERTISE_10FULL 0x0040 |
Try for 10mbps full-duplex. | |
#define | ADVERTISE_10HALF 0x0020 |
Try for 10mbps half-duplex. | |
#define | ADVERTISE_CSMA 0x0001 |
Only selector supported. | |
#define | ADVERTISE_LPACK 0x4000 |
Ack link partners response. | |
#define | ADVERTISE_NPAGE 0x8000 |
Next page bit. | |
#define | ADVERTISE_PAUSE_ASYM 0x0800 |
Try for asymetric pause. | |
#define | ADVERTISE_PAUSE_CAP 0x0400 |
Try for pause. | |
#define | ADVERTISE_RESV 0x1000 |
Unused... | |
#define | ADVERTISE_RFAULT 0x2000 |
Say we can detect faults. | |
#define | ADVERTISE_SLCT 0x001f |
Selector bits. | |
#define | AVR32_BROADCAST_ADDR ((unsigned int) (1 << 31)) |
#define | AVR32_CFI_IND ((unsigned int) (1 << 16)) |
#define | AVR32_EOF ((unsigned int) (1 << 15)) |
#define | AVR32_EXTERNAL_ADDR ((unsigned int) (1 << 28)) |
#define | AVR32_LENGTH_FRAME ((unsigned int) 0x0FFF) |
#define | AVR32_MULTICAST_HASH ((unsigned int) (1 << 30)) |
#define | AVR32_PRIORITY_TAG ((unsigned int) (1 << 20)) |
#define | AVR32_RBF_OFFSET ((unsigned int) (3 << 12)) |
#define | AVR32_SA1_ADDR ((unsigned int) (1 << 26)) |
#define | AVR32_SA2_ADDR ((unsigned int) (1 << 25)) |
#define | AVR32_SA3_ADDR ((unsigned int) (1 << 24)) |
#define | AVR32_SA4_ADDR ((unsigned int) (1 << 23)) |
#define | AVR32_SOF ((unsigned int) (1 << 14)) |
#define | AVR32_TYPE_ID ((unsigned int) (1 << 22)) |
#define | AVR32_UNICAST_HASH ((unsigned int) (1 << 29)) |
#define | AVR32_VLAN_PRIORITY ((unsigned int) (7 << 17)) |
#define | AVR32_VLAN_TAG ((unsigned int) (1 << 21)) |
#define | AVR32_BUF_EX ((unsigned int) (1 << 27)) |
#define | AVR32_LAST_BUFFER ((unsigned int) (1 << 15)) |
#define | AVR32_TRANSMIT_ERR ((unsigned int) (1 << 29)) |
#define | AVR32_TRANSMIT_NO_CRC ((unsigned int) (1 << 16)) |
#define | AVR32_TRANSMIT_OK ((unsigned int) (1 << 31)) |
#define | AVR32_TRANSMIT_UND ((unsigned int) (1 << 28)) |
#define | AVR32_TRANSMIT_WRAP ((unsigned int) (1 << 30)) |
Rx Ring descriptor flags | |
#define | AVR32_MACB_RX_CFI_OFFSET 16 |
#define | AVR32_MACB_RX_CFI_SIZE 1 |
#define | AVR32_MACB_RX_EOF_OFFSET 15 |
#define | AVR32_MACB_RX_EOF_SIZE 1 |
#define | AVR32_MACB_RX_LEN_OFFSET 0 |
#define | AVR32_MACB_RX_LEN_SIZE 12 |
#define | AVR32_MACB_RX_OFFSET_OFFSET 12 |
#define | AVR32_MACB_RX_OFFSET_SIZE 2 |
#define | AVR32_MACB_RX_SOF_OFFSET 14 |
#define | AVR32_MACB_RX_SOF_SIZE 1 |
#define | AVR32_MACB_RX_USED_OFFSET 0 |
#define | AVR32_MACB_RX_USED_SIZE 1 |
#define | AVR32_MACB_RX_WRAP_OFFSET 1 |
#define | AVR32_MACB_RX_WRAP_SIZE 1 |
Tx Ring descriptor flags | |
#define | AVR32_MACB_TX_EMF_OFFSET 27 |
#define | AVR32_MACB_TX_EMF_SIZE 1 |
#define | AVR32_MACB_TX_EOF_OFFSET 15 |
#define | AVR32_MACB_TX_EOF_SIZE 1 |
#define | AVR32_MACB_TX_LEN_OFFSET 0 |
#define | AVR32_MACB_TX_LEN_SIZE 11 |
#define | AVR32_MACB_TX_MAXRETRY_OFFSET 29 |
#define | AVR32_MACB_TX_MAXRETRY_SIZE 1 |
#define | AVR32_MACB_TX_NOCRC_OFFSET 16 |
#define | AVR32_MACB_TX_NOCRC_SIZE 1 |
#define | AVR32_MACB_TX_UNR_OFFSET 28 |
#define | AVR32_MACB_TX_UNR_SIZE 1 |
#define | AVR32_MACB_TX_USED_OFFSET 31 |
#define | AVR32_MACB_TX_USED_SIZE 1 |
#define | AVR32_MACB_TX_WRAP_OFFSET 30 |
#define | AVR32_MACB_TX_WRAP_SIZE 1 |
Basic mode control register. | |
#define | BMCR_ANENABLE 0x1000 |
Enable auto negotiation. | |
#define | BMCR_ANRESTART 0x0200 |
Auto negotiation restart. | |
#define | BMCR_CTST 0x0080 |
Collision test. | |
#define | BMCR_FULLDPLX 0x0100 |
Full duplex. | |
#define | BMCR_ISOLATE 0x0400 |
Disconnect PHY from MII. | |
#define | BMCR_LOOPBACK 0x4000 |
TXD loopback bits. | |
#define | BMCR_PDOWN 0x0800 |
Powerdown the PHY. | |
#define | BMCR_RESET 0x8000 |
Reset the PHY. | |
#define | BMCR_RESV 0x007f |
Unused... | |
#define | BMCR_SPEED100 0x2000 |
Select 100Mbps. | |
Basic mode status register. | |
#define | BMSR_100BASE4 0x8000 |
Can do 100mbps, 4k packets. | |
#define | BMSR_100FULL 0x4000 |
Can do 100mbps, full-duplex. | |
#define | BMSR_100FULL2 0x0200 |
Can do 100BASE-T2 HDX. | |
#define | BMSR_100HALF 0x2000 |
Can do 100mbps, half-duplex. | |
#define | BMSR_100HALF2 0x0400 |
Can do 100BASE-T2 FDX. | |
#define | BMSR_10FULL 0x1000 |
Can do 10mbps, full-duplex. | |
#define | BMSR_10HALF 0x0800 |
Can do 10mbps, half-duplex. | |
#define | BMSR_ANEGCAPABLE 0x0008 |
Able to do auto-negotiation. | |
#define | BMSR_ANEGCOMPLETE 0x0020 |
Auto-negotiation complete. | |
#define | BMSR_ERCAP 0x0001 |
Ext-reg capability. | |
#define | BMSR_ESTATEN 0x0100 |
Extended Status in R15. | |
#define | BMSR_JCD 0x0002 |
Jabber detected. | |
#define | BMSR_LSTATUS 0x0004 |
Link status. | |
#define | BMSR_RESV 0x00c0 |
Unused... | |
#define | BMSR_RFAULT 0x0010 |
Remote fault detected. | |
Link partner ability register. | |
#define | LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) |
#define | LPA_1000XFULL 0x0020 |
Can do 1000BASE-X full-duplex. | |
#define | LPA_1000XHALF 0x0040 |
Can do 1000BASE-X half-duplex. | |
#define | LPA_1000XPAUSE 0x0080 |
Can do 1000BASE-X pause. | |
#define | LPA_1000XPAUSE_ASYM 0x0100 |
Can do 1000BASE-X pause asym. | |
#define | LPA_100BASE4 0x0200 |
Can do 100mbps 4k packets. | |
#define | LPA_100FULL 0x0100 |
Can do 100mbps full-duplex. | |
#define | LPA_100HALF 0x0080 |
Can do 100mbps half-duplex. | |
#define | LPA_10FULL 0x0040 |
Can do 10mbps full-duplex. | |
#define | LPA_10HALF 0x0020 |
Can do 10mbps half-duplex. | |
#define | LPA_DUPLEX (LPA_10FULL | LPA_100FULL) |
#define | LPA_LPACK 0x4000 |
Link partner acked us. | |
#define | LPA_NPAGE 0x8000 |
Next page bit. | |
#define | LPA_PAUSE_ASYM 0x0800 |
Can pause asymetrically. | |
#define | LPA_PAUSE_CAP 0x0400 |
Can pause. | |
#define | LPA_RESV 0x1000 |
Unused... | |
#define | LPA_RFAULT 0x2000 |
Link partner faulted. | |
#define | LPA_SLCT 0x001f |
Same as advertise selector. | |
Interrupt Ctrl Register. | |
#define | MICR_INTEN 0x0002 |
Enable interrupts. | |
#define | MICR_INTOE 0x0001 |
Enable INT output. | |
Interrupt Status Register. | |
#define | MISR_ANC_INT 0x0400 |
Auto-Neg complete. | |
#define | MISR_ANC_INT_EN 0x0004 |
Auto-Neg complete enabled. | |
#define | MISR_DP_INT 0x0800 |
Duplex mode change. | |
#define | MISR_DP_INT_EN 0x0008 |
Duplex mode change enabled. | |
#define | MISR_ED_INT 0x4000 |
Energy Detect. | |
#define | MISR_ED_INT_EN 0x0040 |
Energy Detect enabled. | |
#define | MISR_FHF_INT 0x0200 |
False Carrier. | |
#define | MISR_FHF_INT_EN 0x0002 |
False Carrier enabled. | |
#define | MISR_LINK_INT 0x2000 |
Link status change. | |
#define | MISR_LINK_INT_EN 0x0020 |
Link status change enabled. | |
#define | MISR_RHF_INT 0x0100 |
Receive Error. | |
#define | MISR_RHF_INT_EN 0x0001 |
Receive Error enabled. | |
#define | MISR_SPD_INT 0x1000 |
Speed change. | |
#define | MISR_SPD_INT_EN 0x0010 |
Speed change enabled. | |
Generic MII registers. | |
#define | PHY_ADVERTISE 0x04 |
Advertisement control reg. | |
#define | PHY_BMCR 0x00 |
Basic mode control register. | |
#define | PHY_BMSR 0x01 |
Basic mode status register. | |
#define | PHY_LPA 0x05 |
Link partner ability reg. | |
#define | PHY_PHYSID1 0x02 |
PHYS ID 1. | |
#define | PHY_PHYSID2 0x03 |
PHYS ID 2. | |
Extended registers for DP83848 | |
#define | PHY_MICR 0x11 |
Interrupt Control reg. | |
#define | PHY_MISR 0x12 |
Interrupt Status reg. | |
#define | PHY_PHYCR 0x19 |
Phy CTRL reg. | |
#define | PHY_RBR 0x17 |
RMII Bypass reg. | |
Phy Ctrl Register. | |
#define | PHYCR_MDIX_EN 0x8000 |
Enable Auto MDIX. | |
#define | PHYCR_MDIX_FORCE 0x4000 |
Force MDIX crossed. | |
Typedefs | |
typedef struct _AVR32_RxTdDescriptor | AVR32_RxTdDescriptor |
typedef struct _AVR32_RxTdDescriptor * | AVR32P_RxTdDescriptor |
typedef struct _AVR32_TxTdDescriptor | AVR32_TxTdDescriptor |
typedef struct _AVR32_TxTdDescriptor * | AVR32P_TxTdDescriptor |
Functions | |
long | lMACBSend (volatile avr32_macb_t *macb, const void *pvFrom, unsigned long ulLength, long lEndOfFrame) |
Send ulLength bytes from pcFrom. | |
unsigned long | ulMACBInputLength (void) |
Function to get length of the next frame in the receive buffers. | |
void | vClearMACBTxBuffer (void) |
Called by the Tx interrupt, this function traverses the buffers used to hold the frame that has just completed transmission and marks each as free again. | |
void | vDisableMACBOperations (volatile avr32_macb_t *macb) |
Disable MACB operations (Tx and Rx). | |
void | vMACBFlushCurrentPacket (unsigned long ulTotalFrameLength) |
Flush the current received packet. | |
void | vMACBRead (void *pvTo, unsigned long ulSectionLength, unsigned long ulTotalFrameLength) |
Frames can be read from the MACB in multiple sections. | |
void | vMACBSetMACAddress (const unsigned char *MACAddress) |
Set the MACB Physical address (SA1B & SA1T registers). | |
void | vMACBWaitForInput (unsigned long ulTimeOut) |
Suspend on a semaphore waiting either for the semaphore to be obtained or a timeout. | |
Bool | xMACBInit (volatile avr32_macb_t *macb) |
Initialise the MACB driver. |
#define ADVERTISE_1000XFULL 0x0020 |
#define ADVERTISE_1000XHALF 0x0040 |
#define ADVERTISE_1000XPAUSE 0x0080 |
#define ADVERTISE_1000XPSE_ASYM 0x0100 |
#define ADVERTISE_100BASE4 0x0200 |
#define ADVERTISE_100FULL 0x0100 |
#define ADVERTISE_100HALF 0x0080 |
#define ADVERTISE_10FULL 0x0040 |
#define ADVERTISE_10HALF 0x0020 |
#define ADVERTISE_ALL |
#define ADVERTISE_CSMA 0x0001 |
#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | ADVERTISE_CSMA) |
#define AVR32_BROADCAST_ADDR ((unsigned int) (1 << 31)) |
#define AVR32_CFI_IND ((unsigned int) (1 << 16)) |
#define AVR32_EOF ((unsigned int) (1 << 15)) |
#define AVR32_EXTERNAL_ADDR ((unsigned int) (1 << 28)) |
#define AVR32_LAST_BUFFER ((unsigned int) (1 << 15)) |
#define AVR32_LENGTH_FRAME ((unsigned int) 0x0FFF) |
Receive status defintion.
Definition at line 338 of file macb.h.
Referenced by lMACBSend(), and ulMACBInputLength().
#define AVR32_MULTICAST_HASH ((unsigned int) (1 << 30)) |
#define AVR32_OWNERSHIP_BIT 0x00000001 |
Mask for frame used.
Definition at line 317 of file macb.h.
Referenced by ulMACBInputLength(), vMACBFlushCurrentPacket(), vMACBRead(), and vResetMacbRxFrames().
#define AVR32_PRIORITY_TAG ((unsigned int) (1 << 20)) |
#define AVR32_RBF_OFFSET ((unsigned int) (3 << 12)) |
#define AVR32_SA1_ADDR ((unsigned int) (1 << 26)) |
#define AVR32_SA2_ADDR ((unsigned int) (1 << 25)) |
#define AVR32_SA3_ADDR ((unsigned int) (1 << 24)) |
#define AVR32_SA4_ADDR ((unsigned int) (1 << 23)) |
#define AVR32_SOF ((unsigned int) (1 << 14)) |
#define AVR32_TRANSMIT_OK ((unsigned int) (1 << 31)) |
Definition at line 343 of file macb.h.
Referenced by lMACBSend(), prvSetupDescriptors(), and vClearMACBTxBuffer().
#define AVR32_TRANSMIT_WRAP ((unsigned int) (1 << 30)) |
#define AVR32_TYPE_ID ((unsigned int) (1 << 22)) |
#define AVR32_UNICAST_HASH ((unsigned int) (1 << 29)) |
#define AVR32_VLAN_PRIORITY ((unsigned int) (7 << 17)) |
#define AVR32_VLAN_TAG ((unsigned int) (1 << 21)) |
#define BMCR_ANENABLE 0x1000 |
#define BMCR_ANRESTART 0x0200 |
#define BMCR_FULLDPLX 0x0100 |
#define BMCR_SPEED100 0x2000 |
#define BMSR_LSTATUS 0x0004 |
#define LPA_1000XPAUSE_ASYM 0x0100 |
#define LPA_100FULL 0x0100 |
#define LPA_100HALF 0x0080 |
#define LPA_10FULL 0x0040 |
#define MICR_INTEN 0x0002 |
#define MICR_INTOE 0x0001 |
#define MISR_LINK_INT_EN 0x0020 |
Link status change enabled.
Definition at line 224 of file macb.h.
Referenced by prvSetupMACBInterrupt().
#define PHY_ADVERTISE 0x04 |
#define PHY_BMCR 0x00 |
#define PHY_BMSR 0x01 |
Basic mode status register.
Definition at line 107 of file macb.h.
Referenced by prvPHY_ISR_NonNakedBehaviour(), and prvProbePHY().
#define PHY_LPA 0x05 |
#define PHY_MICR 0x11 |
Interrupt Control reg.
Definition at line 119 of file macb.h.
Referenced by prvSetupMACBInterrupt().
#define PHY_MISR 0x12 |
Interrupt Status reg.
Definition at line 120 of file macb.h.
Referenced by prvPHY_ISR_NonNakedBehaviour(), and prvSetupMACBInterrupt().
#define PHY_PHYCR 0x19 |
#define PHY_PHYSID1 0x02 |
#define PHY_PHYSID2 0x03 |
#define PHY_RBR 0x17 |
#define PHYCR_MDIX_EN 0x8000 |
#define PHYCR_MDIX_FORCE 0x4000 |
#define RBR_RMII 0x0020 |
typedef struct _AVR32_RxTdDescriptor AVR32_RxTdDescriptor |
typedef struct _AVR32_TxTdDescriptor AVR32_TxTdDescriptor |
typedef struct _AVR32_RxTdDescriptor * AVR32P_RxTdDescriptor |
typedef struct _AVR32_TxTdDescriptor * AVR32P_TxTdDescriptor |
long lMACBSend | ( | volatile avr32_macb_t * | macb, | |
const void * | pvFrom, | |||
unsigned long | ulLength, | |||
long | lEndOfFrame | |||
) |
Send ulLength bytes from pcFrom.
This copies the buffer to one of the MACB Tx buffers, then indicates to the MACB that the buffer is ready. If lEndOfFrame is true then the data being copied is the end of the frame and the frame can be transmitted.
*macb | Base address of the MACB | |
*pvFrom | Address of the data buffer | |
ulLength | Length of the frame | |
lEndOfFrame | Flag for End Of Frame |
Definition at line 210 of file macb.c.
References AVR32_LAST_BUFFER, AVR32_LENGTH_FRAME, AVR32_TRANSMIT_OK, AVR32_TRANSMIT_WRAP, BUFFER_WAIT_DELAY, ETHERNET_CONF_NB_TX_BUFFERS, ETHERNET_CONF_TX_BUFFER_SIZE, portENTER_CRITICAL, portEXIT_CRITICAL, _AVR32_TxTdDescriptor::status, and _AVR32_TxTdDescriptor::U_Status.
Referenced by macb_example_receive_packet(), macb_example_send_ARP_request(), and macb_example_send_ping_response().
00211 { 00212 const unsigned char *pcFrom = pvFrom; 00213 static unsigned long uxTxBufferIndex = 0; 00214 void *pcBuffer; 00215 unsigned long ulLastBuffer, ulDataBuffered = 0, ulDataRemainingToSend, ulLengthToSend; 00216 00217 /* If the length of data to be transmitted is greater than each individual 00218 transmit buffer then the data will be split into more than one buffer. 00219 Loop until the entire length has been buffered. */ 00220 while( ulDataBuffered < ulLength ) 00221 { 00222 // Is a buffer available ? 00223 while( !( xTxDescriptors[ uxTxBufferIndex ].U_Status.status & AVR32_TRANSMIT_OK ) ) 00224 { 00225 // There is no room to write the Tx data to the Tx buffer. 00226 // Wait a short while, then try again. 00227 #ifdef FREERTOS_USED 00228 vTaskDelay( BUFFER_WAIT_DELAY ); 00229 #else 00230 __asm__ __volatile__ ("nop"); 00231 #endif 00232 } 00233 00234 portENTER_CRITICAL(); 00235 { 00236 // Get the address of the buffer from the descriptor, 00237 // then copy the data into the buffer. 00238 pcBuffer = ( void * ) xTxDescriptors[ uxTxBufferIndex ].addr; 00239 00240 // How much can we write to the buffer ? 00241 ulDataRemainingToSend = ulLength - ulDataBuffered; 00242 if( ulDataRemainingToSend <= ETHERNET_CONF_TX_BUFFER_SIZE ) 00243 { 00244 // We can write all the remaining bytes. 00245 ulLengthToSend = ulDataRemainingToSend; 00246 } 00247 else 00248 { 00249 // We can't write more than ETH_TX_BUFFER_SIZE in one go. 00250 ulLengthToSend = ETHERNET_CONF_TX_BUFFER_SIZE; 00251 } 00252 // Copy the data into the buffer. 00253 memcpy( pcBuffer, &( pcFrom[ ulDataBuffered ] ), ulLengthToSend ); 00254 ulDataBuffered += ulLengthToSend; 00255 // Is this the last data for the frame ? 00256 if( lEndOfFrame && ( ulDataBuffered >= ulLength ) ) 00257 { 00258 // No more data remains for this frame so we can start the transmission. 00259 ulLastBuffer = AVR32_LAST_BUFFER; 00260 } 00261 else 00262 { 00263 // More data to come for this frame. 00264 ulLastBuffer = 0; 00265 } 00266 // Fill out the necessary in the descriptor to get the data sent, 00267 // then move to the next descriptor, wrapping if necessary. 00268 if( uxTxBufferIndex >= ( ETHERNET_CONF_NB_TX_BUFFERS - 1 ) ) 00269 { 00270 xTxDescriptors[ uxTxBufferIndex ].U_Status.status = ( ulLengthToSend & ( unsigned long ) AVR32_LENGTH_FRAME ) 00271 | ulLastBuffer 00272 | AVR32_TRANSMIT_WRAP; 00273 uxTxBufferIndex = 0; 00274 } 00275 else 00276 { 00277 xTxDescriptors[ uxTxBufferIndex ].U_Status.status = ( ulLengthToSend & ( unsigned long ) AVR32_LENGTH_FRAME ) 00278 | ulLastBuffer; 00279 uxTxBufferIndex++; 00280 } 00281 /* If this is the last buffer to be sent for this frame we can 00282 start the transmission. */ 00283 if( ulLastBuffer ) 00284 { 00285 macb->ncr |= AVR32_MACB_TSTART_MASK; 00286 } 00287 } 00288 portEXIT_CRITICAL(); 00289 } 00290 00291 return PASS; 00292 }
unsigned long ulMACBInputLength | ( | void | ) |
Function to get length of the next frame in the receive buffers.
Definition at line 295 of file macb.c.
References _AVR32_RxTdDescriptor::addr, AVR32_LENGTH_FRAME, AVR32_OWNERSHIP_BIT, AVR32_SOF, ETHERNET_CONF_NB_RX_BUFFERS, _AVR32_RxTdDescriptor::status, _AVR32_RxTdDescriptor::U_Status, and vResetMacbRxFrames().
Referenced by main().
00296 { 00297 register unsigned long ulIndex , ulLength = 0; 00298 unsigned int uiTemp; 00299 volatile unsigned long ulEventStatus; 00300 00301 // Check if the MACB encountered a problem. 00302 ulEventStatus = AVR32_MACB.rsr; 00303 if( ulEventStatus & AVR32_MACB_RSR_BNA_MASK ) 00304 { // MACB couldn't get ownership of a buffer. This could typically 00305 // happen if the total numbers of Rx buffers is tailored too small 00306 // for a noisy network with big frames. 00307 // We might as well restore ownership of all buffers to the MACB to 00308 // restart from a clean state. 00309 vResetMacbRxFrames(); 00310 return( ulLength ); 00311 } 00312 00313 // Skip any fragments. We are looking for the first buffer that contains 00314 // data and has the SOF (start of frame) bit set. 00315 while( ( xRxDescriptors[ ulNextRxBuffer ].addr & AVR32_OWNERSHIP_BIT ) 00316 && !( xRxDescriptors[ ulNextRxBuffer ].U_Status.status & AVR32_SOF ) ) 00317 { 00318 // Ignoring this buffer. Mark it as free again. 00319 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr; 00320 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT ); 00321 ulNextRxBuffer++; 00322 if( ulNextRxBuffer >= ETHERNET_CONF_NB_RX_BUFFERS ) 00323 { 00324 ulNextRxBuffer = 0; 00325 } 00326 } 00327 00328 // We are going to walk through the descriptors that make up this frame, 00329 // but don't want to alter ulNextRxBuffer as this would prevent vMACBRead() 00330 // from finding the data. Therefore use a copy of ulNextRxBuffer instead. 00331 ulIndex = ulNextRxBuffer; 00332 00333 // Walk through the descriptors until we find the last buffer for this frame. 00334 // The last buffer will give us the length of the entire frame. 00335 while ( xRxDescriptors[ ulIndex ].addr & AVR32_OWNERSHIP_BIT ) 00336 { 00337 ulLength = xRxDescriptors[ ulIndex ].U_Status.status & AVR32_LENGTH_FRAME; 00338 if (ulLength) break; //return ulLength 00339 00340 // Increment to the next buffer, wrapping if necessary. 00341 if( ++ulIndex >= ETHERNET_CONF_NB_RX_BUFFERS ) ulIndex = 0; 00342 00343 // Is the descriptor valid? 00344 if (!(xRxDescriptors[ ulIndex ].addr & AVR32_OWNERSHIP_BIT)) break; //return 0 00345 00346 // Is it a SOF? If so, the head packet is bad and should be discarded 00347 if (xRxDescriptors[ ulIndex ].U_Status.status & AVR32_SOF) 00348 { 00349 // Mark the buffers of the CURRENT, FAULTY packet available. 00350 unsigned int i = ulNextRxBuffer; 00351 do{ 00352 // Ignore the faulty frame. Mark its buffers as owned by the MACB. 00353 uiTemp = xRxDescriptors[ i ].addr; 00354 xRxDescriptors[ i ].addr = uiTemp & ~(AVR32_OWNERSHIP_BIT); 00355 if (++i>=ETHERNET_CONF_NB_RX_BUFFERS) i=0; 00356 }while (i!=ulIndex); 00357 ulNextRxBuffer=ulIndex; 00358 // We have the start of a new packet, look at that one instead. 00359 } 00360 } 00361 return ulLength; 00362 }
void vClearMACBTxBuffer | ( | void | ) |
Called by the Tx interrupt, this function traverses the buffers used to hold the frame that has just completed transmission and marks each as free again.
Definition at line 588 of file macb.c.
References AVR32_LAST_BUFFER, AVR32_TRANSMIT_OK, ETHERNET_CONF_NB_TX_BUFFERS, _AVR32_TxTdDescriptor::status, and _AVR32_TxTdDescriptor::U_Status.
Referenced by prvMACB_ISR_NonNakedBehaviour().
00589 { 00590 static unsigned long uxNextBufferToClear = 0; 00591 00592 // Called on Tx interrupt events to set the AVR32_TRANSMIT_OK bit in each 00593 // Tx buffer within the frame just transmitted. This marks all the buffers 00594 // as available again. 00595 00596 // The first buffer in the frame should have the bit set automatically. */ 00597 if( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_TRANSMIT_OK ) 00598 { 00599 // Loop through the other buffers in the frame. 00600 while( !( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_LAST_BUFFER ) ) 00601 { 00602 uxNextBufferToClear++; 00603 00604 if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS ) 00605 { 00606 uxNextBufferToClear = 0; 00607 } 00608 00609 xTxDescriptors[ uxNextBufferToClear ].U_Status.status |= AVR32_TRANSMIT_OK; 00610 } 00611 00612 // Start with the next buffer the next time a Tx interrupt is called. 00613 uxNextBufferToClear++; 00614 00615 // Do we need to wrap back to the first buffer? 00616 if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS ) 00617 { 00618 uxNextBufferToClear = 0; 00619 } 00620 } 00621 }
void vDisableMACBOperations | ( | volatile avr32_macb_t * | macb | ) |
Disable MACB operations (Tx and Rx).
*macb | Base address of the MACB |
Definition at line 567 of file macb.c.
00568 { 00569 Bool global_interrupt_enabled = Is_global_interrupt_enabled(); 00570 #if ETHERNET_CONF_USE_PHY_IT == 1 00571 volatile avr32_gpio_t *gpio = &AVR32_GPIO; 00572 volatile avr32_gpio_port_t *gpio_port = &gpio->port[MACB_INTERRUPT_PIN/32]; 00573 00574 gpio_port->ierc = 1 << (MACB_INTERRUPT_PIN%32); 00575 #endif 00576 00577 // write the MACB control register : disable Tx & Rx 00578 macb->ncr &= ~((1 << AVR32_MACB_RE_OFFSET) | (1 << AVR32_MACB_TE_OFFSET)); 00579 00580 // We no more want to interrupt on Rx and Tx events. 00581 if (global_interrupt_enabled) Disable_global_interrupt(); 00582 macb->idr = AVR32_MACB_IER_RCOMP_MASK | AVR32_MACB_IER_TCOMP_MASK; 00583 macb->isr; 00584 if (global_interrupt_enabled) Enable_global_interrupt(); 00585 }
void vMACBFlushCurrentPacket | ( | unsigned long | ulTotalFrameLength | ) |
Flush the current received packet.
ulTotalFrameLength | Length of the packet to flush |
Definition at line 471 of file macb.c.
References _AVR32_RxTdDescriptor::addr, AVR32_OWNERSHIP_BIT, ETHERNET_CONF_NB_RX_BUFFERS, and RX_BUFFER_SIZE.
00472 { 00473 unsigned int uiTemp; 00474 long int lTotalFrameLen = (long int)ulTotalFrameLength; 00475 00476 00477 // Loop until the whole current packet is flushed. 00478 /* do 00479 { 00480 // Ignoring this buffer. Mark it as free again. 00481 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr; 00482 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT ); 00483 00484 // Move on to the next buffer. 00485 ulNextRxBuffer++; 00486 ulNextRxBuffer = ulNextRxBuffer%ETHERNET_CONF_NB_RX_BUFFERS; 00487 }while( ( xRxDescriptors[ ulNextRxBuffer ].addr & AVR32_OWNERSHIP_BIT ) 00488 && !( xRxDescriptors[ ulNextRxBuffer ].U_Status.status & AVR32_SOF ) );*/ 00489 while( lTotalFrameLen > 0 ) 00490 { 00491 // Ignoring this buffer. Mark it as free again. 00492 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr; 00493 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT ); 00494 00495 // Move on to the next buffer. 00496 ulNextRxBuffer++; 00497 ulNextRxBuffer = ulNextRxBuffer%ETHERNET_CONF_NB_RX_BUFFERS; 00498 00499 lTotalFrameLen -= RX_BUFFER_SIZE; 00500 } 00501 }
void vMACBRead | ( | void * | pvTo, | |
unsigned long | ulSectionLength, | |||
unsigned long | ulTotalFrameLength | |||
) |
Frames can be read from the MACB in multiple sections.
Read ulSectionLength bytes from the MACB receive buffers to pcTo. ulTotalFrameLength is the size of the entire frame. Generally vMACBRead will be repetedly called until the sum of all the ulSectionLenths totals the value of ulTotalFrameLength.
*pvTo | Address of the buffer | |
ulSectionLength | Length of the buffer | |
ulTotalFrameLength | Length of the frame |
Definition at line 365 of file macb.c.
References _AVR32_RxTdDescriptor::addr, ADDRESS_MASK, AVR32_OWNERSHIP_BIT, ETHERNET_CONF_NB_RX_BUFFERS, and RX_BUFFER_SIZE.
Referenced by main().
00366 { 00367 unsigned char *pcTo = pvTo; 00368 static unsigned long ulSectionBytesReadSoFar = 0, ulBufferPosition = 0, ulFrameBytesReadSoFar = 0; 00369 static const unsigned char *pcSource; 00370 register unsigned long ulBytesRemainingInBuffer, ulRemainingSectionBytes; 00371 unsigned int uiTemp; 00372 00373 // Read ulSectionLength bytes from the Rx buffers. 00374 // This is not necessarily any correspondence between the length of our Rx buffers, 00375 // and the length of the data we are returning or the length of the data being requested. 00376 // Therefore, between calls we have to remember not only which buffer we are currently 00377 // processing, but our position within that buffer. 00378 // This would be greatly simplified if PBUF_POOL_BUFSIZE could be guaranteed to be greater 00379 // than the size of each Rx buffer, and that memory fragmentation did not occur. 00380 00381 // This function should only be called after a call to ulMACBInputLength(). 00382 // This will ensure ulNextRxBuffer is set to the correct buffer. */ 00383 00384 // vMACBRead is called with pcTo set to NULL to indicate that we are about 00385 // to read a new frame. Any fragments remaining in the frame we were 00386 // processing during the last call should be dropped. 00387 if( pcTo == NULL ) 00388 { 00389 // How many bytes are indicated as being in this buffer? 00390 // If none then the buffer is completely full and the frame is contained within more 00391 // than one buffer. 00392 // Reset our state variables ready for the next read from this buffer. 00393 pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK ); 00394 ulFrameBytesReadSoFar = ( unsigned long ) 0; 00395 ulBufferPosition = ( unsigned long ) 0; 00396 } 00397 else 00398 { 00399 // Loop until we have obtained the required amount of data. 00400 ulSectionBytesReadSoFar = 0; 00401 while( ulSectionBytesReadSoFar < ulSectionLength ) 00402 { 00403 // We may have already read some data from this buffer. 00404 // How much data remains in the buffer? 00405 ulBytesRemainingInBuffer = ( RX_BUFFER_SIZE - ulBufferPosition ); 00406 00407 // How many more bytes do we need to read before we have the 00408 // required amount of data? 00409 ulRemainingSectionBytes = ulSectionLength - ulSectionBytesReadSoFar; 00410 00411 // Do we want more data than remains in the buffer? 00412 if( ulRemainingSectionBytes > ulBytesRemainingInBuffer ) 00413 { 00414 // We want more data than remains in the buffer so we can 00415 // write the remains of the buffer to the destination, then move 00416 // onto the next buffer to get the rest. 00417 memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulBytesRemainingInBuffer ); 00418 ulSectionBytesReadSoFar += ulBytesRemainingInBuffer; 00419 ulFrameBytesReadSoFar += ulBytesRemainingInBuffer; 00420 00421 // Mark the buffer as free again. 00422 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr; 00423 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT ); 00424 // Move onto the next buffer. 00425 ulNextRxBuffer++; 00426 00427 if( ulNextRxBuffer >= ETHERNET_CONF_NB_RX_BUFFERS ) 00428 { 00429 ulNextRxBuffer = ( unsigned long ) 0; 00430 } 00431 00432 // Reset the variables for the new buffer. 00433 pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK ); 00434 ulBufferPosition = ( unsigned long ) 0; 00435 } 00436 else 00437 { 00438 // We have enough data in this buffer to send back. 00439 // Read out enough data and remember how far we read up to. 00440 memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulRemainingSectionBytes ); 00441 00442 // There may be more data in this buffer yet. 00443 // Increment our position in this buffer past the data we have just read. 00444 ulBufferPosition += ulRemainingSectionBytes; 00445 ulSectionBytesReadSoFar += ulRemainingSectionBytes; 00446 ulFrameBytesReadSoFar += ulRemainingSectionBytes; 00447 00448 // Have we now finished with this buffer? 00449 if( ( ulBufferPosition >= RX_BUFFER_SIZE ) || ( ulFrameBytesReadSoFar >= ulTotalFrameLength ) ) 00450 { 00451 // Mark the buffer as free again. 00452 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr; 00453 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT ); 00454 // Move onto the next buffer. 00455 ulNextRxBuffer++; 00456 00457 if( ulNextRxBuffer >= ETHERNET_CONF_NB_RX_BUFFERS ) 00458 { 00459 ulNextRxBuffer = 0; 00460 } 00461 00462 pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK ); 00463 ulBufferPosition = 0; 00464 } 00465 } 00466 } 00467 } 00468 }
void vMACBSetMACAddress | ( | const unsigned char * | MACAddress | ) |
Set the MACB Physical address (SA1B & SA1T registers).
*MACAddress | the MAC address to set. |
Definition at line 505 of file macb.c.
00506 { 00507 memcpy(cMACAddress, MACAddress, sizeof(cMACAddress)); 00508 }
void vMACBWaitForInput | ( | unsigned long | ulTimeOut | ) |
Suspend on a semaphore waiting either for the semaphore to be obtained or a timeout.
The semaphore is used by the MACB ISR to indicate that data has been received and is ready for processing.
ulTimeOut | time to wait for an input |
Definition at line 960 of file macb.c.
References portENTER_CRITICAL, and portEXIT_CRITICAL.
Referenced by main().
00961 { 00962 #ifdef FREERTOS_USED 00963 // Just wait until we are signled from an ISR that data is available, or 00964 // we simply time out. 00965 xSemaphoreTake( xSemaphore, ulTimeOut ); 00966 #else 00967 unsigned long i; 00968 00969 i = ulTimeOut * 1000; 00970 // wait for an interrupt to occurs 00971 do 00972 { 00973 if ( DataToRead == TRUE ) 00974 { 00975 // IT occurs, reset interrupt flag 00976 portENTER_CRITICAL(); 00977 DataToRead = FALSE; 00978 portEXIT_CRITICAL(); 00979 break; 00980 } 00981 i--; 00982 } 00983 while(i != 0); 00984 #endif 00985 }
Bool xMACBInit | ( | volatile avr32_macb_t * | macb | ) |
Initialise the MACB driver.
*macb | Base address of the MACB |
Definition at line 510 of file macb.c.
References portENTER_CRITICAL, portEXIT_CRITICAL, prvProbePHY(), prvSetupDescriptors(), prvSetupMACAddress(), and prvSetupMACBInterrupt().
Referenced by main().
00511 { 00512 Bool global_interrupt_enabled = Is_global_interrupt_enabled(); 00513 volatile unsigned long status; 00514 00515 // set up registers 00516 macb->ncr = 0; 00517 macb->tsr = ~0UL; 00518 macb->rsr = ~0UL; 00519 00520 if (global_interrupt_enabled) Disable_global_interrupt(); 00521 macb->idr = ~0UL; 00522 status = macb->isr; 00523 if (global_interrupt_enabled) Enable_global_interrupt(); 00524 00525 #if ETHERNET_CONF_USE_RMII_INTERFACE 00526 // RMII used, set 0 to the USRIO Register 00527 macb->usrio &= ~AVR32_MACB_RMII_MASK; 00528 #else 00529 // RMII not used, set 1 to the USRIO Register 00530 macb->usrio |= AVR32_MACB_RMII_MASK; 00531 #endif 00532 00533 // Load our MAC address into the MACB. 00534 prvSetupMACAddress(macb); 00535 00536 // Setup the buffers and descriptors. 00537 prvSetupDescriptors(macb); 00538 00539 #if ETHERNET_CONF_SYSTEM_CLOCK <= 20000000 00540 macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV8 << AVR32_MACB_NCFGR_CLK_OFFSET); 00541 #elif ETHERNET_CONF_SYSTEM_CLOCK <= 40000000 00542 macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV16 << AVR32_MACB_NCFGR_CLK_OFFSET); 00543 #elif ETHERNET_CONF_SYSTEM_CLOCK <= 80000000 00544 macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV32 << AVR32_MACB_NCFGR_CLK_OFFSET; 00545 #elif ETHERNET_CONF_SYSTEM_CLOCK <= 160000000 00546 macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV64 << AVR32_MACB_NCFGR_CLK_OFFSET; 00547 #else 00548 # error System clock too fast 00549 #endif 00550 00551 // Are we connected? 00552 if( prvProbePHY(macb) == TRUE ) 00553 { 00554 // Enable the interrupt! 00555 portENTER_CRITICAL(); 00556 { 00557 prvSetupMACBInterrupt(macb); 00558 } 00559 portEXIT_CRITICAL(); 00560 // Enable Rx and Tx, plus the stats register. 00561 macb->ncr = AVR32_MACB_NCR_TE_MASK | AVR32_MACB_NCR_RE_MASK; 00562 return (TRUE); 00563 } 00564 return (FALSE); 00565 }