【MCAL】TC397+EB-tresos之GPT配置实战 - TOM

部署运行你感兴趣的模型镜像

概述

GPT(General Purpose Timer)驱动程序负责为 AUTOSAR规范中定义的标准计时器功能提供对应的API。相应的底层定时器引擎是可以是包含在AURIX2G系列处理器中的GTM定时器通道(TOM/ATOM slice)或者GPT12定时器。用户可以基于驱动程序配置实现多个通道,在每个通道上上层程序的可以执行以下操作:

下图是英飞凌针对Autosar MCAL的架构实现,GPT位置如下。

  • 启动/停止定时器
  • 启用/禁用唤醒功能
  • 启用/禁用回调通知
  • 单次或连续操作模式
  • 使用TOM切片实现的GPT Predef Timer功能。

下图为GPT驱动模块的软硬件调用接口图

GTM(Generic Timer Module) 

GPT驱动利用 GTM IP核提供的通道来实现连续定时模式单次定时模式预定义定时器

GPT驱动程序所使用的GTM-TOM/ATOM IP核心硬件功能特性包括:

  •  连续递增计数模式
  •  单次递增计数模式
  •  ATOM脉宽调制信号输出模式(SOMP)

GPT驱动程序利用GTM IP模块实现连续定时器模式、单次定时器模式及预定义定时器功能。连续模式与单次模式的逻辑通道仅需占用TOM/ATOM切片中的单个定时器通道。

预定义定时器仅使用GTM IP的TOM切片,原因是TOM作为16位定时器,相较于24位的ATOM更易于派生出16位、24位及32位定时器。若fGTM(GTM模块时钟频率)配置可直接生成目标频率(1MHz对应1微秒预定义定时器,10kHz对应100微秒预定义定时器),则:

  • 16位预定义定时器仅需1个TOM通道(x)
  •  24位或32位预定义定时器分别需要2个TOM通道(x与x+1)

 对于24/32位定时器,通过硬件TRIGOUT特性实现:前一个TOM通道在比较匹配事件发生时触发下一个TOM通道。若fGTM配置无法直接生成目标频率,则需额外增加一个通道(x-1)作为预分频器来产生预定义定时器所需的节拍频率。此时同样利用硬件TRIGOUT特性来实现1微秒/100微秒的节拍频率。

从上面可以得到结论,如果fGTM配置不能直接推导出定时器所需频率,且要实现一个24位/32位的定时器,那么我们需要3个通道,三个通道号需要按顺序依次递增。

我们此次使用了 TOM0_CH0 ,TOM0_CH8 配置成两路的GPT  功能

GTM内部由多个簇(Cluster)组成,有些模块如ATOMTOMSPE在多个簇里面存在,每个簇中功能相同,具体的数量取决于芯片型号;而有些模块如CMUTBU只在主簇(Cluster0)中存在。每个簇有一个独立的输入时钟源,多个输入信号到TIM模块,多个输出经过TOM/ATOM然后从DTM输出;输入/输出信号一般是通过Port与外部进行信号交互,也可与其他模块如Adc、Iom等模块进行交互。

每个簇及其中的模块都有相应的配置寄存器,可直接通过Aurix2G的外设总线进行设置。

时钟方面,fGTM 可在MCU模块中的McuPllDistributionSettingConfig进行直接配置(200Mhz),因为CMU(Clock Management Unit)属于Cluster0,所以可以在GtmClusterConf_0里对其进行分频(2分频)得到fCLS0

CMU(Clock Management Unit)

功能介绍

时钟管理单元(Clock Management Unit, CMU)负责生成计数器和GTM的时钟。CMU由三个子单元组成,包括CFGU 、FXUEGU,为整个GTM模块生成不同的时钟源。CMU的主时钟源是簇0时钟信号cls0_clk,该信号由寄存器GTM_CLS_CLK_CFG中的位字段CLS0_CLK_DIV的值定义(默认为2)。CMU模块框图如图示。

CFGU(Configurable Clock Generation Unit,可配置时钟生成模块)

