您尚未登录。

楼主 # 2022-05-10 11:23:52

ubuntu
会员
注册时间: 2020-03-30
已发帖子: 221
积分: 204

搞定 T113 / T113-S3 裸奔驱动CAN (转)

转载地址:

T113-S3  CAN模块使用的全部信息
https://bbs.aw-ol.com/topic/1383

离线

楼主 #1 2022-05-10 11:25:05

ubuntu
会员
注册时间: 2020-03-30
已发帖子: 221
积分: 204

Re: 搞定 T113 / T113-S3 裸奔驱动CAN (转)

#define  CAN0  0x02504000
#define  CAN1  0x02504400


#define CAN_OFFSET(can_base,offset)          (*((volatile uint32_t *)(can_base + (offset))))

#define CAN_MSEL(can_base)       CAN_OFFSET(can_base,0x0000) //CAN mode select register
#define CAN_CMD(can_base)        CAN_OFFSET(can_base,0x0004)  //CAN command register
#define CAN_STA(can_base)        CAN_OFFSET(can_base,0x0008)  //CAN status register
#define CAN_INT(can_base)        CAN_OFFSET(can_base,0x000C)  //CAN interrupt register
#define CAN_INTEN(can_base)      CAN_OFFSET(can_base,0x0010) //CAN interrupt enable register
#define CAN_BUSTIME(can_base)    CAN_OFFSET(can_base,0x0014) //CAN bus timing register
#define CAN_TEWL(can_base)       CAN_OFFSET(can_base,0x0018)  //CAN TX error warning limit register
#define CAN_ERRC(can_base)       CAN_OFFSET(can_base,0x001c)  //CAN error counter register
#define CAN_RMCNT(can_base)      CAN_OFFSET(can_base,0x0020)  //CAN receive message counter register
#define CAN_RBUF_SADDR(can_base) CAN_OFFSET(can_base,0x0024) //CAN receive buffer start address register
#define CAN_TRBUF0(can_base)     CAN_OFFSET(can_base,0x0040) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF1(can_base)     CAN_OFFSET(can_base,0x0044) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF2(can_base)     CAN_OFFSET(can_base,0x0048) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF3(can_base)     CAN_OFFSET(can_base,0x004c) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF4(can_base)     CAN_OFFSET(can_base,0x0050) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF5(can_base)     CAN_OFFSET(can_base,0x0054) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF6(can_base)     CAN_OFFSET(can_base,0x0058) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF7(can_base)     CAN_OFFSET(can_base,0x005c) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF8(can_base)     CAN_OFFSET(can_base,0x0060) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF9(can_base)     CAN_OFFSET(can_base,0x0064) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF10(can_base)    CAN_OFFSET(can_base,0x0068) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF11(can_base)    CAN_OFFSET(can_base,0x006c) //CAN TX/RX message buffer 0 register
#define CAN_TRBUF12(can_base)    CAN_OFFSET(can_base,0x0070) //CAN TX/RX message buffer 0 register
#define CAN_ACPC(can_base)       CAN_OFFSET(can_base,0x0028) //CAN acceptance code 0 register(reset mode)
#define CAN_ACPM(can_base)       CAN_OFFSET(can_base,0x002C) //CAN acceptance mask 0 register(reset mode)
#define CAN_RBUF_RBACK(can_base) CAN_OFFSET(can_base,0x0180) //~0x1b0 //CAN transmit buffer for read back register
#define CAN_VERSION(can_base)    CAN_OFFSET(can_base,0x0300) //CAN Version Register




typedef  struct _t113_can_control_t_
{
  volatile uint32_t  * can_clk_gate;
  uint32_t  can_base;
  uint32_t  int_id;
  
}t113_can_control_t;


t113_can_control_t t113_can[2] = 
{
  {
    (volatile uint32_t  *)0x0200192C,
    0x02504000,
    53
  },
  {
    (volatile uint32_t  *)0x0200192C,
    0x02504400,
    54
  }
    
};

uint32_t rxd_buf[13];

void t113_can_irq_handle(void*  p)
{
   uint32_t    can_base = (uint32_t) p;
   uint32_t    int_sta =   CAN_INT(can_base);
   if(int_sta &  1)
   {
       /* 接收中断 */
       can_read_data(can_base,rxd_buf);
       /*  后续处理  */
   }
   if(int_sta & 2 )
   {
      /*发送中断*/    
   }
   if(int_sta & 0xFC )
   {
      /* 错 误 中断  */
   }
   
   CAN_INT(can_base) = int_sta;
   
}
       

