搜索
bottom↓
回复: 6

请教一个lpc1768官方以太网驱动接收数据帧的问题

[复制链接]

出0入0汤圆

发表于 2013-1-16 12:23:33 | 显示全部楼层 |阅读模式
本帖最后由 zhongshu_1988 于 2013-1-16 12:33 编辑

一、硬件:
开发板用的是微雪的open1768,lpc1768的芯片;
以太网物理芯片用的是DP83848;

二、驱动:
驱动用的是lpc官方驱动包:lpc175x_6x_cmsis_driver_library

三、方案:
我在测试接收以太网数据帧,用一台linux笔记本写了一个以太网帧发送程序,每隔一秒向开发板发送一个以太网帧。然后,设置断点,测试接收情况。

四、源文件:
1. emactest.c
  1. #include "string.h"
  2. #include "crc32.h"
  3. #include "lpc17xx_emac.h"
  4. #include "lpc17xx_gpio.h"
  5. #include "lpc17xx_pinsel.h"
  6. #include "lpc17xx_libcfg.h"

  7. /*目标:接收一个以太网帧,然后把该帧发送回去*/

  8. /* This is the MAC address of LPC1768 */
  9. #define EMAC_ADDR12                0x00006666
  10. #define EMAC_ADDR34                0x00006666
  11. #define EMAC_ADDR56                0x00006666
  12. /* A pseudo destination MAC address is defined for
  13. * both TX_ONLY and BOUNCE_RX test */
  14. #define EMAC_DST_ADDR12                0x0000E386
  15. #define EMAC_DST_ADDR34                0x00006BDA
  16. #define EMAC_DST_ADDR56                0x00005000


  17. /* INTERNAL MACROS ----------------------------------------------- */

  18. #define TX_PACKET_SIZE                114

  19. #define MYMAC_1         ((EMAC_ADDR12 & 0xFF00) >> 8)
  20. #define MYMAC_2         ((EMAC_ADDR12 & 0xFF))
  21. #define MYMAC_3         ((EMAC_ADDR34 & 0xFF00) >> 8)
  22. #define MYMAC_4         ((EMAC_ADDR34 & 0xFF))
  23. #define MYMAC_5         ((EMAC_ADDR56 & 0xFF00) >> 8)
  24. #define MYMAC_6         ((EMAC_ADDR56 & 0xFF))


  25. /*  PRIVATE VARIABLES ----------------------------------------------- */
  26. /* Global Tx Buffer data 应用程序发送缓冲区*/
  27. uint8_t __attribute__ ((aligned (4))) gTxBuf[TX_PACKET_SIZE + 0x10];
  28. /* Global Rx Buffer data 应用程序发送缓冲区*/
  29. uint8_t __attribute__ ((aligned (4))) gRxBuf[TX_PACKET_SIZE + 0x10];


  30. /* EMAC address */
  31. uint8_t EMACAddr[] = {MYMAC_6, MYMAC_5, MYMAC_4, MYMAC_3, MYMAC_2, MYMAC_1};

  32. /* Tx, Rx Counters */
  33. __IO uint32_t RXOverrunCount = 0;
  34. __IO uint32_t RXErrorCount = 0;
  35. __IO uint32_t TXUnderrunCount = 0;
  36. __IO uint32_t TXErrorCount = 0;
  37. __IO uint32_t RxFinishedCount = 0;
  38. __IO uint32_t TxFinishedCount = 0;
  39. __IO uint32_t TxDoneCount = 0;
  40. __IO uint32_t RxDoneCount = 0;
  41. __IO uint32_t ReceiveLength = 0;
  42. __IO Bool PacketReceived = FALSE;

  43. /************************** PRIVATE FUNCTON **********************************/
  44. /* Interrupt service routines */
  45. void ENET_IRQHandler (void);

  46. void PacketGen(uint8_t *txptr);
  47. void Usr_Init_Emac(void);

  48. /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
  49. /*********************************************************************//**
  50. * @brief                Ethernet service routine handler
  51. * @param[in]        none
  52. * @return                 none
  53. **********************************************************************/
  54. void ENET_IRQHandler (void)
  55. {
  56.         EMAC_PACKETBUF_Type RxDatbuf;
  57.         uint32_t RxLen;

  58.         /* EMAC Ethernet Controller Interrupt function. */
  59.         uint32_t int_stat;
  60.         // Get EMAC interrupt status
  61.         while ((int_stat = (LPC_EMAC->IntStatus & LPC_EMAC->IntEnable)) != 0) {
  62.                 // Clear interrupt status
  63.                 LPC_EMAC->IntClear = int_stat;
  64.                 /* scan interrupt status source */

  65.                 /* ---------- receive overrun ------------*/
  66.                 if((int_stat & EMAC_INT_RX_OVERRUN))
  67.                 {
  68.                         RXOverrunCount++;
  69.                 }

  70.                 /*-----------  receive error -------------*/
  71.                 /* Note:
  72.                  * The EMAC doesn't distinguish the frame type and frame length,
  73.                  * so, e.g. when the IP(0x8000) or ARP(0x0806) packets are received,
  74.                  * it compares the frame type with the max length and gives the
  75.                  * "Range" error. In fact, this bit is not an error indication,
  76.                  * but simply a statement by the chip regarding the status of
  77.                  * the received frame
  78.                  */
  79.                 if ((int_stat & EMAC_INT_RX_ERR))
  80.                 {
  81.                         if (EMAC_CheckReceiveDataStatus(EMAC_RINFO_RANGE_ERR) == RESET){
  82.                                 RXErrorCount++;
  83.                         }
  84.                 }

  85.                 /* ---------- RX Finished Process Descriptors ----------*/
  86.                 if ((int_stat & EMAC_INT_RX_FIN))
  87.                 {
  88.                         RxFinishedCount++;
  89.                 }

  90.                 /* ---------- Receive Done -----------------------------*/
  91.                 /* Note: All packets are greater than (TX_PACKET_SIZE + 4)
  92.                  * will be ignore!
  93.                  */
  94.                 if ((int_stat & EMAC_INT_RX_DONE))
  95.                 {
  96.                         /* Packet received, check if packet is valid. */
  97.                         if (EMAC_CheckReceiveIndex()){
  98.                                 if (!EMAC_CheckReceiveDataStatus(EMAC_RINFO_LAST_FLAG)){
  99.                                         goto rel;
  100.                                 }
  101.                                 // Get data size, trip out 4-bytes CRC field, note that length in (-1) style format
  102.                                 RxLen = EMAC_GetReceiveDataSize() - 3;
  103.                                 // Note that packet added 4-bytes CRC created by yourself
  104.                                 if ((RxLen > (TX_PACKET_SIZE + 4)) || (EMAC_CheckReceiveDataStatus(EMAC_RINFO_SYM_ERR))) {
  105.                                         /* Invalid frame, ignore it and free buffer */
  106.                                         goto rel;
  107.                                 }
  108.                                 ReceiveLength = RxLen;
  109.                                 // Valid Frame, just copy it
  110.                                 RxDatbuf.pbDataBuf = (uint32_t *)gRxBuf;
  111.                                 RxDatbuf.ulDataLen = RxLen;
  112.                                 EMAC_ReadPacketBuffer(&RxDatbuf);
  113.                                 PacketReceived = TRUE;

  114.                 rel:
  115.                                 /* Release frame from EMAC buffer */
  116.                                 EMAC_UpdateRxConsumeIndex();
  117.                         }
  118.                         RxDoneCount++;
  119.                 }

  120.                 /*------------------- Transmit Underrun -----------------------*/
  121.                 if ((int_stat & EMAC_INT_TX_UNDERRUN))
  122.                 {
  123.                         TXUnderrunCount++;
  124.                 }

  125.                 /*------------------- Transmit Error --------------------------*/
  126.                 if ((int_stat & EMAC_INT_TX_ERR))
  127.                 {
  128.                         TXErrorCount++;
  129.                 }

  130.                 /* ----------------- TX Finished Process Descriptors ----------*/
  131.                 if ((int_stat & EMAC_INT_TX_FIN))
  132.                 {
  133.                         TxFinishedCount++;
  134.                 }

  135.                 /* ----------------- Transmit Done ----------------------------*/
  136.                 if ((int_stat & EMAC_INT_TX_DONE))
  137.                 {
  138.                         TxDoneCount++;
  139.                 }
  140.         }
  141. }


  142. /*-------------------------PRIVATE FUNCTIONS-----------------------------------*/
  143. /*********************************************************************//**
  144. * @brief                Create a perfect packet for TX
  145. * @param[in]        pointer to TX packet
  146. * @return                 none
  147. **********************************************************************/
  148. void PacketGen( uint8_t *txptr )
  149. {
  150.   int i;
  151.   uint32_t crcValue;
  152.   uint32_t BodyLength = TX_PACKET_SIZE - 14;

  153.   /* Dest address */
  154.   *(txptr+0) = EMAC_DST_ADDR56 & 0xFF;
  155.   *(txptr+1) = (EMAC_DST_ADDR56 >> 0x08) & 0xFF;
  156.   *(txptr+2) = EMAC_DST_ADDR34 & 0xFF;
  157.   *(txptr+3) = (EMAC_DST_ADDR34 >> 0x08) & 0xFF;
  158.   *(txptr+4) = EMAC_DST_ADDR12 & 0xFF;
  159.   *(txptr+5) = (EMAC_DST_ADDR12 >> 0x08) & 0xFF;

  160.   /* Src address */
  161.   *(txptr+6) = EMAC_ADDR56 & 0xFF;
  162.   *(txptr+7) = (EMAC_ADDR56 >> 0x08) & 0xFF;
  163.   *(txptr+8) = EMAC_ADDR34 & 0xFF;
  164.   *(txptr+9) = (EMAC_ADDR34 >> 0x08) & 0xFF;
  165.   *(txptr+10) = EMAC_ADDR12 & 0xFF;
  166.   *(txptr+11) = (EMAC_ADDR12 >> 0x08) & 0xFF;

  167.   /* Type or length, body length is TX_PACKET_SIZE - 14 bytes */
  168.   *(txptr+12) = BodyLength & 0xFF;
  169.   *(txptr+13) = (BodyLength >> 0x08) & 0xFF;

  170.   /* Skip the first 14 bytes for dst, src, and type/length */
  171.   for ( i=0; i < BodyLength; i++ )
  172.   {
  173.         *(txptr+i+14) = 0x55;
  174.   }

  175.   // Calculate CRC
  176.   crcValue = crc32_bfr( txptr, TX_PACKET_SIZE );

  177.   // Add 4-byte CRC
  178.   *(txptr+TX_PACKET_SIZE) = (0xff & crcValue);
  179.   *(txptr+TX_PACKET_SIZE+1) = 0xff & (crcValue >> 8 );
  180.   *(txptr+TX_PACKET_SIZE+2) = 0xff & (crcValue >> 16);
  181.   *(txptr+TX_PACKET_SIZE+3) = 0xff & (crcValue >> 24);
  182. }


  183. /*********************************************************************//**
  184. * @brief                User EMAC initialize
  185. * @param[in]        none
  186. * @return                 none
  187. **********************************************************************/
  188. void Usr_Init_Emac(void)
  189. {
  190.         /* EMAC configuration type */
  191.         EMAC_CFG_Type Emac_Config;
  192.         /* pin configuration */
  193.         PINSEL_CFG_Type PinCfg;
  194.         uint32_t i;
  195.         /*
  196.          * Enable P1 Ethernet Pins:
  197.          * P1.0 - ENET_TXD0
  198.          * P1.1 - ENET_TXD1
  199.          * P1.4 - ENET_TX_EN
  200.          * P1.8 - ENET_CRS
  201.          * P1.9 - ENET_RXD0
  202.          * P1.10 - ENET_RXD1
  203.          * P1.14 - ENET_RX_ER
  204.          * P1.15 - ENET_REF_CLK
  205.          * P1.16 - ENET_MDC
  206.          * P1.17 - ENET_MDIO
  207.          */
  208.         PinCfg.Funcnum = 1;
  209.         PinCfg.OpenDrain = 0;
  210.         PinCfg.Pinmode = 0;
  211.         PinCfg.Portnum = 1;

  212.         PinCfg.Pinnum = 0;
  213.         PINSEL_ConfigPin(&PinCfg);
  214.         PinCfg.Pinnum = 1;
  215.         PINSEL_ConfigPin(&PinCfg);
  216.         PinCfg.Pinnum = 4;
  217.         PINSEL_ConfigPin(&PinCfg);
  218.         PinCfg.Pinnum = 8;
  219.         PINSEL_ConfigPin(&PinCfg);
  220.         PinCfg.Pinnum = 9;
  221.         PINSEL_ConfigPin(&PinCfg);
  222.         PinCfg.Pinnum = 10;
  223.         PINSEL_ConfigPin(&PinCfg);
  224.         PinCfg.Pinnum = 14;
  225.         PINSEL_ConfigPin(&PinCfg);
  226.         PinCfg.Pinnum = 15;
  227.         PINSEL_ConfigPin(&PinCfg);
  228.         PinCfg.Pinnum = 16;
  229.         PINSEL_ConfigPin(&PinCfg);
  230.         PinCfg.Pinnum = 17;
  231.         PINSEL_ConfigPin(&PinCfg);

  232.         Emac_Config.Mode = EMAC_MODE_AUTO;
  233.         Emac_Config.pbEMAC_Addr = EMACAddr;
  234.         // Initialize EMAC module with given parameter
  235.         while (EMAC_Init(&Emac_Config) == ERROR){
  236.                 // Delay for a while then continue initializing EMAC module
  237.                 for (i = 0x100000; i; i--);
  238.         }
  239.         // Enable all interrupt
  240.         EMAC_IntCmd((EMAC_INT_RX_OVERRUN | EMAC_INT_RX_ERR | EMAC_INT_RX_FIN \
  241.                         | EMAC_INT_RX_DONE | EMAC_INT_TX_UNDERRUN | EMAC_INT_TX_ERR \
  242.                         | EMAC_INT_TX_FIN | EMAC_INT_TX_DONE), ENABLE);
  243.         NVIC_SetPriority(ENET_IRQn, 0);
  244.         NVIC_EnableIRQ(ENET_IRQn);
  245. }

  246. /*-------------------------MAIN FUNCTION------------------------------*/
  247. /*********************************************************************//**
  248. * @brief                c_entry: Main EMAC program body
  249. * @param[in]        None
  250. * @return                 int
  251. **********************************************************************/
  252. int c_entry (void)
  253. {
  254.         /* Data Packet format */
  255.         EMAC_PACKETBUF_Type DataPacket;

  256.         uint8_t *txptr;

  257.         //uint32_t j;

  258.         /*BOUNCE_RX*/
  259.         uint8_t *rxptr;

  260.         NVIC_SetPriorityGrouping(4);  //sets PRIGROUP to 3:2 (XXX:YY)

  261.         // Init EMAC
  262.         Usr_Init_Emac();

  263.         //txptr = (uint8_t *)gTxBuf;
  264.         /* pre-format the transmit packets */
  265.         //PacketGen(txptr);

  266.         /*BOUNCE_RX*/
  267.         //copy just received data from RX buffer to TX buffer and send out
  268.         txptr = (uint8_t *)gTxBuf;
  269.         rxptr = (uint8_t *)gRxBuf;

  270.         /*BOUNCE_RX*/
  271.         while( 1 )
  272.         {
  273.                 //LED_Blink(BLINK_LED_PIN);
  274.                 if ( PacketReceived == TRUE )
  275.                 {
  276.                           PacketReceived = FALSE;
  277.                         //Reverse Source and Destination, then copy the body
  278.                         memcpy( (uint8_t *)txptr, (uint8_t *)(rxptr+6), 6);
  279.                         memcpy( (uint8_t *)(txptr+6), (uint8_t *)rxptr, 6);
  280.                         memcpy( (uint8_t *)(txptr+12), (uint8_t *)(rxptr+12), (ReceiveLength - 12));
  281.                         //Send packet back
  282.                         DataPacket.pbDataBuf = (uint32_t *)txptr;
  283.                         DataPacket.ulDataLen = ReceiveLength;
  284.                         EMAC_WritePacketBuffer(&DataPacket);
  285.                         EMAC_UpdateTxProduceIndex();
  286.                 }
  287.         }

  288.         /* Transmit packets only */
  289.         /*
  290.         while ( 1 ) {
  291.                 txptr = (uint8_t *)gTxBuf;
  292.                 //_DBG_("Send packet");
  293.                 //LED_Blink(TX_LED_PIN);
  294.                 DataPacket.pbDataBuf = (uint32_t *)txptr;
  295.                 // Note that there're 4-byte CRC added
  296.                 DataPacket.ulDataLen = TX_PACKET_SIZE + 4;
  297.                 EMAC_WritePacketBuffer(&DataPacket);
  298.                 EMAC_UpdateTxProduceIndex();
  299.                 for ( j = 0; j < 0x200000; j++ );        //delay
  300.         }
  301.         */
  302. }

  303. int main(void)
  304. {
  305.     return c_entry();
  306. }