可根据用户需求进行较大范围的时钟配置(分频参数为24位宽),是CMU主要的时钟控制单元。其输入源为Cluster0的输入时钟CLS0_CLK,可输出8路不同频率的时钟,供TIMATOMTBU等模块使用,且连接丰富,例如同一ATOM模块内部多个通道可使用不同的CMU_CLK。

每路CMU_CLK与GTM总时钟源之间有3层分频,

第一层经Cluster0分频得到CLS0_CLK

第二层经过Global Clock Divider得到CMU_GCLK_EN

然后经过Clock SourceX Divider分频得到CMU_CLKx

计算公式如下:

f_{CMUCLK_{x}} = \frac{f_{GTM}}{CLS_{0}CLKDIV*GLOBALDIV*CLKCNT_{x}}

  • fCMUCLKx:CMU通道x可配置时钟输出,x取0~8
  • fGTM:GTM模块主时钟
  • CLS0CLKDIV:簇0分频系数,寄存器CLS0_CLK_DIV,只可选1或者2,默认为2,即半分频
  • GLOBALDIV:全局分频,为GCLK_NUM/GCLK_DEN的值
  • CLKCNTx:CMU时钟通道x分频系数,对应寄存器CLK_CNT

FXU(Fixed Clock Generation Unit)为固定分频时钟,所有通道共用一个时钟源,

时钟源可选CFGU输出的通道时钟或者CMU_GCLK_EN时钟,如图所示其每路分频参数不可配置。

FXU主要供TOM模块使用。当选择CMU_GCLK_EN为时钟源时,计算公式如下:

f_{CMUCLK_{x}} = \frac{f_{GTM}}{CLS_{0}CLKDIV*GLOBALDIV*FXCLKCNT_{x}}

与可配置CMU时钟的计算公式仅有FXCLKDIV不同。

