一、介绍
接上一篇,v3s的timer中断-优快云博客 ,讲到了V3S的寄存器结构体调用。它就像是一把武器,一方面节省我们查找的时间,减少错误率,还能使用代码易读,更优雅。
二、生成原理:
由timer的基地址0x1c20c00,和偏移地址可以知道第一个寄存器的地址。这是第一级优化。
由已知寄存器找出每一位或数位代表的意思,按bit寻值,可以精细化操作。
三、生成后的结构体举例:
v3s_timer.h:
1、数据结构:
#ifndef _V3S_TIMER_H_
#define _V3S_TIMER_H_
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int AVS_CNT0 :32 ;
}bits;
}AVS_CNT0_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int AVS_CNT1 :32 ;
}bits;
}AVS_CNT1_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int AVS_CNT0_EN :1 ;
volatile unsigned int AVS_CNT1_EN :1 ;
volatile unsigned int reserved0 : 6 ;
volatile unsigned int AVS_CNT0_PS :1 ;
volatile unsigned int AVS_CNT1_PS :1 ;
volatile unsigned int reserved1 : 22 ;
}bits;
}AVS_CNT_CTL_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int AVS_CNT0_D :12 ;
volatile unsigned int reserved2 : 4 ;
volatile unsigned int AVS_CNT1_D :12 ;
volatile unsigned int reserved3 : 4 ;
}bits;
}AVS_CNT_DIV_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int CNT64_CLR_EN :1 ;
volatile unsigned int CNT64_RL_EN :1 ;
volatile unsigned int CNT64_CLK_SRC_SEL :1 ;
volatile unsigned int reserved4 : 28 ;
volatile unsigned int CNT64_TEST_EN :1 ;
}bits;
}CNT64_CTRL_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int CNT64_HI :32 ;
}bits;
}CNT64_HIGH_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int CNT64_LO :32 ;
}bits;
}CNT64_LOW_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR0_EN :1 ;
volatile unsigned int TMR0_RELOAD :1 ;
volatile unsigned int TMR0_CLK_SRC :2 ;
volatile unsigned int TMR0_CLK_PRES :3 ;
volatile unsigned int TMR0_MODE :1 ;
volatile unsigned int reserved5 : 24 ;
}bits;
}TMR0_CTRL_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR0_CUR_VALUE :32 ;
}bits;
}TMR0_CUR_VALUE_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR0_INTV_VALUE :32 ;
}bits;
}TMR0_INTV_VALUE_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR1_EN :1 ;
volatile unsigned int TMR1_RELOAD :1 ;
volatile unsigned int TMR1_CLK_SRC :2 ;
volatile unsigned int TMR1_CLK_PRES :3 ;
volatile unsigned int TMR1_MODE :1 ;
volatile unsigned int reserved6 : 24 ;
}bits;
}TMR1_CTRL_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR1_CUR_VALUE :32 ;
}bits;
}TMR1_CUR_VALUE_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR1_INTV_VALUE :32 ;
}bits;
}TMR1_INTV_VALUE_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR2_EN :1 ;
volatile unsigned int TMR2_RELOAD :1 ;
volatile unsigned int TMR2_CLK_SRC :2 ;
volatile unsigned int TMR2_CLK_PRES :3 ;
volatile unsigned int TMR2_MODE :1 ;
volatile unsigned int reserved7 : 24 ;
}bits;
}TMR2_CTRL_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR2_CUR_VALUE :32 ;
}bits;
}TMR2_CUR_VALUE_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR2_INTV_VALUE :32 ;
}bits;
}TMR2_INTV_VALUE_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR0_IRQ_EN :1 ;
volatile unsigned int TMR1_IRQ_EN :1 ;
volatile unsigned int TMR2_IRQ_EN :1 ;
volatile unsigned int reserved8 : 29 ;
}bits;
}TMR_IRQ_EN_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int TMR0_IRQ_PEND :1 ;
volatile unsigned int TMR1_IRQ_PEND :1 ;
volatile unsigned int TMR2_IRQ_PEND :1 ;
volatile unsigned int reserved9 : 29 ;
}bits;
}TMR_IRQ_STA_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int WDOG_CONFIG :2 ;
volatile unsigned int reserved10 : 30 ;
}bits;
}WDOG_CFG_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int WDOG_RSTART :1 ;
volatile unsigned int WDOG_KEY_FIELD :12 ;
volatile unsigned int reserved11 : 19 ;
}bits;
}WDOG_CTRL_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int WDOG_IRQ_EN :1 ;
volatile unsigned int reserved12 : 31 ;
}bits;
}WDOG_IRQ_EN_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int WDOG_IRQ :1 ;
volatile unsigned int reserved13 : 31 ;
}bits;
}WDOG_IRQ_STA_REG_unionDef;
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int WDOG_EN :1 ;
volatile unsigned int reserved14 : 3 ;
volatile unsigned int WDOG_INTV_VALUE :4 ;
volatile unsigned int reserved15 : 24 ;
}bits;
}WDOG_MODE_REG_unionDef;
typedef struct{
TMR_IRQ_EN_REG_unionDef TMR_IRQ_EN_REG ; //Timer IRQ Enable Register
TMR_IRQ_STA_REG_unionDef TMR_IRQ_STA_REG ; //Timer Status Register
volatile unsigned char reserved72[8] ;
TMR0_CTRL_REG_unionDef TMR0_CTRL_REG ; //Timer 0 Control Register
TMR0_INTV_VALUE_REG_unionDef TMR0_INTV_VALUE_REG ; //Timer 0 Interval Value Register
TMR0_CUR_VALUE_REG_unionDef TMR0_CUR_VALUE_REG ; //Timer 0 Current Value Register
volatile unsigned char reserved73[4] ;
TMR1_CTRL_REG_unionDef TMR1_CTRL_REG ; //Timer 1 Control Register
TMR1_INTV_VALUE_REG_unionDef TMR1_INTV_VALUE_REG ; //Timer 1 Interval Value Register
TMR1_CUR_VALUE_REG_unionDef TMR1_CUR_VALUE_REG ; //Timer 1 Current Value Register
volatile unsigned char reserved74[4] ;
TMR2_CTRL_REG_unionDef TMR2_CTRL_REG ; //Timer 2 Control Register
TMR2_INTV_VALUE_REG_unionDef TMR2_INTV_VALUE_REG ; //Timer 2 Interval Value Register
TMR2_CUR_VALUE_REG_unionDef TMR2_CUR_VALUE_REG ; //Timer 2 Current Value Register
volatile unsigned char reserved75[68] ;
AVS_CNT_CTL_REG_unionDef AVS_CNT_CTL_REG ; //AVS Control Register
AVS_CNT0_REG_unionDef AVS_CNT0_REG ; //AVS Counter 0 Register
AVS_CNT1_REG_unionDef AVS_CNT1_REG ; //AVS Counter 1 Register
AVS_CNT_DIV_REG_unionDef AVS_CNT_DIV_REG ; //AVS Divisor Register
volatile unsigned char reserved76[16] ;
WDOG_IRQ_EN_REG_unionDef WDOG_IRQ_EN_REG ; //Watchdog IRQ Enable Register
WDOG_IRQ_STA_REG_unionDef WDOG_IRQ_STA_REG ; //Watchdog Status Register
volatile unsigned char reserved77[8] ;
WDOG_CTRL_REG_unionDef WDOG_CTRL_REG ; //Watchdog Control Register
WDOG_CFG_REG_unionDef WDOG_CFG_REG ; //Watchdog Configuration Register
WDOG_MODE_REG_unionDef WDOG_MODE_REG ; //Watchdog Mode Register
volatile unsigned char reserved78[20] ;
CNT64_CTRL_REG_unionDef CNT64_CTRL_REG ; //64-bit Counter Control Register
CNT64_LOW_REG_unionDef CNT64_LOW_REG ; //64-bit Counter Low Register
CNT64_HIGH_REG_unionDef CNT64_HIGH_REG ; //64-bit Counter High Register
}TIMER_structDef;
#define V3S_TIMER_MODE_CONTINUE (0U)
#define V3S_TIMER_MODE_SINGLE (1U)
#define V3S_TIMER_CLR_PRES_1 (0U)
#define V3S_TIMER_CLR_PRES_2 (1U)
#define V3S_TIMER_CLR_PRES_4 (2U)
#define V3S_TIMER_CLR_PRES_8 (3U)
#define V3S_TIMER_CLR_PRES_16 (4U)
#define V3S_TIMER_CLR_PRES_32 (5U)
#define V3S_TIMER_CLR_PRES_64 (6U)
#define V3S_TIMER_CLR_PRES_128 (7U)
#define V3S_TIMER_CLK_SRC_OSC_512 (0U)
#define V3S_TIMER_CLK_SRC_OSC24M (1U)
#endif
2、使用案例
void a_InitSystemTick(){
TIMER->TMR_IRQ_EN_REG.bits.TMR1_IRQ_EN |= 1;
TIMER->TMR_IRQ_STA_REG.bits.TMR1_IRQ_PEND |= 1;
TIMER->TMR1_CTRL_REG.bits.TMR1_MODE = V3S_TIMER_MODE_CONTINUE;
TIMER->TMR1_CTRL_REG.bits.TMR1_CLK_SRC = V3S_TIMER_CLK_SRC_OSC24M;
TIMER->TMR1_CTRL_REG.bits.TMR1_CLK_PRES = V3S_TIMER_CLR_PRES_64;
TIMER->TMR1_CTRL_REG.bits.TMR1_RELOAD = 1;
TIMER->TMR1_INTV_VALUE_REG.all = 375 * 100; //5ms
GIC->D_IPRIORITYR.byte.d51 = PRIORITY_TIMER1;
GIC->D_ITARGETSR.byte.d51 = 0XFF;
GIC->D_ISENABLER.bit.d51 = 1;
TIMER->TMR1_CTRL_REG.bits.TMR1_EN = 1;
}
是不是比writel(addr, value)的方式方便多了。
四、生成脚本介绍:
1、生成目录:
第一级:
dir_path = r"C:\Users\nisag\Desktop\v3s_sunxi"
第二级:
dir_path = r"C:\Users\nisag\Desktop\v3s_sunxi2"
2、生成方法:
将数据手册里的寄存器数据复制下来,以寄存器命令文件,粘贴到相应目录下。
分别运行
allwinner.py
allwinnerSub.py
eg:
allwinnerSub.py的输入文件为:
31:18 / / /
17:16 R/W 0x1 HCLKC_DIV
15:14 / / /
13:12 R/W 0x1 AHB_CLK_SRC_SEL
11:10 / / /
9:8 R/W 0x0 APB_CLK_RATIO
7:6 R/W 0x0 AHB_PRE_DIV
5:4 R/W 0x1 AHB_CLK_DIV_RATIO
3:0 / / /
运行allwinnerSub.py后生成:
typedef union{
volatile unsigned int all;
struct{
volatile unsigned int reserved0 : 4 ;
volatile unsigned int AHB_CLK_DIV_RATIO :2 ;
volatile unsigned int AHB_PRE_DIV :2 ;
volatile unsigned int APB_CLK_RATIO :2 ;
volatile unsigned int reserved1 : 2 ;
volatile unsigned int AHB_CLK_SRC_SEL :2 ;
volatile unsigned int reserved2 : 2 ;
volatile unsigned int HCLKC_DIV :2 ;
volatile unsigned int reserved3 : 14 ;
}bits;
}AHB_APB_HCLKC_CFG_REG_unionDef;
然后将第一级生成的结构体与第二级生成的结构体放进同一文件内。注意,第一级应在最下方。
修改后,将第一级结构体转为指针类型,把该寄存器基地址转为此类型指针,如下:
#include "v3s_timer.h"
#define TIMER ((TIMER_structDef*)TIMER_BASE)
五、附下载链接:
如果有类似结构(看四、2)的数据手册,也适用。