Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页

    T113裸跑不能产生中断请教:

    MR Series
    5
    12
    4142
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L
      L13819506056 LV 5 last edited by whycan

      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);
      }
      
      1 Reply Last reply Reply Quote Share 0
      • L
        L13819506056 LV 5 last edited by

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

        mangogeek 1 Reply Last reply Reply Quote Share 0
        • mangogeek
          mangogeek LV 8 @L13819506056 last edited by

          @l13819506056 串口可正常交互嘛?

          L 1 Reply Last reply Reply Quote Share 0
          • L
            L13819506056 LV 5 @mangogeek last edited by

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

            1 Reply Last reply Reply Quote Share 0
            • mangogeek
              mangogeek LV 8 last edited by

              感觉你可以尝试用uboot来run你这个代码测试下,起码uboot给你准备了个正常的环境。然后再对比中断相关的寄存器和你纯裸跑有无差异。

              L 1 Reply Last reply Reply Quote Share 0
              • L
                L13819506056 LV 5 @mangogeek last edited by

                @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
                
                T L 2 Replies Last reply Reply Quote Share 1
                • T
                  tripod9 LV 5 @L13819506056 last edited by

                  @l13819506056 我实验T113中断时,只要一中断,就会产生SWI异常,很神奇,我是裸奔,根本没执行swi相关指令。一直理解不了。

                  L 1 Reply Last reply Reply Quote Share 0
                  • L
                    L13819506056 LV 5 @tripod9 last edited by

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

                    T 1 Reply Last reply Reply Quote Share 0
                    • T
                      tripod9 LV 5 @L13819506056 last edited by

                      @l13819506056 频率是1.008G ,是否方便提供一个简单的可以测试中断的裸机程序。我debug下,现在我实验后发现总是产生swi异常,不知哪里在触发。

                      1 Reply Last reply Reply Quote Share 0
                      • M
                        musich LV 5 last edited by

                        正在打算入坑, 不知能否逃过此劫.

                        L 1 Reply Last reply Reply Quote Share 0
                        • L
                          L13819506056 LV 5 @musich last edited by

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

                          1 Reply Last reply Reply Quote Share 0
                          • L
                            ld1633 LV 2 @L13819506056 last edited by

                            @l13819506056 你好,这段代码加在启动文件的哪个位置啊

                            1 Reply Last reply Reply Quote Share 0
                            • 1 / 1
                            • First post
                              Last post

                            Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

                            行为准则 | 用户协议 | 隐私权政策