导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. L13819506056
    3. 帖子
    L
    • 资料
    • 关注 1
    • 粉丝 2
    • 我的积分 1258
    • 主题 7
    • 帖子 21
    • 最佳 6
    • 群组 0

    L13819506056 发布的帖子

    • T113-i 通用工控主板

      T113-i 通用工控主板

      20231118172755.jpg

      KDTU.png

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: 终于拿到了量产版MCore-H616

      全频运行发热不,需不需要散热片?

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: T113-S3 G2D 裸机测试
      __s32 drv_g2d_init(void)
      {
      	memset(&g2d_ext_hd, 0, sizeof(__g2d_drv_t));
      	init_wait_event(&g2d_ext_hd.wait_event);
      	g2d_top_set_base((unsigned long) para.io);
      
      #if defined(CONFIG_SUNXI_G2D_ROTATE)
      	g2d_rot_set_base((unsigned long) para.io);
      #endif
      	return 0;
      }
      
      
      int g2d_probe(void )
      {
      
      	__g2d_info_t *info = NULL;
      
      	info = ¶
      	info->dev =  0;
      	info->io =  (__u32 *)0x05410000;
       	info->irq = 121;
        info->clk = (__u32 *)0x02001630;
        info->clk_parent = 0;
        info->bus_clk = (__u32 *)0x0200163c;
      	info->mbus_clk = (__u32 *)0x02001804;
      
        bsp_int_vect_set(info->irq,  /* Assign ISR handler. */
                         8u,            /* 中断的优先级         */
                         1u,            /* 中断的目标CPU        */
                         0u,            /* 参数                 */
                         g2d_handle_irq);
      
        irq_enable(info->irq);//
      	drv_g2d_init();
      	mutex_init(&info->mutex);
      	mutex_init(&global_lock);
      	return 0;
      
      }
      
      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: T113-S3 的SMHC1连接SD-NAND问题:

      @jordonwu 工控板,两个网口,其余两座是CAN +422+IO 口。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: T113-S3 的SMHC1连接SD-NAND问题:

      原来是这样。总是有意外的惊喜。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • T113-S3 的SMHC1连接SD-NAND问题:

      t113_cb.jpg
      T113-s3的SMHC1接一片SD NAND ,但在读取数据时,传输描述符配置都正确的情况下。iDMA始终报描述符不可用中断。

      status_t sd_mmc_set_dma_table_config(v3x_sd_mmc_t *base,
      sd_mmc_dma_config_t *dma_config,
      sd_mmc_data_t *data_config,
      uint32_t flags)
      {
      base->DMAC = 1;//IMAC 复位
      const uint32_t *start_address;
      uint32_t entries;
      uint32_t i, dma_buffer_len = 0U;
      sd_mmc_dma_descriptor_t *dma_entry_address;

      uint32_t data_bytes = data_config->block_size * data_config->block_count;
      const uint32_t *data = (data_config->rx_data == NULL) ? data_config->tx_data : data_config->rx_data;
      
      /* check DMA data buffer address align or not */
      if ( ((uint32_t)data & 0x03) != 0U )
      {
          return STA_DMA_DATA_ADDR_NOT_ALIGN;
      }
      
      /*
      * Add non aligned access support ,user need make sure your buffer size is big
      * enough to hold the data,in other words,user need make sure the buffer size
      * is 4 byte aligned
      */
      data_bytes = (data_bytes + 3) & (~3);
      
      start_address = data;
      
      base->GCTL |= (SDXC_FIFO_RESET | SDXC_DMA_RESET | SDXC_DMA_ENABLE_BIT);/* reset fifo & dma*/
      
      /* Check if ADMA descriptor's number is enough. */
      if ((data_bytes % MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) == 0U)
         entries = data_bytes / MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY;
      else
         entries = ((data_bytes / MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U);
      
      if (entries > ((dma_config->dma_table_words * sizeof(uint32_t)) / sizeof(sd_mmc_dma_descriptor_t)))
      {
         /*如果超过预置(1个)数量,应该支持动态分配描述符表 */
      
         if( STA_SUCCESS != sd_mmc_malloc_dma_descriptor( dma_config,entries))
            return STA_MEM_ERROR;
      }
      
      dma_entry_address = (sd_mmc_dma_descriptor_t *)(dma_config->dma_table);
      
      for (i = 0U; i < entries; i++)
      {
         if (data_bytes > MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY)
         {
           dma_buffer_len = MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY;
           data_bytes -= dma_buffer_len;
         }
         else
         {
            dma_buffer_len = data_bytes;
         }
      
         /* */
         dma_entry_address[i].buf_addr_ptr = (uint32_t)start_address;
         dma_entry_address[i].buf_size = dma_buffer_len  ;
         dma_entry_address[i].config   =  SD_MMC_DESCRIPTOR_TC_INT_DIS
                                         | SD_MMC_DESCRIPTOR_CHAIM_MOD
                                         | SD_MMC_DESCRIPTOR_OWN_FLAG;
      
         dma_entry_address[i].buf_addr_next =  (uint32_t)&dma_entry_address[i + 1];
      
         start_address += (dma_buffer_len / sizeof(uint32_t));/*32bit 偏移*/
      }
      /* set the end bit */
      dma_entry_address[0].config             =   SD_MMC_DESCRIPTOR_FIRST_FLAG
                                                | SD_MMC_DESCRIPTOR_TC_INT_DIS
                                                | SD_MMC_DESCRIPTOR_CHAIM_MOD
                                                | SD_MMC_DESCRIPTOR_OWN_FLAG;
      uint32_t config = dma_entry_address[i - 1U].config & (~(SD_MMC_DESCRIPTOR_TC_INT_DIS
                                                               ));
      
      dma_entry_address[i - 1U].config = config | SD_MMC_DESCRIPTOR_LAST_FLAG;// \
                                                           // | (1 << 5); /* end of ring */
      dma_entry_address[i - 1U].buf_addr_next = 0;
      
       base->DMAC = (1 << 1) | (1 << 7);
      /* enable dma interrupt */
      base->IDST = 0x3F; /*清除DMA中断状态 */
      /*config the burst length */
      base->FWLR = (burst_len_16 << 28) | (0x0f << 16) | 240;//0x10;
      /*允许dma中断 */
      if(data_config->rx_data)
      {
        /*DMA 接收利用 DMA传输完毕产生中断*/
        base->IDIE  = (   SDXC_IDMAC_RECEIVE_INTERRUPT
                      | SDXC_IDMAC_FATAL_BUS_ERROR
                      | SDXC_IDMAC_DESTINATION_INVALID
                      | SDXC_IDMAC_CARD_ERROR_SUM);
        base->IMKR &=  ~(1 << 3);
      }
      else if(data_config->tx_data)
      {
        /*DMA 传输利用 MCI传输完毕产生中断*/
        base->IDIE  = (  SDXC_IDMAC_FATAL_BUS_ERROR
                       | SDXC_IDMAC_TRANSMIT_INTERRUPT
                       | SDXC_IDMAC_DESTINATION_INVALID
                       | SDXC_IDMAC_CARD_ERROR_SUM);
        base->IMKR |= (1 << 3);
      }
      else
         base->IDIE = 0;
      base->DLBA = (uint32_t)(dma_config->dma_table);
      /* enable DMA */
      sd_mmc_enable_dma(base);
      

      /*动态分配的内存 ,需要刷新cache */
      if (entries > ((dma_config->dma_table_words * sizeof(uint32_t)) / sizeof(sd_mmc_dma_descriptor_t)))
      {
      L1C_CleanDataCacheRange(dma_config->dma_table,dma_config->dma_table_words * entries);
      }

      return STA_SUCCESS;
      

      }

      上面说使用的描述符的内存空间是位于非cache段的内存中。

      c3504034-f420-4caf-9849-efc6c9ff206e-image.png
      ec8347e7-d9e9-4538-9264-be130d2648cc-image.png
      从内存数据看配置都是正确的,数据已经从sd nsnd 传输到fifo中了,而 IDMA总是报描述符不可用,致使数据不能从fifo读取到内存中。 大家帮我看看问题可能在哪里。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: T113裸跑不能产生中断请教:

      @musich 这些坑都已经解决掉了。

      发布在 MR Series
      L
      L13819506056
    • T113-S3 G2D 裸机测试

      终于将G2D裸机环境使用搞定了。 简单测试了一下bitblt 和矩形填充。

      extern const unsigned char image_mn_map[800*480*4];/*图片文件*/
      void  g2d_test(void)
      {
         g2d_probe();
         g2d_open();
      	 g2d_blt_h blit_para;
         while(1)
         {
            /* bitblt测试  */
            memset(&blit_para,0,sizeof(g2d_blt_h));
            g2d_image_enh *src = &blit_para.src_image_h;
            g2d_image_enh *des = &blit_para.dst_image_h;
            blit_para.flag_h   =  G2D_ROT_180;//G2D_ROT_V;// G2D_ROT_0;
      
            src->laddr[0] = (uint32_t)image_mn_map;
            src->align[0] = 4;
            src->clip_rect.w = 800;
            src->clip_rect.h = 480;
            src->width       = 800;
            src->height      = 480;
            src->format      = G2D_FORMAT_ARGB8888;
            src->mode        = G2D_PIXEL_ALPHA;
            src->bpremul     = 0;
      
            des->laddr[0]    = r528_de_config.LayerAddr[0] ;
            des->align[0]    = 4;
            des->clip_rect.w = 800;
            des->clip_rect.h = 480;
            des->width       = 800;
            des->height      = 480;
            des->format      = G2D_FORMAT_ARGB8888;
            des->mode        = G2D_PIXEL_ALPHA;
            des->bpremul     = 0;
            long ret         = g2d_ioctl( G2D_CMD_BITBLT_H, (unsigned long )&blit_para);
      
            /* 矩形填充测试  */
            g2d_fillrect_h fill_para;
            memset(&fill_para,0,sizeof(g2d_fillrect_h));
            src = &fill_para.dst_image_h;
            src->laddr[0] = (uint32_t)r528_de_config.LayerAddr[0] ;;
            src->align[0] = 4;
            src->clip_rect.w = 800;
            src->clip_rect.h = 480;
            src->width       = 800;
            src->height      = 480;
            src->format      = G2D_FORMAT_ARGB8888;
            src->mode = G2D_PIXEL_ALPHA;
            src->bpremul = 0;
            src->gamut = G2D_BT709;
            src->color = 0xFFFF0000;
            src->alpha = 0xff;
            ret = g2d_ioctl( G2D_CMD_FILLRECT_H, (unsigned long )&fill_para);
         }
      }
      
      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: 用T113画了一个工控板

      @aozima 两个网口用途不一样:一个用于实时控制,一个用于网络连接。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: 用T113画了一个工控板

      @yelong98 实际需要用到两个网口。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: T113-S3 CAN模块使用的全部信息

      没有,做的测试代码测试出来的。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • T113-S3 CAN模块使用的全部信息

      经过实际测试,T133-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);
      
         }
         
      }
      
      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: 用T113画了一个工控板

      33854902-71f7-4c9a-8653-80b1ab9f2634-image.png

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 用T113画了一个工控板

      1259c966-af2a-4e37-93cd-eb2171a650c1-image.png

      c7609b89-e992-483d-a483-77b3f6c0fca0-image.png

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: T113裸跑不能产生中断请教:

      @tripod9 我也是裸奔,没遇到这个问题。请教你裸奔,主频最高能跑到多少MHz?我这里最高就只能跑到800MHz,高于800M值,切换主频源时CPU就跑飞了。

      发布在 MR Series
      L
      L13819506056
    • 回复: T113的can总线怎么用啊?

      管脚 和中断向量都需要确认。我也期待中。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 请教T113运行主频的设置问题

      使用芒果派小麻雀板的T113做测试,CPU运行主频高于800MHz,切换时就跑飞。测试代码如下,请求大佬们支招:

      #define CPU_RUN_FREQ           1200000000 
      #define SYS_XTOSC_CLK            24000000 
      static void set_pll_cpux_axi(void)
      {
      		uint32_t val;
      	
        int n =  (CPU_RUN_FREQ / SYS_XTOSC_CLK -1 ) & 0xFF;
      
        
      	/* Switch to PLL_PERI(1X) clock while changing cpu pll (600MHz) */
      	CCU_CPU_AXI_CFG  =  (4<<24)  ;
        sdelay(10000);
      	/*  cpu pll rate = 24000000 * n      */
        val = PLL_CPU_CTRL_REG & (~((0xff << 8) | (1 << 27)));
       	val |= (n << 8);
      	
      	PLL_CPU_CTRL_REG  = val;
      	PLL_CPU_CTRL_REG &= ~(1 << 29);
        sdelay(5);
        PLL_CPU_CTRL_REG |= (1 << 29);
        sdelay(1000);
        while( (PLL_CPU_CTRL_REG &(1 << 28)) == 0 );  /* wait for pll lock */
        PLL_CPU_CTRL_REG |= (1 << 27);                 /* open pll out gate */
        sdelay(10000);
      
      /* Switch clock source */  
      	CCU_CPU_AXI_CFG  =    (3 << 24);
        sdelay(10000);
                                 
      }
      

      这一句CCU_CPU_AXI_CFG = (3 << 24)一执行,CPU就跑飞了.
      请求支援。期待中。

      发布在 其它全志芯片讨论区
      L
      L13819506056
    • 回复: T113裸跑不能产生中断请教:

      @mangogeek 在staru.s中添加下面一段后,中断就正常了。
      /* Set vector base address register */
      ldr r0, =__vector_table
      mcr p15, 0, r0, c12, c0, 0
      mrc p15, 0, r0, c1, c0, 0
      bic r0, #(1 << 13)
      mcr p15, 0, r0, c1, c0, 0

           /* Enable SMP mode for dcache, by setting bit 6 of auxiliary ctl reg */
           mrc p15, 0, r0, c1, c0, 1
           orr r0, r0, #(1 << 6)
           mcr p15, 0, r0, c1, c0, 1
        
         /* enable branch prediction */
         mrc p15, 0, r0, c1, c0, 0
         orr     r0, r0, #(1<<11)
         mcr p15, 0, r0, c1, c0, 0
      
           /* Enable neon/vfp unit */
           mrc p15, 0, r0, c1, c0, 2
           orr r0, r0, #(0xf << 20)
           mcr p15, 0, r0, c1, c0, 2
           isb
           mov r0, #0x40000000
           vmsr fpexc, r0
      
      发布在 MR Series
      L
      L13819506056
    • 回复: T113裸跑不能产生中断请教:

      @mangogeek 串口是可以打印输出的(非中断方式)。

      发布在 MR Series
      L
      L13819506056
    • 回复: T113裸跑不能产生中断请教:

      将完整的IAR裸机测试项目上传。T113_test.rar

      发布在 MR Series
      L
      L13819506056
    • T113裸跑不能产生中断请教:

      T113就配置TIMER0做tick时钟:

      #define TIMER_IRQ_CON_BASE    (0x02050000)
      #define TIMER0_BASE           (0x02050010)
      #define TIMER1_BASE           (0x02050020)
      #define timer0        ((timer_t *)(TIMER0_BASE))
      #define timer1        ((timer_t *)(TIMER1_BASE))
      
      /* for  R528/T113     */
      #define T113_GIC_BASE		(0x03021000)
      #define T113_CPUIF_BASE	(0x03022000)
      
      #define   PRESCALER_VALUE     1UL
      #define   OS_CFG_TICK_RATE_HZ 1000
      #define   GPTIM_LOAD_CONST    ((24000000 / OS_CFG_TICK_RATE_HZ) /(PRESCALER_VALUE) )
      timer_irq_con_t * timer_irq_con  = (timer_irq_con_t * )TIMER_IRQ_CON_BASE;
       
      
      void  BSP_OS_TickInit (void)
      {
          timer0->INTV_VALUE = GPTIM_LOAD_CONST;
          timer0->CUR_VALUE  = GPTIM_LOAD_CONST;
          
          bsp_int_vect_set(INT_TIMER0,  /* Assign ISR handler. */
                         1u,            /* 中断的优先级         */
                         3u,            /* 中断的目标CPU        */
                         0u,            /* 参数                 */
                         BSP_OS_TickISR_Handler);
        
          /* 周期连续模式 */
          timer0->CTRL_REG   = (1 << 2);
          
          irq_enable(INT_TIMER0);
         
          timer_irq_con->TMR_IRQ_STA  = 1;/*clear int sta     */
          timer_irq_con->TMR_IRQ_EN  |= 1;/*enable timer0 int */
          timer0->CTRL_REG           |= 1;/*enable timer0     */
         
      }
      

      运行后timer0的计数正常,中断标志也已经置1了,但就是不产生中断。请教各位大佬,问题该如何定位。

      gic模块的代码基本上是提取uboot的代码,代码在V3s上是能够正常运行的,只是迁移时根据T113的地址分布更改了各模块的基地址:

      /*
       * (C) Copyright 2007-2013
       * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
       * Jerry Wang <wangflord@allwinnertech.com>
       *
       * See file CREDITS for list of people who contributed to this
       * project.
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License as
       * published by the Free Software Foundation; either version 2 of
       * the License, or (at your option) any later version.
       *
       * This program is distributed in the hope that it will be useful,
       * but WITHOUT ANY WARRANTY; without even the implied warranty of
       * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
       * GNU General Public License for more details.
       *
       * You should have received a copy of the GNU General Public License
       * along with this program; if not, write to the Free Software
       * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
       * MA 02111-1307 USA
       */
      
      #include  "v3s_map.h"
      #include "reg-ccu.h"
      #include "gic.h"
      #include "v3s_irq_id.h"
      #include <stdio.h>
      #include <stdint.h>
      #include "bsp_sys.h"
      
      struct _irq_handler
      {
      	void                *m_data;
      	void (*m_func)( void * data);
      };
      
      struct _irq_handler sunxi_int_handlers[NUMBER_OF_INT_VECTORS]@"OcramData";
      
        
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      static void default_isr(void *data)
      {
      	sysprintf("default_isr():  called from IRQ %d\n", (uint32_t)data);
      	while(1);
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      int irq_enable(int irq_no)
      {
      	uint32_t reg_val;
      	uint32_t offset;
      
      	if (irq_no >= NUMBER_OF_INT_VECTORS)
      	{
      		printf("irq NO.(%d) > NUMBER_OF_INT_VECTORS(%d) !!\n", irq_no, NUMBER_OF_INT_VECTORS);
      		return -1;
      	}
      	if(irq_no == INT_NMI)
      	{
      		*(volatile unsigned int *)(0x01f00c00 + 0x10) |= 1;
      		*(volatile unsigned int *)(0x01f00c00 + 0x40) |= 1;
      	}
       
      	offset   = irq_no >> 5; // 除32
      	reg_val  = readl(GIC_SET_EN(offset));
      	reg_val |= 1 << (irq_no & 0x1f);
      	writel(reg_val, GIC_SET_EN(offset));
      
      	return 0;
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      int irq_disable(int irq_no)
      {
      	uint32_t reg_val;
      	uint32_t offset;
      
      	if (irq_no >= NUMBER_OF_INT_VECTORS)
      	{
      		sysprintf("irq NO.(%d) > NUMBER_OF_INT_VECTORS(%d) !!\n", irq_no, NUMBER_OF_INT_VECTORS);
      		return -1;
      	}
      	if(irq_no == INT_NMI)
      	{
      		*(volatile unsigned int *)(0x01f00c00 + 0x10) |= 1;
      		*(volatile unsigned int *)(0x01f00c00 + 0x40) &= ~1;
      	}
       
      	offset   = irq_no >> 5; // 除32
      	reg_val  = (1 << (irq_no & 0x1f));
      	writel(reg_val, GIC_CLR_EN(offset));
      
      	return 0;
      }
      
      void irq_int_prio_set (uint32_t  int_id,
                             uint32_t  prio)
      {
        if (int_id >= NUMBER_OF_INT_VECTORS)
      	{
      		sysprintf("irq NO.(%d) > NUMBER_OF_INT_VECTORS(%d) !!\n", int_id, NUMBER_OF_INT_VECTORS);
      		return ;
      	}
      
          if (prio > BSP_INT_PRIO_LVL_MAX) {
            prio = BSP_INT_PRIO_LVL_MAX;
              return;
          }
      
         CPU_SR_ALLOC();
         CPU_CRITICAL_ENTER();
        // uint32_t  * prio_r = (uint32_t  *)GIC_SGI_PRIO((int_id>>5));  
         //prio_r[int_id] =   (uint8_t)((prio << (8UL - __GIC_PRIO_BITS)) & (uint8_t)0xFFUL);
         
         
         uint32_t  reg_val, addr, offset;
         /* dispatch the usb interrupt to CPU1 */
      	 addr = GIC_SGI_PRIO(int_id>>2);
      	 reg_val = readl(addr);
      	 offset  = 8 * (int_id & 3);
      	 reg_val &= ~(0xff<<offset);
      	 reg_val |=  ((prio << (8UL - __GIC_PRIO_BITS)) << offset);
      	 writel(reg_val, addr);
         CPU_CRITICAL_EXIT();
      }
       
      
      void  irq_int_target_cpu_set (uint32_t  int_id,
                                      uint8_t  int_target_cpu)
      {
         if (int_id >= NUMBER_OF_INT_VECTORS)
       	 {
      		 sysprintf("irq NO.(%d) > NUMBER_OF_INT_VECTORS(%d) !!\n", int_id, NUMBER_OF_INT_VECTORS);
      		 return ;
      	 }
      
          CPU_SR_ALLOC();
          CPU_CRITICAL_ENTER();
         uint32_t  reg_val, addr, offset;
         /* dispatch the usb interrupt to CPU1 */
      	 addr = GIC_SGI_PROC_TARG(int_id>>2);
      	 reg_val = readl(addr);
      	 offset  = 8 * (int_id & 3);
      	 reg_val &= ~(0xff<<offset);
      	 reg_val |=  (int_target_cpu <<offset);
      	 writel(reg_val, addr);
        
         CPU_CRITICAL_EXIT();
       	 return ;
        
      }
      
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      static void gic_sgi_handler(uint32_t irq_no)
      {
      	sysprintf("SGI irq %d coming... \n", irq_no);
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      static void gic_ppi_handler(uint32_t irq_no)
      {
      	sysprintf("PPI irq %d coming... \n", irq_no);
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      static void gic_spi_handler(uint32_t irq_no)
      {
      	if (sunxi_int_handlers[irq_no].m_func != default_isr)
      	{
      		sunxi_int_handlers[irq_no].m_func(sunxi_int_handlers[irq_no].m_data);
      	}
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      static void gic_clear_pending(uint32_t irq_no)
      {
       	uint32_t reg_val;
      	uint32_t offset;
      
      	offset = irq_no >> 5; // 除32
      	reg_val = readl(GIC_PEND_CLR(offset));
      	reg_val |= (1 << (irq_no & 0x1f));
      	writel(reg_val, GIC_PEND_CLR(offset));
      
      	return ;
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      void irq_install_handler (int irq, interrupt_handler_t handle_irq, void *data)
      {
        CPU_SR_ALLOC();
        CPU_CRITICAL_ENTER();
        
      	if (irq >= NUMBER_OF_INT_VECTORS || !handle_irq)
      	{
      		 CPU_CRITICAL_EXIT();
      		return;
      	}
      
      	sunxi_int_handlers[irq].m_data = data;
      	sunxi_int_handlers[irq].m_func = handle_irq;
      
      	 CPU_CRITICAL_EXIT();
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      void irq_free_handler(int irq)
      {
      	 CPU_SR_ALLOC();
         CPU_CRITICAL_ENTER();
      	if (irq >= NUMBER_OF_INT_VECTORS)
      	{
      		 CPU_CRITICAL_EXIT();
      		return;
      	}
      
      	sunxi_int_handlers[irq].m_data = NULL;
      	sunxi_int_handlers[irq].m_func = default_isr;
      
      	 CPU_CRITICAL_EXIT();
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
       
      void BSP_IntHandler (void)
      {
      	u32 idnum;
      
      	idnum = readl(GIC_INT_ACK_REG);
      	
       
        if ((idnum == 1023) ||(idnum == 1022))
      	{
      		sysprintf("spurious irq !!\n");
      		return;
      	}
        if (idnum >= NUMBER_OF_INT_VECTORS) 
        {
      		sysprintf("irq NO.(%d) > NUMBER_OF_INT_VECTORS(%d) !!\n", idnum, NUMBER_OF_INT_VECTORS-32);
      		return;
      	}
       // u32 int_cpu = (idnum >> 10) & 0x0f;
        
      	 
      	if (idnum < 16)
      		gic_sgi_handler(idnum);
      	else if (idnum < 32)
      		gic_ppi_handler(idnum);
      	else
      		gic_spi_handler(idnum);
      
      	if(idnum == INT_NMI)
      	{
      		*(volatile unsigned int *)(0x01f00c00 + 0x10) |= 1;
      	}
        writel(idnum, GIC_END_INT_REG);/*write GICC_EOIR, to cause priority drop on the GIC CPU interface*/
        writel(idnum, GIC_DEACT_INT_REG);/* write to the GICC_DIR, to deactivate the interrupt*/
      	gic_clear_pending(idnum);
      
      	return;
      }
      //#endif
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      static void gic_distributor_init(void)
      {
      	uint32_t cpumask = 0x01010101;
      	uint32_t gic_irqs;
      	uint32_t i;
      
      	writel(0, GIC_DIST_CON);
      
      	/* check GIC hardware configutation */
      	gic_irqs = ((readl(GIC_CON_TYPE) & 0x1f) + 1) * 32;
      	if (gic_irqs > 1020)
      	{
      		gic_irqs = 1020;
      	}
      	if (gic_irqs < NUMBER_OF_INT_VECTORS)
      	{
      		sysprintf("GIC parameter config error, only support %d"
      				" irqs < %d(spec define)!!\n", gic_irqs, NUMBER_OF_INT_VECTORS);
      		return ;
      	}
      
      	/* set trigger type to be level-triggered, active low */
      	for (i=0; i<NUMBER_OF_INT_VECTORS; i+=16)
      	{
      		writel(0, GIC_IRQ_MOD_CFG(i>>4));
      	}
      	/* set priority */
      	for (i=GIC_SRC_SPI(0); i<NUMBER_OF_INT_VECTORS; i+=4)
      	{
      		writel(0xffffffff, GIC_SPI_PRIO((i-32)>>2));
      	}
      	/* set processor target */
      	for (i=32; i<NUMBER_OF_INT_VECTORS; i+=4)
      	{
      		writel(cpumask, GIC_SPI_PROC_TARG((i-32)>>2));
      	}
      	/* disable all interrupts */
      	for (i=32; i<NUMBER_OF_INT_VECTORS; i+=32)
      	{
      		writel(0xffffffff, GIC_CLR_EN(i>>5));
      	}
      	/* clear all interrupt active state */
      	for (i=32; i<NUMBER_OF_INT_VECTORS; i+=32)
      	{
      		writel(0xffffffff, GIC_ACT_CLR(i>>5));
      	}
      	writel(1, GIC_DIST_CON);
      
      	return ;
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      static void gic_cpuif_init(void)
      {
      	uint32_t i;
      
      	writel(0, GIC_CPU_IF_CTRL);
      	/*
      	 * Deal with the banked PPI and SGI interrupts - disable all
      	 * PPI interrupts, ensure all SGI interrupts are enabled.
      	*/
      	writel(0xffff0000, GIC_CLR_EN(0));
      	writel(0x0000ffff, GIC_SET_EN(0));
      	/* Set priority on PPI and SGI interrupts */
      	for (i=0; i<16; i+=4)
      	{
      		writel(0xffffffff, GIC_SGI_PRIO(i>>2));
      	}
      	for (i=16; i<32; i+=4)
      	{
      		writel(0xffffffff, GIC_PPI_PRIO((i-16)>>2));
      	}
      
         /* Priority level is implementation defined.
         To determine the number of priority bits implemented write 0xFF to an IPRIORITYR
         priority field and read back the value stored.*/
       // GIC_SetPriority((IRQn_Type)0U, 0xFFU);
        //priority_field = GIC_GetPriority((IRQn_Type)0U);
        
      	writel(0xff, GIC_INT_PRIO_MASK);
      	writel(1, GIC_CPU_IF_CTRL);
      
      	return ;
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      int arch_interrupt_init (void)
      {
      	int i;
       
      	for (i=0; i<NUMBER_OF_INT_VECTORS; i++)
      	{
      		sunxi_int_handlers[i].m_func = default_isr;
      	}
      	gic_distributor_init();
      	gic_cpuif_init();
      	
      
      	return 0;
      }
      /*
      ************************************************************************************************************
      *
      *                                             function
      *
      *    name          :
      *
      *    parmeters     :
      *
      *    return        :
      *
      *    note          :
      *
      *
      ************************************************************************************************************
      */
      int arch_interrupt_exit(void)
      {
      	gic_distributor_init();
      	gic_cpuif_init();
      
      	return 0;
      }
      void bsp_int_vect_set( uint32_t        int_id,
                             uint32_t        int_prio,
                             uint8_t        int_target_list,
                             void *            pParam,
                             system_irq_handler_t  int_fnct)
      {
         irq_install_handler (int_id, int_fnct, pParam);
         irq_int_prio_set(int_id,int_prio); 
         irq_int_target_cpu_set(int_id,int_target_list);
      }
      
      发布在 MR Series
      L
      L13819506056
    • 1 / 1