⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethisr.c

📁 在luminary平台下移植lwip到freertos,集成开发环境KEIL
💻 C
📖 第 1 页 / 共 2 页
字号:
//*****************************************************************************
//
// ETHIsr.c - Driver for Ethernet controller.
//
//*****************************************************************************

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

#include "hw_ethernet.h"
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "debug.h"
#include "gpio.h"
#include "ethernet.h"
#include "interrupt.h"
#include "sysctl.h"
#include "flash.h"

#include "ETHIsr.h"

//*****************************************************************************
//
// This structure represents status of SSI device and port(ETH0,ETH1,..).
// Every state is defined in one bit. Access to these bits is via special function of
// Cortex M3, bit band mapping.
//
//*****************************************************************************
static volatile unsigned long ETHDevice[MAX_ETH_PORTS];

//*****************************************************************************
//
//! Ethernet peripheral identification.
//
//*****************************************************************************
static const unsigned long ETHPeripheral[MAX_ETH_PORTS] ={ SYSCTL_PERIPH_ETH, };

//*****************************************************************************
//
//! Ethernet peripheral pin gate.
//
//*****************************************************************************
static const unsigned long ETHPeripheralGate[MAX_ETH_PORTS] ={ SYSCTL_PERIPH_GPIOF, };

//*****************************************************************************
//
//! The base address for the Ethernet associated with a port.
//
//*****************************************************************************
static const unsigned long ETHBase[MAX_ETH_PORTS] ={ ETH_BASE, };

//*****************************************************************************
//
//! The port address for the ETH associated pins.
//
//*****************************************************************************
static const unsigned long ETHPortBase[MAX_ETH_PORTS] ={ GPIO_PORTF_BASE, };

//*****************************************************************************
//
//! The pins associated with ETH peripheral.
//
//*****************************************************************************
static const unsigned long ETHPins[MAX_ETH_PORTS] ={GPIO_PIN_2 | GPIO_PIN_3, };

//*****************************************************************************
//
//! The interrupt for the ETH associated with a port.
//
//*****************************************************************************
static const unsigned long ETHInterrupt[MAX_ETH_PORTS] ={ INT_ETH, };

//*****************************************************************************
//
// Informs service task about RX event from interrupt routine
//
//*****************************************************************************
//yxh xSemaphoreHandle ETHRxBinSemaphore [MAX_ETH_PORTS] ={ [0 ... (MAX_ETH_PORTS - 1)] = NULL };
xSemaphoreHandle ETHRxBinSemaphore [MAX_ETH_PORTS] ={ NULL, };

//*****************************************************************************
//
// Informs service task about TX event from interrupt routine
//
//*****************************************************************************
//yxh xSemaphoreHandle ETHTxBinSemaphore [MAX_ETH_PORTS] ={ [0 ... (MAX_ETH_PORTS - 1)] = NULL };
xSemaphoreHandle ETHTxBinSemaphore [MAX_ETH_PORTS] ={NULL,};

//*****************************************************************************
//
// Prevents Tx simultaneously accessing devices from different tasks
//
//*****************************************************************************
//yxh xSemaphoreHandle ETHTxAccessMutex[MAX_ETH_PORTS] ={ [0 ... (MAX_ETH_PORTS - 1)] = NULL };
xSemaphoreHandle ETHTxAccessMutex[MAX_ETH_PORTS] ={ NULL, };

//*****************************************************************************
//
// Prevents Rx simultaneously accessing devices from different tasks
//
//*****************************************************************************
//yxh xSemaphoreHandle ETHRxAccessMutex[MAX_ETH_PORTS] ={ [0 ... (MAX_ETH_PORTS - 1)] = NULL };
xSemaphoreHandle ETHRxAccessMutex[MAX_ETH_PORTS] ={NULL, };

