/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */ /*This file has been prepared for Doxygen automatic documentation generation.*/ /*! \file ********************************************************************* * * \brief EMAC abstraction layer for AVR32 UC3. * * - Compiler: GNU GCC for AVR32 * - Supported devices: All AVR32 devices can be used. * - AppNote: * * \author Atmel Corporation: http://www.atmel.com \n * Support email: avr32@atmel.com * *****************************************************************************/ /* Copyright (c) 2007, Atmel Corporation All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name of ATMEL may not be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "AVR32_EMAC.h" #include "AVR32_CONF_EMAC.h" #include "lwipopts.h" /*-----------------------------------------------------------*/ /* The semaphore used to signal the arrival of new data to the interface task. */ static xSemaphoreHandle xSemaphore = NULL; static __attribute__((__noinline__)) portBASE_TYPE prvEMAC_ISR_NonNakedBehaviour( void ); /* * The EMAC ISR. Handles both Tx and Rx complete interrupts. */ //__attribute__((naked,section (".handlers"))) void vEMAC_ISR( void ) __attribute__((naked)) void vEMAC_ISR( void ) { /* This ISR can cause a context switch, so the first statement must be a call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any variable declarations. */ portENTER_SWITCHING_ISR(); prvEMAC_ISR_NonNakedBehaviour(); /* Exit the ISR. If a task was woken by either a character being received or transmitted then a context switch will occur. */ portEXIT_SWITCHING_ISR(); } /*-----------------------------------------------------------*/ static __attribute__((__noinline__)) portBASE_TYPE prvEMAC_ISR_NonNakedBehaviour( void ) { /* Variable definitions can be made now. */ volatile unsigned portLONG ulIntStatus, ulEventStatus; portBASE_TYPE xSwitchRequired = pdFALSE; extern void vClearEMACTxBuffer( void ); /* Find the cause of the interrupt. */ ulIntStatus = AVR32_MACB.isr; ulEventStatus = AVR32_MACB.rsr; if( ( ulIntStatus & AVR32_MACB_IDR_RCOMP_MASK ) || ( ulEventStatus & AVR32_MACB_REC_MASK ) ) { /* A frame has been received, signal the lwIP task so it can process the Rx descriptors. */ portENTER_CRITICAL(); xSwitchRequired = xSemaphoreGiveFromISR( xSemaphore, pdFALSE ); portEXIT_CRITICAL(); AVR32_MACB.rsr = AVR32_MACB_REC_MASK; AVR32_MACB.rsr; } if( ulIntStatus & AVR32_MACB_TCOMP_MASK ) { /* A frame has been transmitted. Mark all the buffers used by the frame just transmitted as free again. */ vClearEMACTxBuffer(); AVR32_MACB.tsr = AVR32_MACB_TSR_COMP_MASK; AVR32_MACB.tsr; } return ( xSwitchRequired ); } /*-----------------------------------------------------------*/ void vPassEMACSemaphore( xSemaphoreHandle xCreatedSemaphore ) { /* Simply store the semaphore that should be used by the ISR. */ xSemaphore = xCreatedSemaphore; }