复制代码
2. lpc17xx_emac.c
这个文件我没有任何改动。

3. 用于发送以太网帧的linux程序pf_packet_sock.c
在附件中。

五、遇到的问题
用JLINK调试开发板,当网口接收到一个以太网帧时,就会进入ENET_IRQHandler中断处理程序,清中断、检查中断类型等等,直到进入第123行语句,发现总是跳转到rel,这说明出现了一个“EMAC_RINFO_SYM_ERR”错误。我查了数据手册,说是“SymbolError,在接收过程中,PHY通过PHY接口报告有一个位错误”。我不明白为什么会出现这种错误。实际上,我尝试过把“EMAC_CheckReceiveDataStatus(EMAC_RINFO_SYM_ERR)”注释,那么程序就接收正常,之后我再把接收到的数据包发送到我台式机,通过抓包,我发现,此时抓到的数据帧与我发送的数据帧一样。这又说明我接收的数据帧没有什么问题。但为什么报EMAC_RINFO_SYM_ERR错误呢?很困惑,迷茫,希望各位能给点提示,谢谢了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-1-16 15:24:22 | 显示全部楼层
找到问题了,我用同样的程序测试刚焊接好的一块板卡,没问题,可以推断,问题出在微雪板卡或者DP83848以太网物理层芯片上。

出0入0汤圆

发表于 2013-2-20 17:54:57 | 显示全部楼层
请教个问题,lpc1768做以太网通信 - 可以正常通信,只是在大量数据包下网络会断(能发,但是不能接收)

出0入0汤圆

发表于 2013-4-23 22:16:11 | 显示全部楼层
zhongshu_1988 发表于 2013-1-16 15:24
找到问题了,我用同样的程序测试刚焊接好的一块板卡,没问题,可以推断,问题出在微雪板卡或者DP83848以太 ...

楼主,问一下arm的网口怎么连接啊,我就一个网线啊,是用一根网线把arm跟电脑相连吗

出0入0汤圆

发表于 2013-5-11 20:37:20 | 显示全部楼层
能用吧

出0入0汤圆

发表于 2013-5-11 20:39:04 | 显示全部楼层
有电路图没

出0入0汤圆

发表于 2013-9-12 18:55:01 | 显示全部楼层
这位兄弟,我也在用微雪的这个模块,也跟你发现同样的问题,你最后早到了产生SymbolError的原因了吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-14 00:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表