硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2492|回复: 3
收起左侧

[网络] RT1052使用的以太网IP核跟飞思卡尔的K60,K70应该是同一个,为以后移植RL-TCPnet打下坚实基础

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115694
QQ
发表于 2018-3-19 12:08:29 | 显示全部楼层 |阅读模式
当前ARM的CMSIS-Driver未对RT1052的以太网做驱动支持,仅对I2C和SPI做了驱动。只能自己实现了,所以找了下飞思卡尔之前的系列。
下面是K60的底层MAC+KSZ8081,当前RT1052也是同样配置和外设。

  1. /*-----------------------------------------------------------------------------
  2. *      RL-ARM - TCPnet
  3. *-----------------------------------------------------------------------------
  4. *      Name:    ENET_MK6x.C
  5. *      Purpose: Driver for Freescale MK60 Ethernet Controller
  6. *      Rev.:    V4.70
  7. *-----------------------------------------------------------------------------
  8. *      This code is part of the RealView Run-Time Library.
  9. *      Copyright (c) 2004-2013 KEIL - An ARM Company. All rights reserved.
  10. *----------------------------------------------------------------------------*/

  11. #include <Net_Config.h>
  12. #include <MK60F12.H>
  13. #include "ENET_MKxx.h"

  14. /* The following macro definitions may be used to select the speed
  15.    of the physical link:

  16.   _10MBIT_   - connect at 10 MBit only
  17.   _100MBIT_  - connect at 100 MBit only

  18.   By default an autonegotiation of the link speed is used. This may take
  19.   longer to connect, but it works for 10MBit and 100MBit physical links.      */

  20. /* Net_Config.c */
  21. extern U8 own_hw_adr[];

  22. /* Local variables */
  23. static U8 TxBufIndex;
  24. static U8 RxBufIndex;

  25. /* ENET local DMA Descriptors. */
  26. static __align(16) RX_Desc Rx_Desc[NUM_RX_BUF];
  27. static __align(16) TX_Desc Tx_Desc[NUM_TX_BUF];

  28. /* ENET local DMA buffers. */
  29. static U32 rx_buf[NUM_RX_BUF][ETH_BUF_SIZE>>2];
  30. static U32 tx_buf[NUM_TX_BUF][ETH_BUF_SIZE>>2];

  31. #define IDX(x) (x/2)
  32. #define SWE(n) ((((n) & 0x00FF) << 8) | (((n) & 0xFF00) >> 8))

  33. /*-----------------------------------------------------------------------------
  34. *      ENET Ethernet Driver Functions
  35. *-----------------------------------------------------------------------------
  36. *  Required functions for Ethernet driver module:
  37. *  a. Polling mode: - void init_ethernet ()
  38. *                   - void send_frame (OS_FRAME *frame)
  39. *                   - void poll_ethernet (void)
  40. *  b. Interrupt mode: - void init_ethernet ()
  41. *                     - void send_frame (OS_FRAME *frame)
  42. *                     - void int_enable_eth ()
  43. *                     - void int_disable_eth ()
  44. *                     - interrupt function
  45. *----------------------------------------------------------------------------*/

  46. /* Local Function Prototypes */
  47. static void rx_descr_init (void);
  48. static void tx_descr_init (void);
  49. static void write_PHY (U32 PhyReg, U16 Value);
  50. static U16  read_PHY (U32 PhyReg);

  51. /*--------------------------- init_ethernet ----------------------------------*/
  52. void init_ethernet (void) {
  53.   /* Initialize the ETH ethernet controller. */
  54.   U32 regv,tout,id1,id2,ctrl;
  55.   
  56.   OSC0->CR   |= OSC_CR_ERCLKEN_MASK;    /* Enable external reference clock    */
  57.   SIM->SCGC2 |= SIM_SCGC2_ENET_MASK;    /* Enable ENET module gate clocking   */
  58.   SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK |  /* Enable Port A module gate clocking */
  59.                 SIM_SCGC5_PORTB_MASK ;  /* Enable Port B module gate clocking */

  60.   /* Configure Ethernet Pins  */
  61.   PORTA->PCR[5]  &= ~(PORT_PCR_MUX_MASK | PORT_PCR_PS_MASK);
  62.   PORTA->PCR[5]  |=  PORT_PCR_MUX(4);   /* Pull-down on RX_ER is enabled      */

  63.   PORTA->PCR[12]  = (PORTA->PCR[12] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4);
  64.   PORTA->PCR[13]  = (PORTA->PCR[13] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4);
  65.   PORTA->PCR[14]  = (PORTA->PCR[14] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4);
  66.   PORTA->PCR[15]  = (PORTA->PCR[15] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4);
  67.   PORTA->PCR[16]  = (PORTA->PCR[16] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4);
  68.   PORTA->PCR[17]  = (PORTA->PCR[17] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4);

  69.   PORTB->PCR[0]   = (PORTB->PCR[0]  & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4)| PORT_PCR_ODE_MASK;
  70.   PORTB->PCR[1]   = (PORTB->PCR[1]  & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(4);

  71.   /* Reset Ethernet MAC */
  72.   ENET->ECR =  ENET_ECR_RESET_MASK;
  73.   while (ENET->ECR & ENET_ECR_RESET_MASK);

  74.   /* Set MDC clock frequency @ 50MHz MAC clock frequency */
  75.   ENET->MSCR = ENET_MSCR_MII_SPEED(0x13);

  76.   /* Set receive control */
  77.   ENET->RCR = ENET_RCR_MAX_FL (0x5EE) |
  78.               ENET_RCR_RMII_MODE_MASK | /* MAC Configured for RMII operation  */
  79.               ENET_RCR_MII_MODE_MASK  ; /* This bit must always be set        */

  80.   /* Set transmit control */
  81.   ENET->TCR = ENET_TCR_ADDINS_MASK |    /* MAC overwrites the source MAC */
  82.               ENET_TCR_ADDSEL(0)   ;    /* MAC address is in PADDR 1 and 2 */

  83.   ENET->MRBR = ETH_BUF_SIZE;

  84.   /* Set thresholds */
  85.   ENET->RAEM = 4;
  86.   ENET->RAFL = 4;
  87.   ENET->TAEM = 4;
  88.   ENET->TAFL = 8;
  89.   ENET->RSFL = 0;                       /* Store and forward on the RX FIFO   */
  90.   ENET->FTRL = 0x7FF;                   /* Frame Truncation Length            */

  91.   /* Read PHY ID */
  92.   id1 = read_PHY (PHY_REG_ID1);
  93.   id2 = read_PHY (PHY_REG_ID2);

  94.   /* Check if this is a KSZ8041NL PHY. */
  95.   if (((id1 << 16) | (id2 & 0xFFF0)) == PHY_ID_KSZ8041) {
  96.     /* Put the PHY in reset mode */
  97.     write_PHY (PHY_REG_BCTRL, 0x8000);

  98.     /* Wait for hardware reset to end. */
  99.     for (tout = 0; tout < 0x10000; tout++) {
  100.       regv = read_PHY (PHY_REG_BCTRL);
  101.       if (!(regv & 0x8800)) {
  102.         /* Reset complete, device not Power Down. */
  103.         break;
  104.       }
  105.     }
  106.     /* Configure the PHY device */
  107. #if defined (_10MBIT_)
  108.     /* Connect at 10MBit */
  109.     write_PHY (PHY_REG_BCTRL, PHY_FULLD_10M);
  110. #elif defined (_100MBIT_)
  111.     /* Connect at 100MBit */
  112.     write_PHY (PHY_REG_BCTRL, PHY_FULLD_100M);
  113. #else
  114.     /* Use autonegotiation about the link speed. */
  115.     write_PHY (PHY_REG_BCTRL, PHY_AUTO_NEG);
  116.     /* Wait to complete Auto_Negotiation. */
  117.     for (tout = 0; tout < 0x10000; tout++) {
  118.       regv = read_PHY (PHY_REG_BSTAT);
  119.       if (regv & 0x0020) {        
  120.         break;                          /* Autonegotiation Complete           */
  121.       }
  122.     }
  123. #endif
  124.     /* Check the link status. */
  125.     for (tout = 0; tout < 0x10000; tout++) {
  126.       regv = read_PHY (PHY_REG_BSTAT);
  127.       if (regv & 0x0004) {        
  128.         break;                          /* Link is on                         */
  129.       }
  130.     }

  131.     /* Check Operation Mode Indication in PHY Control register */
  132.     regv = read_PHY (PHY_REG_PC2);
  133.     /* Configure Full/Half Duplex mode. */
  134.     switch ((regv & 0x001C) >> 2) {
  135.       case 1:  ctrl = PHY_CON_10M  | PHY_CON_HD; break;
  136.       case 2:  ctrl = PHY_CON_100M | PHY_CON_HD; break;
  137.       case 5:  ctrl = PHY_CON_10M  | PHY_CON_FD; break;
  138.       case 6:  ctrl = PHY_CON_100M | PHY_CON_FD; break;
  139.       default: ctrl = 0;                         break;
  140.     }
  141.     if (ctrl & PHY_CON_FD) {
  142.       ENET->TCR |= ENET_TCR_FDEN_MASK;  /* Enable Full duplex                 */
  143.     }

  144.     /* Configure 100MBit/10MBit mode. */
  145.     if (ctrl & PHY_CON_100M) {      
  146.       ENET->RCR &= ~ENET_RCR_RMII_10T_MASK; /* 100MBit mode.                  */
  147.     }
  148.   }

  149.   /* MAC address filtering, accept multicast packets. */

  150.   /* Set the Ethernet MAC Address registers */
  151.   ENET->PAUR = ENET_PAUR_TYPE (0x8808) |
  152.                ENET_PAUR_PADDR2(((U32)own_hw_adr[4] << 8) | (U32)own_hw_adr[5]);
  153.   ENET->PALR = ((U32)own_hw_adr[0] << 24) | (U32)own_hw_adr[1] << 16 |
  154.                ((U32)own_hw_adr[2] <<  8) | (U32)own_hw_adr[3];

  155.   ENET->MIBC |= ENET_MIBC_MIB_CLEAR_MASK;

  156.   /* Initialize Tx and Rx DMA Descriptors */
  157.   rx_descr_init ();
  158.   tx_descr_init ();

  159.   /* Reset all interrupts */
  160.   ENET->EIR = 0x7FFF8000;
  161.   
  162.   /* Enable receive interrupt */
  163.   ENET->EIMR = ENET_EIMR_RXF_MASK;

  164.   /* Enable Ethernet, reception and transmission are possible */
  165.   ENET->ECR  |= ENET_ECR_EN1588_MASK | ENET_ECR_ETHEREN_MASK;

  166.   /* Start MAC receive descriptor ring pooling */
  167.   ENET->RDAR = ENET_RDAR_RDAR_MASK;
  168. }

  169. /*--------------------------- int_enable_eth ---------------------------------*/

  170. void int_enable_eth (void) {
  171.   /* Ethernet Interrupt Enable function. */
  172.   NVIC_EnableIRQ (ENET_Receive_IRQn);
  173. }


  174. /*--------------------------- int_disable_eth --------------------------------*/

  175. void int_disable_eth (void) {
  176.   /* Ethernet Interrupt Disable function. */
  177.   NVIC_DisableIRQ (ENET_Receive_IRQn);
  178. }


  179. /*--------------------------- send_frame -------------------------------------*/

  180. void send_frame (OS_FRAME *frame) {
  181.   /* Send frame to ETH ethernet controller */
  182.   U32 *sp,*dp;
  183.   U32 i,j, adr;

  184.   j = TxBufIndex;
  185.   /* Wait until previous packet transmitted. */
  186.   while (Tx_Desc[j].TBD[IDX(0)] & SWE(DESC_TX_R));

  187.   adr  = SWE(Tx_Desc[j].TBD[IDX(4)]) << 16;
  188.   adr |= SWE(Tx_Desc[j].TBD[IDX(6)]);

  189.   dp = (U32 *)(adr & ~3);
  190.   sp = (U32 *)&frame->data[0];

  191.   /* Copy frame data to ETH IO buffer. */
  192.   for (i = (frame->length + 3) >> 2; i; i--) {
  193.     *dp++ = *sp++;
  194.   }
  195.   Tx_Desc[j].TBD[IDX(2)]  = SWE(frame->length);
  196.   Tx_Desc[j].TBD[IDX(0)] |= SWE(DESC_TX_R | DESC_TX_L | DESC_TX_TC);
  197.   Tx_Desc[j].TBD[IDX(0x10)] = 0;
  198.   if (++j == NUM_TX_BUF) j = 0;
  199.   TxBufIndex = j;
  200.   /* Start frame transmission. */
  201.   ENET->TDAR = ENET_TDAR_TDAR_MASK;
  202. }


  203. /*--------------------------- interrupt_ethernet -----------------------------*/

  204. void ENET_Receive_IRQHandler (void) {
  205.   OS_FRAME *frame;
  206.   U32 i, adr, RxLen;
  207.   U32 *sp,*dp;

  208.   i = RxBufIndex;
  209.   do {
  210.     if (Rx_Desc[i].RBD[IDX(0)] & SWE(DESC_RX_TR)) {
  211.       /* Frame is truncated */
  212.       goto rel;
  213.     }
  214.     RxLen = SWE(Rx_Desc[i].RBD[IDX(2)]);
  215.    
  216.     if (Rx_Desc[i].RBD[IDX(0)] & SWE(DESC_RX_L)) {
  217.       /* Last in a frame, length includes CRC bytes */
  218.       RxLen -= 4;
  219.       if (Rx_Desc[i].RBD[IDX(0)] & SWE(DESC_RX_OV)) {
  220.         /* Receive FIFO overrun */
  221.         goto rel;
  222.       }
  223.       if (Rx_Desc[i].RBD[IDX(0)] & SWE(DESC_RX_NO)) {
  224.         /* Received non-octet aligned frame */
  225.         goto rel;
  226.       }
  227.       if (Rx_Desc[i].RBD[IDX(0)] & SWE(DESC_RX_CR)) {
  228.         /* CRC or frame error */
  229.         goto rel;
  230.       }
  231.     }

  232.     if (RxLen > ETH_MTU) {
  233.       /* Packet too big, ignore it and free buffer. */
  234.       goto rel;
  235.     }
  236.     /* Flag 0x80000000 to skip sys_error() call when out of memory. */
  237.     frame = alloc_mem (RxLen | 0x80000000);
  238.     /* if 'alloc_mem()' has failed, ignore this packet. */
  239.     if (frame != NULL) {
  240.       adr  = SWE(Rx_Desc[i].RBD[IDX(4)]) << 16;
  241.       adr |= SWE(Rx_Desc[i].RBD[IDX(6)]);
  242.       sp = (U32 *)(adr & ~3);
  243.       dp = (U32 *)&frame->data[0];
  244.       for (RxLen = (RxLen + 3) >> 2; RxLen; RxLen--) {
  245.         *dp++ = *sp++;
  246.       }
  247.       put_in_queue (frame);
  248.     }
  249.     /* Release this frame from ETH IO buffer. */
  250. rel:Rx_Desc[i].RBD[IDX(0)] |= SWE(DESC_RX_E);
  251.     Rx_Desc[i].RBD[IDX(0x10)] = 0;

  252.     if (++i == NUM_RX_BUF) i = 0;
  253.     RxBufIndex = i;
  254.   }
  255.   while (!(Rx_Desc[i].RBD[IDX(0)] & SWE(DESC_RX_E)));
  256.   RxBufIndex = i;

  257.   /* Clear pending interrupt bits */
  258.   ENET->EIR = ENET_EIR_RXB_MASK | ENET_EIR_RXF_MASK;
  259.   
  260.   /* Start MAC receive descriptor ring pooling */
  261.   ENET->RDAR = ENET_RDAR_RDAR_MASK;
  262. }


  263. /*--------------------------- rx_descr_init ----------------------------------*/

  264. static void rx_descr_init (void) {
  265.   /* Initialize Receive DMA Descriptor array. */
  266.   U32 i,next;

  267.   RxBufIndex = 0;
  268.   for (i = 0, next = 0; i < NUM_RX_BUF; i++) {
  269.     if (++next == NUM_RX_BUF) next = 0;
  270.     Rx_Desc[i].RBD[IDX(0x00)] = SWE(DESC_RX_E);
  271.     Rx_Desc[i].RBD[IDX(0x04)] = SWE((U32)&rx_buf[i] >> 16);
  272.     Rx_Desc[i].RBD[IDX(0x06)] = SWE((U32)&rx_buf[i] & 0xFFFF);
  273.     Rx_Desc[i].RBD[IDX(0x08)] = SWE(DESC_RX_INT);
  274.     Rx_Desc[i].RBD[IDX(0x10)] = 0;
  275.   }
  276.   Rx_Desc[i-1].RBD[IDX(0)] |= SWE(DESC_RX_W);
  277.   ENET->RDSR = (U32)&Rx_Desc[0];
  278. }



  279. /*--------------------------- tx_descr_init ----------------------------------*/

  280. static void tx_descr_init (void) {
  281.   /* Initialize Transmit DMA Descriptor array. */
  282.   U32 i,next;

  283.   TxBufIndex = 0;
  284.   for (i = 0, next = 0; i < NUM_TX_BUF; i++) {
  285.     if (++next == NUM_TX_BUF) next = 0;
  286.     Tx_Desc[i].TBD[IDX(0x00)] = SWE(DESC_TX_L);
  287.     Tx_Desc[i].TBD[IDX(0x04)] = SWE((U32)&tx_buf[i] >> 16);
  288.     Tx_Desc[i].TBD[IDX(0x06)] = SWE((U32)&tx_buf[i] & 0xFFFF);
  289.     Tx_Desc[i].TBD[IDX(0x10)] = 0;
  290.   }
  291.   Tx_Desc[i-1].TBD[IDX(0x00)] |= SWE(DESC_TX_W);
  292.   ENET->TDSR = (U32)&Tx_Desc[0];
  293. }


  294. /*--------------------------- write_PHY --------------------------------------*/

  295. static void write_PHY (U32 PhyReg, U16 Value) {
  296.   /* Write a data 'Value' to PHY register 'PhyReg'. */
  297.   U32 tout;

  298.   /* Clear MII Interrupt */
  299.   ENET->EIR = ENET_EIR_MII_MASK;

  300.   /* Send MDIO write command */
  301.   ENET->MMFR =  ENET_MMFR_ST (1)            |
  302.                 ENET_MMFR_OP (1)            |
  303.                 ENET_MMFR_PA (PHY_DEF_ADDR) |
  304.                 ENET_MMFR_RA (PhyReg)       |
  305.                 ENET_MMFR_TA (2)            |
  306.                 ENET_MMFR_DATA (Value)      ;

  307.   /* Wait until operation completed */
  308.   tout = 0;
  309.   for (tout = 0; tout < MII_WR_TOUT; tout++) {
  310.     if (ENET->EIR & ENET_EIR_MII_MASK) {
  311.       break;
  312.     }
  313.   }
  314. }


  315. /*--------------------------- read_PHY ---------------------------------------*/

  316. static U16 read_PHY (U32 PhyReg) {
  317.   /* Read a PHY register 'PhyReg'. */
  318.   U32 tout;

  319.   /* Clear MII Interrupt */
  320.   ENET->EIR = ENET_EIR_MII_MASK;

  321.   /* Send MDIO read command */
  322.   ENET->MMFR =  ENET_MMFR_ST (1)            |
  323.                 ENET_MMFR_OP (2)            |
  324.                 ENET_MMFR_PA (PHY_DEF_ADDR) |
  325.                 ENET_MMFR_RA (PhyReg)       |
  326.                 ENET_MMFR_TA (2)            ;

  327.   /* Wait until operation completed */
  328.   tout = 0;
  329.   for (tout = 0; tout < MII_RD_TOUT; tout++) {
  330.     if (ENET->EIR & ENET_EIR_MII_MASK) {
  331.       break;
  332.     }
  333.   }
  334.   return (ENET->MMFR & ENET_MMFR_DATA_MASK);
  335. }

  336. /*-----------------------------------------------------------------------------
  337. * End of file
  338. *----------------------------------------------------------------------------*/
复制代码




回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115694
QQ
 楼主| 发表于 2018-3-19 12:34:29 | 显示全部楼层
QQ截图20180319123152.png
回复

使用道具 举报

7

主题

70

回帖

91

积分

初级会员

积分
91
发表于 2018-3-19 14:44:43 | 显示全部楼层
速度好快 到以太网了   是不是马上能开买了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115694
QQ
 楼主| 发表于 2018-3-19 15:19:33 | 显示全部楼层
wuhaichuan 发表于 2018-3-19 14:44
速度好快 到以太网了   是不是马上能开买了

没,还不知道RT1052芯片长什么样子,我现在只是把软件准备好
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-12 20:55 , Processed in 0.262277 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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