专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
OMAPL138以太网通讯无法ping通,烦烦烦,求大神帮忙
2019-03-26 16:25
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
DSP
10841
4
1238
我用的是OMAPL138的芯片,网卡是KSZ8041FTL,用的平台是CCS3.3,调试dsp,并且移植了Ucos操作系统,我把板子的网口和主机的网口用网线连起来,然后在主机的cmd中ping板子的IP地址,到目前为止就出现2次ping通,而且ping通了一下就超时了,一次丢包率是50%,另一次是75%。到目前为止我还找不到啥问题,可否请知道的人士请帮忙啊,可以直接QQ联系744936375. 此帖出自
小平头技术问答
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
kooking
1楼-- · 2019-03-26 23:42
< CCS下的网络测试,基本上都是回环测试,自发自收。
在U-Boot下可以通过板卡ping通主机,可能无法从主机ping通板卡。
进入操作系统后(如Linux),板卡和主机可以互相ping通。
加载中...
HMILY_YLIMH
2楼-- · 2019-03-27 01:49
< 关键我现在没有在linux下用,只在平常的PC机上用CCS,而且程序里面移植了Ucos代码,现在不知道从何下手了,网络部分初始化都是按照MDIO&EMAC文档上面操作的,其他的话,也不知道从何调试开始。
加载中...
kooking
3楼-- · 2019-03-27 07:49
精彩回答 2 元偷偷看……
加载中...
HMILY_YLIMH
4楼-- · 2019-03-27 13:09
代码其中之一: //-----------------------------------------------------------------------------
// file evmomapl138_emac.c
// rief implementation of the emac/mdio driver for the OMAP-L138 EVM.
//
//-----------------------------------------------------------------------------
#include "stdio.h"
#include "string.h"
#include "os_cpu_isr.h"
#include "includes.h"
#include "inc/evmomapl138_emac.h"
#include "inc/types.h"
#include "evmomapl138.h"
#include "evmomapl138_timer.h"
#include "inc/ethernet_smsc.h"
#include "inc/evmomapl138_gpio.h"
#include "inc/evmomapl138_i2c_gpio.h"
#include "inc/evmomapl138_cdce913.h"
#include "evmomapl138_aintc.h" // add_ISR需要
#include "netif/etharp.h"
#include "Emac_des.h"
#include "ethernetif.h"
#ifndef USE_HDTIME_DLY
#define USTIMER_delay(x)
#endif //USE_HDTIME_DLY
#define MAX_POLLING_NUM (0x0FFFFFFF)
//-----------------------------------------------------------------------------
// Private Defines and Macros
//-----------------------------------------------------------------------------
// INTCONTROL >> INTPRESCALE , number of EMAC clk period within a 4 us time window
#define NUM_INTPRESCALE (4*SYSCLOCK4_HZ/1000000) //4/(1000000/SYSCLOCK4_HZ) , 4us
// mdio clock divide down value.
#define MDIO_CLK_FREQ_HZ (2000000) //2M HZ
#define MDIO_CLK_DIVISOR ((SYSCLOCK4_HZ / MDIO_CLK_FREQ_HZ) - 1)
// rx / tx desriptor memory offsets.
#define RX_DESC_OFFSET (0)
#define TX_DESC_OFFSET (0x1000)
//MII pinmux
#define PINMUX_MII_REG_0 (2)
#define PINMUX_MII_MASK_0 (0xFFFFFFF0)
#define PINMUX_MII_VAL_0 (0x88888880)
#define PINMUX_MII_REG_1 (3)
#define PINMUX_MII_MASK_1 (0xFFFFFFFF)
#define PINMUX_MII_VAL_1 (0x88888888)
//RMII pinmux
#define PINMUX_RMII_REG_0 (14)
#define PINMUX_RMII_MASK_0 (0xFFFFFF00)
#define PINMUX_RMII_VAL_0 (0x88888800)
#define PINMUX_RMII_REG_1 (15)
#define PINMUX_RMII_MASK_1 (0x000000FF)
#define PINMUX_RMII_VAL_1 (0x00000080)
//MDIO pinmux
#define PINMUX_MDIO_REG (4)
#define PINMUX_MDIO_MASK (0x000000FF)
#define PINMUX_MDIO_VAL (0x00000088)
//GPIO pinmux
#define PINMUX_MII_MDIO_EN_REG (6)
#define PINMUX_MII_MDIO_EN_MASK (0x000000F0)
#define PINMUX_MII_MDIO_EN_VAL (0x00000080)
//
#define EMAC_RMII_SPEED_100 (0x00008000)
//-----------------------------------------------------------------------------
// Private Static Variables
//-----------------------------------------------------------------------------
static uint8_t g_active_phy_id = 0x0; //我们选用的L138是phy_id是为0的
//-----------------------------------------------------------------------------
// Private Function Prototypes
//-----------------------------------------------------------------------------
static uint32_t initMdioPhy(void);
static uint8_t isLinkActive(uint8_t in_phy);
static uint16_t phyRegRead(uint8_t in_phy, uint8_t in_reg);
static void phyRegWrite(uint8_t in_phy, uint8_t in_reg, uint16_t in_data);
//----------------------------------------------------------------------------
//Public value definitions
//----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Public Function Definitions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// rief initialize the EMAC and MDIO for use.
//
// param none.
//
// eturn uint32_t
// ERR_NO_ERROR - everything is ok...emac ready to use.
// ERR_INIT_FAIL - something happened during initialization.
//-----------------------------------------------------------------------------
uint32_t Lowlevel_Emac_Init(void)
{
uint32_t rtn = 0;
uint32_t i;
SYS_ARCH_DECL_PROTECT(sr);
SYS_ARCH_PROTECT(sr);
// reset emac module.
EMAC->SOFTRESET = 1;
while (EMAC->SOFTRESET != 0) {;}
//init emac control module
//----------------------------------------
// AddISR() -- configuration of the interrupt to the CPU.
//AINTC --Number34 core0 Receive Interrupt
AddISR(34,L138Ethif_RxHandler,(void *)0);
aintcRegs->SICR = 34; //clear index status
aintcRegs->CMR8 = 0x00170000;//(Sets channel map, system interrupt --> host channel interrupt )
aintcRegs->EISR = 34; //Enable Index Set Register
aintcRegs->SECR2 = 0x00000004; //34 status clear
//configure Tx Interrupt Handler
AddISR(35,L138Ethif_TxHandler,(void *)0);
aintcRegs->SICR = 35; //clear index status
aintcRegs->CMR8 = 0x18000000; //SETS CHannel map
aintcRegs->EISR = 35; //Enable Index Set Register
aintcRegs->SECR2 = 0x00000008; //clear 35 status register ...
// configure INTCONTORL , CnRXIMAX, CnTXIMAX,
EMAC_CTRL->INTCTL = (NUM_INTPRESCALE| 0x00000300);
EMAC_CTRL->C0RXIMAX = 2;
EMAC_CTRL->C0TXIMAX = 2;
//--& init emac module.
//------------------
// make sure emac control interrupts are disabled.
EMAC_CTRL->C0RXTHRESHEN = 0;
EMAC_CTRL->C1RXTHRESHEN = 0;
EMAC_CTRL->C2RXTHRESHEN = 0;
EMAC_CTRL->C0RXEN = 0;
EMAC_CTRL->C1RXEN = 0;
EMAC_CTRL->C2RXEN = 0;
EMAC_CTRL->C0TXEN = 0;
EMAC_CTRL->C1TXEN = 0;
EMAC_CTRL->C2TXEN = 0;
EMAC_CTRL->C0MISCEN = 0;
EMAC_CTRL->C1MISCEN = 0;
EMAC_CTRL->C2MISCEN = 0;
EVMOMAPL138_pinmuxConfig(PINMUX_MDIO_REG, PINMUX_MDIO_MASK, PINMUX_MDIO_VAL); //MDIO shared by both RMII and MII
// EVMOMAPL138_pinmuxConfig(PINMUX_MII_MDIO_EN_REG, PINMUX_MII_MDIO_EN_MASK, PINMUX_MII_MDIO_EN_VAL); //pinmux to select gpio bank2 pin6
//PINMUXING
EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_0, PINMUX_MII_MASK_0, PINMUX_MII_VAL_0);
EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_1, PINMUX_MII_MASK_1, PINMUX_MII_VAL_1);
SYSCONFIG->KICKR[0] = KICK0R_UNLOCK;
SYSCONFIG->KICKR[1] = KICK1R_UNLOCK;
CLRBIT(SYSCONFIG->CFGCHIP[3], 0x00000100); //select mii mode !
//as software reset consideration, do this here
EVMOMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_EMAC, PSC_ENABLE);
// clear MAC control register, receive control register, transmiter control register
EMAC->MACCONTROL = 0;
EMAC->RXCONTROL = 0;
EMAC->TXCONTROL = 0;
// init header descriptor pointer regs to 0.
for (i = 0; i < 8; i++)
{
EMAC->TXHDP[i] = 0;
EMAC->RXHDP[i] = 0;
}
// clear all statistic register
#ifndef BOOT
memset((uint8_t *)NET_STAT_REG_BASE, 0, NET_STAT_REG_NUM_BYTES);
#endif
// setup local MAC address, only channel 0 is valid.
// program all 8, only need to set MACADDRHI for index = 0.
// use duplicate address for all unused channels.
// TODO: read MAC address from SPI flash.
//写的顺序是MACINDEX, ADDRHI, ADDRLO,由于高40bits是共享的
//只用了通道0,EMAC->MACADDRLO = 0X000000506 |VALID|MATCHFILT
for (i = 1; i < 8; i++)
{
EMAC->MACINDEX = i;
EMAC->MACADDRHI = 0x42020304; //index -> hi -> lo
EMAC->MACADDRLO = 0x00000506;
}
EMAC->MACINDEX = 0;
EMAC->MACADDRHI = 0x42020304;
// channel bit = 0, match mac address = 1
EMAC->MACADDRLO = 0x00000506 | MACADDRLO_VALID | MACADDRLO_MATCHFILT;
// for use tx DMA descriptor configuration:
EMAC->MACSRCADDRHI = 0x42020304;
EMAC->MACSRCADDRLO = 0x00000506;
// initialize receive channel free buffer count regs, if buffer flow
// control is to be enabled.
// NOTE: this example does not use buffer flow control.
// enable unicast chan 0 only.
EMAC->RXUNICASTSET = 0x01;
// no multicast addresses, clear MAC address hash registers.
EMAC->MACHASH1 = 0;
EMAC->MACHASH2 = 0;
// 只允许broadcast的ARP数据包,和发给自己的包,以太网的其他数据不放入Memmory里去.
//但是我单独设置RxBroadEn却没有作用。
EMAC->RXMBPENABLE = 0;
SETBIT(EMAC->RXMBPENABLE, (RXBROADEN|RXCAFEN));
// EMAC->RXMBPENABLE = 0x01E02020; //enable reception of almost all frames inc error
//11. configure MACCONTROL (Don't set GMIIEN Bit)
SETBIT(EMAC->MACCONTROL, (RMIISPEED|FULLDUPLEX|TXPACE)); //RMII_SPEED,为了适应RMII
// 12. Clear all unused channel interrupt bits by writing the receive interrupt mask clear register
//(RXINTMASKCLEAR) and the transmit interrupt mask clear register (TXINTMASKCLEAR).
EMAC->RXINTMASKCLEAR |= 0xFE; //RX channel 0的中断不屏蔽
EMAC->TXINTMASKCLEAR |= 0xFE; //TX CH0 中断屏蔽
//13. Modify RXINTMASKSET, TXINTMASKSET,MACINTMASKSET
EMAC->RXINTMASKSET |= 0x01;
EMAC->TXINTMASKSET |= 0x01;
EMAC->MACINTMASKCLR = 0x03; //disabled host mask , stat interrupt
//14 init receive buffer offset and max length.
EMAC->RXBUFFEROFFSET = 0;
EMAC->RXMAXLEN = MAX_PACKET_SIZE;
// initialize receive/transmit descriptor list queues.
Emac_des_init(); //modify 04/18
//16 enable receive / transmit DMA controllers...set GMIIEN.
EMAC->RXCONTROL = 1;
EMAC->TXCONTROL = 1;
SETBIT(EMAC->MACCONTROL, GMIIEN );
#if 1 //文档说未经测试,删除貌似没效果啊,先不管它
SETBIT(EMAC->EMCONTROL, SOFT);
#endif
// -->& init mdio / phy, 再加上MAC中断
//-----------------
rtn = initMdioPhy();
// if (rtn != ERR_NO_ERROR)
// return (rtn);
SYS_ARCH_UNPROTECT(sr);
//17>Enable the device interrupt in EMAC control module registers CnRXTHRESHEN, CnRXEN, CnTXEN,
//and CnMISCEN. -- LP Add
EMAC_CTRL->C0RXEN = 1; //C0RXPULSE Is Enabled for RX channel 0
EMAC_CTRL->C0TXEN = 1; //C0TXPULSE IS enabled for tx channel 0
return (rtn);
}
//-----------------------------------------------------------------------------
// rief power on the phy.
//
// param none.
//
// eturn uint32_t
// ERR_NO_ERROR - everything is ok...phy is on.
// ERR_FAIL - something happened and could not power on.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyPowerOn(void)
{
uint32_t rtn;
uint16_t ctrl_reg;
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
if (!CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
{
// phy is already on...nothing left to do.
#if DEBUG
printf("phy powered, basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// clear power down bit and write back to phy.
CLRBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN);
phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
// short delay, then read the reg back to verify loopback is enabled.
USTIMER_delay(500);
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
if (!CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
{
// phy is powered...return success.
#if DEBUG
printf("phy powered, basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// power down bit did not clear...return error.
#if DEBUG
printf("power down did not clear: %04x ", ctrl_reg);
#endif
rtn = ERR_FAIL;
}
}
return (rtn);
}
//-----------------------------------------------------------------------------
// rief power down the phy.
//
// param none.
//
// eturn uint32_t
// ERR_NO_ERROR - everything is ok...phy is powered down.
// ERR_FAIL - something happened and could not power down.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyPowerDown(void)
{
uint32_t rtn;
uint16_t ctrl_reg;
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
if(CHKBIT(ctrl_reg, BASIC_CTRL_ISOLATE) && CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
{
// phy is already powered down...nothing left to do.
#if DEBUG
printf("phy powered down, basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// set power down bit and write back to phy.
SETBIT(ctrl_reg, BASIC_CTRL_ISOLATE | BASIC_CTRL_POWER_DOWN);
phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
// short delay, then read the reg back to verify loopback is disabled.
USTIMER_delay(500);
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
if(CHKBIT(ctrl_reg, BASIC_CTRL_ISOLATE) && CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
{
// phy is powered down...return success.
#if DEBUG
printf("phy powered down, basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// power down bit did not set...return error.
#if DEBUG
printf("power down bit did not set: %04x ", ctrl_reg);
#endif
rtn = ERR_FAIL;
}
}
return (rtn);
}
//-----------------------------------------------------------------------------
// rief put the phy into loopback mode.
//
// param none.
//
// eturn uint32_t
// ERR_NO_ERROR - everything is ok...phy is in loopback mode.
// ERR_FAIL - something happened and could not enter loopback.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyEnterLoopback(void)
{
uint32_t rtn;
uint16_t ctrl_reg;
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
rtn = ERR_NO_ERROR;
if (ctrl_reg & BASIC_CTRL_LOOPBACK)
{
// loopback is already enabled...nothing left to do.
#if DEBUG
printf("loopback enabled, basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// set loopback bit and write back to phy.
ctrl_reg |= BASIC_CTRL_LOOPBACK;
phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
// short delay, then read the reg back to verify loopback is enabled.
USTIMER_delay(500);
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
if (ctrl_reg & BASIC_CTRL_LOOPBACK)
{
// loopback is enabled...return success.
#if DEBUG
printf("loopback enabled , basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// loopback bit did not get set...return error.
#if DEBUG
printf("loopback did not set: %04x ", ctrl_reg);
#endif
rtn = ERR_FAIL;
}
}
return (rtn);
}
//-----------------------------------------------------------------------------
// rief remove the phy from loopback mode.
//
// param none.
//
// eturn uint32_t
// ERR_NO_ERROR - everything is ok...phy is out of loopback mode.
// ERR_FAIL - something happened and could not disable loopback.
//-----------------------------------------------------------------------------
uint32_t EMAC_phyExitLoopback(void)
{
uint32_t rtn;
uint16_t ctrl_reg;
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
if (!(ctrl_reg & BASIC_CTRL_LOOPBACK))
{
// loopback is already disabled...nothing left to do.
#if DEBUG
printf("loopback disabled, basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// clear loopback bit and write back to phy.
ctrl_reg &= ~BASIC_CTRL_LOOPBACK;
phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
// short delay, then read the reg back to verify loopback is disabled.
USTIMER_delay(5);
ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
if (!(ctrl_reg & BASIC_CTRL_LOOPBACK))
{
// loopback is disabled...return success.
#if DEBUG
printf("loopback disabled , basic ctrl reg: %04x ", ctrl_reg);
#endif
rtn = ERR_NO_ERROR;
}
else
{
// loopback bit did not clear...return error.
#if DEBUG
printf("loopback did not clear: %04x ", ctrl_reg);
#endif
rtn = ERR_FAIL;
}
}
return (rtn);
}
//-----------------------------------------------------------------------------
// Private Function Definitions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// initialize the mdio module and identify the active phy.
//-----------------------------------------------------------------------------
uint32_t initMdioPhy(void)
{
uint32_t i = 0;
uint16_t phy_reg;
// init the mdio regs.
MDIO->CONTROL = MDIO_CTRL_ENABLE |
MDIO_CTRL_FAULT |
MDIO_CTRL_FAULTENB |
MDIO_CLK_DIVISOR;
while (CHKBIT(MDIO->CONTROL, MDIO_CTRL_IDLE)) {;}
#if DEBUG_MDIO_LINK
// look for an active phy...takes up to 50 us for each phy to be checked.
//以下只是调试时有用,真正烧入程序中去时,是不行的,因为没插上网线,AddISR还要上的。
for (i = 0; i < MAX_POLLING_NUM; i++)
{
if (MDIO->ALIVE)
{
// at least one phy has acknowledged us...break the loop.
break;
}
USTIMER_delay(50); // polling , 采用polling方式,LP- delete
}
while(!(MDIO->ALIVE)); //还是没有找到PHY,它就在此处挂住
#else
while(!(MDIO->ALIVE)) //没有网线连接
{
i++;
if(i >= MAX_POLLING_NUM)
{
break;
}
}//只是为了延时让phy与PC自适应的时涞却??
#endif
//
g_active_phy_id = 0; //确实是个发生错误,现在可以读到PHY。
MDIO->USERPHYSEL0 = 0; //USERPHYSEL0 = 0,表示PHY0被选中监控。
#if DEBUG_MDIO_LINK
phy_reg = phyRegRead(g_active_phy_id,0x02); //phy-id,查看phyRegRead是否正确;
if(phy_reg != 0x0022) //不等则芯片焊错
{
while(1);
}
#endif
return (ERR_NO_ERROR);
}
//-----------------------------------------------------------------------------
// returns if the link is currently active...1 -> active, 0 -> not active.
//-----------------------------------------------------------------------------
uint8_t isLinkActive(uint8_t in_phy)
{
uint16_t status;
status = phyRegRead(in_phy, SMSC_REG_BASIC_STAT);
if (CHKBIT(status, BASIC_STAT_LINK_STAT))
return (1);
else
return (0);
}
//-----------------------------------------------------------------------------
// read a phy register using the MDIO.
//-----------------------------------------------------------------------------
uint16_t phyRegRead(uint8_t in_phy, uint8_t in_reg)
{
// make sure mdio is not busy.
while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
MDIO->USERACCESS0 = USERACC_GO |
(in_reg << USERACC_SHIFT_REG) |
(in_phy << USERACC_SHIFT_PHY);
while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
return ((uint16_t)(MDIO->USERACCESS0 & USERACC_MASK_DATA));
}
//-----------------------------------------------------------------------------
// write a phy register using the MDIO.
//-----------------------------------------------------------------------------
void phyRegWrite(uint8_t in_phy, uint8_t in_reg, uint16_t in_data)
{
// make sure mdio is not busy.
while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
MDIO->USERACCESS0 = USERACC_GO |
USERACC_WRITE |
(in_reg << USERACC_SHIFT_REG) |
(in_phy << USERACC_SHIFT_PHY) |
in_data;
}
代码其中之二:
/** Emac_des.c
** 由于在接收的过程中,可能存在一定的descriptor 问题,同时在与pbuf结合的情况
** 也存在着一些问题,故作如下修改。
** 现在决定作如下修改:
************************************/
#include "includes.h"
#include "Emac_des.h"
#include "evmomapl138.h"
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "inc/evmomapl138_emac.h"
#include "etharp.h"
#include "ethernetif.h"
/* CPPI RAM size in bytes */
#ifndef SIZE_CPPI_RAM
#define SIZE_CPPI_RAM 0x2000 //8K, L138也一样
#endif
#define MAX_ALE_ENTRIES 1024
#define ENTRY_TYPE 0x30
#define ENTRY_TYPE_IDX 7
#define ENTRY_FREE 0
/* MDIO input and output frequencies in Hz */
#define MDIO_FREQ_INPUT 125000000
#define MDIO_FREQ_OUTPUT 1000000
//flag --> 一样的描述
#define CPDMA_BUF_DESC_OWNER 0x20000000
#define CPDMA_BUF_DESC_SOP 0x80000000
#define CPDMA_BUF_DESC_EOP 0x40000000
#define CPDMA_BUF_DESC_EOQ 0x10000000
#define MAX_TRANSFER_UNIT 1518 // Lp modified
#define PBUF_LEN_MAX MAX_TRANSFER_UNIT
#define MAX_RX_PBUF_ALLOC 20 //使用20个看看
#define MIN_PKT_LEN 60
/* Define those to better describe the network interface. */
#define IFNAME0 'e'
#define IFNAME1 'n'
/* TX Buffer descriptor data structure */
struct cpdma_tx_bd {
volatile struct cpdma_tx_bd *next;
volatile u32_t bufptr;
volatile u32_t bufoff_len;
volatile u32_t flags_pktlen;
/* 添加了一个这样的数据结构 */
volatile struct pbuf *pbuf;
}cpdma_tx_bd;
/* RX Buffer descriptor data structure */
struct cpdma_rx_bd {
volatile struct cpdma_rx_bd *next;
volatile u32_t bufptr;
volatile u32_t bufoff_len;
volatile u32_t flags_pktlen;
/*添加了pbuf数据结构*/
volatile struct pbuf *pbuf;
}cpdma_rx_bd;
/**为的是编程者更好的处理RX channel发生的事件。***/
struct rxch {
volatile struct cpdma_rx_bd *free_head;
volatile struct cpdma_rx_bd *active_head;
volatile struct cpdma_rx_bd *active_tail;
u32_t freed_pbuf_len;
}rxch;
/** 是TX Channel 更好的处理事件 ***/
struct txch {
volatile struct cpdma_tx_bd *free_head;
volatile struct cpdma_tx_bd *active_tail;
volatile struct cpdma_tx_bd *next_bd_to_process;
}txch;
/**
** 这个是整个EMAC的操作界面数据结构 -- 不需要
*/
struct emac_trif {
/* The tx/rx channels for the interface */
struct txch txch;
struct rxch rxch;
}emac_trif;
/*
** 初始化buffer descriptor
** 换了一个方式,用一个pbuf 链的方式来接收,免去拷贝。
*/
err_t
Emac_des_init( void )
{
u32_t num_bd, pbuf_cnt = 0;
volatile struct cpdma_tx_bd *curr_txbd, *last_txbd;
volatile struct cpdma_rx_bd *curr_bd, *last_bd;
struct txch *txch;
struct rxch *rxch;
struct pbuf *p, *q;
//初始化.... 结构体..
//struct emac_trif {
memset((u8_t *)&emac_trif, 0, sizeof(emac_trif));
//struct txch {
memset((u8_t *)&txch, 0, sizeof(txch));
//struct rxch
memset((u8_t *)&rxch, 0, sizeof(rxch));
//struct cpdma_rx_bd {
memset((u8_t *)&cpdma_rx_bd, 0, sizeof(cpdma_rx_bd));
//struct cpdma_tx_bd {
memset((u8_t *)&cpdma_tx_bd, 0, sizeof(cpdma_rx_bd));
//取出txch的地址,以便操作
txch = &(emac_trif.txch);
//EMAC_RAM_BASE是L138的buffer descriptor 所在CPPI RAM的起始地址
txch->free_head = (volatile struct cpdma_tx_bd*)(EMAC_RAM_BASE);
txch->next_bd_to_process = txch->free_head;
txch->active_tail = (volatile struct cpdma_tx_bd *)NULL;
//多少个buffer desc, tx_bd... 特意SIZE_CPPI_RAM/2
num_bd = (SIZE_CPPI_RAM >> 1) / sizeof(cpdma_tx_bd);
curr_txbd = txch->free_head;
/* Initialize all the TX buffer Descriptors */
while(num_bd--) {
curr_txbd->next = curr_txbd + 1;
curr_txbd->bufptr = 0; //初始化为0
curr_txbd->bufoff_len = 0; //也初始化为0
curr_txbd->flags_pktlen = 0;
curr_txbd->pbuf = 0;//现在还并没有pbuf要准备发送
last_txbd = curr_txbd;
curr_txbd = curr_txbd->next;
}
last_txbd->next = txch->free_head;
/* Initialize the descriptors for the RX channel */
rxch = &(emac_trif.rxch);
rxch->active_head = (volatile struct cpdma_rx_bd*)(curr_txbd + 1);
rxch->free_head = (volatile struct cpdma_rx_bd *)NULL;
rxch->freed_pbuf_len = 0;
num_bd = ((SIZE_CPPI_RAM >> 1) / sizeof(cpdma_rx_bd) - 1);
curr_bd = rxch->active_head;
last_bd = curr_bd;
/*
** 该驱动一个最大的不同就在此处,将接收的数据直接用DMA传送到pbuf,
** 以前我们都是用全局ram接收,而后拷贝至pbuf,还有一个不同就是
** 这里使用了EMAC部的CPPI_RAM空间,这样达到最好的效率。
** 但是为了考虑字节对齐的问题,还需要做点小小的修改
*/
while(pbuf_cnt < MAX_RX_PBUF_ALLOC) {//产生10个pbuf..供接收DMA传送
#if ETH_PAD_SIZE
p = pbuf_alloc(PBUF_RAW,(PBUF_LEN_MAX+ETH_PAD_SIZE), PBUF_POOL); //10 * 1500
pbuf_header(p, -ETH_PAD_SIZE); //向后移2个字节,接收过后,刚刚好
#endif //ETH_PAD_SIZE
pbuf_cnt++;
if(p != NULL) {
/* write the descriptors if there are enough numbers to hold the pbuf*/
if(((u32_t)pbuf_clen(p)) <= num_bd) {
// pbuf_clen(p)计算从p开始,pbuf链的长度
//如果pbuf_alloc产生比num_bd更大长度的描述符,那么就是个悲剧了。
for(q = p; q != NULL; q = q->next) {
curr_bd->bufptr = (u32_t)(q->payload); //buffer_ptr
curr_bd->bufoff_len = q->len; //buffoff & buffer_len
curr_bd->next = curr_bd + 1; //next buffer descriptor
curr_bd->flags_pktlen = CPDMA_BUF_DESC_OWNER; //flag set or clear
/* Save the pbuf */
curr_bd->pbuf = q;
last_bd = curr_bd;
curr_bd = curr_bd->next;
num_bd--;
}//for
}//if <= num_bd
/* free the allocated pbuf if no free descriptors are left */
else {
pbuf_free(p);
break;
}//else pbuf chain len > num_bd
}//if p != NULL
else {
break;
}//else p== NULL
}//while 产生10个
last_bd->next = (volatile struct cpdma_rx_bd *)NULL; //buff des chain 构造完成
rxch->active_tail = last_bd; //rxch控制着整个rxch的接收方式
EMAC->RXHDP[0] = (u32_t)(rxch->active_head); //add - lp
return ERR_OK;
}
/**
** 使用该rx_inhandler处理接收中断
** 每个pbuf链在处理之前必须要向前移ETH_PAD_SIZE个字节,以便4字节对齐
** 当你还要产生pbuf的时候,也要向后移ETH_PAD_SIZE个字节,以便接收。
* @param netif the lwip network interface structure for this ethernetif
* @return none
*/
void
Emac_rxint_handler(struct netif *netif) {
struct rxch *rxch;
volatile struct cpdma_rx_bd *curr_bd, *processed_bd, *curr_tail, *last_bd;
volatile struct pbuf *pbuf, *q, *new_pbuf;
u32_t ex_len = 0, len_to_alloc = 0;
u16_t tot_len;
// sitaraif = netif->state;
rxch = &(emac_trif.rxch);
//得到当前的rxch buffer desc
curr_bd = rxch->active_head;
last_bd = rxch->active_tail;
//pbuf链中,SOP只出现一次,但是curr_bd已将buffer链推向下一个可能出现
//SOP的开头,所以这种方式更加严谨和有效。
while(curr_bd->flags_pktlen & CPDMA_BUF_DESC_SOP) {
//用while是因为pbuf链来处理的
ex_len = 0;
len_to_alloc = 0;
//当OWNER被EMAC清掉的时候,EMAC就放弃了buff desc,可以做一些处理
if((curr_bd->flags_pktlen & CPDMA_BUF_DESC_OWNER)
!= CPDMA_BUF_DESC_OWNER) {
if(rxch->free_head == NULL) {
/* this bd chain will be freed after processing */
rxch->free_head = curr_bd;
}//if NULL
//得到该接收到packet_len的长度
tot_len = (curr_bd->flags_pktlen) & 0xFFFF;
//保存当前接收的起始pbuf
q = curr_bd->pbuf;
//以下循环体为了更新除pbuf->payload除外,在结构体pbuf中
//的len,tot_len数据
do {
//得到当前pbuf地址
pbuf = curr_bd->pbuf;
/* If the earlier pbuf ended, update the chain */
if(pbuf->next == NULL) {
pbuf->next = (struct pbuf*)(curr_bd->next)->pbuf;
} //if Null
//len_to_alloc , pbuf链中的len的总和
len_to_alloc += pbuf->len;
/* Update the len and tot_len fields for the pbuf in the chain*/
pbuf->len = (curr_bd->bufoff_len) & 0xFFFF; //当前pbuf长度
pbuf->tot_len = tot_len - ex_len ; //当前pbuf后的tot_len长度(含自己)
processed_bd = curr_bd; //处理中的desc
ex_len += pbuf->len;
curr_bd = curr_bd->next;
} while((processed_bd->flags_pktlen & CPDMA_BUF_DESC_EOP)
!= CPDMA_BUF_DESC_EOP);
/**
* Close the chain for this pbuf. A full packet is received in
* this pbuf chain. Now this pbuf can be given to upper layers for
* processing. The start of the pbuf chain is now 'q'.
*/
pbuf->next = (struct pbuf *)NULL;
//在q处理之前,需要加上ETH_PAD_SIZE个空间,以便4字节对齐
#if ETH_PAD_SIZE
if(q != NULL)
{
pbuf_header((struct pbuf *)q, ETH_PAD_SIZE);
#endif //ETH_PAD_SIZE
//为了节省中断的处理效率,这里节省时间,直接post msg给tcpip_thread
if((netif->input((struct pbuf *)q,netif)) != ERR_OK)
{
pbuf_free((struct pbuf *)q);
q = (volatile struct pbuf *)NULL;
}
#if ETH_PAD_SIZE
} //ETH_PAD_SIZE
#endif //ETH_PAD_SIZE
/* Acknowledge that this packet is processed */
// CPSWCPDMARxCPWrite(sitaraif->cpsw_cpdma_base, 0, (unsigned int)processed_bd);
EMAC->RXCP[0] = (u32_t)processed_bd;
rxch->active_head = curr_bd;
/**
* The earlier pbuf chain is freed from the upper layer. So, we need to
* allocate a new pbuf chain and update the descriptors with the pbuf info.
* To support chaining, the total length freed by the upper layer is tracked.
* Care should be taken even if the allocation fails.
*/
/**
* now len_to_alloc will contain the length of the pbuf which was freed
* from the upper layer
*/
rxch->freed_pbuf_len += len_to_alloc;
new_pbuf = pbuf_alloc(PBUF_RAW, ((rxch->freed_pbuf_len)+ETH_PAD_SIZE), PBUF_POOL);
/* Write the descriptors with the pbuf info till either of them expires */
if(new_pbuf != NULL) {
#if ETH_PAD_SIZE
pbuf_header((struct pbuf *)new_pbuf, -ETH_PAD_SIZE);
#endif //ETH_PAD_SIZE
curr_bd = rxch->free_head; //free_head,已经被释放的head,需要重新set
//以下循环体添加新的pbuf到curr_bd中去
for(q = new_pbuf; (q != NULL) && (curr_bd != rxch->active_head); q = q->next) {
curr_bd->bufptr = (u32_t)(q->payload);
/* no support for buf_offset. RXBUFFEROFFEST register is 0 */
curr_bd->bufoff_len = (q->len) & 0xFFFF;
curr_bd->flags_pktlen = CPDMA_BUF_DESC_OWNER;
rxch->freed_pbuf_len -= q->len;
/* Save the pbuf */
curr_bd->pbuf = q;
last_bd = curr_bd;
curr_bd = curr_bd->next;
}//for
/**
* At this point either pbuf expired or no rxbd to allocate. If
* there are no, enough rx bds to allocate all pbufs in the chain,
* free the rest of the pbuf
*/
if(q != NULL) {
pbuf_free((struct pbuf *)q);
}
curr_tail = rxch->active_tail;
last_bd->next = (volatile struct cpdma_rx_bd *)NULL;
curr_tail->next = rxch->free_head;
/**
* Check if the reception has ended. If the EOQ flag is set, the NULL
* Pointer is taken by the DMA engine. So we need to write the RX HDP
* with the next descriptor.
*/
if(curr_tail->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
// CPSWCPDMARxHdrDescPtrWrite(sitaraif->cpsw_cpdma_base,
// (u32_t)(rxch->free_head), 0);
EMAC->RXHDP[0] = (u32_t)(rxch->free_head);
}//if EOQ
rxch->free_head = curr_bd;
rxch->active_tail = last_bd;
}//if new_pbuf
}//if OWNER
curr_bd = rxch->active_head;
//以下这句,L138未做要求.
// CPSWCPDMANumFreeBufSet(sitaraif->cpsw_cpdma_base, 0, 1);
// -----------括号不要删-------------------------------
}//While ....
//-------------------------------------------
// 以下在外面写
// CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_TX_PULSE);
// CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_RX_PULSE);
}
//---------------------------------------------------------------
//以下是发送部分
//---------------------------------------------------------------
/**
** 这个函数将pbuf链的数据发送给物理层,可能buffer_des连接多处,因为是
** pbuf链连接而成的
* @return None
**/
void Emac_transmit(struct pbuf *pbuf) {
struct pbuf *q;
struct txch *txch;
volatile struct cpdma_tx_bd *curr_bd, *active_head, *bd_end;
// 取地址。
txch = &(emac_trif.txch);
//得到可以使用的空闲head
curr_bd = txch->free_head;
//激活的head
active_head = curr_bd;
//更新该头的packet len 字段
curr_bd->flags_pktlen &= ~0xFFFF;
curr_bd->flags_pktlen |= pbuf->tot_len;
//交给EMAC之前,置位flags, SOP,OWNER
curr_bd->flags_pktlen |= (CPDMA_BUF_DESC_SOP | CPDMA_BUF_DESC_OWNER);
//把pbuf信息构建成buffer desc 链
for(q = pbuf; q != NULL; q = q->next) {
/* Intialize the buffer pointer and length */
curr_bd->bufptr = (u32_t)(q->payload);
curr_bd->bufoff_len = (q->len) & 0xFFFF;
bd_end = curr_bd;
curr_bd->pbuf = pbuf;
curr_bd = curr_bd->next;
}
//将buffer desc结尾
bd_end->next = (volatile struct cpdma_tx_bd *)NULL;
bd_end->flags_pktlen |= CPDMA_BUF_DESC_EOP;
//free_head指向下一个空的buff descriptor 处
txch->free_head = curr_bd;
//经过初始化之后,txch->active_tail指向NULL,但是发送buffer desc是一个
//单向的循环链表。所以这也是上面为什么bd_end->next要赋NULL值
if(txch->active_tail == NULL) {
// 第一次发送active_head
EMAC->TXHDP[0] = (u32_t)active_head;
}
/*
**第1次发送过后,假如发送完了,那么transmiter 将会halt,这样CPU在
**发送之前必须确认EOQ是否set,如果set,那么对于CPU来讲可以写HDP启动
**TXDMA发送了。
*/
else {
curr_bd = txch->active_tail;
curr_bd->next = active_head;
if(curr_bd->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
//假如EOQ被EMAC set之后,就启动tx DMA
EMAC->TXHDP[0] = (u32_t)active_head;
}
}
txch->active_tail = bd_end;
}
/**
* This function will send a packet through the emac if the channel is
* available. Otherwise, the packet will be queued in a pbuf queue.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
*/
err_t
OmapEmac_output(struct netif *netif, struct pbuf *p)
{
INT8U os_err = 0;
SYS_ARCH_DECL_PROTECT(lev);
//等待有效的信号量才能发送
// OSSemPend(TxCmpSem, 1000, &os_err); // --LP , 2012/04/28 DLT
/**
* This entire function must run within a "critical section" to preserve
* the integrity of the transmit pbuf queue.
*
*/
SYS_ARCH_PROTECT(lev);
//在选择发送之前,要调整p->payload的两字节,因为它们不能发送出去
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE);
#endif
/* adjust the packet length if less than minimum required */
if(p->tot_len < MIN_PKT_LEN) {
p->tot_len = MIN_PKT_LEN;
p->len = MIN_PKT_LEN;
}
/**
* Bump the reference count on the pbuf to prevent it from being
* freed till we are done with it.
*
*/
pbuf_ref(p);
//Emac物理层的发送。DMA 用了TX中断的方式
Emac_transmit(p);
/* Return to prior interrupt state and return. */
SYS_ARCH_UNPROTECT(lev);
return ERR_OK;
}
/**
** lower level 已经启动DMA发送了吗,这里是为了软件清掉SOP和EOP,然后就是pbuf
** 链表的回收。
* @param netif the lwip network interface structure for this ethernetif
* @return none
*/
void
Emac_txint_handler(struct netif *netif) {
struct txch *txch;
volatile struct cpdma_tx_bd *curr_bd, *next_bd_to_process;
//取txch结构体的地址
txch = &(emac_trif.txch);
//下一待处理的buff des, next_bd_to_process被初始化为(EMAC_RAM_BASE)
next_bd_to_process = txch->next_bd_to_process;
// 用curr_bd来处理
curr_bd = next_bd_to_process;
/* Check for correct start of packet */
while((curr_bd->flags_pktlen) & CPDMA_BUF_DESC_SOP) {
/* Make sure that the transmission is over */
while((curr_bd->flags_pktlen & CPDMA_BUF_DESC_OWNER)
== CPDMA_BUF_DESC_OWNER);
/* Traverse till the end of packet is reached */
while(((curr_bd->flags_pktlen) & CPDMA_BUF_DESC_EOP) != CPDMA_BUF_DESC_EOP) {
curr_bd = curr_bd->next;
}//while(!EOP)
next_bd_to_process->flags_pktlen &= ~(CPDMA_BUF_DESC_SOP);
curr_bd->flags_pktlen &= ~(CPDMA_BUF_DESC_EOP);
/**
* If there are no more data transmitted, the next interrupt
* shall happen with the pbuf associated with the free_head
*/
if(curr_bd->next == NULL) {
txch->next_bd_to_process = txch->free_head;
}
else {
txch->next_bd_to_process = curr_bd->next; //接着处理下一帧数据包
}
//写TXCP[],该帧数据包已经写完
// CPSWCPDMATxCPWrite(sitaraif->cpsw_cpdma_base, 0, (u32_t)curr_bd);
EMAC->TXCP[0] = (u32_t)curr_bd;
pbuf_free((struct pbuf *)curr_bd->pbuf);
// LINK_STATS_INC(link.xmit);
next_bd_to_process = txch->next_bd_to_process;
curr_bd = next_bd_to_process;
}
//发送信号量给发送部分保证发送的完整性。
// OSSemPost(TxCmpSem); //--lp , 2012/04/28 delete,查看效果。
//在外面写的
// CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_TX_PULSE);
// CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_RX_PULSE);
}
/********************* this file is end ****************************/
代码其中之三:
/**************************************************************************
* *
* PROJECT : TMON (Transparent monitor) *
* *
* MODULE : LWIP.c *
* *
* AUTHOR : Michael Anburaj *
* URL : http://geocities.com/michaelanburaj/ *
* EMAIL: michaelanburaj@hotmail.com *
* *
* PROCESSOR : Any *
* *
* Tool-chain : gcc *
* *
* DESCRIPTION : *
* LwIP master source file. *
* *
**************************************************************************/
#include "tcpip.h"
#include "ethernetif.h"
#include "netconf.h"
/* ********************************************************************* */
/* Global definitions */
netif_t main_net;
/* ********************************************************************* */
/* File local definitions */
/* ********************************************************************* */
/**
*** 初始化LwIP的协议栈
*/
void LwIP_Init( void )
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
tcpip_init(NULL, NULL);
/** 在此处初始化IP地址 **/
IP4_ADDR(&ipaddr,192,168,1,88); //该宏需要执行的!
IP4_ADDR(&netmask,255,255,255,0);
IP4_ADDR(&gw,192,168,0,1);
MEMCPY(main_net.name,"glzn",4);
#if LWIP_NETIF_HOSTNAME
main_net.hostname = GetHostName();
#endif
/* - netif_add(struct netif *netif, struct ip_addr *ipaddr,
struct ip_addr *netmask, struct ip_addr *gw,
void *state, err_t (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif))
Adds your network interface to the netif_list. Allocate a struct
netif and pass a pointer to this structure as the first argument.
Give pointers to cleared ip_addr structures when using DHCP,
or fill them with sane numbers otherwise. The state pointer may be NULL.
The init function pointer must point to a initialization function for
your ethernet netif interface. The following code illustrates it's use.*/
netif_add(&main_net, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);
/* Registers the default network interface.*/
netif_set_default(&main_net); //可以删除 --2012/02/02, netif_default
/* When the netif is fully configured this function must be called.*/
netif_set_up(&main_net); //this functional
}
/* ********************************************************************* */
代码其中之四:
//主程序
//修改成适应LwIP v140的协议,此为系统main主函数
#include
#include
#include "dspint.h"
#include "sample.h"
#include "edma.h"
#include "norflash.h"
#include "evmomapl138.h"
#include "evmomapl138_gpio.h"
#include "evmomapl138_uart.h"
#include "evmomapl138_rtc.h"
#include "io.h"
#include "fpga_emifa.h"
#include "test_fpga.h"
//推荐的任务堆栈区大小为2048 OS_STK,即8192 byte
#define COMMON_STACK_LEN 2048
//给各个任务分配的堆栈区
OS_STK TaskLWIPStk[COMMON_STACK_LEN];
OS_STK TaskAppMainStk[COMMON_STACK_LEN];
OS_STK TaskMMIStk[COMMON_STACK_LEN];
OS_STK TaskFpgaUPPStk[COMMON_STACK_LEN];
OS_STK TaskFpgaEMIFAStk[COMMON_STACK_LEN * 32];
//OS_STK TaskTestStk[COMMON_STACK_LEN];
//各个任务进程主函数
void TaskAppMain(void *pd);
void TaskMMI(void *pd);//通过upp总线刷液晶数据,触发dsp中断,启动upp发送
extern void TaskLWIP(void *p_arg); //TaskLWIP任务
//extern void TaskTest(void *pd);
int main()
{
//初始化中断向量
OS_CPU_InitExceptVect();
//初始化uC/OS-II实时内核
OSInit();
//创建系统主进程任务(放在最高优先级,包括装置定值、参数自检测,并作为其他任务的WatchDog。)
OSTaskCreate(TaskAppMain, (void *)0, (OS_STK*)&TaskAppMainStk[COMMON_STACK_LEN-1], 2);
//启动操作系统内核
OSStart();
}
//系统主进程任务
void TaskAppMain(void *pd)
{
unsigned char ucErr;
tmr0_init();
GPIOInit();
chipint_init();
memset((unsigned char *)TaskLWIPStk, 0, (COMMON_STACK_LEN*sizeof(OS_STK)));
//初始化由Lwip任务堆栈开辟的堆栈区域
//INT8U enledflag = /;
//INT32U counter = 0;
//创建任务
//OSTaskCreate(TaskFPGA_UPP, (void *)0, (OS_STK*)&TaskFpgaUPPStk[COMMON_STACK_LEN-1], 11);
// OSTaskCreate(TaskFPGA_EMIFA, (void *)0, (OS_STK*)&TaskFpgaEMIFAStk[COMMON_STACK_LEN-1], 12);
// OSTaskCreate(TaskMMI, (void *)0, (OS_STK*)&TaskMMIStk[COMMON_STACK_LEN-1], 13);
//OSTaskCreate(TaskTest, (void *)0, (OS_STK*)&TaskTestStk[COMMON_STACK_LEN-1],100);
OSTaskCreate(TaskLWIP,(void *)0,(OS_STK *)&TaskLWIPStk[COMMON_STACK_LEN -1],10);
while(1)
{
/*asm(" nop");
counter++;
if(counter >=20)
{
enledflag ^=0x01;
inb(ARM_DSP_CMD) = enledflag;
DspintArmtrip(DSPINTTYPE_2);
counter = 0;
}
if(enledflag == 0)
{
ledchange();
}*/
// OSTimeDly(500);
// OSMboxPend(RxCntMbox,0,&ucErr);
OSTimeDly(1000);
asm(" nop");
}
}
//
#define SHAREMMI_ADR (0x80000200) //共享液晶显示数据区地址
#define MMI_LNUM (240) //液晶显示一屏数据的行数目
#define MMI_LBYTE (40) //液晶显示一屏数据的行字节数目320/8
#define MMI_DATALEN (MMI_LNUM*MMI_LBYTE) //液晶显示缓冲区长度
#define SHARERAW_ADR (0x8002800) //共享原始数据区地址
#define SHAREMEA_ADR (0x8001f000) //共享测量结果区地址
//显存
#define LCD_XSIZE (320) // X方向像素
#define LCD_YSIZE (240) // Y方向像素
#define LCDMLEN ((LCD_XSIZE*LCD_YSIZE)/8)
INT8U LcdMemory[LCDMLEN];
void loadMMIdata()
{
INT8U *pobject;
INT16U i;
static INT8U showdata = 0;
static INT8U changeflag = 0;
changeflag++;
if(changeflag==6)
{
changeflag=0;
showdata++;
}
pobject =LcdMemory;//(INT8U*)SHAREMMI_ADR;
if(showdata == 0)
{
for(i=0;i
{
*pobject++ = (i+1)&0xff;
}
}
else
{
for(i=0;i
{
*pobject++ = showdata;
}
}
}
void TaskMMI(void *pd)
{
while(1)
{
//pushus(0);
//loadMMIdata();
//EDMA0config(0,(void*)LcdMemory,(void*)SHAREMMI_ADR,LCDMLEN);
//pushus(1);
RelayTest();
OSTimeDly(100);
}
}
代码其中之五:
/* main.c
** test lwip
***************************************************/
#include
#include "evmomapl138.h"
#include
#include
#include
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "lwip.h"
// LwIP task stk Information
/**
** DEBUG Information
****************************************************/
/**
** global value
***************************************************/
/**
** function decl
**************************************************/
static void BSP_Init(void );
void tcpip_init_done(void *arg);
/* App_LwipTask
**
************************************************************************/
void TaskLWIP(void *parg)
{
//加载网卡驱动
//加载L138本身自带的EMAC驱动
//Lwip_v140使用lwip.c处理初始化网口的信息,主任务只要调用lwip_Init()即可
LwIP_Init();
while(1)
{
OSTimeDly(2000);
}
}
/* BSP_Init()
** 配置启动的时钟,貌似omapL138_app/boot.asm 中
** 有初始化STACK等配置,但是没有见到其内有时钟配置,工程初始化时也没有发现。
** 故要初始化PLL
********************************************/
void BSP_Init(void)
{
EVMOMAPL138_Init();
}
我贴了一些代码,请看看帮帮忙,我真不知道该如何解决啦...
复制代码
加载中...
一周热门
更多
>
相关问题
相关文章
事件管理器――PWM
0个评论
FPGA时序分析基础(二):vivado中常用的时序约束命令
0个评论
LDO和BUCK降压稳压器对比
0个评论
伺服控制系统教学实验平台
0个评论
asoc之动态PCM
0个评论
ADS7928
0个评论
基于AD9957实现射频数字化变频模块和AD转换模块的方案详细教程
0个评论
多功能车载DVD智能导航平台
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
在U-Boot下可以通过板卡ping通主机,可能无法从主机ping通板卡。
进入操作系统后(如Linux),板卡和主机可以互相ping通。
- 代码其中之一: //-----------------------------------------------------------------------------
- // file evmomapl138_emac.c
- // rief implementation of the emac/mdio driver for the OMAP-L138 EVM.
- //
- //-----------------------------------------------------------------------------
- #include "stdio.h"
- #include "string.h"
- #include "os_cpu_isr.h"
- #include "includes.h"
- #include "inc/evmomapl138_emac.h"
- #include "inc/types.h"
- #include "evmomapl138.h"
- #include "evmomapl138_timer.h"
- #include "inc/ethernet_smsc.h"
- #include "inc/evmomapl138_gpio.h"
- #include "inc/evmomapl138_i2c_gpio.h"
- #include "inc/evmomapl138_cdce913.h"
- #include "evmomapl138_aintc.h" // add_ISR需要
- #include "netif/etharp.h"
- #include "Emac_des.h"
- #include "ethernetif.h"
- #ifndef USE_HDTIME_DLY
- #define USTIMER_delay(x)
- #endif //USE_HDTIME_DLY
- #define MAX_POLLING_NUM (0x0FFFFFFF)
- //-----------------------------------------------------------------------------
- // Private Defines and Macros
- //-----------------------------------------------------------------------------
- // INTCONTROL >> INTPRESCALE , number of EMAC clk period within a 4 us time window
- #define NUM_INTPRESCALE (4*SYSCLOCK4_HZ/1000000) //4/(1000000/SYSCLOCK4_HZ) , 4us
- // mdio clock divide down value.
- #define MDIO_CLK_FREQ_HZ (2000000) //2M HZ
- #define MDIO_CLK_DIVISOR ((SYSCLOCK4_HZ / MDIO_CLK_FREQ_HZ) - 1)
- // rx / tx desriptor memory offsets.
- #define RX_DESC_OFFSET (0)
- #define TX_DESC_OFFSET (0x1000)
- //MII pinmux
- #define PINMUX_MII_REG_0 (2)
- #define PINMUX_MII_MASK_0 (0xFFFFFFF0)
- #define PINMUX_MII_VAL_0 (0x88888880)
- #define PINMUX_MII_REG_1 (3)
- #define PINMUX_MII_MASK_1 (0xFFFFFFFF)
- #define PINMUX_MII_VAL_1 (0x88888888)
- //RMII pinmux
- #define PINMUX_RMII_REG_0 (14)
- #define PINMUX_RMII_MASK_0 (0xFFFFFF00)
- #define PINMUX_RMII_VAL_0 (0x88888800)
- #define PINMUX_RMII_REG_1 (15)
- #define PINMUX_RMII_MASK_1 (0x000000FF)
- #define PINMUX_RMII_VAL_1 (0x00000080)
- //MDIO pinmux
- #define PINMUX_MDIO_REG (4)
- #define PINMUX_MDIO_MASK (0x000000FF)
- #define PINMUX_MDIO_VAL (0x00000088)
- //GPIO pinmux
- #define PINMUX_MII_MDIO_EN_REG (6)
- #define PINMUX_MII_MDIO_EN_MASK (0x000000F0)
- #define PINMUX_MII_MDIO_EN_VAL (0x00000080)
- //
- #define EMAC_RMII_SPEED_100 (0x00008000)
- //-----------------------------------------------------------------------------
- // Private Static Variables
- //-----------------------------------------------------------------------------
- static uint8_t g_active_phy_id = 0x0; //我们选用的L138是phy_id是为0的
- //-----------------------------------------------------------------------------
- // Private Function Prototypes
- //-----------------------------------------------------------------------------
- static uint32_t initMdioPhy(void);
- static uint8_t isLinkActive(uint8_t in_phy);
- static uint16_t phyRegRead(uint8_t in_phy, uint8_t in_reg);
- static void phyRegWrite(uint8_t in_phy, uint8_t in_reg, uint16_t in_data);
- //----------------------------------------------------------------------------
- //Public value definitions
- //----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // Public Function Definitions
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // rief initialize the EMAC and MDIO for use.
- //
- // param none.
- //
- //
eturn uint32_t
- // ERR_NO_ERROR - everything is ok...emac ready to use.
- // ERR_INIT_FAIL - something happened during initialization.
- //-----------------------------------------------------------------------------
- uint32_t Lowlevel_Emac_Init(void)
- {
- uint32_t rtn = 0;
- uint32_t i;
- SYS_ARCH_DECL_PROTECT(sr);
- SYS_ARCH_PROTECT(sr);
- // reset emac module.
- EMAC->SOFTRESET = 1;
- while (EMAC->SOFTRESET != 0) {;}
- //init emac control module
- //----------------------------------------
- // AddISR() -- configuration of the interrupt to the CPU.
- //AINTC --Number34 core0 Receive Interrupt
- AddISR(34,L138Ethif_RxHandler,(void *)0);
- aintcRegs->SICR = 34; //clear index status
- aintcRegs->CMR8 = 0x00170000;//(Sets channel map, system interrupt --> host channel interrupt )
- aintcRegs->EISR = 34; //Enable Index Set Register
- aintcRegs->SECR2 = 0x00000004; //34 status clear
- //configure Tx Interrupt Handler
- AddISR(35,L138Ethif_TxHandler,(void *)0);
- aintcRegs->SICR = 35; //clear index status
- aintcRegs->CMR8 = 0x18000000; //SETS CHannel map
- aintcRegs->EISR = 35; //Enable Index Set Register
- aintcRegs->SECR2 = 0x00000008; //clear 35 status register ...
- // configure INTCONTORL , CnRXIMAX, CnTXIMAX,
- EMAC_CTRL->INTCTL = (NUM_INTPRESCALE| 0x00000300);
- EMAC_CTRL->C0RXIMAX = 2;
- EMAC_CTRL->C0TXIMAX = 2;
- //--& init emac module.
- //------------------
-
- // make sure emac control interrupts are disabled.
- EMAC_CTRL->C0RXTHRESHEN = 0;
- EMAC_CTRL->C1RXTHRESHEN = 0;
- EMAC_CTRL->C2RXTHRESHEN = 0;
- EMAC_CTRL->C0RXEN = 0;
- EMAC_CTRL->C1RXEN = 0;
- EMAC_CTRL->C2RXEN = 0;
- EMAC_CTRL->C0TXEN = 0;
- EMAC_CTRL->C1TXEN = 0;
- EMAC_CTRL->C2TXEN = 0;
- EMAC_CTRL->C0MISCEN = 0;
- EMAC_CTRL->C1MISCEN = 0;
- EMAC_CTRL->C2MISCEN = 0;
- EVMOMAPL138_pinmuxConfig(PINMUX_MDIO_REG, PINMUX_MDIO_MASK, PINMUX_MDIO_VAL); //MDIO shared by both RMII and MII
- // EVMOMAPL138_pinmuxConfig(PINMUX_MII_MDIO_EN_REG, PINMUX_MII_MDIO_EN_MASK, PINMUX_MII_MDIO_EN_VAL); //pinmux to select gpio bank2 pin6
-
- //PINMUXING
- EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_0, PINMUX_MII_MASK_0, PINMUX_MII_VAL_0);
- EVMOMAPL138_pinmuxConfig(PINMUX_MII_REG_1, PINMUX_MII_MASK_1, PINMUX_MII_VAL_1);
-
- SYSCONFIG->KICKR[0] = KICK0R_UNLOCK;
- SYSCONFIG->KICKR[1] = KICK1R_UNLOCK;
- CLRBIT(SYSCONFIG->CFGCHIP[3], 0x00000100); //select mii mode !
- //as software reset consideration, do this here
- EVMOMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_EMAC, PSC_ENABLE);
- // clear MAC control register, receive control register, transmiter control register
- EMAC->MACCONTROL = 0;
- EMAC->RXCONTROL = 0;
- EMAC->TXCONTROL = 0;
- // init header descriptor pointer regs to 0.
- for (i = 0; i < 8; i++)
- {
- EMAC->TXHDP[i] = 0;
- EMAC->RXHDP[i] = 0;
- }
- // clear all statistic register
- #ifndef BOOT
- memset((uint8_t *)NET_STAT_REG_BASE, 0, NET_STAT_REG_NUM_BYTES);
- #endif
- // setup local MAC address, only channel 0 is valid.
- // program all 8, only need to set MACADDRHI for index = 0.
- // use duplicate address for all unused channels.
- // TODO: read MAC address from SPI flash.
- //写的顺序是MACINDEX, ADDRHI, ADDRLO,由于高40bits是共享的
- //只用了通道0,EMAC->MACADDRLO = 0X000000506 |VALID|MATCHFILT
- for (i = 1; i < 8; i++)
- {
- EMAC->MACINDEX = i;
- EMAC->MACADDRHI = 0x42020304; //index -> hi -> lo
- EMAC->MACADDRLO = 0x00000506;
- }
- EMAC->MACINDEX = 0;
- EMAC->MACADDRHI = 0x42020304;
- // channel bit = 0, match mac address = 1
- EMAC->MACADDRLO = 0x00000506 | MACADDRLO_VALID | MACADDRLO_MATCHFILT;
- // for use tx DMA descriptor configuration:
- EMAC->MACSRCADDRHI = 0x42020304;
- EMAC->MACSRCADDRLO = 0x00000506;
- // initialize receive channel free buffer count regs, if buffer flow
- // control is to be enabled.
- // NOTE: this example does not use buffer flow control.
- // enable unicast chan 0 only.
- EMAC->RXUNICASTSET = 0x01;
-
- // no multicast addresses, clear MAC address hash registers.
- EMAC->MACHASH1 = 0;
- EMAC->MACHASH2 = 0;
- // 只允许broadcast的ARP数据包,和发给自己的包,以太网的其他数据不放入Memmory里去.
- //但是我单独设置RxBroadEn却没有作用。
- EMAC->RXMBPENABLE = 0;
- SETBIT(EMAC->RXMBPENABLE, (RXBROADEN|RXCAFEN));
- // EMAC->RXMBPENABLE = 0x01E02020; //enable reception of almost all frames inc error
-
- //11. configure MACCONTROL (Don't set GMIIEN Bit)
- SETBIT(EMAC->MACCONTROL, (RMIISPEED|FULLDUPLEX|TXPACE)); //RMII_SPEED,为了适应RMII
-
- // 12. Clear all unused channel interrupt bits by writing the receive interrupt mask clear register
- //(RXINTMASKCLEAR) and the transmit interrupt mask clear register (TXINTMASKCLEAR).
- EMAC->RXINTMASKCLEAR |= 0xFE; //RX channel 0的中断不屏蔽
- EMAC->TXINTMASKCLEAR |= 0xFE; //TX CH0 中断屏蔽
- //13. Modify RXINTMASKSET, TXINTMASKSET,MACINTMASKSET
- EMAC->RXINTMASKSET |= 0x01;
- EMAC->TXINTMASKSET |= 0x01;
- EMAC->MACINTMASKCLR = 0x03; //disabled host mask , stat interrupt
-
- //14 init receive buffer offset and max length.
- EMAC->RXBUFFEROFFSET = 0;
- EMAC->RXMAXLEN = MAX_PACKET_SIZE;
-
- // initialize receive/transmit descriptor list queues.
- Emac_des_init(); //modify 04/18
- //16 enable receive / transmit DMA controllers...set GMIIEN.
- EMAC->RXCONTROL = 1;
- EMAC->TXCONTROL = 1;
- SETBIT(EMAC->MACCONTROL, GMIIEN );
- #if 1 //文档说未经测试,删除貌似没效果啊,先不管它
- SETBIT(EMAC->EMCONTROL, SOFT);
- #endif
- // -->& init mdio / phy, 再加上MAC中断
- //-----------------
- rtn = initMdioPhy();
- // if (rtn != ERR_NO_ERROR)
- // return (rtn);
- SYS_ARCH_UNPROTECT(sr);
- //17>Enable the device interrupt in EMAC control module registers CnRXTHRESHEN, CnRXEN, CnTXEN,
- //and CnMISCEN. -- LP Add
- EMAC_CTRL->C0RXEN = 1; //C0RXPULSE Is Enabled for RX channel 0
- EMAC_CTRL->C0TXEN = 1; //C0TXPULSE IS enabled for tx channel 0
- return (rtn);
- }
- //-----------------------------------------------------------------------------
- // rief power on the phy.
- //
- // param none.
- //
- //
eturn uint32_t
- // ERR_NO_ERROR - everything is ok...phy is on.
- // ERR_FAIL - something happened and could not power on.
- //-----------------------------------------------------------------------------
- uint32_t EMAC_phyPowerOn(void)
- {
- uint32_t rtn;
- uint16_t ctrl_reg;
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- if (!CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
- {
- // phy is already on...nothing left to do.
- #if DEBUG
- printf("phy powered, basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // clear power down bit and write back to phy.
- CLRBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN);
- phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
- // short delay, then read the reg back to verify loopback is enabled.
- USTIMER_delay(500);
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- if (!CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
- {
- // phy is powered...return success.
- #if DEBUG
- printf("phy powered, basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // power down bit did not clear...return error.
- #if DEBUG
- printf("power down did not clear: %04x
", ctrl_reg);
- #endif
- rtn = ERR_FAIL;
- }
- }
- return (rtn);
- }
- //-----------------------------------------------------------------------------
- // rief power down the phy.
- //
- // param none.
- //
- //
eturn uint32_t
- // ERR_NO_ERROR - everything is ok...phy is powered down.
- // ERR_FAIL - something happened and could not power down.
- //-----------------------------------------------------------------------------
- uint32_t EMAC_phyPowerDown(void)
- {
- uint32_t rtn;
- uint16_t ctrl_reg;
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- if(CHKBIT(ctrl_reg, BASIC_CTRL_ISOLATE) && CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
- {
- // phy is already powered down...nothing left to do.
- #if DEBUG
- printf("phy powered down, basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // set power down bit and write back to phy.
- SETBIT(ctrl_reg, BASIC_CTRL_ISOLATE | BASIC_CTRL_POWER_DOWN);
- phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
- // short delay, then read the reg back to verify loopback is disabled.
- USTIMER_delay(500);
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- if(CHKBIT(ctrl_reg, BASIC_CTRL_ISOLATE) && CHKBIT(ctrl_reg, BASIC_CTRL_POWER_DOWN))
- {
- // phy is powered down...return success.
- #if DEBUG
- printf("phy powered down, basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // power down bit did not set...return error.
- #if DEBUG
- printf("power down bit did not set: %04x
", ctrl_reg);
- #endif
- rtn = ERR_FAIL;
- }
- }
- return (rtn);
- }
- //-----------------------------------------------------------------------------
- // rief put the phy into loopback mode.
- //
- // param none.
- //
- //
eturn uint32_t
- // ERR_NO_ERROR - everything is ok...phy is in loopback mode.
- // ERR_FAIL - something happened and could not enter loopback.
- //-----------------------------------------------------------------------------
- uint32_t EMAC_phyEnterLoopback(void)
- {
- uint32_t rtn;
- uint16_t ctrl_reg;
-
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- rtn = ERR_NO_ERROR;
- if (ctrl_reg & BASIC_CTRL_LOOPBACK)
- {
- // loopback is already enabled...nothing left to do.
- #if DEBUG
- printf("loopback enabled, basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // set loopback bit and write back to phy.
- ctrl_reg |= BASIC_CTRL_LOOPBACK;
- phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
- // short delay, then read the reg back to verify loopback is enabled.
- USTIMER_delay(500);
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- if (ctrl_reg & BASIC_CTRL_LOOPBACK)
- {
- // loopback is enabled...return success.
- #if DEBUG
- printf("loopback enabled , basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // loopback bit did not get set...return error.
- #if DEBUG
- printf("loopback did not set: %04x
", ctrl_reg);
- #endif
- rtn = ERR_FAIL;
- }
- }
- return (rtn);
- }
- //-----------------------------------------------------------------------------
- // rief remove the phy from loopback mode.
- //
- // param none.
- //
- //
eturn uint32_t
- // ERR_NO_ERROR - everything is ok...phy is out of loopback mode.
- // ERR_FAIL - something happened and could not disable loopback.
- //-----------------------------------------------------------------------------
- uint32_t EMAC_phyExitLoopback(void)
- {
- uint32_t rtn;
- uint16_t ctrl_reg;
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- if (!(ctrl_reg & BASIC_CTRL_LOOPBACK))
- {
- // loopback is already disabled...nothing left to do.
- #if DEBUG
- printf("loopback disabled, basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // clear loopback bit and write back to phy.
- ctrl_reg &= ~BASIC_CTRL_LOOPBACK;
- phyRegWrite(g_active_phy_id, SMSC_REG_BASIC_CTRL, ctrl_reg);
- // short delay, then read the reg back to verify loopback is disabled.
- USTIMER_delay(5);
- ctrl_reg = phyRegRead(g_active_phy_id, SMSC_REG_BASIC_CTRL);
- if (!(ctrl_reg & BASIC_CTRL_LOOPBACK))
- {
- // loopback is disabled...return success.
- #if DEBUG
- printf("loopback disabled , basic ctrl reg: %04x
", ctrl_reg);
- #endif
- rtn = ERR_NO_ERROR;
- }
- else
- {
- // loopback bit did not clear...return error.
- #if DEBUG
- printf("loopback did not clear: %04x
", ctrl_reg);
- #endif
- rtn = ERR_FAIL;
- }
- }
- return (rtn);
- }
- //-----------------------------------------------------------------------------
- // Private Function Definitions
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // initialize the mdio module and identify the active phy.
- //-----------------------------------------------------------------------------
- uint32_t initMdioPhy(void)
- {
- uint32_t i = 0;
- uint16_t phy_reg;
- // init the mdio regs.
- MDIO->CONTROL = MDIO_CTRL_ENABLE |
- MDIO_CTRL_FAULT |
- MDIO_CTRL_FAULTENB |
- MDIO_CLK_DIVISOR;
- while (CHKBIT(MDIO->CONTROL, MDIO_CTRL_IDLE)) {;}
- #if DEBUG_MDIO_LINK
- // look for an active phy...takes up to 50 us for each phy to be checked.
- //以下只是调试时有用,真正烧入程序中去时,是不行的,因为没插上网线,AddISR还要上的。
- for (i = 0; i < MAX_POLLING_NUM; i++)
- {
- if (MDIO->ALIVE)
- {
- // at least one phy has acknowledged us...break the loop.
- break;
- }
- USTIMER_delay(50); // polling , 采用polling方式,LP- delete
- }
- while(!(MDIO->ALIVE)); //还是没有找到PHY,它就在此处挂住
- #else
- while(!(MDIO->ALIVE)) //没有网线连接
- {
- i++;
- if(i >= MAX_POLLING_NUM)
- {
- break;
- }
- }//只是为了延时让phy与PC自适应的时涞却??
- #endif
- //
- g_active_phy_id = 0; //确实是个发生错误,现在可以读到PHY。
- MDIO->USERPHYSEL0 = 0; //USERPHYSEL0 = 0,表示PHY0被选中监控。
- #if DEBUG_MDIO_LINK
- phy_reg = phyRegRead(g_active_phy_id,0x02); //phy-id,查看phyRegRead是否正确;
- if(phy_reg != 0x0022) //不等则芯片焊错
- {
- while(1);
- }
- #endif
- return (ERR_NO_ERROR);
- }
- //-----------------------------------------------------------------------------
- // returns if the link is currently active...1 -> active, 0 -> not active.
- //-----------------------------------------------------------------------------
- uint8_t isLinkActive(uint8_t in_phy)
- {
- uint16_t status;
- status = phyRegRead(in_phy, SMSC_REG_BASIC_STAT);
-
- if (CHKBIT(status, BASIC_STAT_LINK_STAT))
- return (1);
- else
- return (0);
- }
- //-----------------------------------------------------------------------------
- // read a phy register using the MDIO.
- //-----------------------------------------------------------------------------
- uint16_t phyRegRead(uint8_t in_phy, uint8_t in_reg)
- {
- // make sure mdio is not busy.
- while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
- MDIO->USERACCESS0 = USERACC_GO |
- (in_reg << USERACC_SHIFT_REG) |
- (in_phy << USERACC_SHIFT_PHY);
- while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
- return ((uint16_t)(MDIO->USERACCESS0 & USERACC_MASK_DATA));
- }
- //-----------------------------------------------------------------------------
- // write a phy register using the MDIO.
- //-----------------------------------------------------------------------------
- void phyRegWrite(uint8_t in_phy, uint8_t in_reg, uint16_t in_data)
- {
- // make sure mdio is not busy.
- while (CHKBIT(MDIO->USERACCESS0, USERACC_GO)) {}
- MDIO->USERACCESS0 = USERACC_GO |
- USERACC_WRITE |
- (in_reg << USERACC_SHIFT_REG) |
- (in_phy << USERACC_SHIFT_PHY) |
- in_data;
- }
- 代码其中之二:
- /** Emac_des.c
- ** 由于在接收的过程中,可能存在一定的descriptor 问题,同时在与pbuf结合的情况
- ** 也存在着一些问题,故作如下修改。
- ** 现在决定作如下修改:
- ************************************/
- #include "includes.h"
- #include "Emac_des.h"
- #include "evmomapl138.h"
- #include "lwip/def.h"
- #include "lwip/pbuf.h"
- #include "lwip/sys.h"
- #include "lwip/opt.h"
- #include "inc/evmomapl138_emac.h"
- #include "etharp.h"
- #include "ethernetif.h"
- /* CPPI RAM size in bytes */
- #ifndef SIZE_CPPI_RAM
- #define SIZE_CPPI_RAM 0x2000 //8K, L138也一样
- #endif
- #define MAX_ALE_ENTRIES 1024
- #define ENTRY_TYPE 0x30
- #define ENTRY_TYPE_IDX 7
- #define ENTRY_FREE 0
- /* MDIO input and output frequencies in Hz */
- #define MDIO_FREQ_INPUT 125000000
- #define MDIO_FREQ_OUTPUT 1000000
- //flag --> 一样的描述
- #define CPDMA_BUF_DESC_OWNER 0x20000000
- #define CPDMA_BUF_DESC_SOP 0x80000000
- #define CPDMA_BUF_DESC_EOP 0x40000000
- #define CPDMA_BUF_DESC_EOQ 0x10000000
- #define MAX_TRANSFER_UNIT 1518 // Lp modified
- #define PBUF_LEN_MAX MAX_TRANSFER_UNIT
- #define MAX_RX_PBUF_ALLOC 20 //使用20个看看
- #define MIN_PKT_LEN 60
- /* Define those to better describe the network interface. */
- #define IFNAME0 'e'
- #define IFNAME1 'n'
- /* TX Buffer descriptor data structure */
- struct cpdma_tx_bd {
- volatile struct cpdma_tx_bd *next;
- volatile u32_t bufptr;
- volatile u32_t bufoff_len;
- volatile u32_t flags_pktlen;
-
- /* 添加了一个这样的数据结构 */
- volatile struct pbuf *pbuf;
- }cpdma_tx_bd;
- /* RX Buffer descriptor data structure */
- struct cpdma_rx_bd {
- volatile struct cpdma_rx_bd *next;
- volatile u32_t bufptr;
- volatile u32_t bufoff_len;
- volatile u32_t flags_pktlen;
- /*添加了pbuf数据结构*/
- volatile struct pbuf *pbuf;
- }cpdma_rx_bd;
- /**为的是编程者更好的处理RX channel发生的事件。***/
- struct rxch {
- volatile struct cpdma_rx_bd *free_head;
- volatile struct cpdma_rx_bd *active_head;
- volatile struct cpdma_rx_bd *active_tail;
- u32_t freed_pbuf_len;
- }rxch;
- /** 是TX Channel 更好的处理事件 ***/
- struct txch {
- volatile struct cpdma_tx_bd *free_head;
- volatile struct cpdma_tx_bd *active_tail;
- volatile struct cpdma_tx_bd *next_bd_to_process;
- }txch;
-
- /**
- ** 这个是整个EMAC的操作界面数据结构 -- 不需要
- */
- struct emac_trif {
- /* The tx/rx channels for the interface */
- struct txch txch;
- struct rxch rxch;
- }emac_trif;
- /*
- ** 初始化buffer descriptor
- ** 换了一个方式,用一个pbuf 链的方式来接收,免去拷贝。
- */
- err_t
- Emac_des_init( void )
- {
- u32_t num_bd, pbuf_cnt = 0;
- volatile struct cpdma_tx_bd *curr_txbd, *last_txbd;
- volatile struct cpdma_rx_bd *curr_bd, *last_bd;
- struct txch *txch;
- struct rxch *rxch;
- struct pbuf *p, *q;
- //初始化.... 结构体..
- //struct emac_trif {
- memset((u8_t *)&emac_trif, 0, sizeof(emac_trif));
- //struct txch {
- memset((u8_t *)&txch, 0, sizeof(txch));
- //struct rxch
- memset((u8_t *)&rxch, 0, sizeof(rxch));
- //struct cpdma_rx_bd {
- memset((u8_t *)&cpdma_rx_bd, 0, sizeof(cpdma_rx_bd));
- //struct cpdma_tx_bd {
- memset((u8_t *)&cpdma_tx_bd, 0, sizeof(cpdma_rx_bd));
- //取出txch的地址,以便操作
- txch = &(emac_trif.txch);
- //EMAC_RAM_BASE是L138的buffer descriptor 所在CPPI RAM的起始地址
- txch->free_head = (volatile struct cpdma_tx_bd*)(EMAC_RAM_BASE);
- txch->next_bd_to_process = txch->free_head;
- txch->active_tail = (volatile struct cpdma_tx_bd *)NULL;
-
- //多少个buffer desc, tx_bd... 特意SIZE_CPPI_RAM/2
- num_bd = (SIZE_CPPI_RAM >> 1) / sizeof(cpdma_tx_bd);
-
- curr_txbd = txch->free_head;
- /* Initialize all the TX buffer Descriptors */
- while(num_bd--) {
- curr_txbd->next = curr_txbd + 1;
- curr_txbd->bufptr = 0; //初始化为0
- curr_txbd->bufoff_len = 0; //也初始化为0
- curr_txbd->flags_pktlen = 0;
- curr_txbd->pbuf = 0;//现在还并没有pbuf要准备发送
- last_txbd = curr_txbd;
- curr_txbd = curr_txbd->next;
- }
- last_txbd->next = txch->free_head;
-
- /* Initialize the descriptors for the RX channel */
- rxch = &(emac_trif.rxch);
- rxch->active_head = (volatile struct cpdma_rx_bd*)(curr_txbd + 1);
-
- rxch->free_head = (volatile struct cpdma_rx_bd *)NULL;
- rxch->freed_pbuf_len = 0;
- num_bd = ((SIZE_CPPI_RAM >> 1) / sizeof(cpdma_rx_bd) - 1);
- curr_bd = rxch->active_head;
- last_bd = curr_bd;
- /*
- ** 该驱动一个最大的不同就在此处,将接收的数据直接用DMA传送到pbuf,
- ** 以前我们都是用全局ram接收,而后拷贝至pbuf,还有一个不同就是
- ** 这里使用了EMAC部的CPPI_RAM空间,这样达到最好的效率。
- ** 但是为了考虑字节对齐的问题,还需要做点小小的修改
- */
- while(pbuf_cnt < MAX_RX_PBUF_ALLOC) {//产生10个pbuf..供接收DMA传送
- #if ETH_PAD_SIZE
- p = pbuf_alloc(PBUF_RAW,(PBUF_LEN_MAX+ETH_PAD_SIZE), PBUF_POOL); //10 * 1500
- pbuf_header(p, -ETH_PAD_SIZE); //向后移2个字节,接收过后,刚刚好
- #endif //ETH_PAD_SIZE
- pbuf_cnt++;
-
- if(p != NULL) {
- /* write the descriptors if there are enough numbers to hold the pbuf*/
- if(((u32_t)pbuf_clen(p)) <= num_bd) {
- // pbuf_clen(p)计算从p开始,pbuf链的长度
- //如果pbuf_alloc产生比num_bd更大长度的描述符,那么就是个悲剧了。
- for(q = p; q != NULL; q = q->next) {
- curr_bd->bufptr = (u32_t)(q->payload); //buffer_ptr
- curr_bd->bufoff_len = q->len; //buffoff & buffer_len
- curr_bd->next = curr_bd + 1; //next buffer descriptor
- curr_bd->flags_pktlen = CPDMA_BUF_DESC_OWNER; //flag set or clear
-
- /* Save the pbuf */
- curr_bd->pbuf = q;
- last_bd = curr_bd;
- curr_bd = curr_bd->next;
- num_bd--;
- }//for
- }//if <= num_bd
-
- /* free the allocated pbuf if no free descriptors are left */
- else {
- pbuf_free(p);
- break;
- }//else pbuf chain len > num_bd
- }//if p != NULL
- else {
- break;
- }//else p== NULL
- }//while 产生10个
- last_bd->next = (volatile struct cpdma_rx_bd *)NULL; //buff des chain 构造完成
- rxch->active_tail = last_bd; //rxch控制着整个rxch的接收方式
- EMAC->RXHDP[0] = (u32_t)(rxch->active_head); //add - lp
- return ERR_OK;
- }
- /**
- ** 使用该rx_inhandler处理接收中断
- ** 每个pbuf链在处理之前必须要向前移ETH_PAD_SIZE个字节,以便4字节对齐
- ** 当你还要产生pbuf的时候,也要向后移ETH_PAD_SIZE个字节,以便接收。
- * @param netif the lwip network interface structure for this ethernetif
- * @return none
- */
- void
- Emac_rxint_handler(struct netif *netif) {
- struct rxch *rxch;
- volatile struct cpdma_rx_bd *curr_bd, *processed_bd, *curr_tail, *last_bd;
- volatile struct pbuf *pbuf, *q, *new_pbuf;
- u32_t ex_len = 0, len_to_alloc = 0;
- u16_t tot_len;
-
- // sitaraif = netif->state;
- rxch = &(emac_trif.rxch);
- //得到当前的rxch buffer desc
- curr_bd = rxch->active_head;
- last_bd = rxch->active_tail;
-
- //pbuf链中,SOP只出现一次,但是curr_bd已将buffer链推向下一个可能出现
- //SOP的开头,所以这种方式更加严谨和有效。
- while(curr_bd->flags_pktlen & CPDMA_BUF_DESC_SOP) {
- //用while是因为pbuf链来处理的
- ex_len = 0;
- len_to_alloc = 0;
- //当OWNER被EMAC清掉的时候,EMAC就放弃了buff desc,可以做一些处理
- if((curr_bd->flags_pktlen & CPDMA_BUF_DESC_OWNER)
- != CPDMA_BUF_DESC_OWNER) {
-
- if(rxch->free_head == NULL) {
- /* this bd chain will be freed after processing */
- rxch->free_head = curr_bd;
- }//if NULL
-
- //得到该接收到packet_len的长度
- tot_len = (curr_bd->flags_pktlen) & 0xFFFF;
- //保存当前接收的起始pbuf
- q = curr_bd->pbuf;
- //以下循环体为了更新除pbuf->payload除外,在结构体pbuf中
- //的len,tot_len数据
- do {
- //得到当前pbuf地址
- pbuf = curr_bd->pbuf;
-
- /* If the earlier pbuf ended, update the chain */
- if(pbuf->next == NULL) {
- pbuf->next = (struct pbuf*)(curr_bd->next)->pbuf;
- } //if Null
-
- //len_to_alloc , pbuf链中的len的总和
- len_to_alloc += pbuf->len;
- /* Update the len and tot_len fields for the pbuf in the chain*/
- pbuf->len = (curr_bd->bufoff_len) & 0xFFFF; //当前pbuf长度
- pbuf->tot_len = tot_len - ex_len ; //当前pbuf后的tot_len长度(含自己)
- processed_bd = curr_bd; //处理中的desc
- ex_len += pbuf->len;
- curr_bd = curr_bd->next;
- } while((processed_bd->flags_pktlen & CPDMA_BUF_DESC_EOP)
- != CPDMA_BUF_DESC_EOP);
- /**
- * Close the chain for this pbuf. A full packet is received in
- * this pbuf chain. Now this pbuf can be given to upper layers for
- * processing. The start of the pbuf chain is now 'q'.
- */
- pbuf->next = (struct pbuf *)NULL;
-
- //在q处理之前,需要加上ETH_PAD_SIZE个空间,以便4字节对齐
- #if ETH_PAD_SIZE
- if(q != NULL)
- {
- pbuf_header((struct pbuf *)q, ETH_PAD_SIZE);
- #endif //ETH_PAD_SIZE
- //为了节省中断的处理效率,这里节省时间,直接post msg给tcpip_thread
- if((netif->input((struct pbuf *)q,netif)) != ERR_OK)
- {
- pbuf_free((struct pbuf *)q);
- q = (volatile struct pbuf *)NULL;
- }
- #if ETH_PAD_SIZE
- } //ETH_PAD_SIZE
- #endif //ETH_PAD_SIZE
- /* Acknowledge that this packet is processed */
- // CPSWCPDMARxCPWrite(sitaraif->cpsw_cpdma_base, 0, (unsigned int)processed_bd);
- EMAC->RXCP[0] = (u32_t)processed_bd;
- rxch->active_head = curr_bd;
-
- /**
- * The earlier pbuf chain is freed from the upper layer. So, we need to
- * allocate a new pbuf chain and update the descriptors with the pbuf info.
- * To support chaining, the total length freed by the upper layer is tracked.
- * Care should be taken even if the allocation fails.
- */
- /**
- * now len_to_alloc will contain the length of the pbuf which was freed
- * from the upper layer
- */
- rxch->freed_pbuf_len += len_to_alloc;
- new_pbuf = pbuf_alloc(PBUF_RAW, ((rxch->freed_pbuf_len)+ETH_PAD_SIZE), PBUF_POOL);
- /* Write the descriptors with the pbuf info till either of them expires */
- if(new_pbuf != NULL) {
- #if ETH_PAD_SIZE
- pbuf_header((struct pbuf *)new_pbuf, -ETH_PAD_SIZE);
- #endif //ETH_PAD_SIZE
- curr_bd = rxch->free_head; //free_head,已经被释放的head,需要重新set
- //以下循环体添加新的pbuf到curr_bd中去
- for(q = new_pbuf; (q != NULL) && (curr_bd != rxch->active_head); q = q->next) {
- curr_bd->bufptr = (u32_t)(q->payload);
-
- /* no support for buf_offset. RXBUFFEROFFEST register is 0 */
- curr_bd->bufoff_len = (q->len) & 0xFFFF;
- curr_bd->flags_pktlen = CPDMA_BUF_DESC_OWNER;
-
- rxch->freed_pbuf_len -= q->len;
-
- /* Save the pbuf */
- curr_bd->pbuf = q;
- last_bd = curr_bd;
- curr_bd = curr_bd->next;
- }//for
-
- /**
- * At this point either pbuf expired or no rxbd to allocate. If
- * there are no, enough rx bds to allocate all pbufs in the chain,
- * free the rest of the pbuf
- */
- if(q != NULL) {
- pbuf_free((struct pbuf *)q);
- }
-
- curr_tail = rxch->active_tail;
- last_bd->next = (volatile struct cpdma_rx_bd *)NULL;
-
- curr_tail->next = rxch->free_head;
-
- /**
- * Check if the reception has ended. If the EOQ flag is set, the NULL
- * Pointer is taken by the DMA engine. So we need to write the RX HDP
- * with the next descriptor.
- */
- if(curr_tail->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
- // CPSWCPDMARxHdrDescPtrWrite(sitaraif->cpsw_cpdma_base,
- // (u32_t)(rxch->free_head), 0);
- EMAC->RXHDP[0] = (u32_t)(rxch->free_head);
- }//if EOQ
- rxch->free_head = curr_bd;
- rxch->active_tail = last_bd;
- }//if new_pbuf
- }//if OWNER
- curr_bd = rxch->active_head;
- //以下这句,L138未做要求.
- // CPSWCPDMANumFreeBufSet(sitaraif->cpsw_cpdma_base, 0, 1);
- // -----------括号不要删-------------------------------
- }//While ....
- //-------------------------------------------
- // 以下在外面写
- // CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_TX_PULSE);
- // CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_RX_PULSE);
- }
- //---------------------------------------------------------------
- //以下是发送部分
- //---------------------------------------------------------------
- /**
- ** 这个函数将pbuf链的数据发送给物理层,可能buffer_des连接多处,因为是
- ** pbuf链连接而成的
- * @return None
- **/
- void Emac_transmit(struct pbuf *pbuf) {
- struct pbuf *q;
- struct txch *txch;
- volatile struct cpdma_tx_bd *curr_bd, *active_head, *bd_end;
- // 取地址。
- txch = &(emac_trif.txch);
-
- //得到可以使用的空闲head
- curr_bd = txch->free_head;
- //激活的head
- active_head = curr_bd;
-
- //更新该头的packet len 字段
- curr_bd->flags_pktlen &= ~0xFFFF;
- curr_bd->flags_pktlen |= pbuf->tot_len;
- //交给EMAC之前,置位flags, SOP,OWNER
- curr_bd->flags_pktlen |= (CPDMA_BUF_DESC_SOP | CPDMA_BUF_DESC_OWNER);
- //把pbuf信息构建成buffer desc 链
- for(q = pbuf; q != NULL; q = q->next) {
- /* Intialize the buffer pointer and length */
- curr_bd->bufptr = (u32_t)(q->payload);
- curr_bd->bufoff_len = (q->len) & 0xFFFF;
- bd_end = curr_bd;
- curr_bd->pbuf = pbuf;
- curr_bd = curr_bd->next;
- }
- //将buffer desc结尾
- bd_end->next = (volatile struct cpdma_tx_bd *)NULL;
- bd_end->flags_pktlen |= CPDMA_BUF_DESC_EOP;
- //free_head指向下一个空的buff descriptor 处
- txch->free_head = curr_bd;
-
- //经过初始化之后,txch->active_tail指向NULL,但是发送buffer desc是一个
- //单向的循环链表。所以这也是上面为什么bd_end->next要赋NULL值
- if(txch->active_tail == NULL) {
- // 第一次发送active_head
- EMAC->TXHDP[0] = (u32_t)active_head;
- }
-
- /*
- **第1次发送过后,假如发送完了,那么transmiter 将会halt,这样CPU在
- **发送之前必须确认EOQ是否set,如果set,那么对于CPU来讲可以写HDP启动
- **TXDMA发送了。
- */
- else {
- curr_bd = txch->active_tail;
- curr_bd->next = active_head;
- if(curr_bd->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
- //假如EOQ被EMAC set之后,就启动tx DMA
- EMAC->TXHDP[0] = (u32_t)active_head;
- }
- }
- txch->active_tail = bd_end;
- }
- /**
- * This function will send a packet through the emac if the channel is
- * available. Otherwise, the packet will be queued in a pbuf queue.
- *
- * @param netif the lwip network interface structure for this ethernetif
- * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
- * @return ERR_OK if the packet could be sent
- * an err_t value if the packet couldn't be sent
- *
- */
- err_t
- OmapEmac_output(struct netif *netif, struct pbuf *p)
- {
- INT8U os_err = 0;
- SYS_ARCH_DECL_PROTECT(lev);
- //等待有效的信号量才能发送
- // OSSemPend(TxCmpSem, 1000, &os_err); // --LP , 2012/04/28 DLT
- /**
- * This entire function must run within a "critical section" to preserve
- * the integrity of the transmit pbuf queue.
- *
- */
- SYS_ARCH_PROTECT(lev);
- //在选择发送之前,要调整p->payload的两字节,因为它们不能发送出去
- #if ETH_PAD_SIZE
- pbuf_header(p, -ETH_PAD_SIZE);
- #endif
- /* adjust the packet length if less than minimum required */
- if(p->tot_len < MIN_PKT_LEN) {
- p->tot_len = MIN_PKT_LEN;
- p->len = MIN_PKT_LEN;
- }
- /**
- * Bump the reference count on the pbuf to prevent it from being
- * freed till we are done with it.
- *
- */
- pbuf_ref(p);
-
- //Emac物理层的发送。DMA 用了TX中断的方式
- Emac_transmit(p);
- /* Return to prior interrupt state and return. */
- SYS_ARCH_UNPROTECT(lev);
-
- return ERR_OK;
- }
- /**
- ** lower level 已经启动DMA发送了吗,这里是为了软件清掉SOP和EOP,然后就是pbuf
- ** 链表的回收。
- * @param netif the lwip network interface structure for this ethernetif
- * @return none
- */
- void
- Emac_txint_handler(struct netif *netif) {
- struct txch *txch;
- volatile struct cpdma_tx_bd *curr_bd, *next_bd_to_process;
-
- //取txch结构体的地址
- txch = &(emac_trif.txch);
- //下一待处理的buff des, next_bd_to_process被初始化为(EMAC_RAM_BASE)
- next_bd_to_process = txch->next_bd_to_process;
- // 用curr_bd来处理
- curr_bd = next_bd_to_process;
-
- /* Check for correct start of packet */
- while((curr_bd->flags_pktlen) & CPDMA_BUF_DESC_SOP) {
-
- /* Make sure that the transmission is over */
- while((curr_bd->flags_pktlen & CPDMA_BUF_DESC_OWNER)
- == CPDMA_BUF_DESC_OWNER);
-
- /* Traverse till the end of packet is reached */
- while(((curr_bd->flags_pktlen) & CPDMA_BUF_DESC_EOP) != CPDMA_BUF_DESC_EOP) {
- curr_bd = curr_bd->next;
- }//while(!EOP)
-
- next_bd_to_process->flags_pktlen &= ~(CPDMA_BUF_DESC_SOP);
- curr_bd->flags_pktlen &= ~(CPDMA_BUF_DESC_EOP);
- /**
- * If there are no more data transmitted, the next interrupt
- * shall happen with the pbuf associated with the free_head
- */
- if(curr_bd->next == NULL) {
- txch->next_bd_to_process = txch->free_head;
- }
-
- else {
- txch->next_bd_to_process = curr_bd->next; //接着处理下一帧数据包
- }
-
- //写TXCP[],该帧数据包已经写完
- // CPSWCPDMATxCPWrite(sitaraif->cpsw_cpdma_base, 0, (u32_t)curr_bd);
- EMAC->TXCP[0] = (u32_t)curr_bd;
- pbuf_free((struct pbuf *)curr_bd->pbuf);
- // LINK_STATS_INC(link.xmit);
-
- next_bd_to_process = txch->next_bd_to_process;
- curr_bd = next_bd_to_process;
- }
- //发送信号量给发送部分保证发送的完整性。
- // OSSemPost(TxCmpSem); //--lp , 2012/04/28 delete,查看效果。
- //在外面写的
- // CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_TX_PULSE);
- // CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_RX_PULSE);
- }
- /********************* this file is end ****************************/
- 代码其中之三:
- /**************************************************************************
- * *
- * PROJECT : TMON (Transparent monitor) *
- * *
- * MODULE : LWIP.c *
- * *
- * AUTHOR : Michael Anburaj *
- * URL : http://geocities.com/michaelanburaj/ *
- * EMAIL: michaelanburaj@hotmail.com *
- * *
- * PROCESSOR : Any *
- * *
- * Tool-chain : gcc *
- * *
- * DESCRIPTION : *
- * LwIP master source file. *
- * *
- **************************************************************************/
- #include "tcpip.h"
- #include "ethernetif.h"
- #include "netconf.h"
- /* ********************************************************************* */
- /* Global definitions */
- netif_t main_net;
- /* ********************************************************************* */
- /* File local definitions */
- /* ********************************************************************* */
- /**
- *** 初始化LwIP的协议栈
- */
- void LwIP_Init( void )
- {
- struct ip_addr ipaddr;
- struct ip_addr netmask;
- struct ip_addr gw;
-
- tcpip_init(NULL, NULL);
-
- /** 在此处初始化IP地址 **/
- IP4_ADDR(&ipaddr,192,168,1,88); //该宏需要执行的!
- IP4_ADDR(&netmask,255,255,255,0);
- IP4_ADDR(&gw,192,168,0,1);
- MEMCPY(main_net.name,"glzn",4);
- #if LWIP_NETIF_HOSTNAME
- main_net.hostname = GetHostName();
- #endif
- /* - netif_add(struct netif *netif, struct ip_addr *ipaddr,
- struct ip_addr *netmask, struct ip_addr *gw,
- void *state, err_t (* init)(struct netif *netif),
- err_t (* input)(struct pbuf *p, struct netif *netif))
-
- Adds your network interface to the netif_list. Allocate a struct
- netif and pass a pointer to this structure as the first argument.
- Give pointers to cleared ip_addr structures when using DHCP,
- or fill them with sane numbers otherwise. The state pointer may be NULL.
- The init function pointer must point to a initialization function for
- your ethernet netif interface. The following code illustrates it's use.*/
-
-
- netif_add(&main_net, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);
- /* Registers the default network interface.*/
- netif_set_default(&main_net); //可以删除 --2012/02/02, netif_default
- /* When the netif is fully configured this function must be called.*/
- netif_set_up(&main_net); //this functional
- }
- /* ********************************************************************* */
- 代码其中之四:
- //主程序
- //修改成适应LwIP v140的协议,此为系统main主函数
- #include
- #include
- #include "dspint.h"
- #include "sample.h"
- #include "edma.h"
- #include "norflash.h"
- #include "evmomapl138.h"
- #include "evmomapl138_gpio.h"
- #include "evmomapl138_uart.h"
- #include "evmomapl138_rtc.h"
- #include "io.h"
- #include "fpga_emifa.h"
- #include "test_fpga.h"
- //推荐的任务堆栈区大小为2048 OS_STK,即8192 byte
- #define COMMON_STACK_LEN 2048
- //给各个任务分配的堆栈区
- OS_STK TaskLWIPStk[COMMON_STACK_LEN];
- OS_STK TaskAppMainStk[COMMON_STACK_LEN];
- OS_STK TaskMMIStk[COMMON_STACK_LEN];
- OS_STK TaskFpgaUPPStk[COMMON_STACK_LEN];
- OS_STK TaskFpgaEMIFAStk[COMMON_STACK_LEN * 32];
- //OS_STK TaskTestStk[COMMON_STACK_LEN];
- //各个任务进程主函数
- void TaskAppMain(void *pd);
- void TaskMMI(void *pd);//通过upp总线刷液晶数据,触发dsp中断,启动upp发送
- extern void TaskLWIP(void *p_arg); //TaskLWIP任务
- //extern void TaskTest(void *pd);
- int main()
- {
- //初始化中断向量
- OS_CPU_InitExceptVect();
- //初始化uC/OS-II实时内核
- OSInit();
- //创建系统主进程任务(放在最高优先级,包括装置定值、参数自检测,并作为其他任务的WatchDog。)
- OSTaskCreate(TaskAppMain, (void *)0, (OS_STK*)&TaskAppMainStk[COMMON_STACK_LEN-1], 2);
- //启动操作系统内核
- OSStart();
- }
- //系统主进程任务
- void TaskAppMain(void *pd)
- {
- unsigned char ucErr;
- tmr0_init();
- GPIOInit();
- chipint_init();
- memset((unsigned char *)TaskLWIPStk, 0, (COMMON_STACK_LEN*sizeof(OS_STK)));
- //初始化由Lwip任务堆栈开辟的堆栈区域
- //INT8U enledflag = /;
- //INT32U counter = 0;
- //创建任务
- //OSTaskCreate(TaskFPGA_UPP, (void *)0, (OS_STK*)&TaskFpgaUPPStk[COMMON_STACK_LEN-1], 11);
- // OSTaskCreate(TaskFPGA_EMIFA, (void *)0, (OS_STK*)&TaskFpgaEMIFAStk[COMMON_STACK_LEN-1], 12);
- // OSTaskCreate(TaskMMI, (void *)0, (OS_STK*)&TaskMMIStk[COMMON_STACK_LEN-1], 13);
- //OSTaskCreate(TaskTest, (void *)0, (OS_STK*)&TaskTestStk[COMMON_STACK_LEN-1],100);
- OSTaskCreate(TaskLWIP,(void *)0,(OS_STK *)&TaskLWIPStk[COMMON_STACK_LEN -1],10);
- while(1)
- {
- /*asm(" nop");
- counter++;
- if(counter >=20)
- {
- enledflag ^=0x01;
- inb(ARM_DSP_CMD) = enledflag;
- DspintArmtrip(DSPINTTYPE_2);
- counter = 0;
- }
- if(enledflag == 0)
- {
- ledchange();
- }*/
- // OSTimeDly(500);
- // OSMboxPend(RxCntMbox,0,&ucErr);
- OSTimeDly(1000);
- asm(" nop");
- }
- }
- //
- #define SHAREMMI_ADR (0x80000200) //共享液晶显示数据区地址
- #define MMI_LNUM (240) //液晶显示一屏数据的行数目
- #define MMI_LBYTE (40) //液晶显示一屏数据的行字节数目320/8
- #define MMI_DATALEN (MMI_LNUM*MMI_LBYTE) //液晶显示缓冲区长度
- #define SHARERAW_ADR (0x8002800) //共享原始数据区地址
- #define SHAREMEA_ADR (0x8001f000) //共享测量结果区地址
- //显存
- #define LCD_XSIZE (320) // X方向像素
- #define LCD_YSIZE (240) // Y方向像素
- #define LCDMLEN ((LCD_XSIZE*LCD_YSIZE)/8)
- INT8U LcdMemory[LCDMLEN];
- void loadMMIdata()
- {
- INT8U *pobject;
- INT16U i;
- static INT8U showdata = 0;
- static INT8U changeflag = 0;
- changeflag++;
- if(changeflag==6)
- {
- changeflag=0;
- showdata++;
- }
- pobject =LcdMemory;//(INT8U*)SHAREMMI_ADR;
- if(showdata == 0)
- {
- for(i=0;i
- {
- *pobject++ = (i+1)&0xff;
- }
- }
- else
- {
- for(i=0;i
- {
- *pobject++ = showdata;
- }
- }
- }
- void TaskMMI(void *pd)
- {
- while(1)
- {
-
- //pushus(0);
- //loadMMIdata();
- //EDMA0config(0,(void*)LcdMemory,(void*)SHAREMMI_ADR,LCDMLEN);
-
- //pushus(1);
- RelayTest();
- OSTimeDly(100);
- }
- }
- 代码其中之五:
- /* main.c
- ** test lwip
- ***************************************************/
- #include
- #include "evmomapl138.h"
- #include
- #include
- #include
- #include "lwip/mem.h"
- #include "lwip/memp.h"
- #include "lwip/netif.h"
- #include "lwip/tcpip.h"
- #include "lwip.h"
- // LwIP task stk Information
- /**
- ** DEBUG Information
- ****************************************************/
- /**
- ** global value
- ***************************************************/
- /**
- ** function decl
- **************************************************/
- static void BSP_Init(void );
- void tcpip_init_done(void *arg);
- /* App_LwipTask
- **
- ************************************************************************/
- void TaskLWIP(void *parg)
- {
- //加载网卡驱动
- //加载L138本身自带的EMAC驱动
- //Lwip_v140使用lwip.c处理初始化网口的信息,主任务只要调用lwip_Init()即可
- LwIP_Init();
- while(1)
- {
- OSTimeDly(2000);
- }
- }
- /* BSP_Init()
- ** 配置启动的时钟,貌似omapL138_app/boot.asm 中
- ** 有初始化STACK等配置,但是没有见到其内有时钟配置,工程初始化时也没有发现。
- ** 故要初始化PLL
- ********************************************/
- void BSP_Init(void)
- {
- EVMOMAPL138_Init();
- }
- 我贴了一些代码,请看看帮帮忙,我真不知道该如何解决啦...
复制代码一周热门 更多>