X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=inline;f=FreeRTOS%2FDemo%2FRX600_RX63N-RSK_Renesas%2FRTOSDemo%2Fwebserver%2FEMAC.c;fp=FreeRTOS%2FDemo%2FRX600_RX63N-RSK_Renesas%2FRTOSDemo%2Fwebserver%2FEMAC.c;h=0000000000000000000000000000000000000000;hb=b15dfacb6026af3b0ba697e5753844923b468d2b;hp=63c92a75cfa46863bb86e05b56e0f3e23778abb0;hpb=4334233a064299a09d167a497889d3860932a587;p=freertos diff --git a/FreeRTOS/Demo/RX600_RX63N-RSK_Renesas/RTOSDemo/webserver/EMAC.c b/FreeRTOS/Demo/RX600_RX63N-RSK_Renesas/RTOSDemo/webserver/EMAC.c deleted file mode 100644 index 63c92a75c..000000000 --- a/FreeRTOS/Demo/RX600_RX63N-RSK_Renesas/RTOSDemo/webserver/EMAC.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * FreeRTOS Kernel V10.1.0 - * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -/* Hardware specific includes. */ -#include "platform.h" -#include "r_ether.h" -#include "phy.h" - -/* FreeRTOS includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "semphr.h" - -/* uIP includes. */ -#include "net/uip.h" - -/* The time to wait between attempts to obtain a free buffer. */ -#define emacBUFFER_WAIT_DELAY_ms ( 3 / portTICK_PERIOD_MS ) - -/* The number of times emacBUFFER_WAIT_DELAY_ms should be waited before giving -up on attempting to obtain a free buffer all together. */ -#define emacBUFFER_WAIT_ATTEMPTS ( 30 ) - -/* The number of Rx descriptors. */ -#define emacNUM_RX_DESCRIPTORS 8 - -/* The number of Tx descriptors. When using uIP there is not point in having -more than two. */ -#define emacNUM_TX_BUFFERS 2 - -/* The total number of EMAC buffers to allocate. */ -#define emacNUM_BUFFERS ( emacNUM_RX_DESCRIPTORS + emacNUM_TX_BUFFERS ) - -/* The time to wait for the Tx descriptor to become free. */ -#define emacTX_WAIT_DELAY_ms ( 10 / portTICK_PERIOD_MS ) - -/* The total number of times to wait emacTX_WAIT_DELAY_ms for the Tx descriptor to -become free. */ -#define emacTX_WAIT_ATTEMPTS ( 50 ) - -/* Only Rx end and Tx end interrupts are used by this driver. */ -#define emacTX_END_INTERRUPT ( 1UL << 21UL ) -#define emacRX_END_INTERRUPT ( 1UL << 18UL ) - -/*-----------------------------------------------------------*/ - -/* The buffers and descriptors themselves. */ -#pragma section _RX_DESC - volatile ethfifo xRxDescriptors[ emacNUM_RX_DESCRIPTORS ]; -#pragma section _TX_DESC - volatile ethfifo xTxDescriptors[ emacNUM_TX_BUFFERS ]; -#pragma section _ETHERNET_BUFFERS - struct - { - unsigned long ulAlignmentVariable; - char cBuffer[ emacNUM_BUFFERS ][ UIP_BUFSIZE ]; - } xEthernetBuffers; -#pragma section - - - - -/* Used to indicate which buffers are free and which are in use. If an index -contains 0 then the corresponding buffer in xEthernetBuffers is free, otherwise -the buffer is in use or about to be used. */ -static unsigned char ucBufferInUse[ emacNUM_BUFFERS ]; - -/*-----------------------------------------------------------*/ - -/* - * Initialise both the Rx and Tx descriptors. - */ -static void prvInitialiseDescriptors( void ); - -/* - * Return a pointer to a free buffer within xEthernetBuffers. - */ -static unsigned char *prvGetNextBuffer( void ); - -/* - * Return a buffer to the list of free buffers. - */ -static void prvReturnBuffer( unsigned char *pucBuffer ); - -/* - * Examine the status of the next Rx FIFO to see if it contains new data. - */ -static unsigned long prvCheckRxFifoStatus( void ); - -/* - * Setup the microcontroller for communication with the PHY. - */ -static void prvResetMAC( void ); - -/* - * Configure the Ethernet interface peripherals. - */ -static void prvConfigureEtherCAndEDMAC( void ); - -/* - * Something has gone wrong with the descriptor usage. Reset all the buffers - * and descriptors. - */ -static void prvResetEverything( void ); - -/*-----------------------------------------------------------*/ - -/* Points to the Rx descriptor currently in use. */ -static ethfifo *pxCurrentRxDesc = NULL; - -/* The buffer used by the uIP stack to both receive and send. This points to -one of the Ethernet buffers when its actually in use. */ -unsigned char *uip_buf = NULL; - -/*-----------------------------------------------------------*/ - -void vInitEmac( void ) -{ - /* Software reset. */ - prvResetMAC(); - - /* Set the Rx and Tx descriptors into their initial state. */ - prvInitialiseDescriptors(); - - /* Set the MAC address into the ETHERC */ - ETHERC.MAHR = ( ( unsigned long ) configMAC_ADDR0 << 24UL ) | - ( ( unsigned long ) configMAC_ADDR1 << 16UL ) | - ( ( unsigned long ) configMAC_ADDR2 << 8UL ) | - ( unsigned long ) configMAC_ADDR3; - - ETHERC.MALR.BIT.MA = ( ( unsigned long ) configMAC_ADDR4 << 8UL ) | - ( unsigned long ) configMAC_ADDR5; - - /* Perform rest of interface hardware configuration. */ - prvConfigureEtherCAndEDMAC(); - - /* Nothing received yet, so uip_buf points nowhere. */ - uip_buf = NULL; - - /* Initialize the PHY */ - phy_init(); -} -/*-----------------------------------------------------------*/ - -void vEMACWrite( void ) -{ -long x; - - /* Wait until the second transmission of the last packet has completed. */ - for( x = 0; x < emacTX_WAIT_ATTEMPTS; x++ ) - { - if( ( xTxDescriptors[ 1 ].status & ACT ) != 0 ) - { - /* Descriptor is still active. */ - vTaskDelay( emacTX_WAIT_DELAY_ms ); - } - else - { - break; - } - } - - /* Is the descriptor free after waiting for it? */ - if( ( xTxDescriptors[ 1 ].status & ACT ) != 0 ) - { - /* Something has gone wrong. */ - prvResetEverything(); - } - - /* Setup both descriptors to transmit the frame. */ - xTxDescriptors[ 0 ].buf_p = ( char * ) uip_buf; - xTxDescriptors[ 0 ].bufsize = uip_len; - xTxDescriptors[ 1 ].buf_p = ( char * ) uip_buf; - xTxDescriptors[ 1 ].bufsize = uip_len; - - /* uip_buf is being sent by the Tx descriptor. Allocate a new buffer - for use by the stack. */ - uip_buf = prvGetNextBuffer(); - - /* Clear previous settings and go. */ - xTxDescriptors[0].status &= ~( FP1 | FP0 ); - xTxDescriptors[0].status |= ( FP1 | FP0 | ACT ); - xTxDescriptors[1].status &= ~( FP1 | FP0 ); - xTxDescriptors[1].status |= ( FP1 | FP0 | ACT ); - - EDMAC.EDTRR.LONG = 0x00000001; -} -/*-----------------------------------------------------------*/ - -unsigned long ulEMACRead( void ) -{ -unsigned long ulBytesReceived; - - ulBytesReceived = prvCheckRxFifoStatus(); - - if( ulBytesReceived > 0 ) - { - /* Mark the pxDescriptor buffer as free as uip_buf is going to be set to - the buffer that contains the received data. */ - prvReturnBuffer( uip_buf ); - - /* Point uip_buf to the data about ot be processed. */ - uip_buf = ( void * ) pxCurrentRxDesc->buf_p; - - /* Allocate a new buffer to the descriptor, as uip_buf is now using it's - old descriptor. */ - pxCurrentRxDesc->buf_p = prvGetNextBuffer(); - - /* Prepare the descriptor to go again. */ - pxCurrentRxDesc->status &= ~( FP1 | FP0 ); - pxCurrentRxDesc->status |= ACT; - - /* Move onto the next buffer in the ring. */ - pxCurrentRxDesc = pxCurrentRxDesc->next; - - if( EDMAC.EDRRR.LONG == 0x00000000L ) - { - /* Restart Ethernet if it has stopped */ - EDMAC.EDRRR.LONG = 0x00000001L; - } - } - - return ulBytesReceived; -} -/*-----------------------------------------------------------*/ - -long lEMACWaitForLink( void ) -{ -long lReturn; - - /* Set the link status. */ - switch( phy_set_autonegotiate() ) - { - /* Half duplex link */ - case PHY_LINK_100H: - ETHERC.ECMR.BIT.DM = 0; - ETHERC.ECMR.BIT.RTM = 1; - lReturn = pdPASS; - break; - - case PHY_LINK_10H: - ETHERC.ECMR.BIT.DM = 0; - ETHERC.ECMR.BIT.RTM = 0; - lReturn = pdPASS; - break; - - - /* Full duplex link */ - case PHY_LINK_100F: - ETHERC.ECMR.BIT.DM = 1; - ETHERC.ECMR.BIT.RTM = 1; - lReturn = pdPASS; - break; - - case PHY_LINK_10F: - ETHERC.ECMR.BIT.DM = 1; - ETHERC.ECMR.BIT.RTM = 0; - lReturn = pdPASS; - break; - - default: - lReturn = pdFAIL; - break; - } - - if( lReturn == pdPASS ) - { - /* Enable receive and transmit. */ - ETHERC.ECMR.BIT.RE = 1; - ETHERC.ECMR.BIT.TE = 1; - - /* Enable EDMAC receive */ - EDMAC.EDRRR.LONG = 0x1; - } - - return lReturn; -} -/*-----------------------------------------------------------*/ - -static void prvInitialiseDescriptors( void ) -{ -ethfifo *pxDescriptor; -long x; - - for( x = 0; x < emacNUM_BUFFERS; x++ ) - { - /* Ensure none of the buffers are shown as in use at the start. */ - ucBufferInUse[ x ] = pdFALSE; - } - - /* Initialise the Rx descriptors. */ - for( x = 0; x < emacNUM_RX_DESCRIPTORS; x++ ) - { - pxDescriptor = &( xRxDescriptors[ x ] ); - pxDescriptor->buf_p = &( xEthernetBuffers.cBuffer[ x ][ 0 ] ); - - pxDescriptor->bufsize = UIP_BUFSIZE; - pxDescriptor->size = 0; - pxDescriptor->status = ACT; - pxDescriptor->next = &xRxDescriptors[ x + 1 ]; - - /* Mark this buffer as in use. */ - ucBufferInUse[ x ] = pdTRUE; - } - - /* The last descriptor points back to the start. */ - pxDescriptor->status |= DL; - pxDescriptor->next = &xRxDescriptors[ 0 ]; - - /* Initialise the Tx descriptors. */ - for( x = 0; x < emacNUM_TX_BUFFERS; x++ ) - { - pxDescriptor = &( xTxDescriptors[ x ] ); - - /* A buffer is not allocated to the Tx descriptor until a send is - actually required. */ - pxDescriptor->buf_p = NULL; - - pxDescriptor->bufsize = UIP_BUFSIZE; - pxDescriptor->size = 0; - pxDescriptor->status = 0; - pxDescriptor->next = &xTxDescriptors[ x + 1 ]; - } - - /* The last descriptor points back to the start. */ - pxDescriptor->status |= DL; - pxDescriptor->next = &( xTxDescriptors[ 0 ] ); - - /* Use the first Rx descriptor to start with. */ - pxCurrentRxDesc = &( xRxDescriptors[ 0 ] ); -} -/*-----------------------------------------------------------*/ - -static unsigned char *prvGetNextBuffer( void ) -{ -long x; -unsigned char *pucReturn = NULL; -unsigned long ulAttempts = 0; - - while( pucReturn == NULL ) - { - /* Look through the buffers to find one that is not in use by - anything else. */ - for( x = 0; x < emacNUM_BUFFERS; x++ ) - { - if( ucBufferInUse[ x ] == pdFALSE ) - { - ucBufferInUse[ x ] = pdTRUE; - pucReturn = ( unsigned char * ) &( xEthernetBuffers.cBuffer[ x ][ 0 ] ); - break; - } - } - - /* Was a buffer found? */ - if( pucReturn == NULL ) - { - ulAttempts++; - - if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS ) - { - break; - } - - /* Wait then look again. */ - vTaskDelay( emacBUFFER_WAIT_DELAY_ms ); - } - } - - return pucReturn; -} -/*-----------------------------------------------------------*/ - -static void prvReturnBuffer( unsigned char *pucBuffer ) -{ -unsigned long ul; - - /* Return a buffer to the pool of free buffers. */ - for( ul = 0; ul < emacNUM_BUFFERS; ul++ ) - { - if( &( xEthernetBuffers.cBuffer[ ul ][ 0 ] ) == ( void * ) pucBuffer ) - { - ucBufferInUse[ ul ] = pdFALSE; - break; - } - } -} -/*-----------------------------------------------------------*/ - -static void prvResetEverything( void ) -{ - /* Temporary code just to see if this gets called. This function has not - been implemented. */ - portDISABLE_INTERRUPTS(); - for( ;; ); -} -/*-----------------------------------------------------------*/ - -static unsigned long prvCheckRxFifoStatus( void ) -{ -unsigned long ulReturn = 0; - - if( ( pxCurrentRxDesc->status & ACT ) != 0 ) - { - /* Current descriptor is still active. */ - } - else if( ( pxCurrentRxDesc->status & FE ) != 0 ) - { - /* Frame error. Clear the error. */ - pxCurrentRxDesc->status &= ~( FP1 | FP0 | FE ); - pxCurrentRxDesc->status &= ~( RMAF | RRF | RTLF | RTSF | PRE | CERF ); - pxCurrentRxDesc->status |= ACT; - pxCurrentRxDesc = pxCurrentRxDesc->next; - - if( EDMAC.EDRRR.LONG == 0x00000000UL ) - { - /* Restart Ethernet if it has stopped. */ - EDMAC.EDRRR.LONG = 0x00000001UL; - } - } - else - { - /* The descriptor contains a frame. Because of the size of the buffers - the frame should always be complete. */ - if( ( pxCurrentRxDesc->status & FP0 ) == FP0 ) - { - ulReturn = pxCurrentRxDesc->size; - } - else - { - /* Do not expect to get here. */ - prvResetEverything(); - } - } - - return ulReturn; -} -/*-----------------------------------------------------------*/ - -static void prvResetMAC( void ) -{ - /* Ensure the EtherC and EDMAC are enabled. */ - SYSTEM.MSTPCRB.BIT.MSTPB15 = 0; - vTaskDelay( 100 / portTICK_PERIOD_MS ); - - EDMAC.EDMR.BIT.SWR = 1; - - /* Crude wait for reset to complete. */ - vTaskDelay( 500 / portTICK_PERIOD_MS ); -} -/*-----------------------------------------------------------*/ - -static void prvConfigureEtherCAndEDMAC( void ) -{ - /* Initialisation code taken from Renesas example project. */ - - /* TODO: Check bit 5 */ - ETHERC.ECSR.LONG = 0x00000037; /* Clear all ETHERC statuS BFR, PSRTO, LCHNG, MPD, ICD */ - - /* Set the EDMAC interrupt priority. */ - _IPR( _ETHER_EINT ) = configKERNEL_INTERRUPT_PRIORITY; - - /* TODO: Check bit 5 */ - /* Enable interrupts of interest only. */ - EDMAC.EESIPR.LONG = emacTX_END_INTERRUPT | emacRX_END_INTERRUPT; - ETHERC.RFLR.LONG = 1518; /* Ether payload is 1500+ CRC */ - ETHERC.IPGR.LONG = 0x00000014; /* Intergap is 96-bit time */ - - /* EDMAC */ - EDMAC.EESR.LONG = 0x47FF0F9F; /* Clear all ETHERC and EDMAC status bits */ - #ifdef __LIT - EDMAC.EDMR.BIT.DE = 1; - #endif - EDMAC.RDLAR = ( void * ) pxCurrentRxDesc; /* Initialaize Rx Descriptor List Address */ - EDMAC.TDLAR = &( xTxDescriptors[ 0 ] ); /* Initialaize Tx Descriptor List Address */ - EDMAC.TRSCER.LONG = 0x00000000; /* Copy-back status is RFE & TFE only */ - EDMAC.TFTR.LONG = 0x00000000; /* Threshold of Tx_FIFO */ - EDMAC.FDR.LONG = 0x00000000; /* Transmit fifo & receive fifo is 256 bytes */ - EDMAC.RMCR.LONG = 0x00000003; /* Receive function is normal mode(continued) */ - ETHERC.ECMR.BIT.PRM = 0; /* Ensure promiscuous mode is off. */ - - /* Enable the interrupt... */ - _IEN( _ETHER_EINT ) = 1; -} -/*-----------------------------------------------------------*/ - -#pragma interrupt ( vEMAC_ISR_Handler( vect = VECT_ETHER_EINT, enable ) ) -void vEMAC_ISR_Handler( void ) -{ -unsigned long ul = EDMAC.EESR.LONG; -long lHigherPriorityTaskWoken = pdFALSE; -extern QueueHandle_t xEMACEventQueue; -const unsigned long ulRxEvent = uipETHERNET_RX_EVENT; - - /* Has a Tx end occurred? */ - if( ul & emacTX_END_INTERRUPT ) - { - /* Only return the buffer to the pool once both Txes have completed. */ - prvReturnBuffer( ( void * ) xTxDescriptors[ 0 ].buf_p ); - EDMAC.EESR.LONG = emacTX_END_INTERRUPT; - } - - /* Has an Rx end occurred? */ - if( ul & emacRX_END_INTERRUPT ) - { - /* Make sure the Ethernet task is not blocked waiting for a packet. */ - xQueueSendFromISR( xEMACEventQueue, &ulRxEvent, &lHigherPriorityTaskWoken ); - portYIELD_FROM_ISR( lHigherPriorityTaskWoken ); - EDMAC.EESR.LONG = emacRX_END_INTERRUPT; - } -} -