//*****************************************************************************
//
//! Handles the ETH interrupt. 
//! Put it into the interrupt vector of Stellaris
//!
//! This function is called when either of the ETH generate an interrupt.
//! An interrupt will be generated when data is received, transmitted, rx overflow
//! becomes or on link status change.
//!
//! \return None.
//
//*****************************************************************************
void ETH0IntHandler(void)
{
	static portBASE_TYPE xHigherPriorityTaskWoken;

	unsigned long ulStatus;

	// Read and Clear the interrupt.
	ulStatus = EthernetIntStatus(ETHBase[0], false);
	EthernetIntClear(ETHBase[0], ulStatus);

	// See if RX event occured.
	if (ulStatus & ETH_INT_RX)
	{
        // Disable Ethernet RX Interrupt.
        EthernetIntDisable(ETH_BASE, ETH_INT_RX);

		HWREGBITW(&ETHDevice[0], ETH_ERROR) = 0;
		xSemaphoreGiveFromISR(ETHRxBinSemaphore[0], &xHigherPriorityTaskWoken);
	}

	// See if TXERR event occured.
	if (ulStatus & ETH_INT_TXER)
	{
		HWREGBITW(&ETHDevice[0], ETH_ERROR) = 1;
		HWREGBITW(&ETHDevice[0], ETH_TXERROR) = 1;
		xHigherPriorityTaskWoken = 0;
	}

	// See if TX event occured.
	if (ulStatus & ETH_INT_TX)
	{
		HWREGBITW(&ETHDevice[0], ETH_ERROR) = 0;
		xSemaphoreGiveFromISR(ETHTxBinSemaphore[0], &xHigherPriorityTaskWoken);
	}

	// See if RX overflow event occured.
	if (ulStatus & ETH_INT_RXOF)
	{
		// Set error and flag
		HWREGBITW(&ETHDevice[0], ETH_ERROR) = 1;
		HWREGBITW(&ETHDevice[0], ETH_OVERFLOW) = 1;

		xSemaphoreGiveFromISR(ETHRxBinSemaphore[0], &xHigherPriorityTaskWoken);
	}

	// See if PHY event occured.
	if (ulStatus & ETH_INT_PHY)
	{
		// Something important was happened with network
		// no need to worry about while loop in EthernetPHYRead
		// Ethernet PHY Management Register 17 - Interrupt Control/Status
		// Read and Clear the interrupt.
		unsigned long phyStatus = EthernetPHYRead(ETHBase[0], PHY_MR17);

		switch (phyStatus & ETH_PHY_INT_MASKED)
		{
		case ETH_LINK_DOWN:
			HWREGBITW(&ETHDevice[0], ETH_ERROR) = 0;
			HWREGBITW(&ETHDevice[0], ETH_LINK_OK) = 0;
			break;
		case ETH_LINK_UP:
			HWREGBITW(&ETHDevice[0], ETH_ERROR) = 0;
			HWREGBITW(&ETHDevice[0], ETH_LINK_OK) = 1;
			break;
		}
		// no need immediately to switch context
		xHigherPriorityTaskWoken = 0;
	}
	portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}

