STM32F407VET6 基于FreeRTOS实时操作系统和LAN8720网卡移植LwIP协议栈
本次实验是在STM32F407VET6单片机上实现FreeRTOS实时操作系统加LwIP协议栈驱动LAN8720网卡,板子是购买的最小系统开发板,网卡是购买的LAN8720模块。使用的LwIP内核版本为 lwip-1.4.1,FreeRTOS内核版本为 FreeRTOSv10.2.1。使用上一篇博客中移植好的FreeRTOS工程。
1、STM32F407VET6单片机引脚与LAN8720网卡的物理连接如下:
a、ETH_RMII_REF_CLK-------> PA1--------->nINT/RETCLK
b、ETH_MDIO --------------------> PA2--------->MDIO
c、ETH_RMII_CRS_DV --------> PA7--------->CRS
d、ETH_RMII_TX_EN ----------> PB11------->TX_EN
e、ETH_RMII_TXD0 ------------> PB12------->TX0
f、ETH_RMII_TXD1 -------------> PB13------->TX1
g、ETH_RESET-------------------> PC0-------->NC
h、ETH_MDC ---------------------> PC1-------->MDC
i、ETH_RMII_RXD0 -------------> PC4-------->RX0
j、ETH_RMII_RXD1 -------------> PC5-------->RX1
注:在网卡模块上RESET引脚为NC,未连接,但在实际项目中把RESET引脚连接起来使用效果更好,LAN8720网卡的电源建议加一个电源控制,如:三极管或MOS管,在复位前先断一下电源,再复位,因为实际中我遇到过软复位不成功的情况。
OK到这里,硬件操作完成,接下来就是软件的事情了。
2、LwIP驱动框架
在项目中LwIP与FreeRTOS和LAN8720以太网之间的文件关系如下:
a、FreeRTOS与LwIP协议栈之间主要通过sys_arch.c和sys_arch.h文件连接起来的,这两个文件中主要实现了对FreeRTOS的API封装。其中sys_arch.c中实现的函数在sys.h头文件中全部给声明好了,我们只需实现出来即可。
b、LAN8720以太网卡和LwIP协议栈之间主要通过sys_eth.c和sys_eth.h文件连接起来的,这两个文件主要实现了LwIP协议栈对以太网口操作的API函数,比如,以太网的底层收发函数、以太网中断等等。
移植LwIP总共需要修改或新建八个文件,其中上面的四个文件为主要的接口文件,其余四个文件为辅助文件,分别为:cc.h、cpu.h、perf.h、lwipopts.h。
c、cc.h主要完成了LwIP协议栈内部使用的数据类型的定义,如果使用了操作系统的话,就还包含了代码临界保护的API等等。
d、cpu.h是和CPU相关的一个头文件,内部主要是定义了CPU大小端模式。
e、perf.h是和系统测量、统计相关的文件,我们不使用任何的测量和统计,因此文件内部无需做什么操作。
f、lwipopts.h是用来裁剪和配置LwIP的文件,如果我们想要使用LwIP 中的什么功能,就只要在这个文件中配置就行了。
注:上面的八个文件全部保存在LwIP\arch目录下,如果手上没有这些文件时,可以新建文件,然后将下面的代码拷贝到文件中直接使用就好了,无需做其它修改。
3、LwIP内核源码文件拷贝
在工程目录下新建一个LwIP文件夹,在LwIP文件夹中再新建app、arch两个文件夹。然后将下载的LwIP内核源码也直接解压到LwIP目录下,如下图所示:
(注:arch文件夹的名字必须是这个,不能使用其它名字,因为在LwIP内核源码中使用了该目录下的CPU接口文件,arch目录下存放的都是接口文件,包含和CPU的相关的接口文件)
然后在arch文件中新建如下八个文件:
4、LwIP移植相关代码的实现如下:
a、cc.h文件
#define __CC_H
#include <stdio.h>
#include "task.h"
typedef unsigned char u8_t; //无符号8位整数
typedef signed char s8_t; //有符号8位整数
typedef unsigned short u16_t; //无符号16位整数
typedef signed short s16_t; //有符号16位整数
typedef unsigned long u32_t; //无符号32位整数
typedef signed long s32_t; //有符号32位整数
typedef u32_t mem_ptr_t; //内存地址型数据
typedef int sys_prot_t; //临界保护型数据
#define SCB_ICSR_REG (*((volatile u32_t *)0xE000ED04))
extern u32_t Enter_Critical(void); // 用于声明进入保护临界区
extern void Exit_Critical(u32_t lev); // 声明退出保护临界区
//根据不同的编译器定义一些符号
#if defined (__ICCARM__)
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_USE_INCLUDES
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define U16_F "4d"
#define S16_F "4d"
#define X16_F "4x"
#define U32_F "8ld"
#define S32_F "8ld"
#define X32_F "8lx"
#ifndef LWIP_PLATFORM_ASSERT
#define LWIP_PLATFORM_ASSERT(x) do{printf("Assertion \"%s\" failed at line %d in %s\r\n", x, __LINE__, __FILE__);} while(0)
#endif
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
#endif
b、cpu.h文件
#define __CPU_H
#define __PERF_H
#define PERF_STOP(x) /* null definition */
d、lwipopts.h文件
#define __LWIPOPTS_H
#ifndef TCPIP_THREAD_PRIO
#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 1) // 定义内核任务的优先级为最高优先级
#endif
#undef DEFAULT_THREAD_PRIO
#define DEFAULT_THREAD_PRIO 2
#define SYS_LIGHTWEIGHT_PROT 1 //为1时使用实时操作系统的轻量级保护,保护关键代码不被中断打断
#define NO_SYS 0 //使用操作系统
#define MEM_ALIGNMENT 4 //使用4字节对齐模式
#define MEM_SIZE 16000 //内存堆heap大小
#define MEMP_NUM_PBUF 20 //MEMP_NUM_PBUF:memp结构的pbuf数量,如果应用从ROM或者静态存储区发送大量数据时,这个值应该设置大一点
#define MEMP_NUM_UDP_PCB 6 //MEMP_NUM_UDP_PCB:UDP协议控制块(PCB)数量.每个活动的UDP"连接"需要一个PCB.
#define MEMP_NUM_TCP_PCB 10 //MEMP_NUM_TCP_PCB:同时建立激活的TCP数量
#define MEMP_NUM_TCP_PCB_LISTEN 6 //MEMP_NUM_TCP_PCB_LISTEN:能够监听的TCP连接数量
#define MEMP_NUM_TCP_SEG 15 //MEMP_NUM_TCP_SEG:最多同时在队列中的TCP段数量
#define MEMP_NUM_SYS_TIMEOUT 8 //MEMP_NUM_SYS_TIMEOUT:能够同时激活的timeout个数
#define PBUF_POOL_SIZE 20 //PBUF_POOL_SIZE:pbuf内存池个数
#define PBUF_POOL_BUFSIZE 512 //PBUF_POOL_BUFSIZE:每个pbuf内存池大小
#define TCP_TTL 255 //生存时间
#define TCP_QUEUE_OOSEQ 0 //当TCP的数据段超出队列时的控制位,当设备的内存过小的时候此项应为0
#define TCPIP_MBOX_SIZE MAX_QUEUE_ENTRIES //tcpip创建主线程时的消息邮箱大小
#define DEFAULT_TCP_RECVMBOX_SIZE MAX_QUEUE_ENTRIES
#define DEFAULT_ACCEPTMBOX_SIZE MAX_QUEUE_ENTRIES
#define TCP_MSS (1500 - 40) //最大TCP分段,TCP_MSS = (MTU - IP报头大小 - TCP报头大小
#define TCP_SND_BUF (4*TCP_MSS) //TCP发送缓冲区大小(bytes).
#define TCP_SND_QUEUELEN (2* TCP_SND_BUF/TCP_MSS) //TCP_SND_QUEUELEN: TCP发送缓冲区大小(pbuf).这个值最小为(2 * TCP_SND_BUF/TCP_MSS)
#define TCP_WND (2*TCP_MSS) //TCP发送窗口
#define LWIP_ICMP 1 //使用ICMP协议
#define LWIP_DHCP 0 //禁用DHCP
#define LWIP_UDP 1 //使用UDP服务
#define UDP_TTL 255 //UDP数据包生存时间
#define LWIP_STATS 0
#define LWIP_PROVIDE_ERRNO 1
//帧校验和选项,STM32F4x7允许通过硬件识别和计算IP,UDP和ICMP的帧校验和
#define CHECKSUM_BY_HARDWARE //定义CHECKSUM_BY_HARDWARE,使用硬件帧校验
#ifdef CHECKSUM_BY_HARDWARE
//CHECKSUM_GEN_IP==0: 硬件生成IP数据包的帧校验和
#define CHECKSUM_GEN_IP 0
//CHECKSUM_GEN_UDP==0: 硬件生成UDP数据包的帧校验和
#define CHECKSUM_GEN_UDP 0
//CHECKSUM_GEN_TCP==0: 硬件生成TCP数据包的帧校验和
#define CHECKSUM_GEN_TCP 0
//CHECKSUM_CHECK_IP==0: 硬件检查输入的IP数据包帧校验和
#define CHECKSUM_CHECK_IP 0
//CHECKSUM_CHECK_UDP==0: 硬件检查输入的UDP数据包帧校验和
#define CHECKSUM_CHECK_UDP 0
//CHECKSUM_CHECK_TCP==0: 硬件检查输入的TCP数据包帧校验和
#define CHECKSUM_CHECK_TCP 0
#else
//CHECKSUM_GEN_IP==1: 软件生成IP数据包帧校验和
#define CHECKSUM_GEN_IP 1
// CHECKSUM_GEN_UDP==1: 软件生成UDOP数据包帧校验和
#define CHECKSUM_GEN_UDP 1
//CHECKSUM_GEN_TCP==1: 软件生成TCP数据包帧校验和
#define CHECKSUM_GEN_TCP 1
// CHECKSUM_CHECK_IP==1: 软件检查输入的IP数据包帧校验和
#define CHECKSUM_CHECK_IP 1
// CHECKSUM_CHECK_UDP==1: 软件检查输入的UDP数据包帧校验和
#define CHECKSUM_CHECK_UDP 1
//CHECKSUM_CHECK_TCP==1: 软件检查输入的TCP数据包帧校验和
#define CHECKSUM_CHECK_TCP 1
#endif
#define LWIP_SOCKET 1 //LWIP_SOCKET==1:使能Sicket API(要求使用sockets.c)
#define LWIP_COMPAT_MUTEX 1
#define LWIP_SO_RCVTIMEO 1 //通过定义LWIP_SO_RCVTIMEO使能netconn结构体中recv_timeout,使用recv_timeout可以避免阻塞线程
#define TCPIP_THREAD_STACKSIZE 1000 //内核任务堆栈大小
#define DEFAULT_UDP_RECVMBOX_SIZE 2000
#define DEFAULT_THREAD_STACKSIZE 512
#define LWIP_DEBUG 0 //关闭DEBUG选项
#define ICMP_DEBUG LWIP_DBG_OFF //开启/关闭ICMPdebug
#define __SYS_ARCH_H
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
#define MAX_QUEUES 10 // 消息邮箱的数量
#define MAX_QUEUE_ENTRIES 20 // 每个消息邮箱的大小
// LwIP消息邮箱结构体
typedef struct
{
QueueHandle_t xQueue; // 消息列队
}lwip_mbox;
typedef lwip_mbox sys_mbox_t; // LwIP使用的消息邮箱类型
typedef QueueHandle_t sys_mutex_t; // LwIP使用的互斥信号量类型
typedef SemaphoreHandle_t sys_sem_t; // LwIP使用的信号量类型
typedef unsigned char sys_thread_t; // LwIP线程错误类型
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "sys_arch.h"
* 函数功能:创建一个消息邮箱
* 形 参:mbox:消息邮箱
size:邮箱大小
* 返 回 值:ERR_OK=创建成功,其他=创建失败
********************************************************/
err_t sys_mbox_new( sys_mbox_t *mbox, int size)
{
if(size > MAX_QUEUE_ENTRIES)
{
size = MAX_QUEUE_ENTRIES; // 消息列队中的消息数目检查
}
// 创建消息列队,该消息列队存放指针(4字节)
mbox->xQueue = xQueueCreate(size, sizeof(void *));
if(mbox->xQueue != NULL)
{
return ERR_OK; // 消息列队创建成功
}
return ERR_MEM; // 消息列队创建失败
}
* 函数功能:释放并删除一个消息邮箱
* 形 参:mbox:消息邮箱
* 返 回 值:无
********************************************************/
void sys_mbox_free(sys_mbox_t *mbox)
{
vQueueDelete(mbox->xQueue);
mbox->xQueue = NULL;
}
* 函数功能:向消息邮箱中发送一条消息(等待发送成功才会返回)
* 形 参:mbox:消息邮箱
msg:要发送的消息
* 返 回 值:无
********************************************************/
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if(msg == NULL)
{
msg = (void *)&NullValue; // 空指针的处理方式(用常量的地址替换)
}
if((SCB_ICSR_REG & 0xFF) == 0) // 线程执行
{
while(xQueueSendToBack(mbox->xQueue, &msg, portMAX_DELAY) != pdPASS); // 等待发送成功
}
else // 中断执行
{
while(xQueueSendToBackFromISR(mbox->xQueue, &msg, &xHigherPriorityTaskWoken) != pdPASS);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); // 判断是否要进行任务切换
}
}
* 函数功能:向消息邮箱中发送一条消息(发送完就立即返回)
* 形 参:mbox:消息邮箱
msg:要发送的消息
* 返 回 值:ERR_OK=发送OK, ERR_MEM=发送失败
********************************************************/
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if(msg == NULL)
{
msg = (void *)&NullValue; // 空指针的处理方式(用常量的地址替换)
}
if((SCB_ICSR_REG & 0xFF) == 0) // 线程执行
{
if(xQueueSendToBack(mbox->xQueue, &msg, 0) != pdPASS)
{
return ERR_MEM;
}
}
else
{
if(xQueueSendToBackFromISR(mbox->xQueue, &msg, &xHigherPriorityTaskWoken) != pdPASS)
{
return ERR_MEM;
}
}
return ERR_OK;
}
* 函数功能:等待邮箱中的消息
* 形 参:mbox:消息邮箱
msg:要等待的消息
timeout:超时时间(单位:ms),0表示一直等待
* 返 回 值:ERR_OK=发送OK, ERR_MEM=发送失败
********************************************************/
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
{
u32_t start_time = sys_now(); // 获取系统时间,用于计算等待时间
// 等待邮箱中的消息
if(xQueueReceive(mbox->xQueue, msg, (timeout == 0)? portMAX_DELAY : timeout) == errQUEUE_EMPTY)
{
timeout = SYS_ARCH_TIMEOUT; // 请求超时
*msg = NULL;
}
else
{
if(*msg != NULL)
{
if(*msg == (void *)&NullValue)
{
*msg = NULL;
}
}
timeout = sys_now();
if(timeout >= start_time)
{
// 计算请求消息所使用的时间(时间未溢出)
timeout = timeout - start_time;
}
else
{
// 计算请求消息所使用的时间(时间溢出了)
timeout += 0xFFFFFFFFUL - start_time;
}
}
return timeout;
}
* 函数功能:尝试从消息邮箱中接收一个新消息(非阻塞式)
* 形 参:mbox:消息邮箱
msg:要等待的消息
* 返 回 值:等待消息所用的时间/SYS_ARCH_TIMEOUT
********************************************************/
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
return sys_arch_mbox_fetch(mbox, msg, 1); // 尝试获取一个消息
}
* 函数功能:检查一个消息邮箱是否有效
* 形 参:mbox:消息邮箱
* 返 回 值:1=有效. 0=无效
********************************************************/
int sys_mbox_valid(sys_mbox_t *mbox)
{
if(mbox->xQueue != NULL)
{
return 1;
}
return 0;
}
* 函数功能:设置一个消息邮箱为无效
* 形 参:mbox:消息邮箱
* 返 回 值:无
********************************************************/
void sys_mbox_set_invalid(sys_mbox_t *mbox)
{
mbox->xQueue = NULL;
}
* 函数功能:创建一个信号量
* 形 参:sem:信号量指针
count:信号量初值
* 返 回 值:ERR_OK=创建成功,其它=创建失败
********************************************************/
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
{
*sem = xSemaphoreCreateCounting(0xFF, count);
if(*sem == NULL)
{
return ERR_MEM;
}
return ERR_OK;
}
* 函数功能:等待一个信号量
* 形 参:sem:信号量指针
timeout:超时时间,0表示无限等待
* 返 回 值:成功就返回等待的时间,失败就返回超时SYS_ARCH_TIMEOUT
********************************************************/
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
u32_t start_time = sys_now(); // 获取系统时间,用于计算等待时间
{
timeout = SYS_ARCH_TIMEOUT; // 请求超时
}
else
{
timeout = sys_now();
if(timeout >= start_time)
{
timeout = timeout - start_time; // 计算请求消息所使用的时间
}
else
{
timeout += 0xFFFFFFFFUL - start_time;
}
}
return timeout;
}
* 函数功能:发送一个信号量
* 形 参:sem:信号量指针
* 返 回 值:无
********************************************************/
void sys_sem_signal(sys_sem_t *sem)
{
BaseType_t pxHigherPriorityTaskWoken;
if((SCB_ICSR_REG & 0xFF) == 0) // 线程执行
{
xSemaphoreGive(*sem);
}
else
{
xSemaphoreGiveFromISR(*sem, &pxHigherPriorityTaskWoken);
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken); // 检查是否需要进行任务切换
}
}
* 函数功能:释放并删除一个信号量
* 形 参:sem:信号量指针
* 返 回 值:无
********************************************************/
void sys_sem_free(sys_sem_t *sem)
{
vSemaphoreDelete(*sem);
*sem = NULL;
}
* 函数功能:查询信号量的状态
* 形 参:sem:信号量指针
* 返 回 值:1=有效,0=无效
********************************************************/
int sys_sem_valid(sys_sem_t *sem)
{
if(*sem == NULL)
{
return 0; // 无效
}
return 1; // 有效
}
* 函数功能:信号量无效设置
* 形 参:sem:信号量指针
* 返 回 值:无
********************************************************/
void sys_sem_set_invalid(sys_sem_t *sem)
{
*sem = NULL;
}
* 函数功能:创建线程
* 形 参:name:线程名
thred:线程函数
arg:线程任务函数的参数
stacksize:线程栈大小
prio:线程优先级
* 返 回 值:0=成功,1=失败
********************************************************/
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
{
BaseType_t flag;
taskENTER_CRITICAL(); // 进入临界区
flag = xTaskCreate(thread, name, stacksize, arg, prio, NULL); // 创建 TCP/IP 内核线程
taskEXIT_CRITICAL(); // 退出临界区
return (flag == pdPASS)? 0 : 1;
}
* 函数功能:ARCH初始化
* 形 参:无
* 返 回 值:无
********************************************************/
void sys_init(void)
{
// 这里不做任何事情
}
* 函数功能:LwIP内核延时
* 形 参:ms:延时时间(单位:ms)
* 返 回 值:无
********************************************************/
void sys_msleep(u32_t ms)
{
vTaskDelay(ms);
}
* 函数功能:获取系统时间(LWIP1.4.1新增加的函数)
* 形 参:无
* 返 回 值:当前系统时间(单位:毫秒)
********************************************************/
u32_t sys_now(void)
{
if((SCB_ICSR_REG & 0xFF) == 0) // 线程执行
{
return xTaskGetTickCount(); // 获取系统时间
}
else
{
return xTaskGetTickCountFromISR(); // 获取系统时间
}
}
* 函数功能:进入临界区
* 形 参:无
* 返 回 值:中断寄存器basepri的备份值
********************************************************/
u32_t Enter_Critical(void)
{
if(SCB_ICSR_REG & 0xFF)
{
return taskENTER_CRITICAL_FROM_ISR(); // 在中断里
}
else
{
taskENTER_CRITICAL(); // 在线程中
return 0;
}
}
* 函数功能:退出临界区
* 形 参:中断寄存器basepri的备份值
* 返 回 值:无
********************************************************/
void Exit_Critical(u32_t lev)
{
if(SCB_ICSR_REG & 0xFF)
{
taskEXIT_CRITICAL_FROM_ISR(lev); // 在中断里
}
else
{
taskEXIT_CRITICAL(); // 在线程中
}
}
g、sys_eth.h文件
#define __SYS_ETH_H
typedef struct _sLwipDev
{
unsigned char mask[4];
unsigned char gateway[4];
unsigned char localip[4];
unsigned char remoteip[4];
unsigned short localport;
unsigned short remoteport;
}sLwipDev_t;
#pragma pack(pop)
* 函数功能:以太网、协议栈内核等初始化
* 形 参:psLwipDev:IP信息数据结构指针
* 返 回 值:0=初始化成功
1=数据指针为NULL
2=以太网初始化失败
3=网卡注册失败
********************************************************/
unsigned int eth_init(sLwipDev_t * const psLwipDev);
/********************************************************
* 函数功能:获取默认IP信息
* 形 参:psLwipDev:IP信息数据结构指针
* 返 回 值:0=成功,1=数据指针为NULL
********************************************************/
unsigned int eth_default_ip_get(sLwipDev_t * const psLwipDev);
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/err.h"
#include "FreeRTOS.h"
#include "task.h"
#define LAN8720_PHY_ADDRESS (unsigned char)(0x01U)
static sLwipDev_t sLwipDev; // LwIP控制结构体
static unsigned char *pRxData; // 以太网底层驱动接收数据指针
static unsigned char *pTxData; // 以太网底层驱动发送数据指针
static ETH_DMADESCTypeDef *DMARxDscrTab; // 以太网DMA接收描述符数据结构体指针
static ETH_DMADESCTypeDef *DMATxDscrTab; // 以太网DMA发送描述符数据结构体指针
extern ETH_DMADESCTypeDef *DMATxDescToSet; // DMA发送描述符追踪指针
extern ETH_DMADESCTypeDef *DMARxDescToGet; // DMA接收描述符追踪指针
* 函数功能:初始化ETH MAC层及DMA配置
* 形 参:无
* 返 回 值:0=成功,1=失败
********************************************************/
static unsigned char eth_mac_dma_config(void)
{
ETH_InitTypeDef ETH_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx | RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
ETH_SoftwareReset(); // 软件重启网络
while (ETH_GetSoftwareResetStatus() == SET); // 等待软件重启网络完成
ETH_StructInit(Ð_InitStructure); // 初始化网络为默认值
ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; // 开启网络自适应功能
ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable; // 关闭反馈
ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable; // 关闭重传功能
ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; // 关闭自动去除PDA/CRC功能
ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable; // 关闭接收所有的帧
ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable; // 允许接收所有广播帧
ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; // 关闭混合模式的地址过滤
ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;// 对于组播地址使用完美地址过滤
ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; // 对单播地址使用完美地址过滤
#ifdef CHECKSUM_BY_HARDWARE
ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable; // 开启ipv4和TCP/UDP/ICMP的帧校验和卸载
#endif
// 当我们使用帧校验和卸载功能的时候,一定要使能存储转发模式,存储转发模式中要保证整个帧存储在FIFO中,
// 这样MAC能插入/识别出帧校验值,当真校验正确的时候DMA就可以处理帧,否则就丢弃掉该帧
ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable; // 开启丢弃TCP/IP错误帧
ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable; // 开启接收数据的存储转发模式
ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable; // 开启发送数据的存储转发模式
ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable; // 不转发过小的好帧
ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable; // 打开处理第二帧功能
ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; // 开启DMA传输的地址对齐功能
ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable; // 开启固定突发功能
ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; // DMA发送的最大突发长度为32个节拍
ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat; // DMA接收的最大突发长度为32个节拍
ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
{
ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE); // 使能以太网接收中断
return 0;
}
return 1;
}
* 函数功能:释放ETH底层驱动申请的内存
* 形 参:无
* 返 回 值:无
********************************************************/
static void eth_mem_free(void)
{
vPortFree(DMARxDscrTab);
vPortFree(DMATxDscrTab);
vPortFree(pRxData);
vPortFree(pTxData);
}
* 函数功能:为ETH底层驱动申请内存
* 形 参:无
* 返 回 值:0=成功,其它=失败
********************************************************/
static unsigned char eth_mem_malloc(void)
{
eth_mem_free(); // 此处释放是避免重复初始化时将内存消耗完
DMARxDscrTab = pvPortMalloc(ETH_RXBUFNB * sizeof(ETH_DMADESCTypeDef)); // 申请内存
DMATxDscrTab = pvPortMalloc(ETH_TXBUFNB * sizeof(ETH_DMADESCTypeDef)); // 申请内存
pRxData = pvPortMalloc(ETH_RX_BUF_SIZE * ETH_RXBUFNB); // 申请内存
pTxData = pvPortMalloc(ETH_TX_BUF_SIZE * ETH_TXBUFNB); // 申请内存
{
vPortFree(DMARxDscrTab);
return 1; // 内存申请失败
}
if(!DMATxDscrTab)
{
vPortFree(DMATxDscrTab);
return 2; // 内存申请失败
}
if(!pRxData)
{
vPortFree(pRxData);
return 3; // 内存申请失败
}
if(!pTxData)
{
vPortFree(pTxData);
return 4; // 内存申请失败
}
return 0; // 内存申请成功
}
* 函数功能:以太网初始化
* 形 参:无
* 返 回 值:0=成功,其它=失败
********************************************************/
static unsigned int eht_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // 使能SYSCFG时钟
SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
// ETH_MDIO -------------------------> PA2
// ETH_MDC --------------------------> PC1
// ETH_RMII_REF_CLK------------------> PA1
// ETH_RMII_CRS_DV ------------------> PA7
// ETH_RMII_RXD0 --------------------> PC4
// ETH_RMII_RXD1 --------------------> PC5
// ETH_RMII_TX_EN -------------------> PG11
// ETH_RMII_TXD0 --------------------> PG13
// ETH_RMII_TXD1 --------------------> PG14
// ETH_RESET-------------------------> PD3
// ETH_RMII_REF_CLK------------------> PA1
// ETH_MDIO -------------------------> PA2
// ETH_RMII_CRS_DV ------------------> PA7
// ETH_RMII_TX_EN -------------------> PB11
// ETH_RMII_TXD0 --------------------> PB12
// ETH_RMII_TXD1 --------------------> PB13
// ETH_RESET-------------------------> PC0
// ETH_MDC --------------------------> PC1
// ETH_RMII_RXD0 --------------------> PC4
// ETH_RMII_RXD1 --------------------> PC5
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// POWER IO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// LAN8720 硬件复位
GPIO_SetBits(GPIOA, GPIO_Pin_6); // 关闭电源
vTaskDelay(100);
GPIO_ResetBits(GPIOA, GPIO_Pin_6); // 打开电源
vTaskDelay(100);
vTaskDelay(100);
GPIO_SetBits(GPIOC, GPIO_Pin_0); // 复位结束
vTaskDelay(100);
// 设置中断优先级
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn; // 以太网中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7; // 中断寄存器组2最高优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 给ETH申请内存
if(eth_mem_malloc())
{
return 1; // 内存申请失败
}
// 配置ETH的MAC及DMA
if(eth_mac_dma_config() != 0)
{
return 2; // ETH配置失败
}
// 从LAN8720的31号寄存器中读取网络速度和双工模式
unsigned char speed = (unsigned char)ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 31);
speed = (unsigned char)((speed & 0x1C) >> 2);
// 1:10M半双工; 5:10M全双工; 2:100M半双工; 6:100M全双工
if(speed != 0x1 && speed != 0x2 && speed != 0x5 && speed != 0x6)
{
return 3; // LAN8720网卡初始化失败
}
return 0;
}
* 函数功能:接收一个以太网数据包
* 形 参:无
* 返 回 值:网络数据包帧结构体
********************************************************/
static FrameTypeDef eth_rx_packet(void)
{
unsigned int framelength = 0;
FrameTypeDef frame = {0, 0};
// 检查当前描述符,是否属于ETHERNET DMA(设置的时候)/CPU(复位的时候)
if((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (u32)RESET)
{
frame.length = ETH_ERROR;
if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
{
ETH->DMASR = ETH_DMASR_RBUS; // 清除ETH DMA的RBUS位
ETH->DMARPDR = 0; // 恢复DMA接收
}
return frame; // 错误,OWN位被设置了
}
if((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (u32)RESET && (DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (u32)RESET && (DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (u32)RESET)
{
framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4; // 得到接收包帧长度(不包含4字节CRC)
frame.buffer = DMARxDescToGet->Buffer1Addr; // 得到包数据所在的位置
}
else
{
framelength = ETH_ERROR; // 错误
}
frame.length = framelength;
frame.descriptor = DMARxDescToGet;
// 更新ETH DMA全局Rx描述符为下一个Rx描述符,为下一次buffer读取设置下一个DMA Rx描述符
DMARxDescToGet = (ETH_DMADESCTypeDef *)(DMARxDescToGet->Buffer2NextDescAddr);
return frame;
}
* 函数功能:发送一个以太网数据包
* 形 参:frame_length:数据包长度
* 返 回 值:0=成功,1=失败
********************************************************/
static unsigned int eth_tx_packet(unsigned short frame_length)
{
//检查当前描述符,是否属于ETHERNET DMA(设置的时候)/CPU(复位的时候)
if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
return 1; // 错误,OWN位被设置了
}
DMATxDescToSet->ControlBufferSize = (frame_length & ETH_DMATxDesc_TBS1); // 设置帧长度,bits[12:0]
DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS; // 设置最后一个和第一个位段置位(1个描述符传输一帧)
DMATxDescToSet->Status |= ETH_DMATxDesc_OWN; // 设置Tx描述符的OWN位,buffer重归ETH DMA
if((ETH->DMASR & ETH_DMASR_TBUS) != (u32)RESET) // 当Tx Buffer不可用位(TBUS)被设置的时候,重置它.恢复传输
{
ETH->DMASR = ETH_DMASR_TBUS; // 重置ETH DMA TBUS位
ETH->DMATPDR = 0; // 恢复DMA发送
}
// 更新ETH DMA全局Tx描述符为下一个Tx描述符
// 为下一次buffer发送设置下一个DMA Tx描述符
DMATxDescToSet = (ETH_DMADESCTypeDef *)(DMATxDescToSet->Buffer2NextDescAddr);
return 0;
}
* 函数功能:以太网数据包发送的底层函数(ARP发送)
* 形 参:netif:网卡结构体指针
p:pbuf数据结构体指针
* 返 回 值:ERR_OK=发送正常;ERR_MEM=内存异常
********************************************************/
static err_t arp_output(struct netif *netif, struct pbuf *p)
{
unsigned int length = 0;
unsigned char *pdata = (unsigned char *)DMATxDescToSet->Buffer1Addr;
for(struct pbuf *q = p; q != NULL; q = q->next)
{
unsigned char *pload = (unsigned char *)q->payload;
for(unsigned int i = 0; i < q->len; i++)
{
pdata[length++] = pload[i];
}
}
if(eth_tx_packet(length) == ETH_ERROR)
{
return ERR_MEM; // 返回错误状态
}
return ERR_OK;
}
* 函数功能:以太网接收数据(以太网中断函数调用)
* 形 参:netif:网卡结构体指针
* 返 回 值:ERR_OK=发送正常;ERR_MEM=内存异常
********************************************************/
static err_t ethernetif_input(struct netif *netif)
{
err_t err = ERR_OK;
unsigned int length = 0;
FrameTypeDef frame = eth_rx_packet();
unsigned char *pdata=(unsigned char *)frame.buffer;
struct pbuf *p = pbuf_alloc(PBUF_RAW, frame.length, PBUF_POOL); // 从pbufs内存池中给pbuf分配内存
if(p != NULL)
{
for(struct pbuf *q = p; q != NULL; q = q->next)
{
unsigned char *pload = (unsigned char *)q->payload;
for(unsigned int i = 0; i < q->len; i++)
{
pload[i] = pdata[length++];
}
}
if(netif->input(p, netif) != ERR_OK)
{
pbuf_free(p);
p = NULL;
}
}
else
{
err = ERR_MEM; // 内存异常
}
// 设置Rx描述符OWN位,数据进入ETH DMA
frame.descriptor->Status = ETH_DMARxDesc_OWN;
if((ETH->DMASRÐ_DMASR_RBUS) != RESET)
{
ETH->DMASR=ETH_DMASR_RBUS; // 重置ETH DMA RBUS位
ETH->DMARPDR = 0; // 恢复DMA接收
}
return err;
}
* 函数功能:以太网初始化(协议栈内核调用)
* 形 参:netif:网卡结构体指针
* 返 回 值:ERR_OK=发送正常;ERR_BUF=数据指针异常
********************************************************/
static err_t ethernetif_init(struct netif *netif)
{
if(netif == NULL)
{
return ERR_BUF;
}
#if LWIP_NETIF_HOSTNAME // LWIP_NETIF_HOSTNAME
netif->hostname = "lwip"; // 初始化名称
#endif
netif->name[0] = 'e'; // 初始化变量netif的name字段
netif->name[1] = '0'; // 在文件外定义这里不用关心具体值
netif->output = etharp_output; // IP层数据包发送函数
netif->linkoutput = arp_output; // ARP模块发送数据包函数
netif->hwaddr_len = ETHARP_HWADDR_LEN; // 设置MAC地址长度,为6个字节
// 注:MAC地址不能与网络中其他设备的MAC地址相同
// 获取STM32的唯一ID的前32位作为MAC地址后四个字节
unsigned int id = *(unsigned int *)(0x1FFF7A10);
netif->hwaddr[1] = 0;
netif->hwaddr[2] = (id >> 24) & 0xFF;
netif->hwaddr[3] = (id >> 16) & 0xFF;
netif->hwaddr[4] = (id >> 8) & 0xFF;
netif->hwaddr[5] = (id >> 0) & 0xFF;
// 允许该网卡广播和ARP功能,并且该网卡允许有硬件链路连接
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
// 向STM32F4的MAC地址寄存器中写入MAC地址
ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr);
// 以太网DMA传输配置
ETH_DMATxDescChainInit(DMATxDscrTab, pTxData, ETH_TXBUFNB);
ETH_DMARxDescChainInit(DMARxDscrTab, pRxData, ETH_RXBUFNB);
#ifdef CHECKSUM_BY_HARDWARE // 使用硬件帧校验
// 使能TCP,UDP和ICMP的发送帧校验
// TCP,UDP和ICMP的接收帧校验在DMA中配置了
for(unsigned int i = 0; i < ETH_TXBUFNB; i++)
{
ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
}
#endif
ETH_Start(); // 开启MAC和DMA
return ERR_OK;
}
* 函数功能:以太网DMA接收中断服务函数
* 形 参:无
* 返 回 值:无
********************************************************/
void ETH_IRQHandler(void)
{
// 首先判断是否收到数据包
while(ETH_GetRxPktSize(DMARxDescToGet) != 0)
{
ethernetif_input(ð0);
}
ETH_DMAClearITPendingBit(ETH_DMA_IT_R); // 清除DMA中断标志位
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS); // 清除DMA接收中断标志位
}
* 函数功能:DHCP处理任务
* 形 参:psLwipDev:IP信息数据结构之指针
* 返 回 值:无
********************************************************/
static void dhcp_task(sLwipDev_t * const psLwipDev)
{
dhcp_start(ð0); // 开启DHCP
while(eth0.dhcp->tries < 5U && psLwipDev != NULL)
{
if(eth0.ip_addr.addr != 0)
{
// 解析出通过DHCP获取到的网关地址
psLwipDev->gateway[3] =(uint8_t)(eth0.gw.addr >> 24);
psLwipDev->gateway[2] =(uint8_t)(eth0.gw.addr >> 16);
psLwipDev->gateway[1] =(uint8_t)(eth0.gw.addr >> 8);
psLwipDev->gateway[0] =(uint8_t)(eth0.gw.addr);
// 解析通过DHCP获取到的子网掩码地址
psLwipDev->mask[3] = (uint8_t)(eth0.netmask.addr >> 24);
psLwipDev->mask[2] = (uint8_t)(eth0.netmask.addr >> 16);
psLwipDev->mask[1] = (uint8_t)(eth0.netmask.addr >> 8);
psLwipDev->mask[0] = (uint8_t)(eth0.netmask.addr);
// 解析出通过DHCP获取到的IP地址
psLwipDev->localip[3] = (uint8_t)(eth0.ip_addr.addr >> 24);
psLwipDev->localip[2] = (uint8_t)(eth0.ip_addr.addr >> 16);
psLwipDev->localip[1] = (uint8_t)(eth0.ip_addr.addr >> 8);
psLwipDev->localip[0] = (uint8_t)(eth0.ip_addr.addr);
break;
}
}
}
* 函数功能:获取默认IP信息
* 形 参:psLwipDev:IP信息数据结构指针
* 返 回 值:0=成功,1=数据指针为NULL
********************************************************/
unsigned int eth_default_ip_get(sLwipDev_t * const psLwipDev)
{
if(psLwipDev == NULL)
{
return 1;
}
psLwipDev->gateway[1] = 168;
psLwipDev->gateway[2] = 1;
psLwipDev->gateway[3] = 1;
psLwipDev->mask[0] = 255;
psLwipDev->mask[1] = 255;
psLwipDev->mask[2] = 255;
psLwipDev->mask[3] = 0;
psLwipDev->localip[0] = 192;
psLwipDev->localip[1] = 168;
psLwipDev->localip[2] = 1;
psLwipDev->localip[3] = 100;
psLwipDev->remoteip[0] = 192;
psLwipDev->remoteip[1] = 168;
psLwipDev->remoteip[2] = 1;
psLwipDev->remoteip[3] = 10;
psLwipDev->localport = 8088;
psLwipDev->remoteport = 8086;
return 0;
}
* 函数功能:以太网、协议栈内核等初始化
* 形 参:psLwipDev:IP信息数据结构指针
* 返 回 值:0=初始化成功
1=数据指针为NULL
2=以太网初始化失败
3=网卡注册失败
********************************************************/
unsigned int eth_init(sLwipDev_t * const psLwipDev)
{
if(psLwipDev == NULL)
{
return 1;
}
struct ip_addr mask; // 子网掩码
struct ip_addr gateway; // 默认网关
struct ip_addr localip; // 本地IP地址
if(eht_init() != 0)
{
return 2;
}
// TCPIP内核初始化
tcpip_init(NULL, NULL);
#else
// 设置默认IP地址信息
IP4_ADDR(&mask, psLwipDev->mask[0], psLwipDev->mask[1], psLwipDev->mask[2], psLwipDev->mask[3]);
IP4_ADDR(&gateway, psLwipDev->gateway[0], psLwipDev->gateway[1], psLwipDev->gateway[2], psLwipDev->gateway[3]);
IP4_ADDR(&localip, psLwipDev->localip[0], psLwipDev->localip[1], psLwipDev->localip[2], psLwipDev->localip[3]);
#endif
if(netif_add(ð0, &localip, &mask, &gateway, NULL, ðernetif_init, &tcpip_input) == NULL)
{
return 3; // 网卡注册失败
}
netif_set_default(ð0); // 设置netif为默认网口
netif_set_up(ð0); // 打开netif网口
return 0;
}
5、向工程中添加LwIP相关代码:
a、LwIP-NETIF中添加LwIP\lwip-1.4.1\src\netif目录下etharp.c文件
b、LwIP-CORE中添加LwIP\lwip-1.4.1\src\core\ipv4目录下的所有C文件,以及LwIP\lwip-1.4.1\src\core目录下除sys.c之外的所有C文件
c、LwIP-ARCH中添加LwIP\arch目录下的所有C文件
d、LwIP-API中添加LwIP\lwip-1.4.1\src\api目录下的所有C文件
e、LwIP-APP中添加用户文件,如:TCP客户端文件、TCP服务器文件、UDP文件等等。
源码文件添加完成后需要添加头文件路径,如下图所示:
OK,到这里LwIP协议栈就移植完成了,然后编译,发现有两个警告,如下:
a、LwIP\lwip-1.4.1\src\core\tcp_out.c(845): warning: #550-D: variable "tcphdr" was set but never used
b、LwIP\lwip-1.4.1\src\core\tcp_out.c(1367): warning: #550-D: variable "tcphdr" was set but never used
这两个警告是一样的问题导致的,编译器在编译代码的时候,如果发现变量只有写而没有读的时候,就会报一个从未使用的警告,我们在尽量不修改内核的前提下消去这两个警告,就需要让这两个变量都读一次,操作如下:
最后再编译一下,警告没有了。到这里,LwIP在FreeRTOS操作系统中的移植完成。
补充一:
移植LwIP需要添加STM32的以太网库文件,这个库文件在官方固件库中是没有的,因此在这里给贴出来。总共三个文件分别为:stm32f4x7_eth.c、stm32f4x7_eth.h、stm32f4x7_eth_conf.h
stm32f4x7_eth_conf.h
#define __STM32F4x7_ETH_CONF_H
#include "stm32f4xx.h"
//默认的低精度延时函数
#ifdef USE_Delay
#include "main.h"
#define _eth_delay_ Delay //Delay为用户自己提供的高精度延时函数
#else
#define _eth_delay_ ETH_Delay //默认的_eth_delay功能函数延时精度差
#endif
//重新定义以太网接收和发送缓冲区的大小和数量
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE //接收缓冲区的大小
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE //发送缓冲区的大小
#define ETH_RXBUFNB 20 //接收缓冲区数量
#define ETH_TXBUFNB 5 //发送缓冲区数量
#endif
#ifdef USE_Delay
#define PHY_RESET_DELAY ((uint32_t)0x000000FF) //PHY复位延时
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) //PHY配置延时
#define ETH_REG_WRITE_DELAY ((uint32_t)0x00000001) //向以太网寄存器写数据时的延时
#else
#define PHY_RESET_DELAY ((uint32_t)0x000FFFFF) //PHY复位延时
#define PHY_CONFIG_DELAY ((uint32_t)0x00FFFFFF) //PHY配置延时
#define ETH_REG_WRITE_DELAY ((uint32_t)0x0000FFFF) //向以太网寄存器写数据时的延时
#endif
#define PHY_SR ((uint16_t)31) //LAN8720的PHY状态寄存器地址
#define PHY_SPEED_STATUS ((uint16_t)0x0004) //LAN8720 PHY速度值掩码
#define PHY_DUPLEX_STATUS ((uint16_t)0x00010) //LAN8720 PHY连接状态值掩码
#endif
******************************************************************************
* @file stm32f4x7_eth.h
* @author MCD Application Team
* @version V1.0.0
* @date 14-October-2011
* @brief This file contains all the functions prototypes for the Ethernet
* firmware driver.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
#ifndef __STM32F4x7_ETH_H
#define __STM32F4x7_ETH_H
extern "C" {
#endif
#include "stm32f4x7_eth_conf.h"
* @{
*/
* @{
*/
* @brief ETH MAC Init structure definition
* @note The user should not configure all the ETH_InitTypeDef structure's fields.
* By calling the ETH_StructInit function the structure抯 fields are set to their default values.
* Only the parameters that will be set to a non-default value should be configured.
*/
typedef struct {
/**
* @brief / * MAC
*/
uint32_t ETH_AutoNegotiation; /*!< Selects or not the AutoNegotiation mode for the external PHY
The AutoNegotiation allows an automatic setting of the Speed (10/100Mbps)
and the mode (half/full-duplex).
This parameter can be a value of @ref ETH_AutoNegotiation */
When enabled, the MAC allows no more then 2048 bytes to be received.
When disabled, the MAC can receive up to 16384 bytes.
This parameter can be a value of @ref ETH_watchdog */
When enabled, the MAC allows no more then 2048 bytes to be sent.
When disabled, the MAC can send up to 16384 bytes.
This parameter can be a value of @ref ETH_Jabber */
This parameter can be a value of @ref ETH_Inter_Frame_Gap */
This parameter can be a value of @ref ETH_Carrier_Sense */
This parameter can be a value of @ref ETH_Speed */
ReceiveOwn allows the reception of frames when the TX_EN signal is asserted
in Half-Duplex mode
This parameter can be a value of @ref ETH_Receive_Own */
This parameter can be a value of @ref ETH_Loop_Back_Mode */
This parameter can be a value of @ref ETH_Duplex_Mode */
This parameter can be a value of @ref ETH_Checksum_Offload */
when a collision occurs (Half-Duplex mode)
This parameter can be a value of @ref ETH_Retry_Transmission */
This parameter can be a value of @ref ETH_Automatic_Pad_CRC_Strip */
This parameter can be a value of @ref ETH_Back_Off_Limit */
This parameter can be a value of @ref ETH_Deferral_Check */
This parameter can be a value of @ref ETH_Receive_All */
This parameter can be a value of @ref ETH_Source_Addr_Filter */
This parameter can be a value of @ref ETH_Pass_Control_Frames */
This parameter can be a value of @ref ETH_Broadcast_Frames_Reception */
This parameter can be a value of @ref ETH_Destination_Addr_Filter */
This parameter can be a value of @ref ETH_Promiscuous_Mode */
This parameter can be a value of @ref ETH_Multicast_Frames_Filter */
This parameter can be a value of @ref ETH_Unicast_Frames_Filter */
transmit control frame */
This parameter can be a value of @ref ETH_Zero_Quanta_Pause */
automatic retransmission of PAUSE Frame
This parameter can be a value of @ref ETH_Pause_Low_Threshold */
uint32_t ETH_UnicastPauseFrameDetect; /*!< Selects or not the MAC detection of the Pause frames (with MAC Address0
unicast address and unique multicast address)
This parameter can be a value of @ref ETH_Unicast_Pause_Frame_Detect */
disable its transmitter for a specified time (Pause Time)
This parameter can be a value of @ref ETH_Receive_Flow_Control */
or the MAC back-pressure operation (Half-Duplex mode)
This parameter can be a value of @ref ETH_Transmit_Flow_Control */
comparison and filtering
This parameter can be a value of @ref ETH_VLAN_Tag_Comparison */
* @brief / * DMA
*/
This parameter can be a value of @ref ETH_Drop_TCP_IP_Checksum_Error_Frame */
This parameter can be a value of @ref ETH_Receive_Store_Forward */
This parameter can be a value of @ref ETH_Flush_Received_Frame */
This parameter can be a value of @ref ETH_Transmit_Store_Forward */
This parameter can be a value of @ref ETH_Transmit_Threshold_Control */
This parameter can be a value of @ref ETH_Forward_Error_Frames */
and length less than 64 bytes) including pad-bytes and CRC)
This parameter can be a value of @ref ETH_Forward_Undersized_Good_Frames */
This parameter can be a value of @ref ETH_Receive_Threshold_Control */
frame of Transmit data even before obtaining the status for the first frame.
This parameter can be a value of @ref ETH_Second_Frame_Operate */
This parameter can be a value of @ref ETH_Address_Aligned_Beats */
This parameter can be a value of @ref ETH_Fixed_Burst */
uint32_t ETH_RxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Rx DMA transaction
This parameter can be a value of @ref ETH_Rx_DMA_Burst_Length */
This parameter can be a value of @ref ETH_Tx_DMA_Burst_Length */
This parameter can be a value of @ref ETH_DMA_Arbitration */
}ETH_InitTypeDef;
/**
* @brief DMA descriptors types
*/
/**--------------------------------------------------------------------------**/
* @brief ETH DMA Descriptors data structure definition
*/
typedef struct {
__IO uint32_t Status; /*!< Status */
uint32_t ControlBufferSize; /*!< Control and Buffer1, Buffer2 lengths */
uint32_t Buffer1Addr; /*!< Buffer1 address pointer */
uint32_t Buffer2NextDescAddr; /*!< Buffer2 or next descriptor address pointer */
/* Enhanced ETHERNET DMA PTP Descriptors */
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
uint32_t ExtendedStatus; /* Extended status for PTP receive descriptor */
uint32_t Reserved1; /* Reserved */
uint32_t TimeStampLow; /* Time Stamp Low value for transmit and receive */
uint32_t TimeStampHigh; /* Time Stamp High value for transmit and receive */
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
} ETH_DMADESCTypeDef;
typedef struct{
u32 length;
u32 buffer;
__IO ETH_DMADESCTypeDef *descriptor;
}FrameTypeDef;
typedef struct {
__IO ETH_DMADESCTypeDef *FS_Rx_Desc; /*!< First Segment Rx Desc */
__IO ETH_DMADESCTypeDef *LS_Rx_Desc; /*!< Last Segment Rx Desc */
__IO uint32_t Seg_Count; /*!< Segment count */
} ETH_DMA_Rx_Frame_infos;
* @}
*/
* @{
*/
/**--------------------------------------------------------------------------**/
/**
* @brief ETH Frames defines
*/
/**--------------------------------------------------------------------------**/
* @{
*/
#define ETH_MAX_PACKET_SIZE 1524 /*!< ETH_HEADER + ETH_EXTRA + VLAN_TAG + MAX_ETH_PAYLOAD + ETH_CRC */
#define ETH_HEADER 14 /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */
#define ETH_CRC 4 /*!< Ethernet CRC */
#define ETH_EXTRA 2 /*!< Extra bytes in some cases */
#define VLAN_TAG 4 /*!< optional 802.1q VLAN Tag */
#define MIN_ETH_PAYLOAD 46 /*!< Minimum Ethernet payload size */
#define MAX_ETH_PAYLOAD 1500 /*!< Maximum Ethernet payload size */
#define JUMBO_FRAME_PAYLOAD 9000 /*!< Jumbo frame payload size */
an ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO
to the driver receive buffers memory.
Depending on the size of the received ethernet packet and the size of
each ethernet driver receive buffer, the received packet can take one or more
ethernet driver receive buffer.
In below are defined the size of one ethernet driver receive buffer ETH_RX_BUF_SIZE
and the total count of the driver receive buffers ETH_RXBUFNB.
The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as
example, they can be reconfigured in the application layer to fit the application
needs */
/* Here we configure each Ethernet driver receive buffer to fit the Max size Ethernet
packet */
#ifndef ETH_RX_BUF_SIZE
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE
#endif
#ifndef ETH_RXBUFNB
#define ETH_RXBUFNB 5 /* 5 Rx buffers of size ETH_RX_BUF_SIZE */
#endif
/* Ethernet driver transmit buffers are organized in a chained linked-list, when
an ethernet packet is transmitted, Tx-DMA will transfer the packet from the
driver transmit buffers memory to the TxFIFO.
Depending on the size of the Ethernet packet to be transmitted and the size of
each ethernet driver transmit buffer, the packet to be transmitted can take
one or more ethernet driver transmit buffer.
In below are defined the size of one ethernet driver transmit buffer ETH_TX_BUF_SIZE
and the total count of the driver transmit buffers ETH_TXBUFNB.
The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as
example, they can be reconfigured in the application layer to fit the application
needs */
/* Here we configure each Ethernet driver transmit buffer to fit the Max size Ethernet
packet */
#ifndef ETH_TX_BUF_SIZE
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE
#endif
#ifndef ETH_TXBUFNB
#define ETH_TXBUFNB 5 /* 5 Tx buffers of size ETH_TX_BUF_SIZE */
#endif
/**
* @brief Ethernet DMA descriptors registers bits definition
*/
/**--------------------------------------------------------------------------**/
@code
DMA Tx Desciptor
-----------------------------------------------------------------------------------------------
TDES0 | OWN(31) | CTRL[30:26] | Reserved[25:24] | CTRL[23:20] | Reserved[19:17] | Status[16:0] |
-----------------------------------------------------------------------------------------------
TDES1 | Reserved[31:29] | Buffer2 ByteCount[28:16] | Reserved[15:13] | Buffer1 ByteCount[12:0] |
-----------------------------------------------------------------------------------------------
TDES2 | Buffer1 Address [31:0] |
-----------------------------------------------------------------------------------------------
TDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] |
-----------------------------------------------------------------------------------------------
@endcode
*/
* @brief Bit definition of TDES0 register: DMA Tx descriptor status register
*/
#define ETH_DMATxDesc_OWN ((uint32_t)0x80000000) /*!< OWN bit: descriptor is owned by DMA engine */
#define ETH_DMATxDesc_IC ((uint32_t)0x40000000) /*!< Interrupt on Completion */
#define ETH_DMATxDesc_LS ((uint32_t)0x20000000) /*!< Last Segment */
#define ETH_DMATxDesc_FS ((uint32_t)0x10000000) /*!< First Segment */
#define ETH_DMATxDesc_DC ((uint32_t)0x08000000) /*!< Disable CRC */
#define ETH_DMATxDesc_DP ((uint32_t)0x04000000) /*!< Disable Padding */
#define ETH_DMATxDesc_TTSE ((uint32_t)0x02000000) /*!< Transmit Time Stamp Enable */
#define ETH_DMATxDesc_CIC ((uint32_t)0x00C00000) /*!< Checksum Insertion Control: 4 cases */
#define ETH_DMATxDesc_CIC_ByPass ((uint32_t)0x00000000) /*!< Do Nothing: Checksum Engine is bypassed */
#define ETH_DMATxDesc_CIC_IPV4Header ((uint32_t)0x00400000) /*!< IPV4 header Checksum Insertion */
#define ETH_DMATxDesc_CIC_TCPUDPICMP_Segment ((uint32_t)0x00800000) /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */
#define ETH_DMATxDesc_CIC_TCPUDPICMP_Full ((uint32_t)0x00C00000) /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */
#define ETH_DMATxDesc_TER ((uint32_t)0x00200000) /*!< Transmit End of Ring */
#define ETH_DMATxDesc_TCH ((uint32_t)0x00100000) /*!< Second Address Chained */
#define ETH_DMATxDesc_TTSS ((uint32_t)0x00020000) /*!< Tx Time Stamp Status */
#define ETH_DMATxDesc_IHE ((uint32_t)0x00010000) /*!< IP Header Error */
#define ETH_DMATxDesc_ES ((uint32_t)0x00008000) /*!< Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */
#define ETH_DMATxDesc_JT ((uint32_t)0x00004000) /*!< Jabber Timeout */
#define ETH_DMATxDesc_FF ((uint32_t)0x00002000) /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */
#define ETH_DMATxDesc_PCE ((uint32_t)0x00001000) /*!< Payload Checksum Error */
#define ETH_DMATxDesc_LCA ((uint32_t)0x00000800) /*!< Loss of Carrier: carrier lost during transmission */
#define ETH_DMATxDesc_NC ((uint32_t)0x00000400) /*!< No Carrier: no carrier signal from the transceiver */
#define ETH_DMATxDesc_LCO ((uint32_t)0x00000200) /*!< Late Collision: transmission aborted due to collision */
#define ETH_DMATxDesc_EC ((uint32_t)0x00000100) /*!< Excessive Collision: transmission aborted after 16 collisions */
#define ETH_DMATxDesc_VF ((uint32_t)0x00000080) /*!< VLAN Frame */
#define ETH_DMATxDesc_CC ((uint32_t)0x00000078) /*!< Collision Count */
#define ETH_DMATxDesc_ED ((uint32_t)0x00000004) /*!< Excessive Deferral */
#define ETH_DMATxDesc_UF ((uint32_t)0x00000002) /*!< Underflow Error: late data arrival from the memory */
#define ETH_DMATxDesc_DB ((uint32_t)0x00000001) /*!< Deferred Bit */
* @brief Bit definition of TDES1 register
*/
#define ETH_DMATxDesc_TBS2 ((uint32_t)0x1FFF0000) /*!< Transmit Buffer2 Size */
#define ETH_DMATxDesc_TBS1 ((uint32_t)0x00001FFF) /*!< Transmit Buffer1 Size */
* @brief Bit definition of TDES2 register
*/
#define ETH_DMATxDesc_B1AP ((uint32_t)0xFFFFFFFF) /*!< Buffer1 Address Pointer */
* @brief Bit definition of TDES3 register
*/
#define ETH_DMATxDesc_B2AP ((uint32_t)0xFFFFFFFF) /*!< Buffer2 Address Pointer */
TDES6 | Transmit Time Stamp Low [31:0] |
-----------------------------------------------------------------------------------------------
TDES7 | Transmit Time Stamp High [31:0] |
----------------------------------------------------------------------------------------------*/
#define ETH_DMAPTPTxDesc_TTSL ((uint32_t)0xFFFFFFFF) /* Transmit Time Stamp Low */
#define ETH_DMAPTPTxDesc_TTSH ((uint32_t)0xFFFFFFFF) /* Transmit Time Stamp High */
* @}
*/
/** @defgroup DMA_Rx_descriptor
* @{
*/
@code
DMA Rx Descriptor
--------------------------------------------------------------------------------------------------------------------
RDES0 | OWN(31) | Status [30:0] |
---------------------------------------------------------------------------------------------------------------------
RDES1 | CTRL(31) | Reserved[30:29] | Buffer2 ByteCount[28:16] | CTRL[15:14] | Reserved(13) | Buffer1 ByteCount[12:0] |
---------------------------------------------------------------------------------------------------------------------
RDES2 | Buffer1 Address [31:0] |
---------------------------------------------------------------------------------------------------------------------
RDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] |
---------------------------------------------------------------------------------------------------------------------
@endcode
*/
* @brief Bit definition of RDES0 register: DMA Rx descriptor status register
*/
#define ETH_DMARxDesc_OWN ((uint32_t)0x80000000) /*!< OWN bit: descriptor is owned by DMA engine */
#define ETH_DMARxDesc_AFM ((uint32_t)0x40000000) /*!< DA Filter Fail for the rx frame */
#define ETH_DMARxDesc_FL ((uint32_t)0x3FFF0000) /*!< Receive descriptor frame length */
#define ETH_DMARxDesc_ES ((uint32_t)0x00008000) /*!< Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */
#define ETH_DMARxDesc_DE ((uint32_t)0x00004000) /*!< Descriptor error: no more descriptors for receive frame */
#define ETH_DMARxDesc_SAF ((uint32_t)0x00002000) /*!< SA Filter Fail for the received frame */
#define ETH_DMARxDesc_LE ((uint32_t)0x00001000) /*!< Frame size not matching with length field */
#define ETH_DMARxDesc_OE ((uint32_t)0x00000800) /*!< Overflow Error: Frame was damaged due to buffer overflow */
#define ETH_DMARxDesc_VLAN ((uint32_t)0x00000400) /*!< VLAN Tag: received frame is a VLAN frame */
#define ETH_DMARxDesc_FS ((uint32_t)0x00000200) /*!< First descriptor of the frame */
#define ETH_DMARxDesc_LS ((uint32_t)0x00000100) /*!< Last descriptor of the frame */
#define ETH_DMARxDesc_IPV4HCE ((uint32_t)0x00000080) /*!< IPC Checksum Error: Rx Ipv4 header checksum error */
#define ETH_DMARxDesc_LC ((uint32_t)0x00000040) /*!< Late collision occurred during reception */
#define ETH_DMARxDesc_FT ((uint32_t)0x00000020) /*!< Frame type - Ethernet, otherwise 802.3 */
#define ETH_DMARxDesc_RWT ((uint32_t)0x00000010) /*!< Receive Watchdog Timeout: watchdog timer expired during reception */
#define ETH_DMARxDesc_RE ((uint32_t)0x00000008) /*!< Receive error: error reported by MII interface */
#define ETH_DMARxDesc_DBE ((uint32_t)0x00000004) /*!< Dribble bit error: frame contains non int multiple of 8 bits */
#define ETH_DMARxDesc_CE ((uint32_t)0x00000002) /*!< CRC error */
#define ETH_DMARxDesc_MAMPCE ((uint32_t)0x00000001) /*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
* @brief Bit definition of RDES1 register
*/
#define ETH_DMARxDesc_DIC ((uint32_t)0x80000000) /*!< Disable Interrupt on Completion */
#define ETH_DMARxDesc_RBS2 ((uint32_t)0x1FFF0000) /*!< Receive Buffer2 Size */
#define ETH_DMARxDesc_RER ((uint32_t)0x00008000) /*!< Receive End of Ring */
#define ETH_DMARxDesc_RCH ((uint32_t)0x00004000) /*!< Second Address Chained */
#define ETH_DMARxDesc_RBS1 ((uint32_t)0x00001FFF) /*!< Receive Buffer1 Size */
* @brief Bit definition of RDES2 register
*/
#define ETH_DMARxDesc_B1AP ((uint32_t)0xFFFFFFFF) /*!< Buffer1 Address Pointer */
* @brief Bit definition of RDES3 register
*/
#define ETH_DMARxDesc_B2AP ((uint32_t)0xFFFFFFFF) /*!< Buffer2 Address Pointer */
RDES4 | Reserved[31:15] | Extended Status [14:0] |
---------------------------------------------------------------------------------------------------------------------
RDES5 | Reserved[31:0] |
---------------------------------------------------------------------------------------------------------------------
RDES6 | Receive Time Stamp Low [31:0] |
---------------------------------------------------------------------------------------------------------------------
RDES7 | Receive Time Stamp High [31:0] |
--------------------------------------------------------------------------------------------------------------------*/
#define ETH_DMAPTPRxDesc_PTPV ((uint32_t)0x00002000) /* PTP Version */
#define ETH_DMAPTPRxDesc_PTPFT ((uint32_t)0x00001000) /* PTP Frame Type */
#define ETH_DMAPTPRxDesc_PTPMT ((uint32_t)0x00000F00) /* PTP Message Type */
#define ETH_DMAPTPRxDesc_PTPMT_Sync ((uint32_t)0x00000100) /* SYNC message (all clock types) */
#define ETH_DMAPTPRxDesc_PTPMT_FollowUp ((uint32_t)0x00000200) /* FollowUp message (all clock types) */
#define ETH_DMAPTPRxDesc_PTPMT_DelayReq ((uint32_t)0x00000300) /* DelayReq message (all clock types) */
#define ETH_DMAPTPRxDesc_PTPMT_DelayResp ((uint32_t)0x00000400) /* DelayResp message (all clock types) */
#define ETH_DMAPTPRxDesc_PTPMT_PdelayReq_Announce ((uint32_t)0x00000500) /* PdelayReq message (peer-to-peer transparent clock) or Announce message (Ordinary or Boundary clock) */
#define ETH_DMAPTPRxDesc_PTPMT_PdelayResp_Manag ((uint32_t)0x00000600) /* PdelayResp message (peer-to-peer transparent clock) or Management message (Ordinary or Boundary clock) */
#define ETH_DMAPTPRxDesc_PTPMT_PdelayRespFollowUp_Signal ((uint32_t)0x00000700) /* PdelayRespFollowUp message (peer-to-peer transparent clock) or Signaling message (Ordinary or Boundary clock) */
#define ETH_DMAPTPRxDesc_IPV6PR ((uint32_t)0x00000080) /* IPv6 Packet Received */
#define ETH_DMAPTPRxDesc_IPV4PR ((uint32_t)0x00000040) /* IPv4 Packet Received */
#define ETH_DMAPTPRxDesc_IPCB ((uint32_t)0x00000020) /* IP Checksum Bypassed */
#define ETH_DMAPTPRxDesc_IPPE ((uint32_t)0x00000010) /* IP Payload Error */
#define ETH_DMAPTPRxDesc_IPHE ((uint32_t)0x00000008) /* IP Header Error */
#define ETH_DMAPTPRxDesc_IPPT ((uint32_t)0x00000007) /* IP Payload Type */
#define ETH_DMAPTPRxDesc_IPPT_UDP ((uint32_t)0x00000001) /* UDP payload encapsulated in the IP datagram */
#define ETH_DMAPTPRxDesc_IPPT_TCP ((uint32_t)0x00000002) /* TCP payload encapsulated in the IP datagram */
#define ETH_DMAPTPRxDesc_IPPT_ICMP ((uint32_t)0x00000003) /* ICMP payload encapsulated in the IP datagram */
#define ETH_DMAPTPRxDesc_RTSL ((uint32_t)0xFFFFFFFF) /* Receive Time Stamp Low */
#define ETH_DMAPTPRxDesc_RTSH ((uint32_t)0xFFFFFFFF) /* Receive Time Stamp High */
/**--------------------------------------------------------------------------**/
/**
* @brief Description of common PHY registers
*/
/**--------------------------------------------------------------------------**/
* @}
*/
* @{
*/
#define PHY_READ_TO ((uint32_t)0x0004FFFF)
#define PHY_WRITE_TO ((uint32_t)0x0004FFFF)
* @}
*/
* @{
*/
#define PHY_BCR 0 /*!< Transceiver Basic Control Register */
#define PHY_BSR 1 /*!< Transceiver Basic Status Register */
#define IS_ETH_PHY_REG(REG) (((REG) == PHY_BCR) || \
((REG) == PHY_BSR) || \
((REG) == PHY_SR))
/**
* @}
*/
* @{
*/
#define PHY_Reset ((uint16_t)0x8000) /*!< PHY Reset */
#define PHY_Loopback ((uint16_t)0x4000) /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
#define PHY_AutoNegotiation ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
#define PHY_Restart_AutoNegotiation ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
#define PHY_Powerdown ((uint16_t)0x0800) /*!< Select the power down mode */
#define PHY_Isolate ((uint16_t)0x0400) /*!< Isolate PHY from MII */
* @}
*/
* @{
*/
#define PHY_AutoNego_Complete ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
#define PHY_Linked_Status ((uint16_t)0x0004) /*!< Valid link established */
#define PHY_Jabber_detection ((uint16_t)0x0002) /*!< Jabber condition detected */
* @}
*/
/**
* @brief MAC defines
*/
/**--------------------------------------------------------------------------**/
* @{
*/
#define ETH_AutoNegotiation_Enable ((uint32_t)0x00000001)
#define ETH_AutoNegotiation_Disable ((uint32_t)0x00000000)
#define IS_ETH_AUTONEGOTIATION(CMD) (((CMD) == ETH_AutoNegotiation_Enable) || \
((CMD) == ETH_AutoNegotiation_Disable))
* @}
*/
* @{
*/
#define ETH_Watchdog_Enable ((uint32_t)0x00000000)
#define ETH_Watchdog_Disable ((uint32_t)0x00800000)
#define IS_ETH_WATCHDOG(CMD) (((CMD) == ETH_Watchdog_Enable) || \
((CMD) == ETH_Watchdog_Disable))
* @}
*/
* @{
*/
#define ETH_Jabber_Enable ((uint32_t)0x00000000)
#define ETH_Jabber_Disable ((uint32_t)0x00400000)
#define IS_ETH_JABBER(CMD) (((CMD) == ETH_Jabber_Enable) || \
((CMD) == ETH_Jabber_Disable))
* @}
*/
* @{
*/
#define ETH_InterFrameGap_96Bit ((uint32_t)0x00000000) /*!< minimum IFG between frames during transmission is 96Bit */
#define ETH_InterFrameGap_88Bit ((uint32_t)0x00020000) /*!< minimum IFG between frames during transmission is 88Bit */
#define ETH_InterFrameGap_80Bit ((uint32_t)0x00040000) /*!< minimum IFG between frames during transmission is 80Bit */
#define ETH_InterFrameGap_72Bit ((uint32_t)0x00060000) /*!< minimum IFG between frames during transmission is 72Bit */
#define ETH_InterFrameGap_64Bit ((uint32_t)0x00080000) /*!< minimum IFG between frames during transmission is 64Bit */
#define ETH_InterFrameGap_56Bit ((uint32_t)0x000A0000) /*!< minimum IFG between frames during transmission is 56Bit */
#define ETH_InterFrameGap_48Bit ((uint32_t)0x000C0000) /*!< minimum IFG between frames during transmission is 48Bit */
#define ETH_InterFrameGap_40Bit ((uint32_t)0x000E0000) /*!< minimum IFG between frames during transmission is 40Bit */
#define IS_ETH_INTER_FRAME_GAP(GAP) (((GAP) == ETH_InterFrameGap_96Bit) || \
((GAP) == ETH_InterFrameGap_88Bit) || \
((GAP) == ETH_InterFrameGap_80Bit) || \
((GAP) == ETH_InterFrameGap_72Bit) || \
((GAP) == ETH_InterFrameGap_64Bit) || \
((GAP) == ETH_InterFrameGap_56Bit) || \
((GAP) == ETH_InterFrameGap_48Bit) || \
((GAP) == ETH_InterFrameGap_40Bit))
* @}
*/
* @{
*/
#define ETH_CarrierSense_Enable ((uint32_t)0x00000000)
#define ETH_CarrierSense_Disable ((uint32_t)0x00010000)
#define IS_ETH_CARRIER_SENSE(CMD) (((CMD) == ETH_CarrierSense_Enable) || \
((CMD) == ETH_CarrierSense_Disable))
* @}
*/
* @{
*/
#define ETH_Speed_10M ((uint32_t)0x00000000)
#define ETH_Speed_100M ((uint32_t)0x00004000)
#define IS_ETH_SPEED(SPEED) (((SPEED) == ETH_Speed_10M) || \
((SPEED) == ETH_Speed_100M))
* @}
*/
* @{
*/
#define ETH_ReceiveOwn_Enable ((uint32_t)0x00000000)
#define ETH_ReceiveOwn_Disable ((uint32_t)0x00002000)
#define IS_ETH_RECEIVE_OWN(CMD) (((CMD) == ETH_ReceiveOwn_Enable) || \
((CMD) == ETH_ReceiveOwn_Disable))
* @}
*/
* @{
*/
#define ETH_LoopbackMode_Enable ((uint32_t)0x00001000)
#define ETH_LoopbackMode_Disable ((uint32_t)0x00000000)
#define IS_ETH_LOOPBACK_MODE(CMD) (((CMD) == ETH_LoopbackMode_Enable) || \
((CMD) == ETH_LoopbackMode_Disable))
* @}
*/
* @{
*/
#define ETH_Mode_FullDuplex ((uint32_t)0x00000800)
#define ETH_Mode_HalfDuplex ((uint32_t)0x00000000)
#define IS_ETH_DUPLEX_MODE(MODE) (((MODE) == ETH_Mode_FullDuplex) || \
((MODE) == ETH_Mode_HalfDuplex))
* @}
*/
* @{
*/
#define ETH_ChecksumOffload_Enable ((uint32_t)0x00000400)
#define ETH_ChecksumOffload_Disable ((uint32_t)0x00000000)
#define IS_ETH_CHECKSUM_OFFLOAD(CMD) (((CMD) == ETH_ChecksumOffload_Enable) || \
((CMD) == ETH_ChecksumOffload_Disable))
* @}
*/
* @{
*/
#define ETH_RetryTransmission_Enable ((uint32_t)0x00000000)
#define ETH_RetryTransmission_Disable ((uint32_t)0x00000200)
#define IS_ETH_RETRY_TRANSMISSION(CMD) (((CMD) == ETH_RetryTransmission_Enable) || \
((CMD) == ETH_RetryTransmission_Disable))
* @}
*/
* @{
*/
#define ETH_AutomaticPadCRCStrip_Enable ((uint32_t)0x00000080)
#define ETH_AutomaticPadCRCStrip_Disable ((uint32_t)0x00000000)
#define IS_ETH_AUTOMATIC_PADCRC_STRIP(CMD) (((CMD) == ETH_AutomaticPadCRCStrip_Enable) || \
((CMD) == ETH_AutomaticPadCRCStrip_Disable))
* @}
*/
* @{
*/
#define ETH_BackOffLimit_10 ((uint32_t)0x00000000)
#define ETH_BackOffLimit_8 ((uint32_t)0x00000020)
#define ETH_BackOffLimit_4 ((uint32_t)0x00000040)
#define ETH_BackOffLimit_1 ((uint32_t)0x00000060)
#define IS_ETH_BACKOFF_LIMIT(LIMIT) (((LIMIT) == ETH_BackOffLimit_10) || \
((LIMIT) == ETH_BackOffLimit_8) || \
((LIMIT) == ETH_BackOffLimit_4) || \
((LIMIT) == ETH_BackOffLimit_1))
* @}
*/
* @{
*/
#define ETH_DeferralCheck_Enable ((uint32_t)0x00000010)
#define ETH_DeferralCheck_Disable ((uint32_t)0x00000000)
#define IS_ETH_DEFERRAL_CHECK(CMD) (((CMD) == ETH_DeferralCheck_Enable) || \
((CMD) == ETH_DeferralCheck_Disable))
* @}
*/
* @{
*/
#define ETH_ReceiveAll_Enable ((uint32_t)0x80000000)
#define ETH_ReceiveAll_Disable ((uint32_t)0x00000000)
#define IS_ETH_RECEIVE_ALL(CMD) (((CMD) == ETH_ReceiveAll_Enable) || \
((CMD) == ETH_ReceiveAll_Disable))
* @}
*/
* @{
*/
#define ETH_SourceAddrFilter_Normal_Enable ((uint32_t)0x00000200)
#define ETH_SourceAddrFilter_Inverse_Enable ((uint32_t)0x00000300)
#define ETH_SourceAddrFilter_Disable ((uint32_t)0x00000000)
#define IS_ETH_SOURCE_ADDR_FILTER(CMD) (((CMD) == ETH_SourceAddrFilter_Normal_Enable) || \
((CMD) == ETH_SourceAddrFilter_Inverse_Enable) || \
((CMD) == ETH_SourceAddrFilter_Disable))
* @}
*/
* @{
*/
#define ETH_PassControlFrames_BlockAll ((uint32_t)0x00000040) /*!< MAC filters all control frames from reaching the application */
#define ETH_PassControlFrames_ForwardAll ((uint32_t)0x00000080) /*!< MAC forwards all control frames to application even if they fail the Address Filter */
#define ETH_PassControlFrames_ForwardPassedAddrFilter ((uint32_t)0x000000C0) /*!< MAC forwards control frames that pass the Address Filter. */
#define IS_ETH_CONTROL_FRAMES(PASS) (((PASS) == ETH_PassControlFrames_BlockAll) || \
((PASS) == ETH_PassControlFrames_ForwardAll) || \
((PASS) == ETH_PassControlFrames_ForwardPassedAddrFilter))
* @}
*/
* @{
*/
#define ETH_BroadcastFramesReception_Enable ((uint32_t)0x00000000)
#define ETH_BroadcastFramesReception_Disable ((uint32_t)0x00000020)
#define IS_ETH_BROADCAST_FRAMES_RECEPTION(CMD) (((CMD) == ETH_BroadcastFramesReception_Enable) || \
((CMD) == ETH_BroadcastFramesReception_Disable))
* @}
*/
* @{
*/
#define ETH_DestinationAddrFilter_Normal ((uint32_t)0x00000000)
#define ETH_DestinationAddrFilter_Inverse ((uint32_t)0x00000008)
#define IS_ETH_DESTINATION_ADDR_FILTER(FILTER) (((FILTER) == ETH_DestinationAddrFilter_Normal) || \
((FILTER) == ETH_DestinationAddrFilter_Inverse))
* @}
*/
* @{
*/
#define ETH_PromiscuousMode_Enable ((uint32_t)0x00000001)
#define ETH_PromiscuousMode_Disable ((uint32_t)0x00000000)
#define IS_ETH_PROMISCUOUS_MODE(CMD) (((CMD) == ETH_PromiscuousMode_Enable) || \
((CMD) == ETH_PromiscuousMode_Disable))
* @}
*/
* @{
*/
#define ETH_MulticastFramesFilter_PerfectHashTable ((uint32_t)0x00000404)
#define ETH_MulticastFramesFilter_HashTable ((uint32_t)0x00000004)
#define ETH_MulticastFramesFilter_Perfect ((uint32_t)0x00000000)
#define ETH_MulticastFramesFilter_None ((uint32_t)0x00000010)
#define IS_ETH_MULTICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_MulticastFramesFilter_PerfectHashTable) || \
((FILTER) == ETH_MulticastFramesFilter_HashTable) || \
((FILTER) == ETH_MulticastFramesFilter_Perfect) || \
((FILTER) == ETH_MulticastFramesFilter_None))
* @}
*/
* @{
*/
#define ETH_UnicastFramesFilter_PerfectHashTable ((uint32_t)0x00000402)
#define ETH_UnicastFramesFilter_HashTable ((uint32_t)0x00000002)
#define ETH_UnicastFramesFilter_Perfect ((uint32_t)0x00000000)
#define IS_ETH_UNICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_UnicastFramesFilter_PerfectHashTable) || \
((FILTER) == ETH_UnicastFramesFilter_HashTable) || \
((FILTER) == ETH_UnicastFramesFilter_Perfect))
* @}
*/
* @{
*/
#define IS_ETH_PAUSE_TIME(TIME) ((TIME) <= 0xFFFF)
* @}
*/
* @{
*/
#define ETH_ZeroQuantaPause_Enable ((uint32_t)0x00000000)
#define ETH_ZeroQuantaPause_Disable ((uint32_t)0x00000080)
#define IS_ETH_ZEROQUANTA_PAUSE(CMD) (((CMD) == ETH_ZeroQuantaPause_Enable) || \
((CMD) == ETH_ZeroQuantaPause_Disable))
/**
* @}
*/
* @{
*/
#define ETH_PauseLowThreshold_Minus4 ((uint32_t)0x00000000) /*!< Pause time minus 4 slot times */
#define ETH_PauseLowThreshold_Minus28 ((uint32_t)0x00000010) /*!< Pause time minus 28 slot times */
#define ETH_PauseLowThreshold_Minus144 ((uint32_t)0x00000020) /*!< Pause time minus 144 slot times */
#define ETH_PauseLowThreshold_Minus256 ((uint32_t)0x00000030) /*!< Pause time minus 256 slot times */
#define IS_ETH_PAUSE_LOW_THRESHOLD(THRESHOLD) (((THRESHOLD) == ETH_PauseLowThreshold_Minus4) || \
((THRESHOLD) == ETH_PauseLowThreshold_Minus28) || \
((THRESHOLD) == ETH_PauseLowThreshold_Minus144) || \
((THRESHOLD) == ETH_PauseLowThreshold_Minus256))
* @}
*/
* @{
*/
#define ETH_UnicastPauseFrameDetect_Enable ((uint32_t)0x00000008)
#define ETH_UnicastPauseFrameDetect_Disable ((uint32_t)0x00000000)
#define IS_ETH_UNICAST_PAUSE_FRAME_DETECT(CMD) (((CMD) == ETH_UnicastPauseFrameDetect_Enable) || \
((CMD) == ETH_UnicastPauseFrameDetect_Disable))
* @}
*/
* @{
*/
#define ETH_ReceiveFlowControl_Enable ((uint32_t)0x00000004)
#define ETH_ReceiveFlowControl_Disable ((uint32_t)0x00000000)
#define IS_ETH_RECEIVE_FLOWCONTROL(CMD) (((CMD) == ETH_ReceiveFlowControl_Enable) || \
((CMD) == ETH_ReceiveFlowControl_Disable))
* @}
*/
* @{
*/
#define ETH_TransmitFlowControl_Enable ((uint32_t)0x00000002)
#define ETH_TransmitFlowControl_Disable ((uint32_t)0x00000000)
#define IS_ETH_TRANSMIT_FLOWCONTROL(CMD) (((CMD) == ETH_TransmitFlowControl_Enable) || \
((CMD) == ETH_TransmitFlowControl_Disable))
* @}
*/
* @{
*/
#define ETH_VLANTagComparison_12Bit ((uint32_t)0x00010000)
#define ETH_VLANTagComparison_16Bit ((uint32_t)0x00000000)
#define IS_ETH_VLAN_TAG_COMPARISON(COMPARISON) (((COMPARISON) == ETH_VLANTagComparison_12Bit) || \
((COMPARISON) == ETH_VLANTagComparison_16Bit))
#define IS_ETH_VLAN_TAG_IDENTIFIER(IDENTIFIER) ((IDENTIFIER) <= 0xFFFF)
* @}
*/
* @{
*/
#define ETH_MAC_FLAG_TST ((uint32_t)0x00000200) /*!< Time stamp trigger flag (on MAC) */
#define ETH_MAC_FLAG_MMCT ((uint32_t)0x00000040) /*!< MMC transmit flag */
#define ETH_MAC_FLAG_MMCR ((uint32_t)0x00000020) /*!< MMC receive flag */
#define ETH_MAC_FLAG_MMC ((uint32_t)0x00000010) /*!< MMC flag (on MAC) */
#define ETH_MAC_FLAG_PMT ((uint32_t)0x00000008) /*!< PMT flag (on MAC) */
#define IS_ETH_MAC_GET_FLAG(FLAG) (((FLAG) == ETH_MAC_FLAG_TST) || ((FLAG) == ETH_MAC_FLAG_MMCT) || \
((FLAG) == ETH_MAC_FLAG_MMCR) || ((FLAG) == ETH_MAC_FLAG_MMC) || \
((FLAG) == ETH_MAC_FLAG_PMT))
/**
* @}
*/
* @{
*/
#define ETH_MAC_IT_TST ((uint32_t)0x00000200) /*!< Time stamp trigger interrupt (on MAC) */
#define ETH_MAC_IT_MMCT ((uint32_t)0x00000040) /*!< MMC transmit interrupt */
#define ETH_MAC_IT_MMCR ((uint32_t)0x00000020) /*!< MMC receive interrupt */
#define ETH_MAC_IT_MMC ((uint32_t)0x00000010) /*!< MMC interrupt (on MAC) */
#define ETH_MAC_IT_PMT ((uint32_t)0x00000008) /*!< PMT interrupt (on MAC) */
#define IS_ETH_MAC_IT(IT) ((((IT) & (uint32_t)0xFFFFFDF7) == 0x00) && ((IT) != 0x00))
#define IS_ETH_MAC_GET_IT(IT) (((IT) == ETH_MAC_IT_TST) || ((IT) == ETH_MAC_IT_MMCT) || \
((IT) == ETH_MAC_IT_MMCR) || ((IT) == ETH_MAC_IT_MMC) || \
((IT) == ETH_MAC_IT_PMT))
/**
* @}
*/
* @{
*/
#define ETH_MAC_Address0 ((uint32_t)0x00000000)
#define ETH_MAC_Address1 ((uint32_t)0x00000008)
#define ETH_MAC_Address2 ((uint32_t)0x00000010)
#define ETH_MAC_Address3 ((uint32_t)0x00000018)
#define IS_ETH_MAC_ADDRESS0123(ADDRESS) (((ADDRESS) == ETH_MAC_Address0) || \
((ADDRESS) == ETH_MAC_Address1) || \
((ADDRESS) == ETH_MAC_Address2) || \
((ADDRESS) == ETH_MAC_Address3))
#define IS_ETH_MAC_ADDRESS123(ADDRESS) (((ADDRESS) == ETH_MAC_Address1) || \
((ADDRESS) == ETH_MAC_Address2) || \
((ADDRESS) == ETH_MAC_Address3))
/**
* @}
*/
* @{
*/
#define ETH_MAC_AddressFilter_SA ((uint32_t)0x00000000)
#define ETH_MAC_AddressFilter_DA ((uint32_t)0x00000008)
#define IS_ETH_MAC_ADDRESS_FILTER(FILTER) (((FILTER) == ETH_MAC_AddressFilter_SA) || \
((FILTER) == ETH_MAC_AddressFilter_DA))
/**
* @}
*/
* @{
*/
#define ETH_MAC_AddressMask_Byte6 ((uint32_t)0x20000000) /*!< Mask MAC Address high reg bits [15:8] */
#define ETH_MAC_AddressMask_Byte5 ((uint32_t)0x10000000) /*!< Mask MAC Address high reg bits [7:0] */
#define ETH_MAC_AddressMask_Byte4 ((uint32_t)0x08000000) /*!< Mask MAC Address low reg bits [31:24] */
#define ETH_MAC_AddressMask_Byte3 ((uint32_t)0x04000000) /*!< Mask MAC Address low reg bits [23:16] */
#define ETH_MAC_AddressMask_Byte2 ((uint32_t)0x02000000) /*!< Mask MAC Address low reg bits [15:8] */
#define ETH_MAC_AddressMask_Byte1 ((uint32_t)0x01000000) /*!< Mask MAC Address low reg bits [70] */
#define IS_ETH_MAC_ADDRESS_MASK(MASK) (((MASK) == ETH_MAC_AddressMask_Byte6) || \
((MASK) == ETH_MAC_AddressMask_Byte5) || \
((MASK) == ETH_MAC_AddressMask_Byte4) || \
((MASK) == ETH_MAC_AddressMask_Byte3) || \
((MASK) == ETH_MAC_AddressMask_Byte2) || \
((MASK) == ETH_MAC_AddressMask_Byte1))
/**
* @brief Ethernet DMA Descriptors defines
*/
/**--------------------------------------------------------------------------**/
/**
* @}
*/
* @{
*/
#define IS_ETH_DMATxDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMATxDesc_OWN) || \
((FLAG) == ETH_DMATxDesc_IC) || \
((FLAG) == ETH_DMATxDesc_LS) || \
((FLAG) == ETH_DMATxDesc_FS) || \
((FLAG) == ETH_DMATxDesc_DC) || \
((FLAG) == ETH_DMATxDesc_DP) || \
((FLAG) == ETH_DMATxDesc_TTSE) || \
((FLAG) == ETH_DMATxDesc_TER) || \
((FLAG) == ETH_DMATxDesc_TCH) || \
((FLAG) == ETH_DMATxDesc_TTSS) || \
((FLAG) == ETH_DMATxDesc_IHE) || \
((FLAG) == ETH_DMATxDesc_ES) || \
((FLAG) == ETH_DMATxDesc_JT) || \
((FLAG) == ETH_DMATxDesc_FF) || \
((FLAG) == ETH_DMATxDesc_PCE) || \
((FLAG) == ETH_DMATxDesc_LCA) || \
((FLAG) == ETH_DMATxDesc_NC) || \
((FLAG) == ETH_DMATxDesc_LCO) || \
((FLAG) == ETH_DMATxDesc_EC) || \
((FLAG) == ETH_DMATxDesc_VF) || \
((FLAG) == ETH_DMATxDesc_CC) || \
((FLAG) == ETH_DMATxDesc_ED) || \
((FLAG) == ETH_DMATxDesc_UF) || \
((FLAG) == ETH_DMATxDesc_DB))
* @}
*/
* @{
*/
#define ETH_DMATxDesc_LastSegment ((uint32_t)0x40000000) /*!< Last Segment */
#define ETH_DMATxDesc_FirstSegment ((uint32_t)0x20000000) /*!< First Segment */
#define IS_ETH_DMA_TXDESC_SEGMENT(SEGMENT) (((SEGMENT) == ETH_DMATxDesc_LastSegment) || \
((SEGMENT) == ETH_DMATxDesc_FirstSegment))
* @}
*/
* @{
*/
#define ETH_DMATxDesc_ChecksumByPass ((uint32_t)0x00000000) /*!< Checksum engine bypass */
#define ETH_DMATxDesc_ChecksumIPV4Header ((uint32_t)0x00400000) /*!< IPv4 header checksum insertion */
#define ETH_DMATxDesc_ChecksumTCPUDPICMPSegment ((uint32_t)0x00800000) /*!< TCP/UDP/ICMP checksum insertion. Pseudo header checksum is assumed to be present */
#define ETH_DMATxDesc_ChecksumTCPUDPICMPFull ((uint32_t)0x00C00000) /*!< TCP/UDP/ICMP checksum fully in hardware including pseudo header */
#define IS_ETH_DMA_TXDESC_CHECKSUM(CHECKSUM) (((CHECKSUM) == ETH_DMATxDesc_ChecksumByPass) || \
((CHECKSUM) == ETH_DMATxDesc_ChecksumIPV4Header) || \
((CHECKSUM) == ETH_DMATxDesc_ChecksumTCPUDPICMPSegment) || \
((CHECKSUM) == ETH_DMATxDesc_ChecksumTCPUDPICMPFull))
/**
* @brief ETH DMA Tx Desciptor buffer size
*/
#define IS_ETH_DMATxDESC_BUFFER_SIZE(SIZE) ((SIZE) <= 0x1FFF)
* @}
*/
* @{
*/
#define IS_ETH_DMARxDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMARxDesc_OWN) || \
((FLAG) == ETH_DMARxDesc_AFM) || \
((FLAG) == ETH_DMARxDesc_ES) || \
((FLAG) == ETH_DMARxDesc_DE) || \
((FLAG) == ETH_DMARxDesc_SAF) || \
((FLAG) == ETH_DMARxDesc_LE) || \
((FLAG) == ETH_DMARxDesc_OE) || \
((FLAG) == ETH_DMARxDesc_VLAN) || \
((FLAG) == ETH_DMARxDesc_FS) || \
((FLAG) == ETH_DMARxDesc_LS) || \
((FLAG) == ETH_DMARxDesc_IPV4HCE) || \
((FLAG) == ETH_DMARxDesc_LC) || \
((FLAG) == ETH_DMARxDesc_FT) || \
((FLAG) == ETH_DMARxDesc_RWT) || \
((FLAG) == ETH_DMARxDesc_RE) || \
((FLAG) == ETH_DMARxDesc_DBE) || \
((FLAG) == ETH_DMARxDesc_CE) || \
((FLAG) == ETH_DMARxDesc_MAMPCE))
#define IS_ETH_DMAPTPRxDESC_GET_EXTENDED_FLAG(FLAG) (((FLAG) == ETH_DMAPTPRxDesc_PTPV) || \
((FLAG) == ETH_DMAPTPRxDesc_PTPFT) || \
((FLAG) == ETH_DMAPTPRxDesc_PTPMT) || \
((FLAG) == ETH_DMAPTPRxDesc_IPV6PR) || \
((FLAG) == ETH_DMAPTPRxDesc_IPV4PR) || \
((FLAG) == ETH_DMAPTPRxDesc_IPCB) || \
((FLAG) == ETH_DMAPTPRxDesc_IPPE) || \
((FLAG) == ETH_DMAPTPRxDesc_IPHE) || \
((FLAG) == ETH_DMAPTPRxDesc_IPPT))
* @}
*/
* @{
*/
#define ETH_DMARxDesc_Buffer1 ((uint32_t)0x00000000) /*!< DMA Rx Desc Buffer1 */
#define ETH_DMARxDesc_Buffer2 ((uint32_t)0x00000001) /*!< DMA Rx Desc Buffer2 */
#define IS_ETH_DMA_RXDESC_BUFFER(BUFFER) (((BUFFER) == ETH_DMARxDesc_Buffer1) || \
((BUFFER) == ETH_DMARxDesc_Buffer2))
/**
* @brief Ethernet DMA defines
*/
/**--------------------------------------------------------------------------**/
/**
* @}
*/
* @{
*/
#define ETH_DropTCPIPChecksumErrorFrame_Enable ((uint32_t)0x00000000)
#define ETH_DropTCPIPChecksumErrorFrame_Disable ((uint32_t)0x04000000)
#define IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(CMD) (((CMD) == ETH_DropTCPIPChecksumErrorFrame_Enable) || \
((CMD) == ETH_DropTCPIPChecksumErrorFrame_Disable))
/**
* @}
*/
* @{
*/
#define ETH_ReceiveStoreForward_Enable ((uint32_t)0x02000000)
#define ETH_ReceiveStoreForward_Disable ((uint32_t)0x00000000)
#define IS_ETH_RECEIVE_STORE_FORWARD(CMD) (((CMD) == ETH_ReceiveStoreForward_Enable) || \
((CMD) == ETH_ReceiveStoreForward_Disable))
/**
* @}
*/
* @{
*/
#define ETH_FlushReceivedFrame_Enable ((uint32_t)0x00000000)
#define ETH_FlushReceivedFrame_Disable ((uint32_t)0x01000000)
#define IS_ETH_FLUSH_RECEIVE_FRAME(CMD) (((CMD) == ETH_FlushReceivedFrame_Enable) || \
((CMD) == ETH_FlushReceivedFrame_Disable))
/**
* @}
*/
* @{
*/
#define ETH_TransmitStoreForward_Enable ((uint32_t)0x00200000)
#define ETH_TransmitStoreForward_Disable ((uint32_t)0x00000000)
#define IS_ETH_TRANSMIT_STORE_FORWARD(CMD) (((CMD) == ETH_TransmitStoreForward_Enable) || \
((CMD) == ETH_TransmitStoreForward_Disable))
/**
* @}
*/
* @{
*/
#define ETH_TransmitThresholdControl_64Bytes ((uint32_t)0x00000000) /*!< threshold level of the MTL Transmit FIFO is 64 Bytes */
#define ETH_TransmitThresholdControl_128Bytes ((uint32_t)0x00004000) /*!< threshold level of the MTL Transmit FIFO is 128 Bytes */
#define ETH_TransmitThresholdControl_192Bytes ((uint32_t)0x00008000) /*!< threshold level of the MTL Transmit FIFO is 192 Bytes */
#define ETH_TransmitThresholdControl_256Bytes ((uint32_t)0x0000C000) /*!< threshold level of the MTL Transmit FIFO is 256 Bytes */
#define ETH_TransmitThresholdControl_40Bytes ((uint32_t)0x00010000) /*!< threshold level of the MTL Transmit FIFO is 40 Bytes */
#define ETH_TransmitThresholdControl_32Bytes ((uint32_t)0x00014000) /*!< threshold level of the MTL Transmit FIFO is 32 Bytes */
#define ETH_TransmitThresholdControl_24Bytes ((uint32_t)0x00018000) /*!< threshold level of the MTL Transmit FIFO is 24 Bytes */
#define ETH_TransmitThresholdControl_16Bytes ((uint32_t)0x0001C000) /*!< threshold level of the MTL Transmit FIFO is 16 Bytes */
#define IS_ETH_TRANSMIT_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_TransmitThresholdControl_64Bytes) || \
((THRESHOLD) == ETH_TransmitThresholdControl_128Bytes) || \
((THRESHOLD) == ETH_TransmitThresholdControl_192Bytes) || \
((THRESHOLD) == ETH_TransmitThresholdControl_256Bytes) || \
((THRESHOLD) == ETH_TransmitThresholdControl_40Bytes) || \
((THRESHOLD) == ETH_TransmitThresholdControl_32Bytes) || \
((THRESHOLD) == ETH_TransmitThresholdControl_24Bytes) || \
((THRESHOLD) == ETH_TransmitThresholdControl_16Bytes))
/**
* @}
*/
* @{
*/
#define ETH_ForwardErrorFrames_Enable ((uint32_t)0x00000080)
#define ETH_ForwardErrorFrames_Disable ((uint32_t)0x00000000)
#define IS_ETH_FORWARD_ERROR_FRAMES(CMD) (((CMD) == ETH_ForwardErrorFrames_Enable) || \
((CMD) == ETH_ForwardErrorFrames_Disable))
/**
* @}
*/
* @{
*/
#define ETH_ForwardUndersizedGoodFrames_Enable ((uint32_t)0x00000040)
#define ETH_ForwardUndersizedGoodFrames_Disable ((uint32_t)0x00000000)
#define IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(CMD) (((CMD) == ETH_ForwardUndersizedGoodFrames_Enable) || \
((CMD) == ETH_ForwardUndersizedGoodFrames_Disable))
* @}
*/
* @{
*/
#define ETH_ReceiveThresholdControl_64Bytes ((uint32_t)0x00000000) /*!< threshold level of the MTL Receive FIFO is 64 Bytes */
#define ETH_ReceiveThresholdControl_32Bytes ((uint32_t)0x00000008) /*!< threshold level of the MTL Receive FIFO is 32 Bytes */
#define ETH_ReceiveThresholdControl_96Bytes ((uint32_t)0x00000010) /*!< threshold level of the MTL Receive FIFO is 96 Bytes */
#define ETH_ReceiveThresholdControl_128Bytes ((uint32_t)0x00000018) /*!< threshold level of the MTL Receive FIFO is 128 Bytes */
#define IS_ETH_RECEIVE_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_ReceiveThresholdControl_64Bytes) || \
((THRESHOLD) == ETH_ReceiveThresholdControl_32Bytes) || \
((THRESHOLD) == ETH_ReceiveThresholdControl_96Bytes) || \
((THRESHOLD) == ETH_ReceiveThresholdControl_128Bytes))
/**
* @}
*/
* @{
*/
#define ETH_SecondFrameOperate_Enable ((uint32_t)0x00000004)
#define ETH_SecondFrameOperate_Disable ((uint32_t)0x00000000)
#define IS_ETH_SECOND_FRAME_OPERATE(CMD) (((CMD) == ETH_SecondFrameOperate_Enable) || \
((CMD) == ETH_SecondFrameOperate_Disable))
* @}
*/
* @{
*/
#define ETH_AddressAlignedBeats_Enable ((uint32_t)0x02000000)
#define ETH_AddressAlignedBeats_Disable ((uint32_t)0x00000000)
#define IS_ETH_ADDRESS_ALIGNED_BEATS(CMD) (((CMD) == ETH_AddressAlignedBeats_Enable) || \
((CMD) == ETH_AddressAlignedBeats_Disable))
* @}
*/
* @{
*/
#define ETH_FixedBurst_Enable ((uint32_t)0x00010000)
#define ETH_FixedBurst_Disable ((uint32_t)0x00000000)
#define IS_ETH_FIXED_BURST(CMD) (((CMD) == ETH_FixedBurst_Enable) || \
((CMD) == ETH_FixedBurst_Disable))
* @}
*/
* @{
*/
#define ETH_RxDMABurstLength_1Beat ((uint32_t)0x00020000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 1 */
#define ETH_RxDMABurstLength_2Beat ((uint32_t)0x00040000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 2 */
#define ETH_RxDMABurstLength_4Beat ((uint32_t)0x00080000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */
#define ETH_RxDMABurstLength_8Beat ((uint32_t)0x00100000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */
#define ETH_RxDMABurstLength_16Beat ((uint32_t)0x00200000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */
#define ETH_RxDMABurstLength_32Beat ((uint32_t)0x00400000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */
#define ETH_RxDMABurstLength_4xPBL_4Beat ((uint32_t)0x01020000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */
#define ETH_RxDMABurstLength_4xPBL_8Beat ((uint32_t)0x01040000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */
#define ETH_RxDMABurstLength_4xPBL_16Beat ((uint32_t)0x01080000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */
#define ETH_RxDMABurstLength_4xPBL_32Beat ((uint32_t)0x01100000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */
#define ETH_RxDMABurstLength_4xPBL_64Beat ((uint32_t)0x01200000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 64 */
#define ETH_RxDMABurstLength_4xPBL_128Beat ((uint32_t)0x01400000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 128 */
((LENGTH) == ETH_RxDMABurstLength_2Beat) || \
((LENGTH) == ETH_RxDMABurstLength_4Beat) || \
((LENGTH) == ETH_RxDMABurstLength_8Beat) || \
((LENGTH) == ETH_RxDMABurstLength_16Beat) || \
((LENGTH) == ETH_RxDMABurstLength_32Beat) || \
((LENGTH) == ETH_RxDMABurstLength_4xPBL_4Beat) || \
((LENGTH) == ETH_RxDMABurstLength_4xPBL_8Beat) || \
((LENGTH) == ETH_RxDMABurstLength_4xPBL_16Beat) || \
((LENGTH) == ETH_RxDMABurstLength_4xPBL_32Beat) || \
((LENGTH) == ETH_RxDMABurstLength_4xPBL_64Beat) || \
((LENGTH) == ETH_RxDMABurstLength_4xPBL_128Beat))
/**
* @}
*/
* @{
*/
#define ETH_TxDMABurstLength_1Beat ((uint32_t)0x00000100) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
#define ETH_TxDMABurstLength_2Beat ((uint32_t)0x00000200) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
#define ETH_TxDMABurstLength_4Beat ((uint32_t)0x00000400) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
#define ETH_TxDMABurstLength_8Beat ((uint32_t)0x00000800) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
#define ETH_TxDMABurstLength_16Beat ((uint32_t)0x00001000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
#define ETH_TxDMABurstLength_32Beat ((uint32_t)0x00002000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
#define ETH_TxDMABurstLength_4xPBL_4Beat ((uint32_t)0x01000100) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
#define ETH_TxDMABurstLength_4xPBL_8Beat ((uint32_t)0x01000200) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
#define ETH_TxDMABurstLength_4xPBL_16Beat ((uint32_t)0x01000400) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
#define ETH_TxDMABurstLength_4xPBL_32Beat ((uint32_t)0x01000800) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
#define ETH_TxDMABurstLength_4xPBL_64Beat ((uint32_t)0x01001000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */
#define ETH_TxDMABurstLength_4xPBL_128Beat ((uint32_t)0x01002000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */
((LENGTH) == ETH_TxDMABurstLength_2Beat) || \
((LENGTH) == ETH_TxDMABurstLength_4Beat) || \
((LENGTH) == ETH_TxDMABurstLength_8Beat) || \
((LENGTH) == ETH_TxDMABurstLength_16Beat) || \
((LENGTH) == ETH_TxDMABurstLength_32Beat) || \
((LENGTH) == ETH_TxDMABurstLength_4xPBL_4Beat) || \
((LENGTH) == ETH_TxDMABurstLength_4xPBL_8Beat) || \
((LENGTH) == ETH_TxDMABurstLength_4xPBL_16Beat) || \
((LENGTH) == ETH_TxDMABurstLength_4xPBL_32Beat) || \
((LENGTH) == ETH_TxDMABurstLength_4xPBL_64Beat) || \
((LENGTH) == ETH_TxDMABurstLength_4xPBL_128Beat))
/**
* @brief ETH DMA Descriptor SkipLength
*/
#define IS_ETH_DMA_DESC_SKIP_LENGTH(LENGTH) ((LENGTH) <= 0x1F)
* @}
*/
* @{
*/
#define ETH_DMAArbitration_RoundRobin_RxTx_1_1 ((uint32_t)0x00000000)
#define ETH_DMAArbitration_RoundRobin_RxTx_2_1 ((uint32_t)0x00004000)
#define ETH_DMAArbitration_RoundRobin_RxTx_3_1 ((uint32_t)0x00008000)
#define ETH_DMAArbitration_RoundRobin_RxTx_4_1 ((uint32_t)0x0000C000)
#define ETH_DMAArbitration_RxPriorTx ((uint32_t)0x00000002)
#define IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(RATIO) (((RATIO) == ETH_DMAArbitration_RoundRobin_RxTx_1_1) || \
((RATIO) == ETH_DMAArbitration_RoundRobin_RxTx_2_1) || \
((RATIO) == ETH_DMAArbitration_RoundRobin_RxTx_3_1) || \
((RATIO) == ETH_DMAArbitration_RoundRobin_RxTx_4_1) || \
((RATIO) == ETH_DMAArbitration_RxPriorTx))
/**
* @}
*/
* @{
*/
#define ETH_DMA_FLAG_TST ((uint32_t)0x20000000) /*!< Time-stamp trigger interrupt (on DMA) */
#define ETH_DMA_FLAG_PMT ((uint32_t)0x10000000) /*!< PMT interrupt (on DMA) */
#define ETH_DMA_FLAG_MMC ((uint32_t)0x08000000) /*!< MMC interrupt (on DMA) */
#define ETH_DMA_FLAG_DataTransferError ((uint32_t)0x00800000) /*!< Error bits 0-Rx DMA, 1-Tx DMA */
#define ETH_DMA_FLAG_ReadWriteError ((uint32_t)0x01000000) /*!< Error bits 0-write trnsf, 1-read transfr */
#define ETH_DMA_FLAG_AccessError ((uint32_t)0x02000000) /*!< Error bits 0-data buffer, 1-desc. access */
#define ETH_DMA_FLAG_NIS ((uint32_t)0x00010000) /*!< Normal interrupt summary flag */
#define ETH_DMA_FLAG_AIS ((uint32_t)0x00008000) /*!< Abnormal interrupt summary flag */
#define ETH_DMA_FLAG_ER ((uint32_t)0x00004000) /*!< Early receive flag */
#define ETH_DMA_FLAG_FBE ((uint32_t)0x00002000) /*!< Fatal bus error flag */
#define ETH_DMA_FLAG_ET ((uint32_t)0x00000400) /*!< Early transmit flag */
#define ETH_DMA_FLAG_RWT ((uint32_t)0x00000200) /*!< Receive watchdog timeout flag */
#define ETH_DMA_FLAG_RPS ((uint32_t)0x00000100) /*!< Receive process stopped flag */
#define ETH_DMA_FLAG_RBU ((uint32_t)0x00000080) /*!< Receive buffer unavailable flag */
#define ETH_DMA_FLAG_R ((uint32_t)0x00000040) /*!< Receive flag */
#define ETH_DMA_FLAG_TU ((uint32_t)0x00000020) /*!< Underflow flag */
#define ETH_DMA_FLAG_RO ((uint32_t)0x00000010) /*!< Overflow flag */
#define ETH_DMA_FLAG_TJT ((uint32_t)0x00000008) /*!< Transmit jabber timeout flag */
#define ETH_DMA_FLAG_TBU ((uint32_t)0x00000004) /*!< Transmit buffer unavailable flag */
#define ETH_DMA_FLAG_TPS ((uint32_t)0x00000002) /*!< Transmit process stopped flag */
#define ETH_DMA_FLAG_T ((uint32_t)0x00000001) /*!< Transmit flag */
#define IS_ETH_DMA_GET_FLAG(FLAG) (((FLAG) == ETH_DMA_FLAG_TST) || ((FLAG) == ETH_DMA_FLAG_PMT) || \
((FLAG) == ETH_DMA_FLAG_MMC) || ((FLAG) == ETH_DMA_FLAG_DataTransferError) || \
((FLAG) == ETH_DMA_FLAG_ReadWriteError) || ((FLAG) == ETH_DMA_FLAG_AccessError) || \
((FLAG) == ETH_DMA_FLAG_NIS) || ((FLAG) == ETH_DMA_FLAG_AIS) || \
((FLAG) == ETH_DMA_FLAG_ER) || ((FLAG) == ETH_DMA_FLAG_FBE) || \
((FLAG) == ETH_DMA_FLAG_ET) || ((FLAG) == ETH_DMA_FLAG_RWT) || \
((FLAG) == ETH_DMA_FLAG_RPS) || ((FLAG) == ETH_DMA_FLAG_RBU) || \
((FLAG) == ETH_DMA_FLAG_R) || ((FLAG) == ETH_DMA_FLAG_TU) || \
((FLAG) == ETH_DMA_FLAG_RO) || ((FLAG) == ETH_DMA_FLAG_TJT) || \
((FLAG) == ETH_DMA_FLAG_TBU) || ((FLAG) == ETH_DMA_FLAG_TPS) || \
((FLAG) == ETH_DMA_FLAG_T))
/**
* @}
*/
* @{
*/
#define ETH_DMA_IT_TST ((uint32_t)0x20000000) /*!< Time-stamp trigger interrupt (on DMA) */
#define ETH_DMA_IT_PMT ((uint32_t)0x10000000) /*!< PMT interrupt (on DMA) */
#define ETH_DMA_IT_MMC ((uint32_t)0x08000000) /*!< MMC interrupt (on DMA) */
#define ETH_DMA_IT_NIS ((uint32_t)0x00010000) /*!< Normal interrupt summary */
#define ETH_DMA_IT_AIS ((uint32_t)0x00008000) /*!< Abnormal interrupt summary */
#define ETH_DMA_IT_ER ((uint32_t)0x00004000) /*!< Early receive interrupt */
#define ETH_DMA_IT_FBE ((uint32_t)0x00002000) /*!< Fatal bus error interrupt */
#define ETH_DMA_IT_ET ((uint32_t)0x00000400) /*!< Early transmit interrupt */
#define ETH_DMA_IT_RWT ((uint32_t)0x00000200) /*!< Receive watchdog timeout interrupt */
#define ETH_DMA_IT_RPS ((uint32_t)0x00000100) /*!< Receive process stopped interrupt */
#define ETH_DMA_IT_RBU ((uint32_t)0x00000080) /*!< Receive buffer unavailable interrupt */
#define ETH_DMA_IT_R ((uint32_t)0x00000040) /*!< Receive interrupt */
#define ETH_DMA_IT_TU ((uint32_t)0x00000020) /*!< Underflow interrupt */
#define ETH_DMA_IT_RO ((uint32_t)0x00000010) /*!< Overflow interrupt */
#define ETH_DMA_IT_TJT ((uint32_t)0x00000008) /*!< Transmit jabber timeout interrupt */
#define ETH_DMA_IT_TBU ((uint32_t)0x00000004) /*!< Transmit buffer unavailable interrupt */
#define ETH_DMA_IT_TPS ((uint32_t)0x00000002) /*!< Transmit process stopped interrupt */
#define ETH_DMA_IT_T ((uint32_t)0x00000001) /*!< Transmit interrupt */
#define IS_ETH_DMA_GET_IT(IT) (((IT) == ETH_DMA_IT_TST) || ((IT) == ETH_DMA_IT_PMT) || \
((IT) == ETH_DMA_IT_MMC) || ((IT) == ETH_DMA_IT_NIS) || \
((IT) == ETH_DMA_IT_AIS) || ((IT) == ETH_DMA_IT_ER) || \
((IT) == ETH_DMA_IT_FBE) || ((IT) == ETH_DMA_IT_ET) || \
((IT) == ETH_DMA_IT_RWT) || ((IT) == ETH_DMA_IT_RPS) || \
((IT) == ETH_DMA_IT_RBU) || ((IT) == ETH_DMA_IT_R) || \
((IT) == ETH_DMA_IT_TU) || ((IT) == ETH_DMA_IT_RO) || \
((IT) == ETH_DMA_IT_TJT) || ((IT) == ETH_DMA_IT_TBU) || \
((IT) == ETH_DMA_IT_TPS) || ((IT) == ETH_DMA_IT_T))
* @}
*/
* @{
*/
#define ETH_DMA_TransmitProcess_Stopped ((uint32_t)0x00000000) /*!< Stopped - Reset or Stop Tx Command issued */
#define ETH_DMA_TransmitProcess_Fetching ((uint32_t)0x00100000) /*!< Running - fetching the Tx descriptor */
#define ETH_DMA_TransmitProcess_Waiting ((uint32_t)0x00200000) /*!< Running - waiting for status */
#define ETH_DMA_TransmitProcess_Reading ((uint32_t)0x00300000) /*!< Running - reading the data from host memory */
#define ETH_DMA_TransmitProcess_Suspended ((uint32_t)0x00600000) /*!< Suspended - Tx Descriptor unavailable */
#define ETH_DMA_TransmitProcess_Closing ((uint32_t)0x00700000) /*!< Running - closing Rx descriptor */
* @}
*/
/** @defgroup ETH_DMA_receive_process_state_
* @{
*/
#define ETH_DMA_ReceiveProcess_Stopped ((uint32_t)0x00000000) /*!< Stopped - Reset or Stop Rx Command issued */
#define ETH_DMA_ReceiveProcess_Fetching ((uint32_t)0x00020000) /*!< Running - fetching the Rx descriptor */
#define ETH_DMA_ReceiveProcess_Waiting ((uint32_t)0x00060000) /*!< Running - waiting for packet */
#define ETH_DMA_ReceiveProcess_Suspended ((uint32_t)0x00080000) /*!< Suspended - Rx Descriptor unavailable */
#define ETH_DMA_ReceiveProcess_Closing ((uint32_t)0x000A0000) /*!< Running - closing descriptor */
#define ETH_DMA_ReceiveProcess_Queuing ((uint32_t)0x000E0000) /*!< Running - queuing the receive frame into host memory */
* @}
*/
* @{
*/
#define ETH_DMA_Overflow_RxFIFOCounter ((uint32_t)0x10000000) /*!< Overflow bit for FIFO overflow counter */
#define ETH_DMA_Overflow_MissedFrameCounter ((uint32_t)0x00010000) /*!< Overflow bit for missed frame counter */
#define IS_ETH_DMA_GET_OVERFLOW(OVERFLOW) (((OVERFLOW) == ETH_DMA_Overflow_RxFIFOCounter) || \
((OVERFLOW) == ETH_DMA_Overflow_MissedFrameCounter))
/**
* @brief Ethernet PMT defines
*/
/**--------------------------------------------------------------------------**/
/**
* @}
*/
* @{
*/
#define ETH_PMT_FLAG_WUFFRPR ((uint32_t)0x80000000) /*!< Wake-Up Frame Filter Register Pointer Reset */
#define ETH_PMT_FLAG_WUFR ((uint32_t)0x00000040) /*!< Wake-Up Frame Received */
#define ETH_PMT_FLAG_MPR ((uint32_t)0x00000020) /*!< Magic Packet Received */
#define IS_ETH_PMT_GET_FLAG(FLAG) (((FLAG) == ETH_PMT_FLAG_WUFR) || \
((FLAG) == ETH_PMT_FLAG_MPR))
/**
* @brief Ethernet MMC defines
*/
/**--------------------------------------------------------------------------**/
/**
* @}
*/
* @{
*/
#define ETH_MMC_IT_TGF ((uint32_t)0x00200000) /*!< When Tx good frame counter reaches half the maximum value */
#define ETH_MMC_IT_TGFMSC ((uint32_t)0x00008000) /*!< When Tx good multi col counter reaches half the maximum value */
#define ETH_MMC_IT_TGFSC ((uint32_t)0x00004000) /*!< When Tx good single col counter reaches half the maximum value */
* @}
*/
* @{
*/
#define ETH_MMC_IT_RGUF ((uint32_t)0x10020000) /*!< When Rx good unicast frames counter reaches half the maximum value */
#define ETH_MMC_IT_RFAE ((uint32_t)0x10000040) /*!< When Rx alignment error counter reaches half the maximum value */
#define ETH_MMC_IT_RFCE ((uint32_t)0x10000020) /*!< When Rx crc error counter reaches half the maximum value */
#define IS_ETH_MMC_IT(IT) (((((IT) & (uint32_t)0xFFDF3FFF) == 0x00) || (((IT) & (uint32_t)0xEFFDFF9F) == 0x00)) && \
((IT) != 0x00))
#define IS_ETH_MMC_GET_IT(IT) (((IT) == ETH_MMC_IT_TGF) || ((IT) == ETH_MMC_IT_TGFMSC) || \
((IT) == ETH_MMC_IT_TGFSC) || ((IT) == ETH_MMC_IT_RGUF) || \
((IT) == ETH_MMC_IT_RFAE) || ((IT) == ETH_MMC_IT_RFCE))
/**
* @}
*/
* @{
*/
#define ETH_MMCCR ((uint32_t)0x00000100) /*!< MMC CR register */
#define ETH_MMCRIR ((uint32_t)0x00000104) /*!< MMC RIR register */
#define ETH_MMCTIR ((uint32_t)0x00000108) /*!< MMC TIR register */
#define ETH_MMCRIMR ((uint32_t)0x0000010C) /*!< MMC RIMR register */
#define ETH_MMCTIMR ((uint32_t)0x00000110) /*!< MMC TIMR register */
#define ETH_MMCTGFSCCR ((uint32_t)0x0000014C) /*!< MMC TGFSCCR register */
#define ETH_MMCTGFMSCCR ((uint32_t)0x00000150) /*!< MMC TGFMSCCR register */
#define ETH_MMCTGFCR ((uint32_t)0x00000168) /*!< MMC TGFCR register */
#define ETH_MMCRFCECR ((uint32_t)0x00000194) /*!< MMC RFCECR register */
#define ETH_MMCRFAECR ((uint32_t)0x00000198) /*!< MMC RFAECR register */
#define ETH_MMCRGUFCR ((uint32_t)0x000001C4) /*!< MMC RGUFCR register */
* @brief ETH MMC registers
*/
#define IS_ETH_MMC_REGISTER(REG) (((REG) == ETH_MMCCR) || ((REG) == ETH_MMCRIR) || \
((REG) == ETH_MMCTIR) || ((REG) == ETH_MMCRIMR) || \
((REG) == ETH_MMCTIMR) || ((REG) == ETH_MMCTGFSCCR) || \
((REG) == ETH_MMCTGFMSCCR) || ((REG) == ETH_MMCTGFCR) || \
((REG) == ETH_MMCRFCECR) || ((REG) == ETH_MMCRFAECR) || \
((REG) == ETH_MMCRGUFCR))
/**
* @brief Ethernet PTP defines
*/
/**--------------------------------------------------------------------------**/
/**
* @}
*/
* @{
*/
#define ETH_PTP_FineUpdate ((uint32_t)0x00000001) /*!< Fine Update method */
#define ETH_PTP_CoarseUpdate ((uint32_t)0x00000000) /*!< Coarse Update method */
#define IS_ETH_PTP_UPDATE(UPDATE) (((UPDATE) == ETH_PTP_FineUpdate) || \
((UPDATE) == ETH_PTP_CoarseUpdate))
* @}
*/
/** @defgroup ETH_PTP_Flags
* @{
*/
#define ETH_PTP_FLAG_TSARU ((uint32_t)0x00000020) /*!< Addend Register Update */
#define ETH_PTP_FLAG_TSITE ((uint32_t)0x00000010) /*!< Time Stamp Interrupt Trigger */
#define ETH_PTP_FLAG_TSSTU ((uint32_t)0x00000008) /*!< Time Stamp Update */
#define ETH_PTP_FLAG_TSSTI ((uint32_t)0x00000004) /*!< Time Stamp Initialize */
#define ETH_PTP_FLAG_TSSO ((uint32_t)0x10000001) /* Time stamp seconds overflow */
((FLAG) == ETH_PTP_FLAG_TSITE) || \
((FLAG) == ETH_PTP_FLAG_TSSTU) || \
((FLAG) == ETH_PTP_FLAG_TSSTI) || \
((FLAG) == ETH_PTP_FLAG_TSTTR) || \
((FLAG) == ETH_PTP_FLAG_TSSO))
* @brief ETH PTP subsecond increment
*/
#define IS_ETH_PTP_SUBSECOND_INCREMENT(SUBSECOND) ((SUBSECOND) <= 0xFF)
* @}
*/
/** @defgroup ETH_PTP_time_sign
* @{
*/
#define ETH_PTP_PositiveTime ((uint32_t)0x00000000) /*!< Positive time value */
#define ETH_PTP_NegativeTime ((uint32_t)0x80000000) /*!< Negative time value */
#define IS_ETH_PTP_TIME_SIGN(SIGN) (((SIGN) == ETH_PTP_PositiveTime) || \
((SIGN) == ETH_PTP_NegativeTime))
* @brief ETH PTP time stamp low update
*/
#define IS_ETH_PTP_TIME_STAMP_UPDATE_SUBSECOND(SUBSECOND) ((SUBSECOND) <= 0x7FFFFFFF)
* @brief ETH PTP registers
*/
#define ETH_PTPTSCR ((uint32_t)0x00000700) /*!< PTP TSCR register */
#define ETH_PTPSSIR ((uint32_t)0x00000704) /*!< PTP SSIR register */
#define ETH_PTPTSHR ((uint32_t)0x00000708) /*!< PTP TSHR register */
#define ETH_PTPTSLR ((uint32_t)0x0000070C) /*!< PTP TSLR register */
#define ETH_PTPTSHUR ((uint32_t)0x00000710) /*!< PTP TSHUR register */
#define ETH_PTPTSLUR ((uint32_t)0x00000714) /*!< PTP TSLUR register */
#define ETH_PTPTSAR ((uint32_t)0x00000718) /*!< PTP TSAR register */
#define ETH_PTPTTHR ((uint32_t)0x0000071C) /*!< PTP TTHR register */
#define ETH_PTPTTLR ((uint32_t)0x00000720) /* PTP TTLR register */
((REG) == ETH_PTPTSHR) || ((REG) == ETH_PTPTSLR) || \
((REG) == ETH_PTPTSHUR) || ((REG) == ETH_PTPTSLUR) || \
((REG) == ETH_PTPTSAR) || ((REG) == ETH_PTPTTHR) || \
((REG) == ETH_PTPTTLR) || ((REG) == ETH_PTPTSSR))
* @brief ETHERNET PTP clock
*/
#define ETH_PTP_OrdinaryClock ((uint32_t)0x00000000) /* Ordinary Clock */
#define ETH_PTP_BoundaryClock ((uint32_t)0x00010000) /* Boundary Clock */
#define ETH_PTP_EndToEndTransparentClock ((uint32_t)0x00020000) /* End To End Transparent Clock */
#define ETH_PTP_PeerToPeerTransparentClock ((uint32_t)0x00030000) /* Peer To Peer Transparent Clock */
((CLOCK) == ETH_PTP_BoundaryClock) || \
((CLOCK) == ETH_PTP_EndToEndTransparentClock) || \
((CLOCK) == ETH_PTP_PeerToPeerTransparentClock))
/**
* @brief ETHERNET snapshot
*/
#define ETH_PTP_SnapshotMasterMessage ((uint32_t)0x00008000) /* Time stamp snapshot for message relevant to master enable */
#define ETH_PTP_SnapshotEventMessage ((uint32_t)0x00004000) /* Time stamp snapshot for event message enable */
#define ETH_PTP_SnapshotIPV4Frames ((uint32_t)0x00002000) /* Time stamp snapshot for IPv4 frames enable */
#define ETH_PTP_SnapshotIPV6Frames ((uint32_t)0x00001000) /* Time stamp snapshot for IPv6 frames enable */
#define ETH_PTP_SnapshotPTPOverEthernetFrames ((uint32_t)0x00000800) /* Time stamp snapshot for PTP over ethernet frames enable */
#define ETH_PTP_SnapshotAllReceivedFrames ((uint32_t)0x00000100) /* Time stamp snapshot for all received frames enable */
((SNAPSHOT) == ETH_PTP_SnapshotEventMessage) || \
((SNAPSHOT) == ETH_PTP_SnapshotIPV4Frames) || \
((SNAPSHOT) == ETH_PTP_SnapshotIPV6Frames) || \
((SNAPSHOT) == ETH_PTP_SnapshotPTPOverEthernetFrames) || \
((SNAPSHOT) == ETH_PTP_SnapshotAllReceivedFrames))
* @}
*/
/* ETHERNET MAC address offsets */
#define ETH_MAC_ADDR_HBASE (ETH_MAC_BASE + 0x40) /* ETHERNET MAC address high offset */
#define ETH_MAC_ADDR_LBASE (ETH_MAC_BASE + 0x44) /* ETHERNET MAC address low offset */
#define MACMIIAR_CR_MASK ((uint32_t)0xFFFFFFE3)
#define MACCR_CLEAR_MASK ((uint32_t)0xFF20810F)
#define MACFCR_CLEAR_MASK ((uint32_t)0x0000FF41)
/* ETHERNET DMAOMR register Mask */
#define DMAOMR_CLEAR_MASK ((uint32_t)0xF8DE3F23)
/* ETHERNET Remote Wake-up frame register length */
#define ETH_WAKEUP_REGISTER_LENGTH 8
#define ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT 17
#define ETH_DMATXDESC_COLLISION_COUNTSHIFT 3
#define ETH_DMATXDESC_BUFFER2_SIZESHIFT 16
#define ETH_DMARXDESC_FRAME_LENGTHSHIFT 16
#define ETH_DMARXDESC_BUFFER2_SIZESHIFT 16
#define ETH_ERROR ((uint32_t)0)
#define ETH_SUCCESS ((uint32_t)1)
* @}
*/
* @{
*/
/**
* @}
*/
* @{
*/
void ETH_DeInit(void);
uint32_t ETH_Init(ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress);
void ETH_StructInit(ETH_InitTypeDef* ETH_InitStruct);
void ETH_SoftwareReset(void);
FlagStatus ETH_GetSoftwareResetStatus(void);
void ETH_Start(void);
uint32_t ETH_GetRxPktSize(ETH_DMADESCTypeDef *DMARxDesc);
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
void ETH_EnhancedDescriptorCmd(FunctionalState NewState);
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
* @brief PHY
*/
uint16_t ETH_ReadPHYRegister(uint16_t PHYAddress, uint16_t PHYReg);
uint32_t ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue);
uint32_t ETH_PHYLoopBackCmd(uint16_t PHYAddress, FunctionalState NewState);
* @brief MAC
*/
void ETH_MACTransmissionCmd(FunctionalState NewState);
void ETH_MACReceptionCmd(FunctionalState NewState);
FlagStatus ETH_GetFlowControlBusyStatus(void);
void ETH_InitiatePauseControlFrame(void);
void ETH_BackPressureActivationCmd(FunctionalState NewState);
FlagStatus ETH_GetMACFlagStatus(uint32_t ETH_MAC_FLAG);
ITStatus ETH_GetMACITStatus(uint32_t ETH_MAC_IT);
void ETH_MACITConfig(uint32_t ETH_MAC_IT, FunctionalState NewState);
void ETH_MACAddressConfig(uint32_t MacAddr, uint8_t *Addr);
void ETH_GetMACAddress(uint32_t MacAddr, uint8_t *Addr);
void ETH_MACAddressPerfectFilterCmd(uint32_t MacAddr, FunctionalState NewState);
void ETH_MACAddressFilterConfig(uint32_t MacAddr, uint32_t Filter);
void ETH_MACAddressMaskBytesFilterConfig(uint32_t MacAddr, uint32_t MaskByte);
* @brief DMA Tx/Rx descriptors
*/
void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount);
void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount);
uint32_t ETH_CheckFrameReceived(void);
uint32_t ETH_Prepare_Transmit_Descriptors(u16 FrameLength);
FrameTypeDef ETH_Get_Received_Frame(void);
FlagStatus ETH_GetDMATxDescFlagStatus(ETH_DMADESCTypeDef *DMATxDesc, uint32_t ETH_DMATxDescFlag);
uint32_t ETH_GetDMATxDescCollisionCount(ETH_DMADESCTypeDef *DMATxDesc);
void ETH_SetDMATxDescOwnBit(ETH_DMADESCTypeDef *DMATxDesc);
void ETH_DMATxDescTransmitITConfig(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState);
void ETH_DMATxDescFrameSegmentConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_FrameSegment);
void ETH_DMATxDescChecksumInsertionConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_Checksum);
void ETH_DMATxDescCRCCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState);
void ETH_DMATxDescSecondAddressChainedCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState);
void ETH_DMATxDescShortFramePaddingCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState);
void ETH_DMATxDescBufferSizeConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t BufferSize1, uint32_t BufferSize2);
FlagStatus ETH_GetDMARxDescFlagStatus(ETH_DMADESCTypeDef *DMARxDesc, uint32_t ETH_DMARxDescFlag);
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
FlagStatus ETH_GetDMAPTPRxDescExtendedFlagStatus(ETH_DMADESCTypeDef *DMAPTPRxDesc, uint32_t ETH_DMAPTPRxDescExtendedFlag);
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
void ETH_SetDMARxDescOwnBit(ETH_DMADESCTypeDef *DMARxDesc);
uint32_t ETH_GetDMARxDescFrameLength(ETH_DMADESCTypeDef *DMARxDesc);
void ETH_DMARxDescReceiveITConfig(ETH_DMADESCTypeDef *DMARxDesc, FunctionalState NewState);
void ETH_DMARxDescSecondAddressChainedCmd(ETH_DMADESCTypeDef *DMARxDesc, FunctionalState NewState);
uint32_t ETH_GetDMARxDescBufferSize(ETH_DMADESCTypeDef *DMARxDesc, uint32_t DMARxDesc_Buffer);
FrameTypeDef ETH_Get_Received_Frame_interrupt(void);
/**
* @brief DMA
*/
FlagStatus ETH_GetDMAFlagStatus(uint32_t ETH_DMA_FLAG);
void ETH_DMAClearFlag(uint32_t ETH_DMA_FLAG);
ITStatus ETH_GetDMAITStatus(uint32_t ETH_DMA_IT);
void ETH_DMAClearITPendingBit(uint32_t ETH_DMA_IT);
uint32_t ETH_GetTransmitProcessState(void);
uint32_t ETH_GetReceiveProcessState(void);
void ETH_FlushTransmitFIFO(void);
FlagStatus ETH_GetFlushTransmitFIFOStatus(void);
void ETH_DMATransmissionCmd(FunctionalState NewState);
void ETH_DMAReceptionCmd(FunctionalState NewState);
void ETH_DMAITConfig(uint32_t ETH_DMA_IT, FunctionalState NewState);
FlagStatus ETH_GetDMAOverflowStatus(uint32_t ETH_DMA_Overflow);
uint32_t ETH_GetRxOverflowMissedFrameCounter(void);
uint32_t ETH_GetBufferUnavailableMissedFrameCounter(void);
uint32_t ETH_GetCurrentTxDescStartAddress(void);
uint32_t ETH_GetCurrentRxDescStartAddress(void);
uint32_t ETH_GetCurrentTxBufferAddress(void);
uint32_t ETH_GetCurrentRxBufferAddress(void);
void ETH_ResumeDMATransmission(void);
void ETH_ResumeDMAReception(void);
void ETH_SetReceiveWatchdogTimer(uint8_t Value);
/**
* @brief PMT
*/
void ETH_ResetWakeUpFrameFilterRegisterPointer(void);
void ETH_SetWakeUpFrameFilterRegister(uint32_t *Buffer);
void ETH_GlobalUnicastWakeUpCmd(FunctionalState NewState);
FlagStatus ETH_GetPMTFlagStatus(uint32_t ETH_PMT_FLAG);
void ETH_WakeUpFrameDetectionCmd(FunctionalState NewState);
void ETH_MagicPacketDetectionCmd(FunctionalState NewState);
void ETH_PowerDownCmd(FunctionalState NewState);
* @brief MMC
*/
void ETH_MMCCounterFullPreset(void);
void ETH_MMCCounterHalfPreset(void);
void ETH_MMCCounterFreezeCmd(FunctionalState NewState);
void ETH_MMCResetOnReadCmd(FunctionalState NewState);
void ETH_MMCCounterRolloverCmd(FunctionalState NewState);
void ETH_MMCCountersReset(void);
void ETH_MMCITConfig(uint32_t ETH_MMC_IT, FunctionalState NewState);
ITStatus ETH_GetMMCITStatus(uint32_t ETH_MMC_IT);
uint32_t ETH_GetMMCRegister(uint32_t ETH_MMCReg);
}
#endif
/**
* @}
*/
/**
* @}
*/
******************************************************************************
* @file stm32f4x7_eth.c
* @author MCD Application Team
* @version V1.0.0
* @date 14-October-2011
* @brief This file is the low level driver for STM32F407xx/417xx Ethernet Controller.
* This driver does not include low level functions for PTP time-stamp.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
#include "stm32f4x7_eth.h"
#include "stm32f4xx_rcc.h"
#include <string.h>
* @brief ETH driver modules
* @{
*/
* @{
*/
/**
* @}
*/
/** @defgroup ETH_Private_Defines
* @{
*/
* @}
*/
* @{
*/
/**
* @}
*/
* @{
*/
// __align(4)
// ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
// __align(4)
// ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
// __align(4)
// uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
// __align(4)
// uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
// #pragma data_alignment=4
// ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
// #pragma data_alignment=4
// ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
// #pragma data_alignment=4
// uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
// #pragma data_alignment=4
// uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
// ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB] __attribute__ ((aligned (4))); /* Ethernet Rx DMA Descriptor */
// ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB] __attribute__ ((aligned (4))); /* Ethernet Tx DMA Descriptor */
// uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__ ((aligned (4))); /* Ethernet Receive Buffer */
// uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__ ((aligned (4))); /* Ethernet Transmit Buffer */
// __align(4)
// ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
// __align(4)
// ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
// __align(4)
// uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
// __align(4)
// uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
/* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */
__IO ETH_DMADESCTypeDef *DMATxDescToSet;
__IO ETH_DMADESCTypeDef *DMARxDescToGet;
/* Structure used to hold the last received packet descriptors info */
__IO ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
__IO uint32_t Frame_Rx_index;
/**
* @}
*/
* @{
*/
/**
* @}
*/
* @{
*/
/**
* @brief Inserts a delay time.
* @param nCount: specifies the delay time length.
* @retval None
*/
static void ETH_Delay(__IO uint32_t nCount)
{
__IO uint32_t index = 0;
for(index = nCount; index != 0; index--)
{
}
}
#endif /* USE_Delay*/
/* Global ETH MAC/DMA functions */
/******************************************************************************/
* @brief Deinitializes the ETHERNET peripheral registers to their default reset values.
* @param None
* @retval None
*/
void ETH_DeInit(void)
{
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, ENABLE);
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, DISABLE);
}
/**
* @brief Fills each ETH_InitStruct member with its default value.
* @param ETH_InitStruct: pointer to a ETH_InitTypeDef structure which will be initialized.
* @retval None
*/
void ETH_StructInit(ETH_InitTypeDef* ETH_InitStruct)
{
/* ETH_InitStruct members default value */
/*------------------------ MAC Configuration ---------------------------*/
/* PHY Auto-negotiation enabled */
ETH_InitStruct->ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; //使能自适应模式
/* MAC watchdog enabled: cuts-off long frame */
ETH_InitStruct->ETH_Watchdog = ETH_Watchdog_Enable; //使能看门狗
/* MAC Jabber enabled in Half-duplex mode */
ETH_InitStruct->ETH_Jabber = ETH_Jabber_Enable; //使能Jabber
/* Ethernet interframe gap set to 96 bits */
ETH_InitStruct->ETH_InterFrameGap = ETH_InterFrameGap_96Bit; //设置帧间隔为96bit
/* Carrier Sense Enabled in Half-Duplex mode */
ETH_InitStruct->ETH_CarrierSense = ETH_CarrierSense_Enable; //半双工模式下使能载波侦听功能
/* PHY speed configured to 100Mbit/s */
ETH_InitStruct->ETH_Speed = ETH_Speed_100M; //PHY层速度为100M
/* Receive own Frames in Half-Duplex mode enabled */
ETH_InitStruct->ETH_ReceiveOwn = ETH_ReceiveOwn_Enable; //半双工模式下允许接收 own frame
/* MAC MII loopback disabled */
ETH_InitStruct->ETH_LoopbackMode = ETH_LoopbackMode_Disable; //关闭MII接口的反馈功能
/* Full-Duplex mode selected */
ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex; //使用全双工模式
/* IPv4 and TCP/UDP/ICMP frame Checksum Offload disabled */
ETH_InitStruct->ETH_ChecksumOffload = ETH_ChecksumOffload_Disable; //关闭ipv4和TCP/UDP/ICMP的帧校验和卸载
/* Retry Transmission enabled for half-duplex mode */
ETH_InitStruct->ETH_RetryTransmission = ETH_RetryTransmission_Enable; //开启半双工模式下的重试传输功能
/* Automatic PAD/CRC strip disabled*/
ETH_InitStruct->ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; //关闭自动去除PDA/CRC功能
/* half-duplex mode retransmission Backoff time_limit = 10 slot times*/
ETH_InitStruct->ETH_BackOffLimit = ETH_BackOffLimit_10; //设置半双工模式下的最大重传回退事件10 slot times
/* half-duplex mode Deferral check disabled */
ETH_InitStruct->ETH_DeferralCheck = ETH_DeferralCheck_Disable; //关闭半双工模式下的延时检查功能
/* Receive all frames disabled */
ETH_InitStruct->ETH_ReceiveAll = ETH_ReceiveAll_Disable; //禁止接收所有帧
/* Source address filtering (on the optional MAC addresses) disabled */
ETH_InitStruct->ETH_SourceAddrFilter = ETH_SourceAddrFilter_Disable; //关闭MAC地址的源地址过滤功能
/* Do not forward control frames that do not pass the address filtering */
ETH_InitStruct->ETH_PassControlFrames = ETH_PassControlFrames_BlockAll; //
/* Disable reception of Broadcast frames */
ETH_InitStruct->ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable;//禁止接收所有的广播帧
/* Normal Destination address filtering (not reverse addressing) */
ETH_InitStruct->ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal; //正常的远端地址过滤
/* Promiscuous address filtering mode disabled */
ETH_InitStruct->ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; //关闭混合模式的地址过滤
/* Perfect address filtering for multicast addresses */
ETH_InitStruct->ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect; //对于组播地址使用完美地址过滤
/* Perfect address filtering for unicast addresses */
ETH_InitStruct->ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; //对单播地址使用完美地址过滤
/* Initialize hash table high and low regs */
ETH_InitStruct->ETH_HashTableHigh = 0x0; //初始化HASH表的高位寄存器
ETH_InitStruct->ETH_HashTableLow = 0x0; //初始化HASH表的低位位寄存器
/* Flow control config (flow control disabled)*/
ETH_InitStruct->ETH_PauseTime = 0x0; //流控配置
ETH_InitStruct->ETH_ZeroQuantaPause = ETH_ZeroQuantaPause_Disable;
ETH_InitStruct->ETH_PauseLowThreshold = ETH_PauseLowThreshold_Minus4;
ETH_InitStruct->ETH_UnicastPauseFrameDetect = ETH_UnicastPauseFrameDetect_Disable;
ETH_InitStruct->ETH_ReceiveFlowControl = ETH_ReceiveFlowControl_Disable;
ETH_InitStruct->ETH_TransmitFlowControl = ETH_TransmitFlowControl_Disable;
/* VLANtag config (VLAN field not checked) */
ETH_InitStruct->ETH_VLANTagComparison = ETH_VLANTagComparison_16Bit;
ETH_InitStruct->ETH_VLANTagIdentifier = 0x0;
/*---------------------- DMA Configuration -------------------------------*/
ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disable; //关闭丢弃TCP/IP错误帧
/* Store and forward mode enabled for receive */
ETH_InitStruct->ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable; //开启接收数据的存储转发功能
/* Flush received frame that created FIFO overflow */
ETH_InitStruct->ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Enable;
/* Store and forward mode enabled for transmit */
ETH_InitStruct->ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable; //开启发送模式的存储转发功能
/* Threshold TXFIFO level set to 64 bytes (used when threshold mode is enabled) */
ETH_InitStruct->ETH_TransmitThresholdControl = ETH_TransmitThresholdControl_64Bytes; //设置阈值模式下的发送FIFO的阈值为64字节
/* Disable forwarding frames with errors (short frames, CRC,...)*/
ETH_InitStruct->ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable; //禁止转发错误帧
/* Disable undersized good frames */
ETH_InitStruct->ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable; //不转发过小的好帧
/* Threshold RXFIFO level set to 64 bytes (used when Cut-through mode is enabled) */
ETH_InitStruct->ETH_ReceiveThresholdControl = ETH_ReceiveThresholdControl_64Bytes; //设置直通模式下的发送FIFO阈值为64字节
/* Disable Operate on second frame (transmit a second frame to FIFO without
waiting status of previous frame*/
ETH_InitStruct->ETH_SecondFrameOperate = ETH_SecondFrameOperate_Disable; //关闭处理第二帧数据
/* DMA works on 32-bit aligned start source and destinations addresses */
ETH_InitStruct->ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; //开启DMA传输的地址对齐功能
/* Enabled Fixed Burst Mode (mix of INC4, INC8, INC16 and SINGLE DMA transactions */
ETH_InitStruct->ETH_FixedBurst = ETH_FixedBurst_Enable; //开启固定突发功能
/* DMA transfer max burst length = 32 beats = 32 x 32bits */
ETH_InitStruct->ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; //DMA发送的最大突发长度为32
ETH_InitStruct->ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat; //DMA接收的最大突发长度为32
/* DMA Ring mode skip length = 0 */
ETH_InitStruct->ETH_DescriptorSkipLength = 0x0;
/* Equal priority (round-robin) between transmit and receive DMA engines */
ETH_InitStruct->ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_1_1;
}
/**
* @brief Initializes the ETHERNET peripheral according to the specified
* parameters in the ETH_InitStruct .
* @param ETH_InitStruct: pointer to a ETH_InitTypeDef structure that contains
* the configuration information for the specified ETHERNET peripheral.
* @param PHYAddress: external PHY address
* @retval ETH_ERROR: Ethernet initialization failed
* ETH_SUCCESS: Ethernet successfully initialized
*/
uint32_t ETH_Init(ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress)
{
uint32_t RegValue = 0, tmpreg = 0;
__IO uint32_t i = 0;
RCC_ClocksTypeDef rcc_clocks;
uint32_t hclk = 60000000;
__IO uint32_t timeout = 0;
/* Check the parameters */
/* MAC --------------------------*/
assert_param(IS_ETH_AUTONEGOTIATION(ETH_InitStruct->ETH_AutoNegotiation));
assert_param(IS_ETH_WATCHDOG(ETH_InitStruct->ETH_Watchdog));
assert_param(IS_ETH_JABBER(ETH_InitStruct->ETH_Jabber));
assert_param(IS_ETH_INTER_FRAME_GAP(ETH_InitStruct->ETH_InterFrameGap));
assert_param(IS_ETH_CARRIER_SENSE(ETH_InitStruct->ETH_CarrierSense));
assert_param(IS_ETH_SPEED(ETH_InitStruct->ETH_Speed));
assert_param(IS_ETH_RECEIVE_OWN(ETH_InitStruct->ETH_ReceiveOwn));
assert_param(IS_ETH_LOOPBACK_MODE(ETH_InitStruct->ETH_LoopbackMode));
assert_param(IS_ETH_DUPLEX_MODE(ETH_InitStruct->ETH_Mode));
assert_param(IS_ETH_CHECKSUM_OFFLOAD(ETH_InitStruct->ETH_ChecksumOffload));
assert_param(IS_ETH_RETRY_TRANSMISSION(ETH_InitStruct->ETH_RetryTransmission));
assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(ETH_InitStruct->ETH_AutomaticPadCRCStrip));
assert_param(IS_ETH_BACKOFF_LIMIT(ETH_InitStruct->ETH_BackOffLimit));
assert_param(IS_ETH_DEFERRAL_CHECK(ETH_InitStruct->ETH_DeferralCheck));
assert_param(IS_ETH_RECEIVE_ALL(ETH_InitStruct->ETH_ReceiveAll));
assert_param(IS_ETH_SOURCE_ADDR_FILTER(ETH_InitStruct->ETH_SourceAddrFilter));
assert_param(IS_ETH_CONTROL_FRAMES(ETH_InitStruct->ETH_PassControlFrames));
assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(ETH_InitStruct->ETH_BroadcastFramesReception));
assert_param(IS_ETH_DESTINATION_ADDR_FILTER(ETH_InitStruct->ETH_DestinationAddrFilter));
assert_param(IS_ETH_PROMISCIOUS_MODE(ETH_InitStruct->ETH_PromiscuousMode));
assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(ETH_InitStruct->ETH_MulticastFramesFilter));
assert_param(IS_ETH_UNICAST_FRAMES_FILTER(ETH_InitStruct->ETH_UnicastFramesFilter));
assert_param(IS_ETH_PAUSE_TIME(ETH_InitStruct->ETH_PauseTime));
assert_param(IS_ETH_ZEROQUANTA_PAUSE(ETH_InitStruct->ETH_ZeroQuantaPause));
assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(ETH_InitStruct->ETH_PauseLowThreshold));
assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(ETH_InitStruct->ETH_UnicastPauseFrameDetect));
assert_param(IS_ETH_RECEIVE_FLOWCONTROL(ETH_InitStruct->ETH_ReceiveFlowControl));
assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(ETH_InitStruct->ETH_TransmitFlowControl));
assert_param(IS_ETH_VLAN_TAG_COMPARISON(ETH_InitStruct->ETH_VLANTagComparison));
assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(ETH_InitStruct->ETH_VLANTagIdentifier));
/* DMA --------------------------*/
assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame));
assert_param(IS_ETH_RECEIVE_STORE_FORWARD(ETH_InitStruct->ETH_ReceiveStoreForward));
assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(ETH_InitStruct->ETH_FlushReceivedFrame));
assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(ETH_InitStruct->ETH_TransmitStoreForward));
assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(ETH_InitStruct->ETH_TransmitThresholdControl));
assert_param(IS_ETH_FORWARD_ERROR_FRAMES(ETH_InitStruct->ETH_ForwardErrorFrames));
assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(ETH_InitStruct->ETH_ForwardUndersizedGoodFrames));
assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(ETH_InitStruct->ETH_ReceiveThresholdControl));
assert_param(IS_ETH_SECOND_FRAME_OPERATE(ETH_InitStruct->ETH_SecondFrameOperate));
assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(ETH_InitStruct->ETH_AddressAlignedBeats));
assert_param(IS_ETH_FIXED_BURST(ETH_InitStruct->ETH_FixedBurst));
assert_param(IS_ETH_RXDMA_BURST_LENGTH(ETH_InitStruct->ETH_RxDMABurstLength));
assert_param(IS_ETH_TXDMA_BURST_LENGTH(ETH_InitStruct->ETH_TxDMABurstLength));
assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(ETH_InitStruct->ETH_DescriptorSkipLength));
assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(ETH_InitStruct->ETH_DMAArbitration));
/*-------------------------------- MAC Config ------------------------------*/
/*---------------------- ETHERNET MACMIIAR Configuration -------------------*/
/* Get the ETHERNET MACMIIAR value */
tmpreg = ETH->MACMIIAR;
/* Clear CSR Clock Range CR[2:0] bits */
tmpreg &= MACMIIAR_CR_MASK;
/* Get hclk frequency value */
RCC_GetClocksFreq(&rcc_clocks);
hclk = rcc_clocks.HCLK_Frequency;
/* Set CR bits depending on hclk value */
if((hclk >= 20000000)&&(hclk < 35000000))
{
/* CSR Clock Range between 20-35 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16;
}
else if((hclk >= 35000000)&&(hclk < 60000000))
{
/* CSR Clock Range between 35-60 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26;
}
else if((hclk >= 60000000)&&(hclk < 100000000))
{
/* CSR Clock Range between 60-100 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
}
else if((hclk >= 100000000)&&(hclk < 150000000))
{
/* CSR Clock Range between 100-150 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
}
else /* ((hclk >= 150000000)&&(hclk <= 168000000)) */
{
/* CSR Clock Range between 150-168 MHz */
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
}
/* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
ETH->MACMIIAR = (uint32_t)tmpreg;
/*-------------------- PHY initialization and configuration ----------------*/
/* Put the PHY in reset mode */
if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset)))
{
/* Return ERROR in case of write timeout */
return ETH_ERROR;
}
/* Delay to assure PHY reset */
_eth_delay_(PHY_RESET_DELAY);
if(ETH_InitStruct->ETH_AutoNegotiation != ETH_AutoNegotiation_Disable)
{
/* We wait for linked status... */
do
{
timeout++;
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO));
if(timeout == PHY_READ_TO)
{
return ETH_ERROR;
}
timeout = 0;
/* Enable Auto-Negotiation */
if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_AutoNegotiation)))
{
/* Return ERROR in case of write timeout */
return ETH_ERROR;
}
do
{
timeout++;
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO));
if(timeout == PHY_READ_TO)
{
return ETH_ERROR;
}
timeout = 0;
/* Read the result of the auto-negotiation */
RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR);
/* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
if((RegValue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
{
/* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;
}
else
{
/* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
}
if(RegValue & PHY_SPEED_STATUS)
{
/* Set Ethernet speed to 10M following the auto-negotiation */
ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
}
else
{
/* Set Ethernet speed to 100M following the auto-negotiation */
ETH_InitStruct->ETH_Speed = ETH_Speed_100M;
}
}
else
{
if(!ETH_WritePHYRegister(PHYAddress, PHY_BCR, ((uint16_t)(ETH_InitStruct->ETH_Mode >> 3) |
(uint16_t)(ETH_InitStruct->ETH_Speed >> 1))))
{
/* Return ERROR in case of write timeout */
return ETH_ERROR;
}
/* Delay to assure PHY configuration */
_eth_delay_(PHY_CONFIG_DELAY);
}
/*------------------------ ETHERNET MACCR Configuration --------------------*/
/* Get the ETHERNET MACCR value */
tmpreg = ETH->MACCR;
/* Clear WD, PCE, PS, TE and RE bits */
tmpreg &= MACCR_CLEAR_MASK;
/* Set the WD bit according to ETH_Watchdog value */
/* Set the JD: bit according to ETH_Jabber value */
/* Set the IFG bit according to ETH_InterFrameGap value */
/* Set the DCRS bit according to ETH_CarrierSense value */
/* Set the FES bit according to ETH_Speed value */
/* Set the DO bit according to ETH_ReceiveOwn value */
/* Set the LM bit according to ETH_LoopbackMode value */
/* Set the DM bit according to ETH_Mode value */
/* Set the IPCO bit according to ETH_ChecksumOffload value */
/* Set the DR bit according to ETH_RetryTransmission value */
/* Set the ACS bit according to ETH_AutomaticPadCRCStrip value */
/* Set the BL bit according to ETH_BackOffLimit value */
/* Set the DC bit according to ETH_DeferralCheck value */
tmpreg |= (uint32_t)(ETH_InitStruct->ETH_Watchdog |
ETH_InitStruct->ETH_Jabber |
ETH_InitStruct->ETH_InterFrameGap |
ETH_InitStruct->ETH_CarrierSense |
ETH_InitStruct->ETH_Speed |
ETH_InitStruct->ETH_ReceiveOwn |
ETH_InitStruct->ETH_LoopbackMode |
ETH_InitStruct->ETH_Mode |
ETH_InitStruct->ETH_ChecksumOffload |
ETH_InitStruct->ETH_RetryTransmission |
ETH_InitStruct->ETH_AutomaticPadCRCStrip |
ETH_InitStruct->ETH_BackOffLimit |
ETH_InitStruct->ETH_DeferralCheck);
/* Write to ETHERNET MACCR */
ETH->MACCR = (uint32_t)tmpreg;
/*----------------------- ETHERNET MACFFR Configuration --------------------*/
/* Set the RA bit according to ETH_ReceiveAll value */
/* Set the SAF and SAIF bits according to ETH_SourceAddrFilter value */
/* Set the PCF bit according to ETH_PassControlFrames value */
/* Set the DBF bit according to ETH_BroadcastFramesReception value */
/* Set the DAIF bit according to ETH_DestinationAddrFilter value */
/* Set the PR bit according to ETH_PromiscuousMode value */
/* Set the PM, HMC and HPF bits according to ETH_MulticastFramesFilter value */
/* Set the HUC and HPF bits according to ETH_UnicastFramesFilter value */
/* Write to ETHERNET MACFFR */
ETH->MACFFR = (uint32_t)(ETH_InitStruct->ETH_ReceiveAll |
ETH_InitStruct->ETH_SourceAddrFilter |
ETH_InitStruct->ETH_PassControlFrames |
ETH_InitStruct->ETH_BroadcastFramesReception |
ETH_InitStruct->ETH_DestinationAddrFilter |
ETH_InitStruct->ETH_PromiscuousMode |
ETH_InitStruct->ETH_MulticastFramesFilter |
ETH_InitStruct->ETH_UnicastFramesFilter);
/*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
/* Write to ETHERNET MACHTHR */
ETH->MACHTHR = (uint32_t)ETH_InitStruct->ETH_HashTableHigh;
/* Write to ETHERNET MACHTLR */
ETH->MACHTLR = (uint32_t)ETH_InitStruct->ETH_HashTableLow;
/*----------------------- ETHERNET MACFCR Configuration --------------------*/
/* Get the ETHERNET MACFCR value */
tmpreg = ETH->MACFCR;
/* Clear xx bits */
tmpreg &= MACFCR_CLEAR_MASK;
/* Set the PT bit according to ETH_PauseTime value */
/* Set the DZPQ bit according to ETH_ZeroQuantaPause value */
/* Set the PLT bit according to ETH_PauseLowThreshold value */
/* Set the UP bit according to ETH_UnicastPauseFrameDetect value */
/* Set the RFE bit according to ETH_ReceiveFlowControl value */
/* Set the TFE bit according to ETH_TransmitFlowControl value */
tmpreg |= (uint32_t)((ETH_InitStruct->ETH_PauseTime << 16) |
ETH_InitStruct->ETH_ZeroQuantaPause |
ETH_InitStruct->ETH_PauseLowThreshold |
ETH_InitStruct->ETH_UnicastPauseFrameDetect |
ETH_InitStruct->ETH_ReceiveFlowControl |
ETH_InitStruct->ETH_TransmitFlowControl);
/* Write to ETHERNET MACFCR */
ETH->MACFCR = (uint32_t)tmpreg;
/*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
/* Set the ETV bit according to ETH_VLANTagComparison value */
/* Set the VL bit according to ETH_VLANTagIdentifier value */
ETH->MACVLANTR = (uint32_t)(ETH_InitStruct->ETH_VLANTagComparison |
ETH_InitStruct->ETH_VLANTagIdentifier);
/*-------------------------------- DMA Config ------------------------------*/
/*----------------------- ETHERNET DMAOMR Configuration --------------------*/
/* Get the ETHERNET DMAOMR value */
tmpreg = ETH->DMAOMR;
/* Clear xx bits */
tmpreg &= DMAOMR_CLEAR_MASK;
/* Set the DT bit according to ETH_DropTCPIPChecksumErrorFrame value */
/* Set the RSF bit according to ETH_ReceiveStoreForward value */
/* Set the DFF bit according to ETH_FlushReceivedFrame value */
/* Set the TSF bit according to ETH_TransmitStoreForward value */
/* Set the TTC bit according to ETH_TransmitThresholdControl value */
/* Set the FEF bit according to ETH_ForwardErrorFrames value */
/* Set the FUF bit according to ETH_ForwardUndersizedGoodFrames value */
/* Set the RTC bit according to ETH_ReceiveThresholdControl value */
/* Set the OSF bit according to ETH_SecondFrameOperate value */
tmpreg |= (uint32_t)(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame |
ETH_InitStruct->ETH_ReceiveStoreForward |
ETH_InitStruct->ETH_FlushReceivedFrame |
ETH_InitStruct->ETH_TransmitStoreForward |
ETH_InitStruct->ETH_TransmitThresholdControl |
ETH_InitStruct->ETH_ForwardErrorFrames |
ETH_InitStruct->ETH_ForwardUndersizedGoodFrames |
ETH_InitStruct->ETH_ReceiveThresholdControl |
ETH_InitStruct->ETH_SecondFrameOperate);
/* Write to ETHERNET DMAOMR */
ETH->DMAOMR = (uint32_t)tmpreg;
/*----------------------- ETHERNET DMABMR Configuration --------------------*/
/* Set the AAL bit according to ETH_AddressAlignedBeats value */
/* Set the FB bit according to ETH_FixedBurst value */
/* Set the RPBL and 4*PBL bits according to ETH_RxDMABurstLength value */
/* Set the PBL and 4*PBL bits according to ETH_TxDMABurstLength value */
/* Set the DSL bit according to ETH_DesciptorSkipLength value */
/* Set the PR and DA bits according to ETH_DMAArbitration value */
ETH->DMABMR = (uint32_t)(ETH_InitStruct->ETH_AddressAlignedBeats |
ETH_InitStruct->ETH_FixedBurst |
ETH_InitStruct->ETH_RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
ETH_InitStruct->ETH_TxDMABurstLength |
(ETH_InitStruct->ETH_DescriptorSkipLength << 2) |
ETH_InitStruct->ETH_DMAArbitration |
ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
#ifdef USE_ENHANCED_DMA_DESCRIPTORS
/* Enable the Enhanced DMA descriptors */
ETH->DMABMR |= ETH_DMABMR_EDE;
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
/* Return Ethernet configuration success */
return ETH_SUCCESS;
}
* @brief Enables ENET MAC and DMA reception/transmission
* @param None
* @retval None
*/
void ETH_Start(void)
{
/* Enable transmit state machine of the MAC for transmission on the MII */
ETH_MACTransmissionCmd(ENABLE);
/* Flush Transmit FIFO */
ETH_FlushTransmitFIFO();
/* Enable receive state machine of the MAC for reception from the MII */
ETH_MACReceptionCmd(ENABLE);
/* Start DMA transmission */
ETH_DMATransmissionCmd(ENABLE);
/* Start DMA reception */
ETH_DMAReceptionCmd(ENABLE);
}
/**
* @brief Enables or disables the MAC transmission.
* @param NewState: new state of the MAC transmission.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACTransmissionCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MAC transmission */
ETH->MACCR |= ETH_MACCR_TE;
}
else
{
/* Disable the MAC transmission */
ETH->MACCR &= ~ETH_MACCR_TE;
}
}
/**
* @brief Enables or disables the MAC reception.
* @param NewState: new state of the MAC reception.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACReceptionCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MAC reception */
ETH->MACCR |= ETH_MACCR_RE;
}
else
{
/* Disable the MAC reception */
ETH->MACCR &= ~ETH_MACCR_RE;
}
}
/**
* @brief Checks whether the ETHERNET flow control busy bit is set or not.
* @param None
* @retval The new state of flow control busy status bit (SET or RESET).
*/
FlagStatus ETH_GetFlowControlBusyStatus(void)
{
FlagStatus bitstatus = RESET;
/* The Flow Control register should not be written to until this bit is cleared */
if ((ETH->MACFCR & ETH_MACFCR_FCBBPA) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/**
* @brief Initiate a Pause Control Frame (Full-duplex only).
* @param None
* @retval None
*/
void ETH_InitiatePauseControlFrame(void)
{
/* When Set In full duplex MAC initiates pause control frame */
ETH->MACFCR |= ETH_MACFCR_FCBBPA;
}
/**
* @brief Enables or disables the MAC BackPressure operation activation (Half-duplex only).
* @param NewState: new state of the MAC BackPressure operation activation.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_BackPressureActivationCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Activate the MAC BackPressure operation */
/* In Half duplex: during backpressure, when the MAC receives a new frame,
the transmitter starts sending a JAM pattern resulting in a collision */
ETH->MACFCR |= ETH_MACFCR_FCBBPA;
}
else
{
/* Desactivate the MAC BackPressure operation */
ETH->MACFCR &= ~ETH_MACFCR_FCBBPA;
}
}
/**
* @brief Checks whether the specified ETHERNET MAC flag is set or not.
* @param ETH_MAC_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* @arg ETH_MAC_FLAG_TST : Time stamp trigger flag
* @arg ETH_MAC_FLAG_MMCT : MMC transmit flag
* @arg ETH_MAC_FLAG_MMCR : MMC receive flag
* @arg ETH_MAC_FLAG_MMC : MMC flag
* @arg ETH_MAC_FLAG_PMT : PMT flag
* @retval The new state of ETHERNET MAC flag (SET or RESET).
*/
FlagStatus ETH_GetMACFlagStatus(uint32_t ETH_MAC_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_MAC_GET_FLAG(ETH_MAC_FLAG));
if ((ETH->MACSR & ETH_MAC_FLAG) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/**
* @brief Checks whether the specified ETHERNET MAC interrupt has occurred or not.
* @param ETH_MAC_IT: specifies the interrupt source to check.
* This parameter can be one of the following values:
* @arg ETH_MAC_IT_TST : Time stamp trigger interrupt
* @arg ETH_MAC_IT_MMCT : MMC transmit interrupt
* @arg ETH_MAC_IT_MMCR : MMC receive interrupt
* @arg ETH_MAC_IT_MMC : MMC interrupt
* @arg ETH_MAC_IT_PMT : PMT interrupt
* @retval The new state of ETHERNET MAC interrupt (SET or RESET).
*/
ITStatus ETH_GetMACITStatus(uint32_t ETH_MAC_IT)
{
ITStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_MAC_GET_IT(ETH_MAC_IT));
if ((ETH->MACSR & ETH_MAC_IT) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/**
* @brief Enables or disables the specified ETHERNET MAC interrupts.
* @param ETH_MAC_IT: specifies the ETHERNET MAC interrupt sources to be
* enabled or disabled.
* This parameter can be any combination of the following values:
* @arg ETH_MAC_IT_TST : Time stamp trigger interrupt
* @arg ETH_MAC_IT_PMT : PMT interrupt
* @param NewState: new state of the specified ETHERNET MAC interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACITConfig(uint32_t ETH_MAC_IT, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_ETH_MAC_IT(ETH_MAC_IT));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected ETHERNET MAC interrupts */
ETH->MACIMR &= (~(uint32_t)ETH_MAC_IT);
}
else
{
/* Disable the selected ETHERNET MAC interrupts */
ETH->MACIMR |= ETH_MAC_IT;
}
}
/**
* @brief Configures the selected MAC address.
* @param MacAddr: The MAC address to configure.
* This parameter can be one of the following values:
* @arg ETH_MAC_Address0 : MAC Address0
* @arg ETH_MAC_Address1 : MAC Address1
* @arg ETH_MAC_Address2 : MAC Address2
* @arg ETH_MAC_Address3 : MAC Address3
* @param Addr: Pointer on MAC address buffer data (6 bytes).
* @retval None
*/
void ETH_MACAddressConfig(uint32_t MacAddr, uint8_t *Addr)
{
uint32_t tmpreg;
/* Check the parameters */
assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
/* Calculate the selected MAC address high register */
tmpreg = ((uint32_t)Addr[5] << 8) | (uint32_t)Addr[4]; //计算出所选择的MAC地址的高位寄存器值
//即ETH_MACA0HR的16位值
/* Load the selected MAC address high register */
(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) = tmpreg; //将计算出的高位值写入ETH_MAC0HR中
/* Calculate the selected MAC address low register */
//计算出所选择的MAC地址的第位寄存器值,即ETH_MACA0LR的16位值
tmpreg = ((uint32_t)Addr[3] << 24) | ((uint32_t)Addr[2] << 16) | ((uint32_t)Addr[1] << 8) | Addr[0];
/* Load the selected MAC address low register */
(*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + MacAddr)) = tmpreg;//将计算出的低位值写入ETH_MAC0LR中
}
/**
* @brief Get the selected MAC address.
* @param MacAddr: The MAC address to return.
* This parameter can be one of the following values:
* @arg ETH_MAC_Address0 : MAC Address0
* @arg ETH_MAC_Address1 : MAC Address1
* @arg ETH_MAC_Address2 : MAC Address2
* @arg ETH_MAC_Address3 : MAC Address3
* @param Addr: Pointer on MAC address buffer data (6 bytes).
* @retval None
*/
void ETH_GetMACAddress(uint32_t MacAddr, uint8_t *Addr)
{
uint32_t tmpreg;
/* Check the parameters */
assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
/* Get the selected MAC address high register */
tmpreg =(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr));
/* Calculate the selected MAC address buffer */
Addr[5] = ((tmpreg >> 8) & (uint8_t)0xFF);
Addr[4] = (tmpreg & (uint8_t)0xFF);
/* Load the selected MAC address low register */
tmpreg =(*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + MacAddr));
/* Calculate the selected MAC address buffer */
Addr[3] = ((tmpreg >> 24) & (uint8_t)0xFF);
Addr[2] = ((tmpreg >> 16) & (uint8_t)0xFF);
Addr[1] = ((tmpreg >> 8 ) & (uint8_t)0xFF);
Addr[0] = (tmpreg & (uint8_t)0xFF);
}
/**
* @brief Enables or disables the Address filter module uses the specified
* ETHERNET MAC address for perfect filtering
* @param MacAddr: specifies the ETHERNET MAC address to be used for perfect filtering.
* This parameter can be one of the following values:
* @arg ETH_MAC_Address1 : MAC Address1
* @arg ETH_MAC_Address2 : MAC Address2
* @arg ETH_MAC_Address3 : MAC Address3
* @param NewState: new state of the specified ETHERNET MAC address use.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACAddressPerfectFilterCmd(uint32_t MacAddr, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_ETH_MAC_ADDRESS123(MacAddr));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected ETHERNET MAC address for perfect filtering */
(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) |= ETH_MACA1HR_AE;
}
else
{
/* Disable the selected ETHERNET MAC address for perfect filtering */
(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) &=(~(uint32_t)ETH_MACA1HR_AE);
}
}
/**
* @brief Set the filter type for the specified ETHERNET MAC address
* @param MacAddr: specifies the ETHERNET MAC address
* This parameter can be one of the following values:
* @arg ETH_MAC_Address1 : MAC Address1
* @arg ETH_MAC_Address2 : MAC Address2
* @arg ETH_MAC_Address3 : MAC Address3
* @param Filter: specifies the used frame received field for comparison
* This parameter can be one of the following values:
* @arg ETH_MAC_AddressFilter_SA : MAC Address is used to compare with the
* SA fields of the received frame.
* @arg ETH_MAC_AddressFilter_DA : MAC Address is used to compare with the
* DA fields of the received frame.
* @retval None
*/
void ETH_MACAddressFilterConfig(uint32_t MacAddr, uint32_t Filter)
{
/* Check the parameters */
assert_param(IS_ETH_MAC_ADDRESS123(MacAddr));
assert_param(IS_ETH_MAC_ADDRESS_FILTER(Filter));
if (Filter != ETH_MAC_AddressFilter_DA)
{
/* The selected ETHERNET MAC address is used to compare with the SA fields of the
received frame. */
(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) |= ETH_MACA1HR_SA;
}
else
{
/* The selected ETHERNET MAC address is used to compare with the DA fields of the
received frame. */
(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) &=(~(uint32_t)ETH_MACA1HR_SA);
}
}
/**
* @brief Set the filter type for the specified ETHERNET MAC address
* @param MacAddr: specifies the ETHERNET MAC address
* This parameter can be one of the following values:
* @arg ETH_MAC_Address1 : MAC Address1
* @arg ETH_MAC_Address2 : MAC Address2
* @arg ETH_MAC_Address3 : MAC Address3
* @param MaskByte: specifies the used address bytes for comparison
* This parameter can be any combination of the following values:
* @arg ETH_MAC_AddressMask_Byte6 : Mask MAC Address high reg bits [15:8].
* @arg ETH_MAC_AddressMask_Byte5 : Mask MAC Address high reg bits [7:0].
* @arg ETH_MAC_AddressMask_Byte4 : Mask MAC Address low reg bits [31:24].
* @arg ETH_MAC_AddressMask_Byte3 : Mask MAC Address low reg bits [23:16].
* @arg ETH_MAC_AddressMask_Byte2 : Mask MAC Address low reg bits [15:8].
* @arg ETH_MAC_AddressMask_Byte1 : Mask MAC Address low reg bits [7:0].
* @retval None
*/
void ETH_MACAddressMaskBytesFilterConfig(uint32_t MacAddr, uint32_t MaskByte)
{
/* Check the parameters */
assert_param(IS_ETH_MAC_ADDRESS123(MacAddr));
assert_param(IS_ETH_MAC_ADDRESS_MASK(MaskByte));
/* Clear MBC bits in the selected MAC address high register */
(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) &=(~(uint32_t)ETH_MACA1HR_MBC);
/* Set the selected Filter mask bytes */
(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) |= MaskByte;
}
/******************************************************************************/
/* DMA Descriptors functions */
/******************************************************************************/
* @brief This function should be called to get the received frame (to be used
* with polling method only).
* @param none
* @retval Structure of type FrameTypeDef
*/
FrameTypeDef ETH_Get_Received_Frame(void)
{
uint32_t framelength = 0;
FrameTypeDef frame = {0,0,0};
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
frame.length = framelength;
/* Get the address of the buffer start address */
/* Check if more than one segment in the frame */
if (DMA_RX_FRAME_infos->Seg_Count >1)
{
frame.buffer =(DMA_RX_FRAME_infos->FS_Rx_Desc)->Buffer1Addr;
}
else
{
frame.buffer = DMARxDescToGet->Buffer1Addr;
}
/* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
/* Chained Mode */
/* Selects the next DMA Rx descriptor list for next buffer to read */
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
/* Return Frame */
return (frame);
}
/**
* @brief This function should be called when a frame is received using DMA
* Receive interrupt, it allows scanning of Rx descriptors to get the
* the receive frame (should be used with interrupt mode only)
* @param None
* @retval Structure of type FrameTypeDef
*/
FrameTypeDef ETH_Get_Received_Frame_interrupt(void)
{
FrameTypeDef frame={0,0,0};
__IO uint32_t descriptor_scan_counter = 0;
/* scan descriptors owned by CPU */
while (((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET)&&
(descriptor_scan_counter<ETH_RXBUFNB))
{
/* Just by security */
descriptor_scan_counter++;
/* check if first segment in frame */
if(((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET)&&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
{
DMA_RX_FRAME_infos->FS_Rx_Desc = DMARxDescToGet;
DMA_RX_FRAME_infos->Seg_Count = 1;
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
}
/* check if intermediate segment */
else if (((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET)&&
((DMARxDescToGet->Status & ETH_DMARxDesc_FS) == (uint32_t)RESET))
{
(DMA_RX_FRAME_infos->Seg_Count) ++;
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
}
else
{
/* last segment */
DMA_RX_FRAME_infos->LS_Rx_Desc = DMARxDescToGet;
(DMA_RX_FRAME_infos->Seg_Count)++;
/* first segment is last segment */
if ((DMA_RX_FRAME_infos->Seg_Count)==1)
DMA_RX_FRAME_infos->FS_Rx_Desc = DMARxDescToGet;
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
frame.length = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
/* Get the address of the buffer start address */
/* Check if more than one segment in the frame */
if (DMA_RX_FRAME_infos->Seg_Count >1)
{
frame.buffer =(DMA_RX_FRAME_infos->FS_Rx_Desc)->Buffer1Addr;
}
else
{
frame.buffer = DMARxDescToGet->Buffer1Addr;
}
frame.descriptor = DMARxDescToGet;
/* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
/* Return Frame */
return (frame);
}
}
return (frame);
}
/**
* @brief Prepares DMA Tx descriptors to transmit an ethernet frame
* @param FrameLength : length of the frame to send
* @retval error status
*/
uint32_t ETH_Prepare_Transmit_Descriptors(u16 FrameLength)
{
uint32_t buf_count =0, size=0,i=0;
__IO ETH_DMADESCTypeDef *DMATxNextDesc;
/* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
/* Return ERROR: OWN bit set */
return ETH_ERROR;
}
DMATxNextDesc = DMATxDescToSet;
if (FrameLength > ETH_TX_BUF_SIZE)
{
buf_count = FrameLength/ETH_TX_BUF_SIZE;
if (FrameLength%ETH_TX_BUF_SIZE) buf_count++;
}
else buf_count =1;
if (buf_count ==1)
{
/*set LAST and FIRST segment */
DMATxDescToSet->Status |=ETH_DMATxDesc_FS|ETH_DMATxDesc_LS;
/* Set frame size */
DMATxDescToSet->ControlBufferSize = (FrameLength& ETH_DMATxDesc_TBS1);
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
DMATxDescToSet= (ETH_DMADESCTypeDef *)(DMATxDescToSet->Buffer2NextDescAddr);
}
else
{
for (i=0; i< buf_count; i++)
{
if (i==0)
{
/* Setting the first segment bit */
DMATxDescToSet->Status |= ETH_DMATxDesc_FS;
}
/* Program size */
DMATxNextDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATxDesc_TBS1);
if (i== (buf_count-1))
{
/* Setting the last segment bit */
DMATxNextDesc->Status |= ETH_DMATxDesc_LS;
size = FrameLength - (buf_count-1)*ETH_TX_BUF_SIZE;
DMATxNextDesc->ControlBufferSize = (size & ETH_DMATxDesc_TBS1);
}
/*give back descriptor to DMA */
DMATxNextDesc->Status |= ETH_DMATxDesc_OWN;
DMATxNextDesc = (ETH_DMADESCTypeDef *)(DMATxNextDesc->Buffer2NextDescAddr);
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
}
DMATxDescToSet = DMATxNextDesc ;
}
/* When Tx Buffer unavailable flag is set: clear it and resume transmission */
if ((ETH->DMASR & ETH_DMASR_TBUS) != (u32)RESET)
{
/* Clear TBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_TBUS;
/* Resume DMA transmission*/
ETH->DMATPDR = 0;
}
/* Return SUCCESS */
return ETH_SUCCESS;
}
/**
* @brief Initializes the DMA Rx descriptors in chain mode.
* @param DMARxDescTab: Pointer on the first Rx desc list
* @param RxBuff: Pointer on the first RxBuffer list
* @param RxBuffCount: Number of the used Rx desc in the list
* @retval None
*/
void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
{
uint32_t i = 0;
ETH_DMADESCTypeDef *DMARxDesc;
/* Set the DMARxDescToGet pointer with the first one of the DMARxDescTab list */
DMARxDescToGet = DMARxDescTab;
/* Fill each DMARxDesc descriptor with the right values */
for(i=0; i < RxBuffCount; i++)
{
/* Get the pointer on the ith member of the Rx Desc list */
DMARxDesc = DMARxDescTab+i;
/* Set Own bit of the Rx descriptor Status */
DMARxDesc->Status = ETH_DMARxDesc_OWN;
DMARxDesc->ControlBufferSize = ETH_DMARxDesc_RCH | (uint32_t)ETH_RX_BUF_SIZE;
/* Set Buffer1 address pointer */
DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i*ETH_RX_BUF_SIZE]);
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
if(i < (RxBuffCount-1))
{
/* Set next descriptor address register with next descriptor base address */
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1);
}
else
{
/* For last descriptor, set next descriptor address register equal to the first descriptor base address */
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
}
}
/* Set Receive Descriptor List Address Register */
ETH->DMARDLAR = (uint32_t) DMARxDescTab;
* @brief This function polls for a frame reception
* @param None
* @retval Returns 1 when a frame is received, 0 if none.
*/
uint32_t ETH_CheckFrameReceived(void)
{
/* check if last segment */
if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET))
{
DMA_RX_FRAME_infos->LS_Rx_Desc = DMARxDescToGet;
DMA_RX_FRAME_infos->Seg_Count++;
return 1;
}
/* check if first segment */
else if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET)&&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
{
DMA_RX_FRAME_infos->FS_Rx_Desc = DMARxDescToGet;
DMA_RX_FRAME_infos->LS_Rx_Desc = NULL;
DMA_RX_FRAME_infos->Seg_Count = 1;
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
}
/* check if intermediate segment */
else if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_FS) == (uint32_t)RESET)&&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
{
(DMA_RX_FRAME_infos->Seg_Count) ++;
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
}
return 0;
}
* @brief Initializes the DMA Tx descriptors in chain mode.
* @param DMATxDescTab: Pointer on the first Tx desc list
* @param TxBuff: Pointer on the first TxBuffer list
* @param TxBuffCount: Number of the used Tx desc in the list
* @retval None
*/
void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount)
{
uint32_t i = 0;
ETH_DMADESCTypeDef *DMATxDesc;
/* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
DMATxDescToSet = DMATxDescTab;
/* Fill each DMATxDesc descriptor with the right values */
for(i=0; i < TxBuffCount; i++)
{
/* Get the pointer on the ith member of the Tx Desc list */
DMATxDesc = DMATxDescTab + i;
/* Set Second Address Chained bit */
DMATxDesc->Status = ETH_DMATxDesc_TCH;
/* Set Buffer1 address pointer */
DMATxDesc->Buffer1Addr = (uint32_t)(&TxBuff[i*ETH_TX_BUF_SIZE]);
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
if(i < (TxBuffCount-1))
{
/* Set next descriptor address register with next descriptor base address */
DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1);
}
else
{
/* For last descriptor, set next descriptor address register equal to the first descriptor base address */
DMATxDesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
}
}
/* Set Transmit Desciptor List Address Register */
ETH->DMATDLAR = (uint32_t) DMATxDescTab;
}
/**
* @brief Checks whether the specified ETHERNET DMA Tx Desc flag is set or not.
* @param DMATxDesc: pointer on a DMA Tx descriptor
* @param ETH_DMATxDescFlag: specifies the flag to check.
* This parameter can be one of the following values:
* @arg ETH_DMATxDesc_OWN : OWN bit: descriptor is owned by DMA engine
* @arg ETH_DMATxDesc_IC : Interrupt on completion
* @arg ETH_DMATxDesc_LS : Last Segment
* @arg ETH_DMATxDesc_FS : First Segment
* @arg ETH_DMATxDesc_DC : Disable CRC
* @arg ETH_DMATxDesc_DP : Disable Pad
* @arg ETH_DMATxDesc_TTSE: Transmit Time Stamp Enable
* @arg ETH_DMATxDesc_CIC : Checksum insertion control
* @arg ETH_DMATxDesc_TER : Transmit End of Ring
* @arg ETH_DMATxDesc_TCH : Second Address Chained
* @arg ETH_DMATxDesc_TTSS: Tx Time Stamp Status
* @arg ETH_DMATxDesc_IHE : IP Header Error
* @arg ETH_DMATxDesc_ES : Error summary
* @arg ETH_DMATxDesc_JT : Jabber Timeout
* @arg ETH_DMATxDesc_FF : Frame Flushed: DMA/MTL flushed the frame due to SW flush
* @arg ETH_DMATxDesc_PCE : Payload Checksum Error
* @arg ETH_DMATxDesc_LCA : Loss of Carrier: carrier lost during transmission
* @arg ETH_DMATxDesc_NC : No Carrier: no carrier signal from the transceiver
* @arg ETH_DMATxDesc_LCO : Late Collision: transmission aborted due to collision
* @arg ETH_DMATxDesc_EC : Excessive Collision: transmission aborted after 16 collisions
* @arg ETH_DMATxDesc_VF : VLAN Frame
* @arg ETH_DMATxDesc_CC : Collision Count
* @arg ETH_DMATxDesc_ED : Excessive Deferral
* @arg ETH_DMATxDesc_UF : Underflow Error: late data arrival from the memory
* @arg ETH_DMATxDesc_DB : Deferred Bit
* @retval The new state of ETH_DMATxDescFlag (SET or RESET).
*/
FlagStatus ETH_GetDMATxDescFlagStatus(ETH_DMADESCTypeDef *DMATxDesc, uint32_t ETH_DMATxDescFlag)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_DMATxDESC_GET_FLAG(ETH_DMATxDescFlag));
if ((DMATxDesc->Status & ETH_DMATxDescFlag) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
* @brief Returns the specified ETHERNET DMA Tx Desc collision count.
* @param DMATxDesc: pointer on a DMA Tx descriptor
* @retval The Transmit descriptor collision counter value.
*/
uint32_t ETH_GetDMATxDescCollisionCount(ETH_DMADESCTypeDef *DMATxDesc)
{
/* Return the Receive descriptor frame length */
return ((DMATxDesc->Status & ETH_DMATxDesc_CC) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT);
}
* @brief Set the specified DMA Tx Desc Own bit.
* @param DMATxDesc: Pointer on a Tx desc
* @retval None
*/
void ETH_SetDMATxDescOwnBit(ETH_DMADESCTypeDef *DMATxDesc)
{
/* Set the DMA Tx Desc Own bit */
DMATxDesc->Status |= ETH_DMATxDesc_OWN;
}
* @brief Enables or disables the specified DMA Tx Desc Transmit interrupt.
* @param DMATxDesc: Pointer on a Tx desc
* @param NewState: new state of the DMA Tx Desc transmit interrupt.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescTransmitITConfig(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the DMA Tx Desc Transmit interrupt */
DMATxDesc->Status |= ETH_DMATxDesc_IC;
}
else
{
/* Disable the DMA Tx Desc Transmit interrupt */
DMATxDesc->Status &=(~(uint32_t)ETH_DMATxDesc_IC);
}
}
* @brief configure Tx descriptor as last or first segment
* @param DMATxDesc: Pointer on a Tx desc
* @param DMATxDesc_FrameSegment: specifies is the actual Tx desc contain last or first segment.
* This parameter can be one of the following values:
* @arg ETH_DMATxDesc_LastSegment : actual Tx desc contain last segment
* @arg ETH_DMATxDesc_FirstSegment : actual Tx desc contain first segment
* @retval None
*/
void ETH_DMATxDescFrameSegmentConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_FrameSegment)
{
/* Check the parameters */
assert_param(IS_ETH_DMA_TXDESC_SEGMENT(DMATxDesc_FrameSegment));
/* Selects the DMA Tx Desc Frame segment */
DMATxDesc->Status |= DMATxDesc_FrameSegment;
}
* @brief Selects the specified ETHERNET DMA Tx Desc Checksum Insertion.
* @param DMATxDesc: pointer on a DMA Tx descriptor
* @param DMATxDesc_Checksum: specifies is the DMA Tx desc checksum insertion.
* This parameter can be one of the following values:
* @arg ETH_DMATxDesc_ChecksumByPass : Checksum bypass
* @arg ETH_DMATxDesc_ChecksumIPV4Header : IPv4 header checksum
* @arg ETH_DMATxDesc_ChecksumTCPUDPICMPSegment : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present
* @arg ETH_DMATxDesc_ChecksumTCPUDPICMPFull : TCP/UDP/ICMP checksum fully in hardware including pseudo header
* @retval None
*/
void ETH_DMATxDescChecksumInsertionConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_Checksum)
{
/* Check the parameters */
assert_param(IS_ETH_DMA_TXDESC_CHECKSUM(DMATxDesc_Checksum));
/* Set the selected DMA Tx desc checksum insertion control */
DMATxDesc->Status |= DMATxDesc_Checksum;
}
* @brief Enables or disables the DMA Tx Desc CRC.
* @param DMATxDesc: pointer on a DMA Tx descriptor
* @param NewState: new state of the specified DMA Tx Desc CRC.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescCRCCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DMA Tx Desc CRC */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATxDesc_DC);
}
else
{
/* Disable the selected DMA Tx Desc CRC */
DMATxDesc->Status |= ETH_DMATxDesc_DC;
}
}
/**
* @brief Enables or disables the DMA Tx Desc second address chained.
* @param DMATxDesc: pointer on a DMA Tx descriptor
* @param NewState: new state of the specified DMA Tx Desc second address chained.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescSecondAddressChainedCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DMA Tx Desc second address chained */
DMATxDesc->Status |= ETH_DMATxDesc_TCH;
}
else
{
/* Disable the selected DMA Tx Desc second address chained */
DMATxDesc->Status &=(~(uint32_t)ETH_DMATxDesc_TCH);
}
}
* @brief Enables or disables the DMA Tx Desc padding for frame shorter than 64 bytes.
* @param DMATxDesc: pointer on a DMA Tx descriptor
* @param NewState: new state of the specified DMA Tx Desc padding for frame shorter than 64 bytes.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescShortFramePaddingCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DMA Tx Desc padding for frame shorter than 64 bytes */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATxDesc_DP);
}
else
{
/* Disable the selected DMA Tx Desc padding for frame shorter than 64 bytes*/
DMATxDesc->Status |= ETH_DMATxDesc_DP;
}
}
/**
* @brief Configures the specified DMA Tx Desc buffer1 and buffer2 sizes.
* @param DMATxDesc: Pointer on a Tx desc
* @param BufferSize1: specifies the Tx desc buffer1 size.
* @param BufferSize2: specifies the Tx desc buffer2 size (put "0" if not used).
* @retval None
*/
void ETH_DMATxDescBufferSizeConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t BufferSize1, uint32_t BufferSize2)
{
/* Check the parameters */
assert_param(IS_ETH_DMATxDESC_BUFFER_SIZE(BufferSize1));
assert_param(IS_ETH_DMATxDESC_BUFFER_SIZE(BufferSize2));
/* Set the DMA Tx Desc buffer1 and buffer2 sizes values */
DMATxDesc->ControlBufferSize |= (BufferSize1 | (BufferSize2 << ETH_DMATXDESC_BUFFER2_SIZESHIFT));
}
/**
* @brief Checks whether the specified ETHERNET Rx Desc flag is set or not.
* @param DMARxDesc: pointer on a DMA Rx descriptor
* @param ETH_DMARxDescFlag: specifies the flag to check.
* This parameter can be one of the following values:
* @arg ETH_DMARxDesc_OWN: OWN bit: descriptor is owned by DMA engine
* @arg ETH_DMARxDesc_AFM: DA Filter Fail for the rx frame
* @arg ETH_DMARxDesc_ES: Error summary
* @arg ETH_DMARxDesc_DE: Descriptor error: no more descriptors for receive frame
* @arg ETH_DMARxDesc_SAF: SA Filter Fail for the received frame
* @arg ETH_DMARxDesc_LE: Frame size not matching with length field
* @arg ETH_DMARxDesc_OE: Overflow Error: Frame was damaged due to buffer overflow
* @arg ETH_DMARxDesc_VLAN: VLAN Tag: received frame is a VLAN frame
* @arg ETH_DMARxDesc_FS: First descriptor of the frame
* @arg ETH_DMARxDesc_LS: Last descriptor of the frame
* @arg ETH_DMARxDesc_IPV4HCE: IPC Checksum Error/Giant Frame: Rx Ipv4 header checksum error
* @arg ETH_DMARxDesc_LC: Late collision occurred during reception
* @arg ETH_DMARxDesc_FT: Frame type - Ethernet, otherwise 802.3
* @arg ETH_DMARxDesc_RWT: Receive Watchdog Timeout: watchdog timer expired during reception
* @arg ETH_DMARxDesc_RE: Receive error: error reported by MII interface
* @arg ETH_DMARxDesc_DE: Dribble bit error: frame contains non int multiple of 8 bits
* @arg ETH_DMARxDesc_CE: CRC error
* @arg ETH_DMARxDesc_MAMPCE: Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error
* @retval The new state of ETH_DMARxDescFlag (SET or RESET).
*/
FlagStatus ETH_GetDMARxDescFlagStatus(ETH_DMADESCTypeDef *DMARxDesc, uint32_t ETH_DMARxDescFlag)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_DMARxDESC_GET_FLAG(ETH_DMARxDescFlag));
if ((DMARxDesc->Status & ETH_DMARxDescFlag) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/**
* @brief Checks whether the specified ETHERNET PTP Rx Desc extended flag is set or not.
* @param DMAPTPRxDesc: pointer on a DMA PTP Rx descriptor
* @param ETH_DMAPTPRxDescFlag: specifies the extended flag to check.
* This parameter can be one of the following values:
* @arg ETH_DMAPTPRxDesc_PTPV: PTP version
* @arg ETH_DMAPTPRxDesc_PTPFT: PTP frame type
* @arg ETH_DMAPTPRxDesc_PTPMT: PTP message type
* @arg ETH_DMAPTPRxDesc_IPV6PR: IPv6 packet received
* @arg ETH_DMAPTPRxDesc_IPV4PR: IPv4 packet received
* @arg ETH_DMAPTPRxDesc_IPCB: IP checksum bypassed
* @arg ETH_DMAPTPRxDesc_IPPE: IP payload error
* @arg ETH_DMAPTPRxDesc_IPHE: IP header error
* @arg ETH_DMAPTPRxDesc_IPPT: IP payload type
* @retval The new state of ETH_DMAPTPRxDescExtendedFlag (SET or RESET).
*/
FlagStatus ETH_GetDMAPTPRxDescExtendedFlagStatus(ETH_DMADESCTypeDef *DMAPTPRxDesc, uint32_t ETH_DMAPTPRxDescExtendedFlag)
{
FlagStatus bitstatus = RESET;
assert_param(IS_ETH_DMAPTPRxDESC_GET_EXTENDED_FLAG(ETH_DMAPTPRxDescExtendedFlag));
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
* @brief Set the specified DMA Rx Desc Own bit.
* @param DMARxDesc: Pointer on a Rx desc
* @retval None
*/
void ETH_SetDMARxDescOwnBit(ETH_DMADESCTypeDef *DMARxDesc)
{
/* Set the DMA Rx Desc Own bit */
DMARxDesc->Status |= ETH_DMARxDesc_OWN;
}
* @brief Returns the specified DMA Rx Desc frame length.
* @param DMARxDesc: pointer on a DMA Rx descriptor
* @retval The Rx descriptor received frame length.
*/
uint32_t ETH_GetDMARxDescFrameLength(ETH_DMADESCTypeDef *DMARxDesc)
{
/* Return the Receive descriptor frame length */
return ((DMARxDesc->Status & ETH_DMARxDesc_FL) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT);
}
* @brief Enables or disables the specified DMA Rx Desc receive interrupt.
* @param DMARxDesc: Pointer on a Rx desc
* @param NewState: new state of the specified DMA Rx Desc interrupt.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMARxDescReceiveITConfig(ETH_DMADESCTypeDef *DMARxDesc, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the DMA Rx Desc receive interrupt */
DMARxDesc->ControlBufferSize &=(~(uint32_t)ETH_DMARxDesc_DIC);
}
else
{
/* Disable the DMA Rx Desc receive interrupt */
DMARxDesc->ControlBufferSize |= ETH_DMARxDesc_DIC;
}
}
/**
* @brief Returns the specified ETHERNET DMA Rx Desc buffer size.
* @param DMARxDesc: pointer on a DMA Rx descriptor
* @param DMARxDesc_Buffer: specifies the DMA Rx Desc buffer.
* This parameter can be any one of the following values:
* @arg ETH_DMARxDesc_Buffer1 : DMA Rx Desc Buffer1
* @arg ETH_DMARxDesc_Buffer2 : DMA Rx Desc Buffer2
* @retval The Receive descriptor frame length.
*/
uint32_t ETH_GetDMARxDescBufferSize(ETH_DMADESCTypeDef *DMARxDesc, uint32_t DMARxDesc_Buffer)
{
/* Check the parameters */
assert_param(IS_ETH_DMA_RXDESC_BUFFER(DMARxDesc_Buffer));
if(DMARxDesc_Buffer != ETH_DMARxDesc_Buffer1)
{
/* Return the DMA Rx Desc buffer2 size */
return ((DMARxDesc->ControlBufferSize & ETH_DMARxDesc_RBS2) >> ETH_DMARXDESC_BUFFER2_SIZESHIFT);
}
else
{
/* Return the DMA Rx Desc buffer1 size */
return (DMARxDesc->ControlBufferSize & ETH_DMARxDesc_RBS1);
}
}
/**
* @brief Get the size of the received packet.
* @param None
* @retval framelength: received packet size
*/
uint32_t ETH_GetRxPktSize(ETH_DMADESCTypeDef *DMARxDesc)
{
uint32_t frameLength = 0;
if(((DMARxDesc->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDesc->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) &&
((DMARxDesc->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET))
{
/* Get the size of the packet: including 4 bytes of the CRC */
frameLength = ETH_GetDMARxDescFrameLength(DMARxDesc);
}
/* Return Frame Length */
return frameLength;
}
/**
* @brief Enables or disables the Enhanced descriptor structure.
* @param NewState: new state of the Enhanced descriptor structure.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_EnhancedDescriptorCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable enhanced descriptor structure */
ETH->DMABMR |= ETH_DMABMR_EDE;
}
else
{
/* Disable enhanced descriptor structure */
ETH->DMABMR &= ~ETH_DMABMR_EDE;
}
}
#endif /* USE_ENHANCED_DMA_DESCRIPTORS */
/* DMA functions */
/******************************************************************************/
/**
* @brief Resets all MAC subsystem internal registers and logic.
* @param None
* @retval None
*/
void ETH_SoftwareReset(void)
{
/* Set the SWR bit: resets all MAC subsystem internal registers and logic */
/* After reset all the registers holds their respective reset values */
ETH->DMABMR |= ETH_DMABMR_SR;
}
* @brief Checks whether the ETHERNET software reset bit is set or not.
* @param None
* @retval The new state of DMA Bus Mode register SR bit (SET or RESET).
*/
FlagStatus ETH_GetSoftwareResetStatus(void)
{
FlagStatus bitstatus = RESET;
if((ETH->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
* @brief Checks whether the specified ETHERNET DMA flag is set or not.
* @param ETH_DMA_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* @arg ETH_DMA_FLAG_TST : Time-stamp trigger flag
* @arg ETH_DMA_FLAG_PMT : PMT flag
* @arg ETH_DMA_FLAG_MMC : MMC flag
* @arg ETH_DMA_FLAG_DataTransferError : Error bits 0-data buffer, 1-desc. access
* @arg ETH_DMA_FLAG_ReadWriteError : Error bits 0-write trnsf, 1-read transfr
* @arg ETH_DMA_FLAG_AccessError : Error bits 0-Rx DMA, 1-Tx DMA
* @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
* @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
* @arg ETH_DMA_FLAG_ER : Early receive flag
* @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
* @arg ETH_DMA_FLAG_ET : Early transmit flag
* @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
* @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
* @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
* @arg ETH_DMA_FLAG_R : Receive flag
* @arg ETH_DMA_FLAG_TU : Underflow flag
* @arg ETH_DMA_FLAG_RO : Overflow flag
* @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
* @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
* @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
* @arg ETH_DMA_FLAG_T : Transmit flag
* @retval The new state of ETH_DMA_FLAG (SET or RESET).
*/
FlagStatus ETH_GetDMAFlagStatus(uint32_t ETH_DMA_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_DMA_GET_IT(ETH_DMA_FLAG));
if ((ETH->DMASR & ETH_DMA_FLAG) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
* @brief Clears the ETHERNET抯 DMA pending flag.
* @param ETH_DMA_FLAG: specifies the flag to clear.
* This parameter can be any combination of the following values:
* @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
* @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
* @arg ETH_DMA_FLAG_ER : Early receive flag
* @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
* @arg ETH_DMA_FLAG_ETI : Early transmit flag
* @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
* @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
* @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
* @arg ETH_DMA_FLAG_R : Receive flag
* @arg ETH_DMA_FLAG_TU : Transmit Underflow flag
* @arg ETH_DMA_FLAG_RO : Receive Overflow flag
* @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
* @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
* @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
* @arg ETH_DMA_FLAG_T : Transmit flag
* @retval None
*/
void ETH_DMAClearFlag(uint32_t ETH_DMA_FLAG)
{
/* Check the parameters */
assert_param(IS_ETH_DMA_FLAG(ETH_DMA_FLAG));
/* Clear the selected ETHERNET DMA FLAG */
ETH->DMASR = (uint32_t) ETH_DMA_FLAG;
}
* @brief Enables or disables the specified ETHERNET DMA interrupts.
* @param ETH_DMA_IT: specifies the ETHERNET DMA interrupt sources to be
* enabled or disabled.
* This parameter can be any combination of the following values:
* @arg ETH_DMA_IT_NIS : Normal interrupt summary
* @arg ETH_DMA_IT_AIS : Abnormal interrupt summary
* @arg ETH_DMA_IT_ER : Early receive interrupt
* @arg ETH_DMA_IT_FBE : Fatal bus error interrupt
* @arg ETH_DMA_IT_ET : Early transmit interrupt
* @arg ETH_DMA_IT_RWT : Receive watchdog timeout interrupt
* @arg ETH_DMA_IT_RPS : Receive process stopped interrupt
* @arg ETH_DMA_IT_RBU : Receive buffer unavailable interrupt
* @arg ETH_DMA_IT_R : Receive interrupt
* @arg ETH_DMA_IT_TU : Underflow interrupt
* @arg ETH_DMA_IT_RO : Overflow interrupt
* @arg ETH_DMA_IT_TJT : Transmit jabber timeout interrupt
* @arg ETH_DMA_IT_TBU : Transmit buffer unavailable interrupt
* @arg ETH_DMA_IT_TPS : Transmit process stopped interrupt
* @arg ETH_DMA_IT_T : Transmit interrupt
* @param NewState: new state of the specified ETHERNET DMA interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMAITConfig(uint32_t ETH_DMA_IT, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_ETH_DMA_IT(ETH_DMA_IT));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected ETHERNET DMA interrupts */
ETH->DMAIER |= ETH_DMA_IT;
}
else
{
/* Disable the selected ETHERNET DMA interrupts */
ETH->DMAIER &=(~(uint32_t)ETH_DMA_IT);
}
}
* @brief Checks whether the specified ETHERNET DMA interrupt has occurred or not.
* @param ETH_DMA_IT: specifies the interrupt source to check.
* This parameter can be one of the following values:
* @arg ETH_DMA_IT_TST : Time-stamp trigger interrupt
* @arg ETH_DMA_IT_PMT : PMT interrupt
* @arg ETH_DMA_IT_MMC : MMC interrupt
* @arg ETH_DMA_IT_NIS : Normal interrupt summary
* @arg ETH_DMA_IT_AIS : Abnormal interrupt summary
* @arg ETH_DMA_IT_ER : Early receive interrupt
* @arg ETH_DMA_IT_FBE : Fatal bus error interrupt
* @arg ETH_DMA_IT_ET : Early transmit interrupt
* @arg ETH_DMA_IT_RWT : Receive watchdog timeout interrupt
* @arg ETH_DMA_IT_RPS : Receive process stopped interrupt
* @arg ETH_DMA_IT_RBU : Receive buffer unavailable interrupt
* @arg ETH_DMA_IT_R : Receive interrupt
* @arg ETH_DMA_IT_TU : Underflow interrupt
* @arg ETH_DMA_IT_RO : Overflow interrupt
* @arg ETH_DMA_IT_TJT : Transmit jabber timeout interrupt
* @arg ETH_DMA_IT_TBU : Transmit buffer unavailable interrupt
* @arg ETH_DMA_IT_TPS : Transmit process stopped interrupt
* @arg ETH_DMA_IT_T : Transmit interrupt
* @retval The new state of ETH_DMA_IT (SET or RESET).
*/
ITStatus ETH_GetDMAITStatus(uint32_t ETH_DMA_IT)
{
ITStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_DMA_GET_IT(ETH_DMA_IT));
if ((ETH->DMASR & ETH_DMA_IT) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
* @brief Clears the ETHERNET抯 DMA IT pending bit.
* @param ETH_DMA_IT: specifies the interrupt pending bit to clear.
* This parameter can be any combination of the following values:
* @arg ETH_DMA_IT_NIS : Normal interrupt summary
* @arg ETH_DMA_IT_AIS : Abnormal interrupt summary
* @arg ETH_DMA_IT_ER : Early receive interrupt
* @arg ETH_DMA_IT_FBE : Fatal bus error interrupt
* @arg ETH_DMA_IT_ETI : Early transmit interrupt
* @arg ETH_DMA_IT_RWT : Receive watchdog timeout interrupt
* @arg ETH_DMA_IT_RPS : Receive process stopped interrupt
* @arg ETH_DMA_IT_RBU : Receive buffer unavailable interrupt
* @arg ETH_DMA_IT_R : Receive interrupt
* @arg ETH_DMA_IT_TU : Transmit Underflow interrupt
* @arg ETH_DMA_IT_RO : Receive Overflow interrupt
* @arg ETH_DMA_IT_TJT : Transmit jabber timeout interrupt
* @arg ETH_DMA_IT_TBU : Transmit buffer unavailable interrupt
* @arg ETH_DMA_IT_TPS : Transmit process stopped interrupt
* @arg ETH_DMA_IT_T : Transmit interrupt
* @retval None
*/
void ETH_DMAClearITPendingBit(uint32_t ETH_DMA_IT)
{
/* Check the parameters */
assert_param(IS_ETH_DMA_IT(ETH_DMA_IT));
/* Clear the selected ETHERNET DMA IT */
ETH->DMASR = (uint32_t) ETH_DMA_IT;
}
* @brief Returns the ETHERNET DMA Transmit Process State.
* @param None
* @retval The new ETHERNET DMA Transmit Process State:
* This can be one of the following values:
* - ETH_DMA_TransmitProcess_Stopped : Stopped - Reset or Stop Tx Command issued
* - ETH_DMA_TransmitProcess_Fetching : Running - fetching the Tx descriptor
* - ETH_DMA_TransmitProcess_Waiting : Running - waiting for status
* - ETH_DMA_TransmitProcess_Reading : Running - reading the data from host memory
* - ETH_DMA_TransmitProcess_Suspended : Suspended - Tx Descriptor unavailable
* - ETH_DMA_TransmitProcess_Closing : Running - closing Rx descriptor
*/
uint32_t ETH_GetTransmitProcessState(void)
{
return ((uint32_t)(ETH->DMASR & ETH_DMASR_TS));
}
* @brief Returns the ETHERNET DMA Receive Process State.
* @param None
* @retval The new ETHERNET DMA Receive Process State:
* This can be one of the following values:
* - ETH_DMA_ReceiveProcess_Stopped : Stopped - Reset or Stop Rx Command issued
* - ETH_DMA_ReceiveProcess_Fetching : Running - fetching the Rx descriptor
* - ETH_DMA_ReceiveProcess_Waiting : Running - waiting for packet
* - ETH_DMA_ReceiveProcess_Suspended : Suspended - Rx Descriptor unavailable
* - ETH_DMA_ReceiveProcess_Closing : Running - closing descriptor
* - ETH_DMA_ReceiveProcess_Queuing : Running - queuing the receive frame into host memory
*/
uint32_t ETH_GetReceiveProcessState(void)
{
return ((uint32_t)(ETH->DMASR & ETH_DMASR_RS));
}
* @brief Clears the ETHERNET transmit FIFO.
* @param None
* @retval None
*/
void ETH_FlushTransmitFIFO(void)
{
/* Set the Flush Transmit FIFO bit */
ETH->DMAOMR |= ETH_DMAOMR_FTF;
}
* @brief Checks whether the ETHERNET flush transmit FIFO bit is cleared or not.
* @param None
* @retval The new state of ETHERNET flush transmit FIFO bit (SET or RESET).
*/
FlagStatus ETH_GetFlushTransmitFIFOStatus(void)
{
FlagStatus bitstatus = RESET;
if ((ETH->DMAOMR & ETH_DMAOMR_FTF) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
* @brief Enables or disables the DMA transmission.
* @param NewState: new state of the DMA transmission.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATransmissionCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the DMA transmission */
ETH->DMAOMR |= ETH_DMAOMR_ST;
}
else
{
/* Disable the DMA transmission */
ETH->DMAOMR &= ~ETH_DMAOMR_ST;
}
}
* @brief Enables or disables the DMA reception.
* @param NewState: new state of the DMA reception.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMAReceptionCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the DMA reception */
ETH->DMAOMR |= ETH_DMAOMR_SR;
}
else
{
/* Disable the DMA reception */
ETH->DMAOMR &= ~ETH_DMAOMR_SR;
}
}
* @brief Checks whether the specified ETHERNET DMA overflow flag is set or not.
* @param ETH_DMA_Overflow: specifies the DMA overflow flag to check.
* This parameter can be one of the following values:
* @arg ETH_DMA_Overflow_RxFIFOCounter : Overflow for FIFO Overflows Counter
* @arg ETH_DMA_Overflow_MissedFrameCounter : Overflow for Buffer Unavailable Missed Frame Counter
* @retval The new state of ETHERNET DMA overflow Flag (SET or RESET).
*/
FlagStatus ETH_GetDMAOverflowStatus(uint32_t ETH_DMA_Overflow)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_DMA_GET_OVERFLOW(ETH_DMA_Overflow));
if ((ETH->DMAMFBOCR & ETH_DMA_Overflow) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
* @brief Get the ETHERNET DMA Rx Overflow Missed Frame Counter value.
* @param None
* @retval The value of Rx overflow Missed Frame Counter.
*/
uint32_t ETH_GetRxOverflowMissedFrameCounter(void)
{
return ((uint32_t)((ETH->DMAMFBOCR & ETH_DMAMFBOCR_MFA)>>ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT));
}
* @brief Get the ETHERNET DMA Buffer Unavailable Missed Frame Counter value.
* @param None
* @retval The value of Buffer unavailable Missed Frame Counter.
*/
uint32_t ETH_GetBufferUnavailableMissedFrameCounter(void)
{
return ((uint32_t)(ETH->DMAMFBOCR) & ETH_DMAMFBOCR_MFC);
}
* @brief Get the ETHERNET DMA DMACHTDR register value.
* @param None
* @retval The value of the current Tx desc start address.
*/
uint32_t ETH_GetCurrentTxDescStartAddress(void)
{
return ((uint32_t)(ETH->DMACHTDR));
}
* @brief Get the ETHERNET DMA DMACHRDR register value.
* @param None
* @retval The value of the current Rx desc start address.
*/
uint32_t ETH_GetCurrentRxDescStartAddress(void)
{
return ((uint32_t)(ETH->DMACHRDR));
}
* @brief Get the ETHERNET DMA DMACHTBAR register value.
* @param None
* @retval The value of the current transmit descriptor data buffer address.
*/
uint32_t ETH_GetCurrentTxBufferAddress(void)
{
return ((uint32_t)(ETH->DMACHTBAR));
}
* @brief Get the ETHERNET DMA DMACHRBAR register value.
* @param None
* @retval The value of the current receive descriptor data buffer address.
*/
uint32_t ETH_GetCurrentRxBufferAddress(void)
{
return ((uint32_t)(ETH->DMACHRBAR));
}
* @brief Resumes the DMA Transmission by writing to the DmaTxPollDemand register
* (the data written could be anything). This forces the DMA to resume transmission.
* @param None
* @retval None.
*/
void ETH_ResumeDMATransmission(void)
{
ETH->DMATPDR = 0;
}
* @brief Resumes the DMA Transmission by writing to the DmaRxPollDemand register
* (the data written could be anything). This forces the DMA to resume reception.
* @param None
* @retval None.
*/
void ETH_ResumeDMAReception(void)
{
ETH->DMARPDR = 0;
}
* @brief Set the DMA Receive status watchdog timer register value
* @param Value: DMA Receive status watchdog timer register value
* @retval None
*/
void ETH_SetReceiveWatchdogTimer(uint8_t Value)
{
/* Set the DMA Receive status watchdog timer register */
ETH->DMARSWTR = Value;
}
/* PHY functions */
/******************************************************************************/
* @brief Read a PHY register
* @param PHYAddress: PHY device address, is the index of one of supported 32 PHY devices.
* This parameter can be one of the following values: 0,..,31
* @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
* This parameter can be one of the following values:
* @arg PHY_BCR: Transceiver Basic Control Register
* @arg PHY_BSR: Transceiver Basic Status Register
* @arg PHY_SR : Transceiver Status Register
* @arg More PHY register could be read depending on the used PHY
* @retval ETH_ERROR: in case of timeout
* MAC MIIDR register value: Data read from the selected PHY register (correct read )
*/
uint16_t ETH_ReadPHYRegister(uint16_t PHYAddress, uint16_t PHYReg)
{
uint32_t tmpreg = 0;
__IO uint32_t timeout = 0;
/* Check the parameters */
assert_param(IS_ETH_PHY_ADDRESS(PHYAddress));
assert_param(IS_ETH_PHY_REG(PHYReg));
/* Get the ETHERNET MACMIIAR value */
tmpreg = ETH->MACMIIAR;
/* Keep only the CSR Clock Range CR[2:0] bits value */
tmpreg &= ~MACMIIAR_CR_MASK;
/* Prepare the MII address register value */
tmpreg |=(((uint32_t)PHYAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */
tmpreg |=(((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */
tmpreg &= ~ETH_MACMIIAR_MW; /* Set the read mode */
tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
/* Write the result value into the MII Address register */
ETH->MACMIIAR = tmpreg;
/* Check for the Busy flag */
do
{
timeout++;
tmpreg = ETH->MACMIIAR;
} while ((tmpreg & ETH_MACMIIAR_MB) && (timeout < (uint32_t)PHY_READ_TO));
/* Return ERROR in case of timeout */
if(timeout == PHY_READ_TO)
{
return (uint16_t)ETH_ERROR;
}
/* Return data register value */
return (uint16_t)(ETH->MACMIIDR);
}
* @brief Write to a PHY register
* @param PHYAddress: PHY device address, is the index of one of supported 32 PHY devices.
* This parameter can be one of the following values: 0,..,31
* @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
* This parameter can be one of the following values:
* @arg PHY_BCR : Transceiver Control Register
* @arg More PHY register could be written depending on the used PHY
* @param PHYValue: the value to write
* @retval ETH_ERROR: in case of timeout
* ETH_SUCCESS: for correct write
*/
uint32_t ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)
{
uint32_t tmpreg = 0;
__IO uint32_t timeout = 0;
/* Check the parameters */
assert_param(IS_ETH_PHY_ADDRESS(PHYAddress));
assert_param(IS_ETH_PHY_REG(PHYReg));
/* Get the ETHERNET MACMIIAR value */
tmpreg = ETH->MACMIIAR;
/* Keep only the CSR Clock Range CR[2:0] bits value */
tmpreg &= ~MACMIIAR_CR_MASK;
/* Prepare the MII register address value */
tmpreg |=(((uint32_t)PHYAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */
tmpreg |=(((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */
tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */
tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
/* Give the value to the MII data register */
ETH->MACMIIDR = PHYValue;
/* Write the result value into the MII Address register */
ETH->MACMIIAR = tmpreg;
/* Check for the Busy flag */
do
{
timeout++;
tmpreg = ETH->MACMIIAR;
} while ((tmpreg & ETH_MACMIIAR_MB) && (timeout < (uint32_t)PHY_WRITE_TO));
/* Return ERROR in case of timeout */
if(timeout == PHY_WRITE_TO)
{
return ETH_ERROR;
}
/* Return SUCCESS */
return ETH_SUCCESS;
}
* @brief Enables or disables the PHY loopBack mode.
* @Note: Don't be confused with ETH_MACLoopBackCmd function which enables internal
* loopback at MII level
* @param PHYAddress: PHY device address, is the index of one of supported 32 PHY devices.
* @param NewState: new state of the PHY loopBack mode.
* This parameter can be: ENABLE or DISABLE.
* @retval ETH_ERROR: in case of bad PHY configuration
* ETH_SUCCESS: for correct PHY configuration
*/
uint32_t ETH_PHYLoopBackCmd(uint16_t PHYAddress, FunctionalState NewState)
{
uint16_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_ETH_PHY_ADDRESS(PHYAddress));
assert_param(IS_FUNCTIONAL_STATE(NewState));
/* Get the PHY configuration to update it */
tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_BCR);
if (NewState != DISABLE)
{
/* Enable the PHY loopback mode */
tmpreg |= PHY_Loopback;
}
else
{
/* Disable the PHY loopback mode: normal mode */
tmpreg &= (uint16_t)(~(uint16_t)PHY_Loopback);
}
/* Update the PHY control register with the new configuration */
if(ETH_WritePHYRegister(PHYAddress, PHY_BCR, tmpreg) != (uint32_t)RESET)
{
return ETH_SUCCESS;
}
else
{
/* Return SUCCESS */
return ETH_ERROR;
}
}
/* Power Management(PMT) functions */
/******************************************************************************/
/**
* @brief Reset Wakeup frame filter register pointer.
* @param None
* @retval None
*/
void ETH_ResetWakeUpFrameFilterRegisterPointer(void)
{
/* Resets the Remote Wake-up Frame Filter register pointer to 0x0000 */
ETH->MACPMTCSR |= ETH_MACPMTCSR_WFFRPR;
}
* @brief Populates the remote wakeup frame registers.
* @param Buffer: Pointer on remote WakeUp Frame Filter Register buffer data (8 words).
* @retval None
*/
void ETH_SetWakeUpFrameFilterRegister(uint32_t *Buffer)
{
uint32_t i = 0;
/* Fill Remote Wake-up Frame Filter register with Buffer data */
for(i =0; i<ETH_WAKEUP_REGISTER_LENGTH; i++)
{
/* Write each time to the same register */
ETH->MACRWUFFR = Buffer[i];
}
}
* @brief Enables or disables any unicast packet filtered by the MAC address
* recognition to be a wake-up frame.
* @param NewState: new state of the MAC Global Unicast Wake-Up.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_GlobalUnicastWakeUpCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MAC Global Unicast Wake-Up */
ETH->MACPMTCSR |= ETH_MACPMTCSR_GU;
}
else
{
/* Disable the MAC Global Unicast Wake-Up */
ETH->MACPMTCSR &= ~ETH_MACPMTCSR_GU;
}
}
* @brief Checks whether the specified ETHERNET PMT flag is set or not.
* @param ETH_PMT_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset
* @arg ETH_PMT_FLAG_WUFR : Wake-Up Frame Received
* @arg ETH_PMT_FLAG_MPR : Magic Packet Received
* @retval The new state of ETHERNET PMT Flag (SET or RESET).
*/
FlagStatus ETH_GetPMTFlagStatus(uint32_t ETH_PMT_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_PMT_GET_FLAG(ETH_PMT_FLAG));
if ((ETH->MACPMTCSR & ETH_PMT_FLAG) != (uint32_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
* @brief Enables or disables the MAC Wake-Up Frame Detection.
* @param NewState: new state of the MAC Wake-Up Frame Detection.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_WakeUpFrameDetectionCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MAC Wake-Up Frame Detection */
ETH->MACPMTCSR |= ETH_MACPMTCSR_WFE;
}
else
{
/* Disable the MAC Wake-Up Frame Detection */
ETH->MACPMTCSR &= ~ETH_MACPMTCSR_WFE;
}
}
* @brief Enables or disables the MAC Magic Packet Detection.
* @param NewState: new state of the MAC Magic Packet Detection.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MagicPacketDetectionCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MAC Magic Packet Detection */
ETH->MACPMTCSR |= ETH_MACPMTCSR_MPE;
}
else
{
/* Disable the MAC Magic Packet Detection */
ETH->MACPMTCSR &= ~ETH_MACPMTCSR_MPE;
}
}
* @brief Enables or disables the MAC Power Down.
* @param NewState: new state of the MAC Power Down.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_PowerDownCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MAC Power Down */
/* This puts the MAC in power down mode */
ETH->MACPMTCSR |= ETH_MACPMTCSR_PD;
}
else
{
/* Disable the MAC Power Down */
ETH->MACPMTCSR &= ~ETH_MACPMTCSR_PD;
}
}
/* MMC functions */
/******************************************************************************/
/**
* @brief Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16)
* @param None
* @retval None
*/
void ETH_MMCCounterFullPreset(void)
{
/* Preset and Initialize the MMC counters to almost-full value */
ETH->MMCCR |= ETH_MMCCR_MCFHP | ETH_MMCCR_MCP;
}
* @brief Preset and Initialize the MMC counters to almost-hal value: 0x7FFF_FFF0 (half - 16).
* @param None
* @retval None
*/
void ETH_MMCCounterHalfPreset(void)
{
/* Preset the MMC counters to almost-full value */
ETH->MMCCR &= ~ETH_MMCCR_MCFHP;
/* Initialize the MMC counters to almost-half value */
ETH->MMCCR |= ETH_MMCCR_MCP;
}
* @brief Enables or disables the MMC Counter Freeze.
* @param NewState: new state of the MMC Counter Freeze.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MMCCounterFreezeCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MMC Counter Freeze */
ETH->MMCCR |= ETH_MMCCR_MCF;
}
else
{
/* Disable the MMC Counter Freeze */
ETH->MMCCR &= ~ETH_MMCCR_MCF;
}
}
* @brief Enables or disables the MMC Reset On Read.
* @param NewState: new state of the MMC Reset On Read.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MMCResetOnReadCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the MMC Counter reset on read */
ETH->MMCCR |= ETH_MMCCR_ROR;
}
else
{
/* Disable the MMC Counter reset on read */
ETH->MMCCR &= ~ETH_MMCCR_ROR;
}
}
* @brief Enables or disables the MMC Counter Stop Rollover.
* @param NewState: new state of the MMC Counter Stop Rollover.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MMCCounterRolloverCmd(FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Disable the MMC Counter Stop Rollover */
ETH->MMCCR &= ~ETH_MMCCR_CSR;
}
else
{
/* Enable the MMC Counter Stop Rollover */
ETH->MMCCR |= ETH_MMCCR_CSR;
}
}
* @brief Resets the MMC Counters.
* @param None
* @retval None
*/
void ETH_MMCCountersReset(void)
{
/* Resets the MMC Counters */
ETH->MMCCR |= ETH_MMCCR_CR;
}
* @brief Enables or disables the specified ETHERNET MMC interrupts.
* @param ETH_MMC_IT: specifies the ETHERNET MMC interrupt sources to be enabled or disabled.
* This parameter can be any combination of Tx interrupt or
* any combination of Rx interrupt (but not both)of the following values:
* @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value
* @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value
* @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value
* @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value
* @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value
* @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value
* @param NewState: new state of the specified ETHERNET MMC interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MMCITConfig(uint32_t ETH_MMC_IT, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_ETH_MMC_IT(ETH_MMC_IT));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if ((ETH_MMC_IT & (uint32_t)0x10000000) != (uint32_t)RESET)
{
/* Remove Register mak from IT */
ETH_MMC_IT &= 0xEFFFFFFF;
/* ETHERNET MMC Rx interrupts selected */
if (NewState != DISABLE)
{
/* Enable the selected ETHERNET MMC interrupts */
ETH->MMCRIMR &=(~(uint32_t)ETH_MMC_IT);
}
else
{
/* Disable the selected ETHERNET MMC interrupts */
ETH->MMCRIMR |= ETH_MMC_IT;
}
}
else
{
/* ETHERNET MMC Tx interrupts selected */
if (NewState != DISABLE)
{
/* Enable the selected ETHERNET MMC interrupts */
ETH->MMCTIMR &=(~(uint32_t)ETH_MMC_IT);
}
else
{
/* Disable the selected ETHERNET MMC interrupts */
ETH->MMCTIMR |= ETH_MMC_IT;
}
}
}
* @brief Checks whether the specified ETHERNET MMC IT is set or not.
* @param ETH_MMC_IT: specifies the ETHERNET MMC interrupt.
* This parameter can be one of the following values:
* @arg ETH_MMC_IT_TxFCGC: When Tx good frame counter reaches half the maximum value
* @arg ETH_MMC_IT_TxMCGC: When Tx good multi col counter reaches half the maximum value
* @arg ETH_MMC_IT_TxSCGC: When Tx good single col counter reaches half the maximum value
* @arg ETH_MMC_IT_RxUGFC: When Rx good unicast frames counter reaches half the maximum value
* @arg ETH_MMC_IT_RxAEC : When Rx alignment error counter reaches half the maximum value
* @arg ETH_MMC_IT_RxCEC : When Rx crc error counter reaches half the maximum value
* @retval The value of ETHERNET MMC IT (SET or RESET).
*/
ITStatus ETH_GetMMCITStatus(uint32_t ETH_MMC_IT)
{
ITStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_ETH_MMC_GET_IT(ETH_MMC_IT));
if ((ETH_MMC_IT & (uint32_t)0x10000000) != (uint32_t)RESET)
{
/* ETHERNET MMC Rx interrupts selected */
/* Check if the ETHERNET MMC Rx selected interrupt is enabled and occurred */
if ((((ETH->MMCRIR & ETH_MMC_IT) != (uint32_t)RESET)) && ((ETH->MMCRIMR & ETH_MMC_IT) == (uint32_t)RESET))
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
else
{
/* ETHERNET MMC Tx interrupts selected */
/* Check if the ETHERNET MMC Tx selected interrupt is enabled and occurred */
if ((((ETH->MMCTIR & ETH_MMC_IT) != (uint32_t)RESET)) && ((ETH->MMCRIMR & ETH_MMC_IT) == (uint32_t)RESET))
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
return bitstatus;
}
* @brief Get the specified ETHERNET MMC register value.
* @param ETH_MMCReg: specifies the ETHERNET MMC register.
* This parameter can be one of the following values:
* @arg ETH_MMCCR : MMC CR register
* @arg ETH_MMCRIR : MMC RIR register
* @arg ETH_MMCTIR : MMC TIR register
* @arg ETH_MMCRIMR : MMC RIMR register
* @arg ETH_MMCTIMR : MMC TIMR register
* @arg ETH_MMCTGFSCCR : MMC TGFSCCR register
* @arg ETH_MMCTGFMSCCR: MMC TGFMSCCR register
* @arg ETH_MMCTGFCR : MMC TGFCR register
* @arg ETH_MMCRFCECR : MMC RFCECR register
* @arg ETH_MMCRFAECR : MMC RFAECR register
* @arg ETH_MMCRGUFCR : MMC RGUFCRregister
* @retval The value of ETHERNET MMC Register value.
*/
uint32_t ETH_GetMMCRegister(uint32_t ETH_MMCReg)
{
/* Check the parameters */
assert_param(IS_ETH_MMC_REGISTER(ETH_MMCReg));
/* Return the selected register value */
return (*(__IO uint32_t *)(ETH_MAC_BASE + ETH_MMCReg));
}
/**
* @}
*/
* @}
*/