void ini_can(int can_id)
{
    if(can_id > 1) return;
    
    GPIOB->CFG0  &= ~(0xff00 <<  (can_id * 8));
    GPIOB->CFG0  |=  (0x8800 <<  (can_id * 8)); 
    GPIOB->DRV0  |=  (0x3300 <<  (can_id * 8));
    
    t113_can_control_t * can_info = &t113_can[can_id];
    
    uint32_t   can_base = can_info->can_base;
    
    int can_int_id = can_info->int_id;

    *can_info->can_clk_gate  |= (1 << (16 + can_id)) | (1 << can_id);/* CCU_CAN_BGR */
    
    
   
    CAN_MSEL(can_base) |= 1; /* Reset mode selected*/
   /* 500KHz CAN速率 */
    CAN_BUSTIME(can_base) = (9          /* apb_clk = 100Mz , 100/10 = 10MHz*/ 
                           | (1 << 14)   /* Synchronization Jump Width :2 Tq clock cycles */
                           | (13 << 16)  /*Phase Segment 1 : 14 Tq clock cycles  */
                           | ( 3 << 20)  /*Phase Segment 2 :  4 Tq clock cycles  */
                           | ( 0 << 23));  /*  Bus line is sampled three times at the sample point */
  
   CAN_ACPC(can_base)  = 0xffffffff; /*实际使用时根据需要设置滤波*/
   CAN_ACPM(can_base)  = 0xffffffff; /*实际使用时根据需要设置滤波*/
   
   
   CAN_MSEL(can_base) &= (~1); 
   
   // CAN_MSEL(can_base) |= (1 << 2); /* Loopback Mode */
  
   CAN_MSEL(can_base) |= (1 << 3);/* Single Filter  */
   
   
   bsp_int_vect_set(can_int_id,  /* Assign ISR handler. */
                   1u,            /* 中断的优先级         */
                   1u,            /* 中断的目标CPU        */
                   (void *)can_base,        /* 参数      */
                   t113_can_irq_handle);
  
   
    irq_enable(can_int_id);//
    /* 使能中断  */
    CAN_INTEN(can_base) = 0x0FF;
    
}
void can_send_data(uint32_t    can_base,uint8_t * buf,int  len)
{
  
    CAN_CMD(can_base) |= (1 << 2);
  
    CAN_MSEL(can_base) &= (~1); 
     
    int retry = 1000;
    do{
      
       if(--retry == 0) break;
    }while(!(CAN_STA(can_base) & (1 << 2)));
    
    if(retry == 0) return;//
    
    uint32_t * des =  &CAN_TRBUF0(can_base);
    
    for(int i = 0; i < len; i++)
     des[i] = buf[i];
     
    //CAN_CMD(can_base) = (1 << 4);
     CAN_CMD(can_base) |= (1 << 0);
}
void can_read_data(uint32_t    can_base,uint8_t * buf)
{
    uint32_t * src =  &CAN_TRBUF0(can_base);
    for(int i = 0; i < 13; i++)
       buf[i] = (char)src[i];
   
     CAN_CMD(can_base) |= (1 << 2);
}


uint8_t can_teat_data[13] = 
   {
      8,
      0,
      0x80,
      0x55, /*   SFF - TX data byte 1 / EFF- ID[12:5]  */
      0x55, /*  SFF-TX data byte2[7:3] / EFF-ID[4:0]
                SFF-TX data byte2[2:0] */  
      0x55, /* SFF-TX data byte 3 / EFF-TX data byte 1 */
      0x55, /* SDATA4_EDATA2  SFF-TX data byte 4 / EFF-TX data byte 2  */
      0x55, /* SDATA5_EDATA3 SFF-TX data byte 5 / EFF-TX data byte 3   */
      0x55,/* SDATA5_EDATA4  SFF-TX data byte 6 / EFF-TX data byte 4   */
      0x55,/* SDATA5_EDATA5  SFF-TX data byte 7 / EFF-TX data byte 5   */
      0x55,/* SDATA5_EDATA6  SFF-TX data byte 8 / EFF-TX data byte 6   */
      0x55, /* SDATA5_EDATA7   */
      0x55 /*  SDATA5_EDATA8   */
   };


/* can_id: is 0 or 1 */
void t113_can_test(void)
{
    ini_can(0);
    ini_can(1);
    
   while(1)
   {
    
    can_send_data(CAN0,can_data);
     ms_delay(500);
    can_send_data(CAN1,can_data);
     ms_delay(500);

   }
   
}

离线

页脚

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

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