打印
[以太网芯片]

请教CH579的网络,不用库自己初始化的问题

[复制链接]
9641|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的寄存器发现有区别。



自己写的初始化代码如下


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

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

    // 2 开启相应的中断,可选的,启用阻抗匹配电阻;
    // 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;
    R8_ETH_EIE = 0; // 参考反汇编
    tmp = R8_ETH_EIE; // 这里回读为0
    PRINT("\r\n@%s L=%d, R8_ETH_EIE read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
    tmp |= 0xdb; // 1101 1011 参考反汇编
    R8_ETH_EIE = tmp; //  参考反汇编
    tmp = R8_ETH_EIE; // 这里回读为 0xDB
    PRINT("@%s L=%d, R8_ETH_EIE read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
    tmp |= 4; // 0b100 50电阻 参考反汇编
    R8_ETH_EIE = tmp; //  参考反汇编
    tmp = R8_ETH_EIE; // 这里回读为 0xDF
    PRINT("@%s L=%d, R8_ETH_EIE read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);

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

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

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

    tmp = R8_ETH_ECON2;
    // PRINT("@%s L=%d, R8_ETH_ECON2 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);
    tmp |= 4;
    R8_ETH_ECON2 = tmp;
    tmp = R8_ETH_ECON2;
    // PRINT("@%s L=%d, R8_ETH_ECON2 read out=%02X\r\n", __FUNCTION__, __LINE__, tmp);

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

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

    R8_ETH_ERXFCON = 0;

    tmp  = R8_ETH_MACON1;
    tmp |= 1; // MAC 接收使能
    R8_ETH_MACON1 = tmp;

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

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

    tmp = R8_ETH_MACON2;
    tmp |= 0x10; // 硬件填充 CRC
    R8_ETH_MACON2 = tmp;

    tmp = R8_ETH_MACON2;
    tmp &= 0xfb; // 1111 1011 清除 巨型帧
    R8_ETH_MACON2 = tmp;

    tmp = R8_ETH_MACON2;
    tmp |= 0x01; // 全双工
    R8_ETH_MACON2 = tmp;

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

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

    R32_ETH_HTL = 0x65820294;
    R32_ETH_HTH = 0x220B1858;

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

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

        for(i=0; i<6; i++)
        {
            tmp = *macaddr;
            PRINT("mac #%d = %02X\r\n", i, tmp);
            *ptr = tmp;
            ptr++;
            macaddr++;
        }

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

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

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

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

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


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

    return 0;
}




使用特权

评论回复
沙发
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

使用特权

评论回复
5
merry_zsp| | 2021-6-16 11:52 | 只看该作者
我也认为是底层初始化的问题,还有一种可能是跟踪调试的问题,不过你是串口直接打印寄存器,不应该出现这样的问题的

使用特权

评论回复
6
aozima|  楼主 | 2021-6-16 12:31 | 只看该作者
谢谢版主,已发邮件

使用特权

评论回复
7
aozima|  楼主 | 2021-6-17 19:52 | 只看该作者
问题解决了,主要是缺了这句
R16_PIN_ANALOG_IE |= RB_PIN_ETH_IE;


使用特权

评论回复
8
wangsongming| | 2021-11-29 09:14 | 只看该作者
大佬。你是使用eth驱动自己移植网络协议吗

使用特权

评论回复
9
aozima|  楼主 | 2021-11-29 10:11 | 只看该作者
没在CH579上面跑协议栈,直接SPI从机出去,让主控去处理了。

使用特权

评论回复
10
asmine| | 2021-12-6 16:19 | 只看该作者
都是大神啊~厉害厉害

使用特权

评论回复
11
gouguoccc| | 2021-12-7 08:46 | 只看该作者
不用库,那就得自己把寄存器的配置弄明白。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:RTOS RT-Thread

55

主题

2016

帖子

23

粉丝