EGU(External Generation Unit)可供外部外设使用,也可作为第二时钟域输出到其他GTM模块使用。GtmExtClockSetting 配置。

    SCU(System Control Unit)

    GPT驱动程序的时钟取决于SCU这个IP核。通用定时器需要fGTM和fSPB(System Peripheral Bus)时钟信号。

    SCU为所有外设提供时钟,MCU驱动程序负责配置芯片时钟树。为避免因同时写入而发生冲突,使用MCALLIB提供的API执行对所有ENDINIT保护寄存器的更新。

    环境与目标 

    本文使用的为英飞凌提供的开发板KIT_A2G_TC397XA_TFT,芯片为TC397,外部的时钟为20Mhz。

    配置目标如下:

    1. 使用GPT实现1ms的定时器中断,在中断处理函数中累加值,用作系统时标。
    2. 双通道TOM定时器的软件控制 
    3. CH1 分配TOM0_CH0 
    4. CH2 分配TOM0_CH8

    EB-tresos配置 :

    一、MCU配置

    • TC3XX支持16-40MHZ的外部晶振或陶瓷振荡器,作为MCU的时钟来源

    配置GTM外设为200Mhz频率。(最大值200MHz)

    1.1 GtmGlobalConfiguration

    访问路径:MCU->GtmGlobalConfiguration

    GtmCmuGlobalClockNumerator:配置可配置时钟和固定时钟的全局分子值

    GtmCmuGlobalClockDenominator:配置可配置时钟和固定时钟的全局分母值

    fGCLK = (GtmCmuGlobalClockNumerator / GtmCmuGlobalClockDenominator+1)*fCLS0

    CLS0时钟来自GTM模块系统时钟,GTM的sys_clk来自时钟source0,source0时钟来自PLL0或者backup时钟(可选),默认来自PLL0,PLL0时钟源默认来自外部晶振

    这里有两个参数,就是上文中决定全局分频GLOBALDIVGCLK_NUMGCLK_DEN,这里一般都配置成1,也就是全局1比1分频。

    1.2 GtmClusterConf_0

    访问路径:MCU->GtmGlobalConfiguration->GtmGlobalConfiguration0->GTMClusterConf

    GTM Clusters  12 (CCM0-11)
    (CCM0-11)

    CCM0-4: 200 MHz max

    CCM5-11: 100 MHz max

    配置fCLS0为fGTM的二分频,即为100Mhz。

    1.3 CFGU的分频

    一共有8路,和对应的时钟开关。这里注意CLKCNTx等于配置参数加1,也就是说0代表1比1分频,3表示四分之一分频。

    1.4 FixedClock配置

    前面提到因为FXU是不可配置分频的,但是可以配置时钟源和开关,就是下面这两个配置参数。

    这里我们完成了CMU的时钟配置,

    假设我们配置的GTM总时钟为100MHz,结合上面的配置,

    Cluster0经过2倍分频得到CLS0_CLK=50MHz,

    全局分频配置为1则CMU_GCLK_EN=50MHz。

    CMU_CLKx的分频参数全部为1,也就是CMU_CLKx(x=0~7)=50MHz。

    FXU时钟源选择CMU_GCLK_EN=50MHz,

    则各路CUM_FXCLK根据固定分频比计算得出。

    1.6 McuGtmAllocationConf 

    用来做GPT的定时功能。

    McuGtmTomChannelAllocationConf 

    TOM(Timer Output Module),定时器输出单元TOM是GTM的主要输出模块之一,负责输出Pwm波形,一般每个GTM簇内有一个TOM模块,一个TOM模块内最多16个通道,每个通道可以独立输出,也可以进行关联做Pwm波的相位对齐,TOM[i]_CH[x]_OUT 表示TOMi的通道x输出。TOM模块的模块框图如图所示:

    TOM 6x16 ch. (TOM0-5)

    McuGtmTomAllocationConf_[0,1,2,3,4,5] 

    6个通道

    McuGtmTomChannelAllocationConfto15]

    16个通道

    我们需要 使用 TOM0_0  作为GPT使用 。

    访问路径MCU 模块
    1MCU
    2McuGtmAllocationConf_0
    3McuHardwareResourceAllocationConf
    4McuHardwareResourceAllocationConf_0
    5McuGtmAllocationConf_0
    6McuGtmTomAllocationConf_0
    7McuGtmTomChannelAllocationConf_0

    这里我们选用Tom0_CH0,将硬件资源分配给GPT 

    如果 这里我们选用TOM0_CH8,将硬件资源分配给GPT

    配置如下图:

    McuGtmTomChannelAllocationConf 配置如下:

    二、 GPT配置

    配置GPT模块General部分,需要我们注意的配置项有以下几个。

    GptEnableDisableNotificationApi:使能回调函数的API,此处属于下面回调函数配置的开关。
    GptTimeElapsedApi:已经运行时间的计数,例如本例子的1ms假设运行了0.3ms,这个API返回值为0.3ms的Ticks。
    GptTimeRemainingApi:剩余时间的计数,例如本例子的1ms假设运行了0.3ms,这个APl返回值为剩余0.7ms的Ticks.

    2.1 GptClockReferencePoint

    2.2 GptChannelConfiguration

    将TOM0_CH0 分配在 GptChannel0   将TOM0_CH8 分配在 GptChannel1,

    2.2.1  GptChannelConfiguration0:

    General 配置如下:

    这里需要注意的配置有以下几个。

    GptAssignedHwUnit:选择硬件时钟是GTM还是GPT12。
    GptChannelMode:运行模式是连续还是单次触发。

    GptNotification 配置如下:

    中断函数命名为 IoHwAb_GptNotification0

    GtmTimerOutputModuleConfiguration

    选择GTM使用的Timer为Tom0Channel0。时钟源选择CMU输出的Fixed_Clock_1。

    5 dedicated clocks  FX_CLK (1:1, 1:16, 1:256..) 可供选择。

    2.2.2 GptChannelConfiguration1:

    General 配置如下:

    GptNotification 配置如下:

    GtmTimerOutputModuleConfiguration

    三、 IRQ配置

    可以看到  TOM0_CH0中断输出使用的是SR0。

                    TOM0_CH8中断输出使用的是SR4。

    中断优先级配置:

    绑定CPU核:

    四、 ResourceM配置

    分配核0使用资源,添加GPT:GptChannelConfiguration_0。

    五、GPT驱动使用与调试

    #ifndef TRB_LED
    //#define TRB_LED DIO_CHANNEL_33_4
    #define TRB_LED DIO_CHANNEL_13_0
    #endif
    
    #ifndef HUGO_LED
    //#define TRB_LED DIO_CHANNEL_33_4
    #define HUGO_LED DIO_CHANNEL_13_1
    #endif
    
    
    
    LOCAL_INLINE void Gpt_lStartDemo(void);
    LOCAL_INLINE void Gpt_l3StartDemo(void);
    
    
    void Gpt_Demo(void)
    {
      volatile uint8 LoopVar = 0;
      char InputString[10];
    
      /* Initialiase interrupt request configurations */
      if( Gpt_DemoCalled == 0U )
      {
    	#if (MCU_GTM_USED == STD_ON)
    	IrqGtm_Init();
    	SRC_GTMTOM00.B.SRE = 1;
    	SRC_GTMTOM04.B.SRE = 1;
    	#endif
        IrqGpt_Init();
    	SRC_GPT120T6.U |= (unsigned_int)(1<<10);
        Gpt_DemoCalled = 1U;
      }
      /* Initialize GPT driver */
      Gpt_Init(&Gpt_Config);
      
      while (LoopVar == 0)
      {
        print_f("\n");
        print_f("\n < >: ............ GPT DRIVER DEMO MENU ............");
        print_f("\n <1>:  Start continuous timer : LED must start blinking");
        print_f("\n <2>:  Stop timer: LED must stop blinking");
        print_f("\n <.>: Go back to previous menu\n");
        print_f("\nEnter option Number: ");
    
        getline(InputString, sizeof InputString - 1);
    
        switch (*InputString)
        {
          case '1':
            print_f("Result = Gpt_lStartDemo;");
            Gpt_lStartDemo();
            StartResult();
            print_f("Result = Pass;");
            EndResult();
            break;
    
          case '2':
            /* Stop the timer, LED blinking stops, remains OFF/ON */
            Gpt_StopTimer(0);
            StartResult();
            print_f("Result = Pass;");
            EndResult();
            break;
          case '3':
            print_f("Result = Gpt_l3StartDemo;");
            Gpt_l3StartDemo();
            StartResult();
            print_f("Result = Pass;");
            EndResult();
            break;
    
          case '.':
            /* De-initialize GPT driver */
            Gpt_DeInit();
            LoopVar = 1;
            StartResult();
            print_f("Result = Pass;");
            EndResult();
            break;
    
          default:
            print_f("\n\n  INVALID OPTION");
            StartResult();
            print_f("Result = Fail;");
            EndResult();
            break;
        }/* End of switch-case */
      }/* End of While loop */
    }
    
    void IoHwAb_GptNotification0(void)
    {
      /* start blinking the LED */
      if( Gpt_ChannelNotif[0] == 0)
      {
        Dio_WriteChannel(TRB_LED, STD_LOW);
        Gpt_ChannelNotif[0] = 1;
      }
      else
      {
        Dio_WriteChannel(TRB_LED, STD_HIGH);
        Gpt_ChannelNotif[0] = 0;
      }
    }
    
    
    void HUGO_HELLO(void)
    {
    
        print_f("Result = hello;");
        /* start blinking the LED */
        if( Gpt_ChannelNotif[1] == 0)
        {
          Dio_WriteChannel(HUGO_LED, STD_LOW);
          Gpt_ChannelNotif[1] = 1;
        }
        else
        {
          Dio_WriteChannel(HUGO_LED, STD_HIGH);
          Gpt_ChannelNotif[1] = 0;
        }
    }
    
    LOCAL_INLINE void Gpt_lStartDemo(void)
    {
      /* Enable notification for Timer channel 0 */
      Gpt_EnableNotification(0);
      /* 16 bit max value in GPT12 timer */
      Gpt_StartTimer(0,65535U);  
     }
    
    
    LOCAL_INLINE void Gpt_l3StartDemo(void)
    {
      /* Enable notification for Timer channel 0 */
    
      Gpt_EnableNotification(1);
      /* 16 bit max value in GPT12 timer */
      Gpt_StartTimer(1,65535U);
     }
    

    感谢:

    【MCAL】TC397+EB-tresos之GPT配置实战 - 定时器_mcal gpt-优快云博客

    您可能感兴趣的与本文相关的镜像

    GPT-oss:20b

    GPT-oss:20b

    图文对话
    Gpt-oss

    GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值