//*****************************************************************************
//
//! Initializes the ethernet controller and driver.
//! Call this function on the your main function.
//!
//! This function initializes and configures the ethernet controller.
//!
//! \return 0 or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskInit(const unsigned long ulPort)
{
	unsigned char hwaddr[ETH_HWADDR_LEN];
	unsigned long ulUser0,ulUser1;

	if (ulPort < MAX_ETH_PORTS)
	{
		// Check if peripheral is present
		if (false == SysCtlPeripheralPresent(ETHPeripheral[ulPort]))
			return -1;

		// Initialize semaphores and mutexes.
		ETHRxBinSemaphore[ulPort] = xSemaphoreCreateCounting( 1, 0 );
		ETHTxBinSemaphore[ulPort] = xSemaphoreCreateCounting( 1, 0 );
		ETHTxAccessMutex[ulPort] = xSemaphoreCreateMutex();
		ETHRxAccessMutex[ulPort] = xSemaphoreCreateMutex();

		// Enable peripheral, other fault is generated
		SysCtlPeripheralEnable(ETHPeripheral[ulPort]);
		SysCtlPeripheralReset(ETHPeripheral[ulPort]);
		SysCtlPeripheralEnable(ETHPeripheralGate[ulPort]);

		// Enable Port for Ethernet LEDs.
		//  LED0        Bit 3   Output
		//  LED1        Bit 2   Output
		GPIODirModeSet(ETHPortBase[ulPort], ETHPins[ulPort], GPIO_DIR_MODE_HW);
		GPIOPadConfigSet(ETHPortBase[ulPort], ETHPins[ulPort], GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);

		// Configure the hardware MAC address for Ethernet Controller filtering of
			// incoming packets.
			//
			// For the LM3S6965 Evaluation Kit, the MAC address will be stored in the
			// non-volatile USER0 and USER1 registers.  These registers can be read
			// using the FlashUserGet function, as illustrated below.
			//
			FlashUserGet(&ulUser0, &ulUser1);
			if ((ulUser0 == 0xffffffff) || (ulUser1 == 0xffffffff))
			{
				// TODO: do something...
			}

			hwaddr[0] = ((ulUser0 >> 0) & 0xff);
			hwaddr[1] = ((ulUser0 >> 8) & 0xff);
			hwaddr[2] = ((ulUser0 >> 16) & 0xff);
			hwaddr[3] = ((ulUser1 >> 0) & 0xff);
			hwaddr[4] = ((ulUser1 >> 8) & 0xff);
			hwaddr[5] = ((ulUser1 >> 16) & 0xff);

			// set MAC hardware address
			EthernetMACAddrSet(ETHBase[ulPort], &(hwaddr[0]));

		// Ethernet controller is a little complicated, all is done in user defined
		// task(thread), thus no open is needed.
		return (0);
	}
	return -1;
}
//!*****************************************************************************
//!
//! Flush Ethernet FIFO's.
//! Call it from your main function.
//!
//!
//! \param ulPort is the Ethernet port number to be accessed.
//! \param flCmd specifies which buffer, RX, TX or both (RX | TX).
//!
//! This function deletes bytes from ring buffer.
//!
//! \return 0 or -1 if error.
//
//*****************************************************************************
int ETHServiceTaskFlush(const unsigned long ulPort, const unsigned long flCmd)
{
	if ((ulPort < MAX_ETH_PORTS) && (HWREGBITW(&ETHDevice[ulPort], ETH_ENABLED)))
	{
		// Checks, if flCmd contains valid command
		if (!(flCmd & (ETH_FLUSH_RX | ETH_FLUSH_TX)))
		{
			HWREGBITW(&ETHDevice[ulPort], ETH_ERROR) = 1;
			HWREGBITW(&ETHDevice[ulPort], ETH_EBADOPT) = 1;
			return(-1);
		}

		if (flCmd & ETH_FLUSH_RX)
		{
			// Access to shared variable
			xSemaphoreTake( ETHRxAccessMutex[ulPort], ( portTickType ) portMAX_DELAY);

			// Disable ethernet receiver, MACRCTL register.
			// BitBand region:  RXEN - Enable Receiver, bit 0
			HWREGBITW(ETHBase[ulPort] + MAC_O_RCTL, 0) = 0;

			// Reset receive FIFO, It is recommended that the receiver be disabled (RXEN = 0), before a
			// reset is initiated (RSTFIFO = 1). This sequence flushes and resets the RX FIFO.
			//MACRCTL register, RSTFIFO clear Receive FIFO, bit 4
			HWREGBITW(ETHBase[ulPort] + MAC_O_RCTL, 4) = 1;

			// This bit is automatically cleared when read.
			HWREGBITW(ETHBase[ulPort] + MAC_O_RCTL, 4);

			// Enable ethernet receiver, MACRCTL register.
			// BitBand region:  RXEN - Enable Receiver, bit 0
			HWREGBITW(ETHBase[ulPort] + MAC_O_RCTL, 0) = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -