跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
折叠
品牌标识

YunTu Forum

YTMicro.com
  1. 主页
  2. Discussion & Question
  3. YTM32B1H系列
  4. can0 fd 模式无法发送数据

can0 fd 模式无法发送数据

已定时 已固定 已锁定 已移动 未解决 YTM32B1H系列
1 帖子 1 发布者 16 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • iyshengI 离线
    iyshengI 离线
    iysheng
    编写于 最后由 编辑
    #1

    我在原来 can 模式基础上添加了 fd 发送支持,目前发现无法正常发送数据。具体关键代码如下:

    
    #define YTM_CANFD_MODE_ENABLE
    
    int board_can_init(uint32_t baudrate)
    {
        // 使能 CAN0 时钟
        REG32(IPC_FLEXCAN0) |= 0X01;
        // 修改为 ALT5 模式 PTE4 can0 rx/PTE5 can0 tx
        REG32(PCTRLE_4) &= ~(0XF << 8);
        REG32(PCTRLE_4) |= 0X5 << 8;
        REG32(PCTRLE_5) &= ~(0XF << 8);
        REG32(PCTRLE_5) |= 0X5 << 8;
        REG32(CAN0_MCR) &= ~CAN0_MCR_MDIS_MASK;
        REG32(CAN0_MCR) |= (CAN0_MCR_FRZ_MASK | CAN0_MCR_HALT_MASK);
    
        while ((REG32(CAN0_MCR) & CAN0_MCR_FRZACK_MASK) == 0X0);
    
    #ifdef YTM_CANFD_MODE_ENABLE
        // 修改 maxmailbox counts
        REG32(CAN0_MCR) &= ~CAN0_MCR_MAXMB_MASK;
        REG32(CAN0_MCR) |= 0X6;
    
        REG32(CAN0_MCR) |= CAN0_MCR_FDEN_MASK;
        // TODO 修改 CAN0_FDCTRL
    #endif
    
        // 使用晶振 24MHz 时钟源
        REG32(CAN0_CTRL1) &= ~CAN0_CTRL1_CLKSRC_MASK;
        REG32(CAN0_CTRL1) &= 0X0000FFF8;
    #ifndef YTM_CANFD_MODE_ENABLE
        //              PRESDIV       RJW     PSEG1     PSEG2   PROPSEG
        REG32(CAN0_CTRL1) |= (1 << 24 | 3 << 22 | 7 << 19 | 7 << 16 | 6);
    #else
        // EPRESDIV ERJW EPROPSEG EPSEG1 EPSEG2
        REG32(CAN0_CBT) |= 1 << 31 | (2 << 21 | 1 << 16 | 4 << 10 | 7 << 5 | 1);
        // FRESDIV FRJW FPROPSEG FPSEG1 FPSEG2
        // 按需修改 CAN0_FDCBT
        REG32(CAN0_FDCBT) = (0 << 20 | 1 << 16 | 6 << 10 | 2 << 5 | 1);
    
        REG32(CAN0_ERFCR) |= CAN0_ERFCR_ERFEN_MASK ;
    
        // 复位 FIFO 引擎
        REG32(CAN_ERFSR) |= (1<<27);
    
        // TODO 配置 ERFCR 寄存器 NFE 和 NEXIF
    
        // TODO 配置滤波器表 0X3000 偏移处
    #endif
        // 清零 RAM 区
        for (int i = 0; i < 0X200; i++)
        {
            REG32(CAN0_MB0_HEAD0 + i * 4) = 0X0;
        }
    
        REG32(CAN0_RXMGMASK) = 0XFFFFFFFF;
        REG32(CAN0_RX14MASK) = 0XFFFFFFFF;
        REG32(CAN0_RX15MASK) = 0XFFFFFFFF;
        REG32(CAN0_RXFGMASK) = 0XFFFFFFFF;
        // 配置 RAM
        REG32(CAN0_CTRL2) |= CAN0_CTRL2_WRMFRZ_MASK;
    
    #ifdef YTM_CANFD_MODE_ENABLE
        // TODO 修改 CAN0_FDCTRL 为 64 bytes
        REG32(CAN0_FDCTRL) |= (CAN0_FDCTRL_MBDSR0_MASK | \
                               CAN0_FDCTRL_MBDSR1_MASK | \
                               CAN0_FDCTRL_MBDSR2_MASK | \
                               CAN0_FDCTRL_MBDSR3_MASK);
        REG32(CAN0_FDCTRL) |= (CAN0_FDCTRL_TDCEN_MASK);
    #else
        REG32(CAN0_FDCTRL) &= ~(CAN0_FDCTRL_MBDSR0_MASK | \
                                CAN0_FDCTRL_MBDSR1_MASK | \
                                CAN0_FDCTRL_MBDSR2_MASK | \
                                CAN0_FDCTRL_MBDSR3_MASK);
        // 设置 8 字节/ message buffer
        REG32(CAN0_FDCTRL) = 0X00;
    #endif
        // 关闭 Self Reception
        REG32(CAN0_MCR) |= 1 << 17;
    
        /* REG32(CAN0_CTRL1) |=  1 << 3; */
        REG32(CAN0_MCR) &= ~(CAN0_MCR_HALT_MASK | CAN0_MCR_FRZ_MASK);
    
        return 0;
    }
    
    int board_can_send(const struct bl_can_msg *msg)
    {
        int ret = 0;
    
        if (!msg)
        {
            return -RT_EINVAL;
        }
    
        //1. 检查相关的中断 bit 是否置位并清零
        //2. 如果 MB 是激活态,写 ABORT(1001)-> CODE /C/S,等待 IFLAG 置位,然后读回 CODE filed 并清除对应的中断寄存器 flag
        //3. 写 ID word
        //4. 写要发送的数据
        //5. 设置 ide, 设置 rtr, 设置 dlc, 激活 MB
        REG32(CAN0_IFLAG1) |= (1 << 0);
        REG32(CAN0_MB0_HEAD1) = msg->id << 18;
        REG32(CAN0_MB0_DATA(0)) = msg->data[0] << 24 | msg->data[1] << 16 | msg->data[2]
                                  << 8 | msg->data[3];
        REG32(CAN0_MB0_DATA(1)) = msg->data[4] << 24 | msg->data[5] << 16 | msg->data[6]
                                  << 8 | msg->data[7];
        REG32(CAN0_MB0_HEAD0) = msg->dlc << 16 | msg->rtr << 20 | msg->ide << 21;
    #ifdef YTM_CANFD_MODE_ENABLE
        // canfd 帧
        REG32(CAN0_MB0_HEAD0) |= 0xC0000000;
    #endif
        REG32(CAN0_MB0_HEAD0) |= 0xC << 24;
        return ret;
    }
    

    相比原来的 can ,主要增加了修改 CAN0_FDCBT 和 CAN0_CBT(之前用的 CAN0_CTRL1),以及寄存器CAN0_FDCTRL和CAN0_MCR开启canfd。
    canfd报文发送时,追加了 EG32(CAN0_MB0_HEAD0) |= 0xC0000000;。
    请问是不是还有哪些遗漏项目没有修改?

    1 条回复 最后回复
    0

  • 云途开发生态介绍

    快速上手云途开发生态

  • 云途论坛规则/Yuntu Forum Rules

    发帖前请查看

  • YT CONFIG TOOL调查问卷

    帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...

  • can
    26
    demo
    23
    lin stack
    13
    uds
    13
    md14
    6
    yt-link
    6
    fbl
    5
    adc模块
    4
    Online Users
    • 登录

    • 登录或注册以进行搜索。
    • 第一个帖子
      最后一个帖子
    0
    • 版块
    • 最新
    • 标签
    • 热门