[以太网芯片] 请教CH579的网络,不用库自己初始化的问题

[复制链接]
10053|10
 楼主| aozima 发表于 2021-6-15 12:43 | 显示全部楼层 |阅读模式
本帖最后由 aozima 于 2021-6-15 12:55 编辑

我想使用CH579做一个网卡,SPI从机转以太网。

对芯片做了验证,基本上可行。现在遇到了2个问题。

1 SPI从机通过 COUNT=SPI0_DMA_NOW-SPI0_DMA_BEG,
在数据长度大于8字节时,无法获取传输长度。
实际传输大于8字节时,依然只显示7或8,但接收时内存中的数据是对的。
发送时,逻辑分析仪抓到的数据也是对的。

这点是否有解决办法?
没有的话,只能通过数据包头和校验来判定了。

不过芯片好像没有单独的硬件CRC,要用软件来算了。
另外吐槽下,就是SPI从机只能单双工,不过这也还能忍。

2 自己初始化以太网时,交换机灯不亮。
因为不需要在CH579里面跑协议栈,所以打算不要 CH57xNET.LIB
所以根据数据手册和 CH57xNET_LibInit 重写了以太网初始化。
但发现自己写的初始化,PHY好像没有工作,交换机的灯没有亮。
dump出PHY的寄存器发现有区别。
diff.png


自己写的初始化代码如下


  1. int ch57x_eth_init(const uint8_t *macaddr)
  2. {
  3.     uint8_t tmp;
  4.     // 配置安全寄存器进入安全模式,打开以太网络的时钟和电源;
  5.     // 最好能关中断,因为只有16个周期有效果
  6.     R8_SAFE_ACCESS_SIG = 0x57;
  7.     R8_SAFE_ACCESS_SIG = 0xA8;
  8.     R8_SLP_CLK_OFF1 &= ~(1<<5); // 打开时钟
  9.     R8_SLP_POWER_CTRL &= ~(1<<1); // 打开电源
  10.     R8_SAFE_ACCESS_SIG = 0;

  11.     // 补充,建议这里做个反初始化,防止意外。

  12.     // 2 开启相应的中断,可选的,启用阻抗匹配电阻;
  13.     // R8_ETH_EIE = RB_ETH_EIE_RXERIE | RB_ETH_EIE_TXERIE | RB_ETH_EIE_R_EN50 | RB_ETH_EIE_TXIE | RB_ETH_EIE_LINKIE | RB_ETH_EIE_RXIE;
  14.     R8_ETH_EIE = 0; // 参考反汇编
  15.     tmp = R8_ETH_EIE; // 这里回读为0
  16.     PRINT("\r\n@%s L=%d, R8_ETH_EIE read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
  17.     tmp |= 0xdb; // 1101 1011 参考反汇编
  18.     R8_ETH_EIE = tmp; //  参考反汇编
  19.     tmp = R8_ETH_EIE; // 这里回读为 0xDB
  20.     PRINT("@%s L=%d, R8_ETH_EIE read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
  21.     tmp |= 4; // 0b100 50电阻 参考反汇编
  22.     R8_ETH_EIE = tmp; //  参考反汇编
  23.     tmp = R8_ETH_EIE; // 这里回读为 0xDF
  24.     PRINT("@%s L=%d, R8_ETH_EIE read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);

  25.     R8_ETH_EIR = 0xFF; //  参考反汇编

  26.     tmp = R8_ETH_ESTAT;
  27.     tmp |= 0xC0; //清中断和buf中断
  28.     R8_ETH_ESTAT = tmp;//  参考反汇编写回

  29.     tmp = R8_ETH_ECON2;
  30.     // PRINT("@%s L=%d, R8_ETH_ECON2 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
  31.     tmp >>= 4;
  32.     tmp <<= 4; // 清理低4位
  33.     R8_ETH_ECON2 = tmp;

  34.     tmp = R8_ETH_ECON2;
  35.     // PRINT("@%s L=%d, R8_ETH_ECON2 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
  36.     tmp |= 4;
  37.     R8_ETH_ECON2 = tmp;
  38.     tmp = R8_ETH_ECON2;
  39.     // PRINT("@%s L=%d, R8_ETH_ECON2 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);

  40.     tmp = R8_ETH_ECON1;
  41.     PRINT("@%s L=%d, R8_ETH_ECON1 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
  42.     tmp |= 0xC0; // 复位发送和接收模块
  43.     R8_ETH_ECON1 = tmp;
  44.     tmp = R8_ETH_ECON1;
  45.     PRINT("@%s L=%d, R8_ETH_ECON1 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);

  46.     //清高2位后,再写回
  47.     tmp &= 0x3F; // 取消复位状态
  48.     R8_ETH_ECON1 = tmp;
  49.     tmp = R8_ETH_ECON1;
  50.     PRINT("@%s L=%d, R8_ETH_ECON1 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);

  51.     R8_ETH_ERXFCON = 0;

  52.     tmp  = R8_ETH_MACON1;
  53.     tmp |= 1; // MAC 接收使能
  54.     R8_ETH_MACON1 = tmp;

  55.     tmp = R8_ETH_MACON2;
  56.     tmp &= 0x1F; //清高3位后,再写回 RB_ETH_MACON2_PADCFG
  57.     R8_ETH_MACON2 = tmp;

  58.     tmp = R8_ETH_MACON2;
  59.     tmp |= 0x20; // 所有短包填充 0 至 60 字节,再 4字节 CRC;
  60.     R8_ETH_MACON2 = tmp;

  61.     tmp = R8_ETH_MACON2;
  62.     tmp |= 0x10; // 硬件填充 CRC
  63.     R8_ETH_MACON2 = tmp;

  64.     tmp = R8_ETH_MACON2;
  65.     tmp &= 0xfb; // 1111 1011 清除 巨型帧
  66.     R8_ETH_MACON2 = tmp;

  67.     tmp = R8_ETH_MACON2;
  68.     tmp |= 0x01; // 全双工
  69.     R8_ETH_MACON2 = tmp;

  70.     R16_ETH_MAMXFL = 0x24f; // 0x24f 1500 最大包长,需要确定

  71.     // 3 配置接收过滤模式、CRC 功能、MAC 地址;
  72.     // R8_ETH_ECON2 = 0x07; // 默认值 0x06,但读出来为4。

  73.     R32_ETH_HTL = 0x65820294;
  74.     R32_ETH_HTH = 0x220B1858;

  75.     // 设置MAC地址
  76.     // R32_ETH_MAADRL = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16) | (macaddr[3] << 24);
  77.     // R16_ETH_MAADRH = macaddr[4] | (macaddr[5] << 8);
  78.     {
  79.         uint8_t *ptr = (uint8_t *)&R32_ETH_MAADRL;
  80.         uint32_t value;
  81.         uint32_t i;

  82.         PRINT("mac ptr = %p\r\n", ptr);

  83.         for(i=0; i<6; i++)
  84.         {
  85.             tmp = *macaddr;
  86.             PRINT("mac #%d = %02X\r\n", i, tmp);
  87.             *ptr = tmp;
  88.             ptr++;
  89.             macaddr++;
  90.         }

  91.         value = R32_ETH_MAADRL;
  92.         PRINT("R32_ETH_MAADRL: 0x%08X\r\n", value);

  93.         value = R16_ETH_MAADRH;
  94.         PRINT("R16_ETH_MAADRH: 0x%04X\r\n", value);
  95.     }

  96.     // R32_ETH_MACON = 0x10310100; //直接用最终值,后面再做分解。

  97.     R8_ETH_ECON1 |= RB_ETH_ECON1_RXEN; // 收发控制,测试用

  98.     // 4 设置缓存;
  99.     R16_ETH_ERXST = (uint32_t)ch57x_rx_buf;


  100.     // 5 启动接收,开启中断。
  101.     R8_ETH_EIE |= RB_ETH_EIE_INTIE;

  102.     return 0;
  103. }




 楼主| aozima 发表于 2021-6-15 12:54 | 显示全部楼层
@WCHTech2 大佬帮看下,是否还漏了什么?

 楼主| aozima 发表于 2021-6-15 13:04 | 显示全部楼层
关于“R8_ETH_ECON2 0x40009006 PHY 模拟参数设置寄存器”这个寄存器,

数据手册上面说的是 “[3:1] 保留,必须写入 011”
但反汇编里面的操作与数据手册不同,这块也很疑惑。
WCHTech2 发表于 2021-6-16 10:53 | 显示全部楼层
发邮件咨询这位工程师PHY层初始化相关例程,mj@wch.cn
merry_zsp 发表于 2021-6-16 11:52 | 显示全部楼层
我也认为是底层初始化的问题,还有一种可能是跟踪调试的问题,不过你是串口直接打印寄存器,不应该出现这样的问题的
 楼主| aozima 发表于 2021-6-16 12:31 | 显示全部楼层
谢谢版主,已发邮件
 楼主| aozima 发表于 2021-6-17 19:52 | 显示全部楼层
问题解决了,主要是缺了这句
  1. R16_PIN_ANALOG_IE |= RB_PIN_ETH_IE;


wangsongming 发表于 2021-11-29 09:14 | 显示全部楼层
大佬。你是使用eth驱动自己移植网络协议吗
 楼主| aozima 发表于 2021-11-29 10:11 | 显示全部楼层
没在CH579上面跑协议栈,直接SPI从机出去,让主控去处理了。
asmine 发表于 2021-12-6 16:19 | 显示全部楼层
都是大神啊~厉害厉害
gouguoccc 发表于 2021-12-7 08:46 来自手机 | 显示全部楼层
不用库,那就得自己把寄存器的配置弄明白。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:RTOS RT-Thread

55

主题

2040

帖子

23

粉丝
快速回复 在线客服 返回列表 返回顶部