📄 ethisr.c
字号:
//*****************************************************************************
//
// 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(ÐDevice[0], ETH_ERROR) = 0;
xSemaphoreGiveFromISR(ETHRxBinSemaphore[0], &xHigherPriorityTaskWoken);
}
// See if TXERR event occured.
if (ulStatus & ETH_INT_TXER)
{
HWREGBITW(ÐDevice[0], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[0], ETH_TXERROR) = 1;
xHigherPriorityTaskWoken = 0;
}
// See if TX event occured.
if (ulStatus & ETH_INT_TX)
{
HWREGBITW(ÐDevice[0], ETH_ERROR) = 0;
xSemaphoreGiveFromISR(ETHTxBinSemaphore[0], &xHigherPriorityTaskWoken);
}
// See if RX overflow event occured.
if (ulStatus & ETH_INT_RXOF)
{
// Set error and flag
HWREGBITW(ÐDevice[0], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[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(ÐDevice[0], ETH_ERROR) = 0;
HWREGBITW(ÐDevice[0], ETH_LINK_OK) = 0;
break;
case ETH_LINK_UP:
HWREGBITW(ÐDevice[0], ETH_ERROR) = 0;
HWREGBITW(ÐDevice[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(ÐDevice[ulPort], ETH_ENABLED)))
{
// Checks, if flCmd contains valid command
if (!(flCmd & (ETH_FLUSH_RX | ETH_FLUSH_TX)))
{
HWREGBITW(ÐDevice[ulPort], ETH_ERROR) = 1;
HWREGBITW(ÐDevice[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 + -