您尚未登录。

楼主 # 2021-06-15 13:30:31

aozima
会员
所在地: 深圳
注册时间: 2019-05-25
已发帖子: 462
积分: 329.5
个人网站

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

我想使用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

自己写的初始化代码如下

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;
}

离线

楼主 #1 2021-06-15 13:31:19

aozima
会员
所在地: 深圳
注册时间: 2019-05-25
已发帖子: 462
积分: 329.5
个人网站

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

关于“R8_ETH_ECON2 0x40009006 PHY 模拟参数设置寄存器”这个寄存器,

数据手册上面说的是 “[3:1] 保留,必须写入 011”
但反汇编里面的操作与数据手册不同,这块也很疑惑。

用的是CH579F,没有SWD引脚。只能看反汇编,这块有些难调。

离线

楼主 #2 2021-06-17 19:52:29

aozima
会员
所在地: 深圳
注册时间: 2019-05-25
已发帖子: 462
积分: 329.5
个人网站

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

问题解决了,主要是缺了这句

R16_PIN_ANALOG_IE |= RB_PIN_ETH_IE;

离线

楼主 #6 2022-01-09 17:42:11

aozima
会员
所在地: 深圳
注册时间: 2019-05-25
已发帖子: 462
积分: 329.5
个人网站

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

秋秋? 应该是你加错号码了,你点上面的 电子信箱 发站内信给我吧。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn