Browse Source

Feat: 增加系统时钟处理修改时钟API接口

juni 7 months ago
parent
commit
74e985ffcf

+ 2 - 0
app_public/fuxi_public/fuxi_bsp/source/bsp.c

@@ -25,6 +25,7 @@ struct init_t  g_bsp_init_func[]=
 	{ccu_init,ERR_CODE_INIT_SOFTWARE},	//初始化系统时钟CCU
 	{bsp_ustimer_init,ERR_CODE_INIT_SOFTWARE},	//初始化内核USTIMER
 	{ustimer_init,ERR_CODE_INIT_SOFTWARE},	//初始化USTIMER
+	{gps_init,ERR_CODE_INIT_SOFTWARE},		//初始化GPS
 	// {shm_init,ERR_CODE_INIT_SOFTWARE},	//初始化shm
 	// {mb_init,ERR_CODE_INIT_SOFTWARE},	//初始化mb
 	{watchdog_init,ERR_CODE_INIT_SOFTWARE},	//初始化watchdog
@@ -78,6 +79,7 @@ INIT_FUNC g_bsp_exit_func[]=
 	mb_exit,
 	ustimer_exit,
 	bsp_ustimer_exit,
+	gps_exit,
 	log_exit,
 	ccu_exit,
 };

+ 172 - 110
app_public/fuxi_public/fuxi_bsp/source/gps.c

@@ -23,8 +23,11 @@
 #include "bspconfig.h"
 #include "my_rtc.h"
 #include "rt.h"
-// sunxi 20220408 #include "mcf5441x_gpio.h"
-//#include "linux/math64.h"
+#include "bsp_ccu.h"
+#include "bsp_ustimer.h"
+#include "rt_printf.h"
+#include "rt_types.h"
+#include <sys/mman.h>
 
 
 /*------------------------------- 宏定义 --------------------------------------
@@ -65,7 +68,9 @@ unsigned int g_irig_code_index;
 unsigned char g_irig_code[100];
 
 
-
+int g_gps_fd = -1;
+unsigned g_gps_mapped_size;
+void *g_gps_map_base, *g_gps_virt_addr; 
 
 /*------------------------------ 函数声明 -------------------------------------
 */
@@ -80,8 +85,8 @@ void gps_isr(void);
 /******************************************************************************
 函数名称:	gps_init
 函数版本:	01.01
-创建作者:	   sunxi
-创建日期:	2008-08-06
+创建作者:	ocean
+创建日期:	2025-11-21
 函数说明:	gps初始化。
 参数说明:	无
 返回值:  	成功返回0.
@@ -89,47 +94,110 @@ void gps_isr(void);
 */
 int gps_init(void)
 {
-	//设置GPIO
-	//GPIO_GPS_INT_INIT();	//对时输入
-	//GPIO_GPS_INIT();		//对时输出
-	
-	//以下设置输入捕获定时器
-	//设置DTIM扩展模式寄存器。
-	MCF_REG08(MCF_DTIM_DTXMR(CFG_DTIM_GPS_CAP)) = 0; 
-	
-	//设置DTIM模式寄存器。定时器时钟源为1M,所以定时器分辨率为1us。
-	//32位计数值的计数周期为4294.967296s(大于1.1小时),
-	MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) = (unsigned short)(0
-					| MCF_DTIM_DTMR_RST			//允许定时器
-					| MCF_DTIM_DTMR_CLK_DIV1	//输入clock除1
-				//	| MCF_DTIM_DTMR_FRR			//自由运行模式(free run)
-					| MCF_DTIM_DTMR_ORRI		//当参考计数值到达后,产生DMA或中断
-				//	| MCF_DTIM_DTMR_OM			//输出模式为低脉冲模式
-				//	| MCF_DTIM_DTMR_CE_ANY		//上升沿和下降沿都捕获
-					| MCF_DTIM_DTMR_PS(DTIM_CLOCK_PER_US - 1));//将定时器clock周期设为1us。
-
-	//不清零,因为内核中使用了该定时器
-	
-	//清除计数值
-	//MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP)) = 0;
-	
-	//清除中断
-	MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_CAP | MCF_DTIM_DTER_REF;
-
-	//申请实时中断
-	rt_request_irq(CFG_DTIM_VECTOR_BEGIN + CFG_DTIM_GPS_CAP,CFG_INT_LEVEL_CLOCK,gps_isr,"gps_isr_cap");
-
-	//设置参考值
-	g_1s_refence = MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP)) + 1000000;
-	MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
-	
+	struct timespec ts;
+	struct rtc_time_t ct;
+	void *temp_ccu_base, *temp_virt_l_base, *temp_virt_h_base, *temp_virt_ctl_base, *temp_virt_irq_base;
+    unsigned long read_result;
+    off_t target;
+	unsigned page_size, offset_in_page;
+    unsigned width = 8 * sizeof(int);
+    target = TIMER_BASE;
+    // 获取页面大小
+    g_gps_mapped_size = page_size = sysconf(_SC_PAGESIZE);
+    offset_in_page = (unsigned)target & (page_size - 1);
+    if (offset_in_page + width > page_size) {
+		/* This access spans pages.
+		 * Must map two pages to make it possible: */
+		g_gps_mapped_size *= 2;
+	}
+    
+    g_gps_fd = open("/dev/mem",  O_RDWR | O_SYNC);
+    if (g_gps_fd < 0)  
+    {
+        printf("open(/dev/mem) failed.\n");    
+        return -1;
+    }
+    fflush(stdout);
+
+    g_gps_map_base = mmap (NULL, g_gps_mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, g_gps_fd, target & ~(off_t)(page_size - 1));
+    if (g_gps_map_base == (void *)-1)
+    {
+        printf ("NULL pointer!\n");
+    }
+    else
+    {
+        printf ("BSP gps map Successfull!\n");
+    }
+    fflush(stdout);
+
+    g_gps_virt_addr = (char*)g_gps_map_base + offset_in_page;
+    // printf("g_ustimer_virt_addr: %p %p %x\n", g_ustimer_virt_addr, g_ustimer_map_base, offset_in_page);
+
+    // Init timer ccu clock
+    /* set TMR3 clock source to HOSC, 8 pre-division */
+    temp_ccu_base = g_ccu_map_base + 0x080C;
+    read_result = *(volatile u_int32_t*)(temp_ccu_base);
+	read_result &= ~(0x01 << 24);
+    read_result |= (1 << 31) | 3;
+    *(volatile u_int32_t*)(temp_ccu_base) = read_result;
+
+    // Enable timer3
+    /* set timer intervalue */
+    temp_virt_l_base = (char*)g_gps_map_base + 0x84;
+    temp_virt_h_base = (char*)g_gps_map_base + 0x8C;
+    *(volatile u_int32_t*)(temp_virt_l_base) = 3000000;
+    *(volatile u_int32_t*)(temp_virt_h_base) = 0x0;
+
+	/* set mode to auto reload */
+    temp_virt_ctl_base = (char*)g_gps_map_base + 0x80;
+	read_result = *(volatile u_int32_t*)(temp_virt_ctl_base);
+    read_result &= TIMER_CTL_PERIODIC;
+    *(volatile u_int32_t*)(temp_virt_ctl_base) = (read_result | TIMER_CTL_AUTORELOAD | TIMER_CTL_ENABLE);
+	
+	/* Enable timer interrupt */
+	temp_virt_irq_base = (char*)g_gps_map_base + 0x00;
+	read_result = *(volatile u_int32_t*)(temp_virt_irq_base);
+	*(volatile u_int32_t*)(temp_virt_irq_base) = (read_result | TIMER_IRQ_EN(3));
+
+	/* Get linux system current time */
+	clock_gettime(CLOCK_REALTIME, &ts);
+	timespec_to_rtc(ts, &ct, 1);
+	if(ct.hour>=24||ct.min>=60||ct.month>12||ct.day>31||ct.day==0||ct.month==0)  // 读取系统时钟错误
+	{
+		/* Reset linux system time */
+		ct.year = 8;
+		ct.month = 8;
+		ct.day = 8;
+		ct.hour = 8;
+		ct.min = 8;
+		rtc_to_timespec(&ct, &ts);
+		rt_printf("gps read system date data error!!!");
+	}
+
+	g_sys_time.tv_sec = ts.tv_sec;
+	g_sys_time.tv_nsec = ts.tv_nsec;
 	return 0;
 }
 
 int gps_exit(void)
 {
-//	MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) = 0; //和内核ustimer共用定时器,不能关闭
-	rt_free_irq(CFG_DTIM_VECTOR_BEGIN + CFG_DTIM_GPS_CAP); 	
+	unsigned long read_result;
+	void *temp_virt_ctl_base;
+	if (g_gps_fd >= 0)
+    {
+        close(g_gps_fd);
+        g_gps_fd = -1;
+    }
+
+	temp_virt_ctl_base = (char*)g_gps_map_base + 0x80;
+	read_result = *(volatile u_int32_t*)(temp_virt_ctl_base);
+	read_result &= ~(TIMER_CTL_ENABLE);
+	*(volatile u_int32_t*)(temp_virt_ctl_base) = (read_result);
+
+    if (munmap(g_gps_map_base, g_gps_mapped_size) == -1) {
+        printf("munmap failed!");
+        return -1;
+    }
 
  	return 0;
 }
@@ -137,76 +205,63 @@ int gps_exit(void)
 
 int gps_get_time(struct timespec *p_ts)
 {
-	//register long tv_sec,tv_nsec;
-	//uint32_t  flags;
-	//unsigned int dtcn,dtrr,ref;
+	unsigned long flags;
+    register long tv_sec,tv_nsec;
+	unsigned long read_result;
+	void *temp_virt_cvl_base, *temp_virt_irq_base;
 	
 	//检查参数
 	if(p_ts == 0)
 		return -1;
-
-#if 0
 	
 	//关中断
 	rt_irq_save(flags);
 
-	dtrr=g_1s_refence;
-	dtcn=MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP));
-	//得到当前时间
 	tv_sec = g_sys_time.tv_sec;
+
+	temp_virt_cvl_base = (char*)g_gps_map_base + 0x88;
+	temp_virt_irq_base = (char*)g_gps_map_base + 0x04;
+	// read_result = *(volatile u_int32_t*)(temp_virt_cvl_base);
+	tv_nsec = 3000000 - (*(volatile u_int32_t*)(temp_virt_cvl_base));
+
+    if (((*(volatile u_int32_t*)(temp_virt_irq_base)) & (1 << 3)) != 0)
+    {
+        tv_sec += 1;
+		tv_nsec = 3000000 - (*(volatile u_int32_t*)(temp_virt_cvl_base));
+    }
 	
 	//恢复中断级别
 	rt_irq_restore(flags);
 
-	ref = dtrr - 1000000;
-	tv_nsec =  (dtcn - ref)*1000;
-	
-	while(tv_nsec > 1000000000)
-	{
-		tv_sec++;
-		tv_nsec -= 1000000000;
-	}
-	
 	p_ts->tv_sec = tv_sec;
-	p_ts->tv_nsec = tv_nsec;
-#else
-	struct timeval tv;
-	
-	gettimeofday(&tv,NULL);
-	p_ts->tv_sec = tv.tv_sec + 8*60*60;
-    p_ts->tv_nsec = tv.tv_usec * 1000;
+    p_ts->tv_nsec = (tv_nsec / 3) * 1000;
 
-#endif
 	return 0;
 }
 
 int gps_set_time(struct timespec *p_ts)
 {
-//	register long tv_sec,tv_nsec;
-	//uint32_t  flags;
-	
-	//检查参数
-	if(p_ts == 0)
+	unsigned int flags;
+	unsigned long tmp;
+	void *temp_virt_cvl_base, *temp_virt_irq_base;
+
+    if (!p_ts) {
 		return -1;
-	
-	//关中断
-	rt_irq_save(flags);
-	g_sys_time = *p_ts;
+	}
+    
+    rt_irq_save(flags);
+    g_sys_time.tv_nsec = p_ts->tv_nsec;
+    g_sys_time.tv_sec = p_ts->tv_sec;
 
-	//(**1**)
-	g_1s_refence = MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP)) + (1000000000 - p_ts->tv_nsec)/1000;
-	//为了防止边界中断问题,这里让MCF_DTIM_DTCN和MCF_DTIM_DTRR的差值人为加多100us,
-	//加多100us后,会导致定时中断推迟100us的产生,但不影响时间的正确获取.
-	//(**2**)
-	MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence+100;
-	
-	//如果参考中断标志产生,清除中断
-	if (MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP))& MCF_DTIM_DTER_REF)
-	{
-		MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
-	}	
-	//恢复中断级别
-	rt_irq_restore(flags);
+	tmp = 3000000 - ((g_sys_time.tv_nsec / 1000) * 3);
+    if (tmp > 3000000)
+    tmp = 3000000;
+
+	temp_virt_cvl_base = (char*)g_gps_map_base + 0x88;
+	*(volatile u_int32_t*)(temp_virt_cvl_base) = tmp;
+	// ((TIMER_TypeDef *) g_timer_base)->TMR3_CVH_REG = 0x0;
+
+    rt_irq_restore(flags);
 	
 	
 	return 0;
@@ -266,6 +321,24 @@ int gps_reset(void)
 	return 0;
 }
 
+/******************************************************************************
+函数名称:	gps_pulse_isr
+函数版本:	01.01
+创建作者:	ocean
+创建日期:	2023-11-24
+函数说明:	gps脉冲中断
+参数说明:	无
+返回值:  	成功返回0.
+修改记录:
+*/
+void gps_pulse_isr(void *data)
+{
+	unsigned int flags;
+
+    rt_irq_save(flags);
+    g_sys_time.tv_sec++;
+    rt_irq_restore(flags);
+}
 
 /******************************************************************************
 函数名称:	gps_isr
@@ -280,28 +353,17 @@ int gps_reset(void)
 
 void gps_isr(void)
 {
-//	rt_printf("gps_isr\n\r");
-	
-	//毫秒中断
-	if(MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) & MCF_DTIM_DTER_REF)
-	{
-		MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
-		
-		_gps_1s_isr();
-	}
-
-	//捕获中断
-	if(MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) & MCF_DTIM_DTER_CAP)
-	{
-		MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_CAP;
-		timespec_to_rtc(g_sys_time, &tmp_sys_time, 1);
-		_gps_capture_isr();
-		rtc_to_timespec(&tmp_sys_time, &g_sys_time);
-		
-	}
-	
+	void *temp_virt_cvl_base, *temp_virt_irq_base;
+	// clear irq flags
+    if (g_gps_map_base) {
+		temp_virt_irq_base = (char*)g_gps_map_base + 0x04;
+		if (((*(volatile u_int32_t*)(temp_virt_irq_base)) & (1 << 3)) != 0)
+		{
+			gps_pulse_isr(NULL);
+			*(volatile u_int32_t*)(temp_virt_irq_base) = (1 << 3);
+		}
+    }
 	
- 
 }
 
 /*------------------------------ 内部函数 -------------------------------------

+ 1 - 2
app_public/fuxi_public/rt_lite/include/rt.h

@@ -77,8 +77,7 @@ int rt_exit(void);
 //#define rt_printf			printf
 #define sys_newstat 		stat
 
-// #define clk_time_get(ts)	clock_gettime(CLOCK_REALTIME, ts); ((struct timespec*)(ts))->tv_sec += 8*60*60;
-#define clk_time_get(ts)	clock_gettime(CLOCK_REALTIME, ts);
+#define clk_time_get(ts)	gps_get_time(ts)
 
 #define rt_save_flags(x) do{}while(0)
 #define rt_irq_disable() do{}while(0)

+ 8 - 4
app_public/fuxi_public/rt_lite/source/rt_printf.c

@@ -104,14 +104,18 @@ void co_printf(const char *fp,const int line)
 {
 	char sDebug[1024];
 	char *ptr=NULL;
-	CP56_TIME2A	Clock_u;
+	struct timespec ts;
+	struct rtc_time_t pt;
+	// CP56_TIME2A	Clock_u;
 
 	memset(sDebug,'\0',sizeof(sDebug));
 	
-	sys_gettime_CP56(&Clock_u);
+	// sys_gettime_CP56(&Clock_u);
+	gps_get_time(&ts);
+	timespec_to_rtc(ts,&pt,1);
 
-	sprintf(sDebug,"%04d-%02d-%02d %02d:%02d:%02d:%03d ",Clock_u.time_t.year + 2000,Clock_u.time_t.month,
-		   Clock_u.time_t.day,Clock_u.time_t.hour,Clock_u.time_t.min,Clock_u.time_t.ms/1000,Clock_u.time_t.ms%1000);
+	sprintf(sDebug,"%04d-%02d-%02d %02d:%02d:%02d:%03d ",pt.year + 2000,pt.month,
+		   pt.day,pt.hour,pt.min,pt.ms/1000,pt.ms%1000);
 
 	ptr=strrchr(fp,'/');
 

+ 2 - 2
dtu/dtu_main_t536/app/sysTime.c

@@ -56,7 +56,7 @@ int sys_time_set(struct rtc_time_t *pct)
 	system("sync");
 	
 	rt_printf("设置系统时间: %s\n", pchDT);
-	//ret = clk_time_set(&ts);
+	ret = gps_set_time(&ts);
 
 	return ret;
 }
@@ -78,7 +78,7 @@ int sys_time_set_kernal(struct rtc_time_t *pct)
 	system("sync");
 	
 	printf("设置系统时间: %s\n", pchDT);
-	//ret = clk_time_set(&ts);
+	ret = gps_set_time(&ts);
 
 	return ret;	
 }

File diff suppressed because it is too large
+ 349 - 349
dtu/dtu_main_t536/compile_commands.json


BIN
dtu/dtu_main_t536/dtu_t536


BIN
dtu/dtu_main_t536/ko/GuoWang/dtu_t536


+ 2 - 0
dtu/dtu_main_t536/main_mod.c

@@ -279,6 +279,7 @@ int mod_init(void)
 	return -3;
 }
 
+extern void gps_isr(void);
 int di_do_adc (void *unused)
 {
 	pid_t tid;
@@ -377,6 +378,7 @@ int di_do_adc (void *unused)
         }
 
 
+		gps_isr();
 		us1 = origin_ext;
 		flags = 1;
     }

BIN
dtu/dtu_main_t536/main_mod.o


Some files were not shown because too many files changed in this diff