00001
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <avr32/io.h>
00052
00053 #include "compiler.h"
00054
00055 #include "gpio.h"
00056
00057
00058 #ifdef FREERTOS_USED
00059 #include "FreeRTOS.h"
00060 #include "task.h"
00061 #include "semphr.h"
00062 #endif
00063 #include "macb.h"
00064 #include "conf_eth.h"
00065 #include "intc.h"
00066
00067
00068
00069 #define RX_BUFFER_SIZE 128
00070
00071
00072
00073
00074
00075 #define ADDRESS_MASK ( ( unsigned long ) 0xFFFFFFFC )
00076
00077
00078
00079 #define RX_WRAP_BIT ( ( unsigned long ) 0x02 )
00080
00081
00082
00083 #define BUFFER_WAIT_DELAY ( 2 )
00084
00085 #ifndef FREERTOS_USED
00086 #define portENTER_CRITICAL Disable_global_interrupt
00087 #define portEXIT_CRITICAL Enable_global_interrupt
00088 #define portENTER_SWITCHING_ISR()
00089 #define portEXIT_SWITCHING_ISR()
00090 #endif
00091
00092
00093
00094
00095 #if defined(__GNUC__)
00096 static volatile char pcRxBuffer[ ETHERNET_CONF_NB_RX_BUFFERS * RX_BUFFER_SIZE ] __attribute__ ((aligned (4)));
00097 #elif defined(__ICCAVR32__)
00098 #pragma data_alignment=4
00099 static volatile char pcRxBuffer[ ETHERNET_CONF_NB_RX_BUFFERS * RX_BUFFER_SIZE ];
00100 #endif
00101
00102
00103
00104
00105 #if defined(__GNUC__)
00106 static volatile char pcTxBuffer[ ETHERNET_CONF_NB_TX_BUFFERS * ETHERNET_CONF_TX_BUFFER_SIZE ] __attribute__ ((aligned (4)));
00107 #elif defined(__ICCAVR32__)
00108 #pragma data_alignment=4
00109 static volatile char pcTxBuffer[ ETHERNET_CONF_NB_TX_BUFFERS * ETHERNET_CONF_TX_BUFFER_SIZE ];
00110 #endif
00111
00112
00113
00114
00115 #if defined(__GNUC__)
00116 static volatile AVR32_TxTdDescriptor xTxDescriptors[ ETHERNET_CONF_NB_TX_BUFFERS ] __attribute__ ((aligned (8)));
00117 static volatile AVR32_RxTdDescriptor xRxDescriptors[ ETHERNET_CONF_NB_RX_BUFFERS ] __attribute__ ((aligned (8)));
00118 #elif defined(__ICCAVR32__)
00119 #pragma data_alignment=8
00120 static volatile AVR32_TxTdDescriptor xTxDescriptors[ ETHERNET_CONF_NB_TX_BUFFERS ];
00121 #pragma data_alignment=8
00122 static volatile AVR32_RxTdDescriptor xRxDescriptors[ ETHERNET_CONF_NB_RX_BUFFERS ];
00123 #endif
00124
00125
00126 unsigned char cMACAddress[ 6 ] = { ETHERNET_CONF_ETHADDR0,ETHERNET_CONF_ETHADDR1,ETHERNET_CONF_ETHADDR2,ETHERNET_CONF_ETHADDR3,ETHERNET_CONF_ETHADDR4,ETHERNET_CONF_ETHADDR5 };
00127
00128
00129
00130
00131
00132
00133
00134
00135 #ifdef FREERTOS_USED
00136 #if defined(__GNUC__)
00137 __attribute__((__naked__))
00138 #elif defined(__ICCAVR32__)
00139 #pragma shadow_registers = full // Naked.
00140 #endif
00141 #else
00142 #if defined(__GNUC__)
00143 __attribute__((__interrupt__))
00144 #elif defined(__ICCAVR32__)
00145 __interrupt
00146 #endif
00147 #endif
00148 void vMACB_ISR(void);
00149 static long prvMACB_ISR_NonNakedBehaviour(void);
00150
00151
00152 #if ETHERNET_CONF_USE_PHY_IT == 1
00153 #ifdef FREERTOS_USED
00154 #if __GNUC__
00155 __attribute__((__naked__))
00156 #elif __ICCAVR32__
00157 #pragma shadow_registers = full // Naked.
00158 #endif
00159 #else
00160 #if __GNUC__
00161 __attribute__((__interrupt__))
00162 #elif __ICCAVR32__
00163 __interrupt
00164 #endif
00165 #endif
00166 void vPHY_ISR(void);
00167 static long prvPHY_ISR_NonNakedBehaviour(void);
00168 #endif
00169
00170
00171
00172
00173
00174 static void prvSetupDescriptors(volatile avr32_macb_t *macb);
00175
00176
00177
00178
00179 static void vResetMacbRxFrames( void );
00180
00181
00182
00183
00184 static void prvSetupMACAddress(volatile avr32_macb_t *macb);
00185
00186
00187
00188
00189 static void prvSetupMACBInterrupt(volatile avr32_macb_t *macb);
00190
00191
00192
00193
00194 static Bool prvProbePHY(volatile avr32_macb_t *macb);
00195 static unsigned long ulReadMDIO(volatile avr32_macb_t *macb, unsigned short usAddress);
00196 static void vWriteMDIO(volatile avr32_macb_t *macb, unsigned short usAddress, unsigned short usValue);
00197
00198
00199 #ifdef FREERTOS_USED
00200
00201 static xSemaphoreHandle xSemaphore = NULL;
00202 #else
00203 static volatile Bool DataToRead = FALSE;
00204 #endif
00205
00206
00207 volatile unsigned long ulNextRxBuffer = 0;
00208
00209
00210 long lMACBSend(volatile avr32_macb_t *macb, const void *pvFrom, unsigned long ulLength, long lEndOfFrame)
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
00218
00219
00220 while( ulDataBuffered < ulLength )
00221 {
00222
00223 while( !( xTxDescriptors[ uxTxBufferIndex ].U_Status.status & AVR32_TRANSMIT_OK ) )
00224 {
00225
00226
00227 #ifdef FREERTOS_USED
00228 vTaskDelay( BUFFER_WAIT_DELAY );
00229 #else
00230 __asm__ __volatile__ ("nop");
00231 #endif
00232 }
00233
00234 portENTER_CRITICAL();
00235 {
00236
00237
00238 pcBuffer = ( void * ) xTxDescriptors[ uxTxBufferIndex ].addr;
00239
00240
00241 ulDataRemainingToSend = ulLength - ulDataBuffered;
00242 if( ulDataRemainingToSend <= ETHERNET_CONF_TX_BUFFER_SIZE )
00243 {
00244
00245 ulLengthToSend = ulDataRemainingToSend;
00246 }
00247 else
00248 {
00249
00250 ulLengthToSend = ETHERNET_CONF_TX_BUFFER_SIZE;
00251 }
00252
00253 memcpy( pcBuffer, &( pcFrom[ ulDataBuffered ] ), ulLengthToSend );
00254 ulDataBuffered += ulLengthToSend;
00255
00256 if( lEndOfFrame && ( ulDataBuffered >= ulLength ) )
00257 {
00258
00259 ulLastBuffer = AVR32_LAST_BUFFER;
00260 }
00261 else
00262 {
00263
00264 ulLastBuffer = 0;
00265 }
00266
00267
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
00282
00283 if( ulLastBuffer )
00284 {
00285 macb->ncr |= AVR32_MACB_TSTART_MASK;
00286 }
00287 }
00288 portEXIT_CRITICAL();
00289 }
00290
00291 return PASS;
00292 }
00293
00294
00295 unsigned long ulMACBInputLength(void)
00296 {
00297 register unsigned long ulIndex , ulLength = 0;
00298 unsigned int uiTemp;
00299 volatile unsigned long ulEventStatus;
00300
00301
00302 ulEventStatus = AVR32_MACB.rsr;
00303 if( ulEventStatus & AVR32_MACB_RSR_BNA_MASK )
00304 {
00305
00306
00307
00308
00309 vResetMacbRxFrames();
00310 return( ulLength );
00311 }
00312
00313
00314
00315 while( ( xRxDescriptors[ ulNextRxBuffer ].addr & AVR32_OWNERSHIP_BIT )
00316 && !( xRxDescriptors[ ulNextRxBuffer ].U_Status.status & AVR32_SOF ) )
00317 {
00318
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
00329
00330
00331 ulIndex = ulNextRxBuffer;
00332
00333
00334
00335 while ( xRxDescriptors[ ulIndex ].addr & AVR32_OWNERSHIP_BIT )
00336 {
00337 ulLength = xRxDescriptors[ ulIndex ].U_Status.status & AVR32_LENGTH_FRAME;
00338 if (ulLength) break;
00339
00340
00341 if( ++ulIndex >= ETHERNET_CONF_NB_RX_BUFFERS ) ulIndex = 0;
00342
00343
00344 if (!(xRxDescriptors[ ulIndex ].addr & AVR32_OWNERSHIP_BIT)) break;
00345
00346
00347 if (xRxDescriptors[ ulIndex ].U_Status.status & AVR32_SOF)
00348 {
00349
00350 unsigned int i = ulNextRxBuffer;
00351 do{
00352
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
00359 }
00360 }
00361 return ulLength;
00362 }
00363
00364
00365 void vMACBRead(void *pvTo, unsigned long ulSectionLength, unsigned long ulTotalFrameLength)
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
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 if( pcTo == NULL )
00388 {
00389
00390
00391
00392
00393 pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK );
00394 ulFrameBytesReadSoFar = ( unsigned long ) 0;
00395 ulBufferPosition = ( unsigned long ) 0;
00396 }
00397 else
00398 {
00399
00400 ulSectionBytesReadSoFar = 0;
00401 while( ulSectionBytesReadSoFar < ulSectionLength )
00402 {
00403
00404
00405 ulBytesRemainingInBuffer = ( RX_BUFFER_SIZE - ulBufferPosition );
00406
00407
00408
00409 ulRemainingSectionBytes = ulSectionLength - ulSectionBytesReadSoFar;
00410
00411
00412 if( ulRemainingSectionBytes > ulBytesRemainingInBuffer )
00413 {
00414
00415
00416
00417 memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulBytesRemainingInBuffer );
00418 ulSectionBytesReadSoFar += ulBytesRemainingInBuffer;
00419 ulFrameBytesReadSoFar += ulBytesRemainingInBuffer;
00420
00421
00422 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr;
00423 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
00424
00425 ulNextRxBuffer++;
00426
00427 if( ulNextRxBuffer >= ETHERNET_CONF_NB_RX_BUFFERS )
00428 {
00429 ulNextRxBuffer = ( unsigned long ) 0;
00430 }
00431
00432
00433 pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK );
00434 ulBufferPosition = ( unsigned long ) 0;
00435 }
00436 else
00437 {
00438
00439
00440 memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulRemainingSectionBytes );
00441
00442
00443
00444 ulBufferPosition += ulRemainingSectionBytes;
00445 ulSectionBytesReadSoFar += ulRemainingSectionBytes;
00446 ulFrameBytesReadSoFar += ulRemainingSectionBytes;
00447
00448
00449 if( ( ulBufferPosition >= RX_BUFFER_SIZE ) || ( ulFrameBytesReadSoFar >= ulTotalFrameLength ) )
00450 {
00451
00452 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr;
00453 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
00454
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 }
00469
00470
00471 void vMACBFlushCurrentPacket(unsigned long ulTotalFrameLength)
00472 {
00473 unsigned int uiTemp;
00474 long int lTotalFrameLen = (long int)ulTotalFrameLength;
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 while( lTotalFrameLen > 0 )
00490 {
00491
00492 uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr;
00493 xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
00494
00495
00496 ulNextRxBuffer++;
00497 ulNextRxBuffer = ulNextRxBuffer%ETHERNET_CONF_NB_RX_BUFFERS;
00498
00499 lTotalFrameLen -= RX_BUFFER_SIZE;
00500 }
00501 }
00502
00503
00504
00505 void vMACBSetMACAddress(const unsigned char *MACAddress)
00506 {
00507 memcpy(cMACAddress, MACAddress, sizeof(cMACAddress));
00508 }
00509
00510 Bool xMACBInit(volatile avr32_macb_t *macb)
00511 {
00512 Bool global_interrupt_enabled = Is_global_interrupt_enabled();
00513 volatile unsigned long status;
00514
00515
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
00527 macb->usrio &= ~AVR32_MACB_RMII_MASK;
00528 #else
00529
00530 macb->usrio |= AVR32_MACB_RMII_MASK;
00531 #endif
00532
00533
00534 prvSetupMACAddress(macb);
00535
00536
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
00552 if( prvProbePHY(macb) == TRUE )
00553 {
00554
00555 portENTER_CRITICAL();
00556 {
00557 prvSetupMACBInterrupt(macb);
00558 }
00559 portEXIT_CRITICAL();
00560
00561 macb->ncr = AVR32_MACB_NCR_TE_MASK | AVR32_MACB_NCR_RE_MASK;
00562 return (TRUE);
00563 }
00564 return (FALSE);
00565 }
00566
00567 void vDisableMACBOperations(volatile avr32_macb_t *macb)
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
00578 macb->ncr &= ~((1 << AVR32_MACB_RE_OFFSET) | (1 << AVR32_MACB_TE_OFFSET));
00579
00580
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 }
00586
00587
00588 void vClearMACBTxBuffer(void)
00589 {
00590 static unsigned long uxNextBufferToClear = 0;
00591
00592
00593
00594
00595
00596
00597 if( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_TRANSMIT_OK )
00598 {
00599
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
00613 uxNextBufferToClear++;
00614
00615
00616 if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS )
00617 {
00618 uxNextBufferToClear = 0;
00619 }
00620 }
00621 }
00622
00623 static void prvSetupDescriptors(volatile avr32_macb_t *macb)
00624 {
00625 unsigned long xIndex;
00626 unsigned long ulAddress;
00627
00628
00629 for( xIndex = 0; xIndex < ETHERNET_CONF_NB_RX_BUFFERS; ++xIndex )
00630 {
00631
00632 ulAddress = ( unsigned long )( pcRxBuffer + ( xIndex * RX_BUFFER_SIZE ) );
00633
00634
00635
00636
00637
00638 xRxDescriptors[ xIndex ].addr = ulAddress;
00639 }
00640
00641
00642
00643 xRxDescriptors[ ETHERNET_CONF_NB_RX_BUFFERS - 1 ].addr |= RX_WRAP_BIT;
00644
00645
00646 for( xIndex = 0; xIndex < ETHERNET_CONF_NB_TX_BUFFERS; ++xIndex )
00647 {
00648
00649 ulAddress = ( unsigned long )( pcTxBuffer + ( xIndex * ETHERNET_CONF_TX_BUFFER_SIZE ) );
00650
00651
00652
00653 xTxDescriptors[ xIndex ].addr = ulAddress;
00654 xTxDescriptors[ xIndex ].U_Status.status = AVR32_TRANSMIT_OK;
00655 }
00656
00657
00658
00659 xTxDescriptors[ ETHERNET_CONF_NB_TX_BUFFERS - 1 ].U_Status.status = AVR32_TRANSMIT_WRAP | AVR32_TRANSMIT_OK;
00660
00661
00662 macb->rbqp = ( unsigned long )xRxDescriptors;
00663 macb->tbqp = ( unsigned long )xTxDescriptors;
00664
00665
00666 macb->ncfgr |= ( AVR32_MACB_NCFGR_DRFCS_MASK );
00667
00668 }
00669
00670
00674 static void vResetMacbRxFrames( void )
00675 {
00676 register unsigned long ulIndex;
00677 unsigned int uiTemp;
00678
00679
00680
00681 AVR32_MACB.ncr &= ~(AVR32_MACB_NCR_RE_MASK);
00682
00683
00684 for( ulIndex = 0; ulIndex < ETHERNET_CONF_NB_RX_BUFFERS; ++ulIndex )
00685 {
00686
00687 uiTemp = xRxDescriptors[ ulIndex ].addr;
00688 xRxDescriptors[ ulIndex ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
00689 }
00690
00691
00692 AVR32_MACB.rsr = AVR32_MACB_RSR_BNA_MASK | AVR32_MACB_RSR_OVR_MASK;
00693 AVR32_MACB.rsr;
00694
00695
00696 AVR32_MACB.rbqp = ( unsigned long )xRxDescriptors;
00697
00698
00699 ulNextRxBuffer = 0;
00700
00701
00702 AVR32_MACB.ncr |= AVR32_MACB_NCR_RE_MASK;
00703 }
00704
00705
00706 static void prvSetupMACAddress(volatile avr32_macb_t *macb)
00707 {
00708
00709 macb->sa1b = ( ( unsigned long ) cMACAddress[ 3 ] << 24 ) |
00710 ( ( unsigned long ) cMACAddress[ 2 ] << 16 ) |
00711 ( ( unsigned long ) cMACAddress[ 1 ] << 8 ) |
00712 cMACAddress[ 0 ];
00713
00714 macb->sa1t = ( ( unsigned long ) cMACAddress[ 5 ] << 8 ) |
00715 cMACAddress[ 4 ];
00716 }
00717
00718 static void prvSetupMACBInterrupt(volatile avr32_macb_t *macb)
00719 {
00720 #ifdef FREERTOS_USED
00721
00722 if (xSemaphore == NULL)
00723 {
00724 vSemaphoreCreateBinary( xSemaphore );
00725 }
00726 #else
00727
00728 DataToRead = FALSE;
00729 #endif
00730
00731
00732 #ifdef FREERTOS_USED
00733 if( xSemaphore != NULL)
00734 {
00735
00736
00737 xSemaphoreTake( xSemaphore, 0 );
00738 #endif
00739
00740
00741 INTC_register_interrupt((__int_handler)&vMACB_ISR, AVR32_MACB_IRQ, AVR32_INTC_INT2);
00742
00743 #if ETHERNET_CONF_USE_PHY_IT == 1
00744
00745 gpio_enable_pin_interrupt(MACB_INTERRUPT_PIN, GPIO_FALLING_EDGE);
00746
00747
00748 INTC_register_interrupt((__int_handler)&vPHY_ISR, (AVR32_GPIO_IRQ_0 + (MACB_INTERRUPT_PIN/8)), AVR32_INTC_INT2);
00749
00750 vWriteMDIO( macb, PHY_MICR , ( MICR_INTEN | MICR_INTOE ));
00751
00752 vWriteMDIO( macb, PHY_MISR , MISR_LINK_INT_EN );
00753 #endif
00754
00755
00756 macb->ier = AVR32_MACB_IER_RCOMP_MASK | AVR32_MACB_IER_TCOMP_MASK;
00757 #ifdef FREERTOS_USED
00758 }
00759 #endif
00760 }
00761
00770 static unsigned long ulReadMDIO(volatile avr32_macb_t *macb, unsigned short usAddress)
00771 {
00772 unsigned long value, status;
00773
00774
00775 macb->ncr |= AVR32_MACB_NCR_MPE_MASK;
00776
00777 macb->man = (AVR32_MACB_SOF_MASK & (0x01<<AVR32_MACB_SOF_OFFSET))
00778 | (2 << AVR32_MACB_CODE_OFFSET)
00779 | (2 << AVR32_MACB_RW_OFFSET)
00780 | ((ETHERNET_CONF_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET)
00781 | (usAddress << AVR32_MACB_REGA_OFFSET);
00782
00783 do {
00784 status = macb->nsr;
00785 } while (!(status & AVR32_MACB_NSR_IDLE_MASK));
00786
00787 value = macb->man & 0x0000ffff;
00788
00789 macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
00790
00791 return (value);
00792 }
00793
00802 static void vWriteMDIO(volatile avr32_macb_t *macb, unsigned short usAddress, unsigned short usValue)
00803 {
00804 unsigned long status;
00805
00806
00807 macb->ncr |= AVR32_MACB_NCR_MPE_MASK;
00808
00809 macb->man = (( AVR32_MACB_SOF_MASK & (0x01<<AVR32_MACB_SOF_OFFSET))
00810 | (2 << AVR32_MACB_CODE_OFFSET)
00811 | (1 << AVR32_MACB_RW_OFFSET)
00812 | ((ETHERNET_CONF_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET)
00813 | (usAddress << AVR32_MACB_REGA_OFFSET))
00814 | (usValue & 0xffff);
00815
00816 do {
00817 status = macb->nsr;
00818 } while (!(status & AVR32_MACB_NSR_IDLE_MASK));
00819
00820 macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
00821 }
00822
00823 static Bool prvProbePHY(volatile avr32_macb_t *macb)
00824 {
00825 volatile unsigned long mii_status, phy_ctrl;
00826 volatile unsigned long config;
00827 unsigned long upper, lower, mode, advertise, lpa;
00828 volatile unsigned long physID;
00829
00830
00831 lower = ulReadMDIO(macb, PHY_PHYSID2);
00832 upper = ulReadMDIO(macb, PHY_PHYSID1);
00833
00834 physID = ((upper << 16) & 0xFFFF0000) | (lower & 0xFFF0);
00835
00836 if (physID == ETHERNET_CONF_PHY_ID)
00837 {
00838
00839 mode = ulReadMDIO(macb, PHY_RBR);
00840
00841 if ((mode & RBR_RMII) != RBR_RMII)
00842 {
00843
00844 mode |= RBR_RMII;
00845 vWriteMDIO(macb, PHY_RBR, mode);
00846 }
00847
00848
00849 #if ETHERNET_CONF_AN_ENABLE == 1
00850 advertise = ADVERTISE_CSMA | ADVERTISE_ALL;
00851 #else
00852 advertise = ADVERTISE_CSMA;
00853 #if ETHERNET_CONF_USE_100MB
00854 #if ETHERNET_CONF_USE_FULL_DUPLEX
00855 advertise |= ADVERTISE_100FULL;
00856 #else
00857 advertise |= ADVERTISE_100HALF;
00858 #endif
00859 #else
00860 #if ETHERNET_CONF_USE_FULL_DUPLEX
00861 advertise |= ADVERTISE_10FULL;
00862 #else
00863 advertise |= ADVERTISE_10HALF;
00864 #endif
00865 #endif
00866 #endif
00867
00868 vWriteMDIO(macb, PHY_ADVERTISE, advertise);
00869
00870 config = ulReadMDIO(macb, PHY_BMCR);
00871
00872 phy_ctrl = ulReadMDIO(macb, PHY_PHYCR);
00873 #if ETHERNET_CONF_AN_ENABLE
00874 #if ETHERNET_CONF_AUTO_CROSS_ENABLE
00875
00876 phy_ctrl |= PHYCR_MDIX_EN;
00877 #else
00878
00879 phy_ctrl &= ~PHYCR_MDIX_EN;
00880 #if ETHERNET_CONF_CROSSED_LINK
00881
00882 phy_ctrl &= ~PHYCR_MDIX_FORCE;
00883 #else
00884
00885 phy_ctrl |= PHYCR_MDIX_FORCE;
00886 #endif
00887 #endif
00888
00889 config |= (BMCR_ANRESTART | BMCR_ANENABLE);
00890 #else
00891
00892 phy_ctrl &= ~PHYCR_MDIX_EN;
00893 #if ETHERNET_CONF_CROSSED_LINK
00894
00895 phy_ctrl &= ~PHYCR_MDIX_FORCE;
00896 #else
00897
00898 phy_ctrl |= PHYCR_MDIX_FORCE;
00899 #endif
00900
00901 config &= ~BMCR_ANENABLE;
00902
00903 #if ETHERNET_CONF_USE_100MB
00904 config |= BMCR_SPEED100;
00905 #else
00906 config &= ~BMCR_SPEED100;
00907 #endif
00908 #if ETHERNET_CONF_USE_FULL_DUPLEX
00909 config |= BMCR_FULLDPLX;
00910 #else
00911 config &= ~BMCR_FULLDPLX;
00912 #endif
00913 #endif
00914
00915 vWriteMDIO(macb, PHY_PHYCR, phy_ctrl);
00916
00917
00918 vWriteMDIO(macb, PHY_BMCR, config);
00919
00920
00921 do {
00922 mii_status = ulReadMDIO(macb, PHY_BMSR);
00923 } while (!(mii_status & BMSR_LSTATUS));
00924
00925
00926 lpa = ulReadMDIO(macb, PHY_LPA);
00927
00928
00929 config = AVR32_MACB.ncfgr;
00930
00931
00932 if ((lpa & advertise) & (LPA_100HALF | LPA_100FULL))
00933 {
00934 config |= AVR32_MACB_SPD_MASK;
00935 }
00936 else
00937 {
00938 config &= ~(AVR32_MACB_SPD_MASK);
00939 }
00940
00941
00942 if ((lpa & advertise) & (LPA_10FULL | LPA_100FULL))
00943 {
00944 config |= AVR32_MACB_FD_MASK;
00945 }
00946 else
00947 {
00948 config &= ~(AVR32_MACB_FD_MASK);
00949 }
00950
00951
00952 macb->ncfgr = config;
00953
00954 return TRUE;
00955 }
00956 return FALSE;
00957 }
00958
00959
00960 void vMACBWaitForInput(unsigned long ulTimeOut)
00961 {
00962 #ifdef FREERTOS_USED
00963
00964
00965 xSemaphoreTake( xSemaphore, ulTimeOut );
00966 #else
00967 unsigned long i;
00968
00969 i = ulTimeOut * 1000;
00970
00971 do
00972 {
00973 if ( DataToRead == TRUE )
00974 {
00975
00976 portENTER_CRITICAL();
00977 DataToRead = FALSE;
00978 portEXIT_CRITICAL();
00979 break;
00980 }
00981 i--;
00982 }
00983 while(i != 0);
00984 #endif
00985 }
00986
00987
00988
00989
00990
00991 #ifdef FREERTOS_USED
00992 #if defined(__GNUC__)
00993 __attribute__((__naked__))
00994 #elif defined(__ICCAVR32__)
00995 #pragma shadow_registers = full // Naked.
00996 #endif
00997 #else
00998 #if defined(__GNUC__)
00999 __attribute__((__interrupt__))
01000 #elif defined(__ICCAVR32__)
01001 __interrupt
01002 #endif
01003 #endif
01004 void vMACB_ISR(void)
01005 {
01006
01007
01008
01009 portENTER_SWITCHING_ISR();
01010
01011
01012
01013 prvMACB_ISR_NonNakedBehaviour();
01014
01015
01016
01017 portEXIT_SWITCHING_ISR();
01018 }
01019
01020
01021 #if defined(__GNUC__)
01022 __attribute__((__noinline__))
01023 #elif defined(__ICCAVR32__)
01024 #pragma optimize = no_inline
01025 #endif
01026 static long prvMACB_ISR_NonNakedBehaviour(void)
01027 {
01028
01029 volatile unsigned long ulIntStatus, ulEventStatus;
01030 long xSwitchRequired = FALSE;
01031
01032
01033 ulIntStatus = AVR32_MACB.isr;
01034 ulEventStatus = AVR32_MACB.rsr;
01035
01036 if( ( ulIntStatus & AVR32_MACB_IDR_RCOMP_MASK ) || ( ulEventStatus & AVR32_MACB_REC_MASK ) )
01037 {
01038
01039
01040 portENTER_CRITICAL();
01041 #ifdef FREERTOS_USED
01042 xSemaphoreGiveFromISR( xSemaphore, &xSwitchRequired );
01043 #else
01044 DataToRead = TRUE;
01045 #endif
01046 portEXIT_CRITICAL();
01047 AVR32_MACB.rsr = AVR32_MACB_REC_MASK;
01048 AVR32_MACB.rsr;
01049 }
01050
01051 if( ulIntStatus & AVR32_MACB_TCOMP_MASK )
01052 {
01053
01054
01055 vClearMACBTxBuffer();
01056 AVR32_MACB.tsr = AVR32_MACB_TSR_COMP_MASK;
01057 AVR32_MACB.tsr;
01058 }
01059
01060 return ( xSwitchRequired );
01061 }
01062
01063
01064 #if ETHERNET_CONF_USE_PHY_IT == 1
01065
01066
01067
01068 #ifdef FREERTOS_USED
01069 #if defined(__GNUC__)
01070 __attribute__((__naked__))
01071 #elif defined(__ICCAVR32__)
01072 #pragma shadow_registers = full // Naked.
01073 #endif
01074 #else
01075 #if defined(__GNUC__)
01076 __attribute__((__interrupt__))
01077 #elif defined(__ICCAVR32__)
01078 __interrupt
01079 #endif
01080 #endif
01081 void vPHY_ISR(void)
01082 {
01083
01084
01085
01086 portENTER_SWITCHING_ISR();
01087
01088
01089
01090 prvPHY_ISR_NonNakedBehaviour();
01091
01092
01093
01094 portEXIT_SWITCHING_ISR();
01095 }
01096
01097
01098 #if defined(__GNUC__)
01099 __attribute__((__noinline__))
01100 #elif defined(__ICCAVR32__)
01101 #pragma optimize = no_inline
01102 #endif
01103 static long prvPHY_ISR_NonNakedBehaviour(void)
01104 {
01105
01106 volatile unsigned long ulIntStatus, ulEventStatus;
01107 long xSwitchRequired = FALSE;
01108 volatile avr32_gpio_t *gpio = &AVR32_GPIO;
01109 volatile avr32_gpio_port_t *gpio_port = &gpio->port[MACB_INTERRUPT_PIN/32];
01110
01111
01112 ulIntStatus = ulReadMDIO(&AVR32_MACB, PHY_MISR);
01113
01114
01115 ulEventStatus = ulReadMDIO(&AVR32_MACB, PHY_BMSR);
01116
01117 ulEventStatus = ulReadMDIO(&AVR32_MACB, PHY_BMSR);
01118
01119
01120 gpio_port->ifrc = 1 << (MACB_INTERRUPT_PIN%32);
01121
01122 return ( xSwitchRequired );
01123 }
01124 #endif