| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916 |
- /******************************************************************************
- 版权所有:
- 文件名称: rt_gps.c
- 文件版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-06-04
- 功能说明: GPS时钟模块驱动程序。
- 其它说明: 1. GPS卫星同步时钟只保证整秒时PR上升沿的精度(一般1us之内),
- 其它bit的上升沿精度并不保证。
- 2. GPS接收模块只给出秒脉冲和串口数据。
- 3. 使用B码对时的时候,B码给的数据中可能包含闰秒(负闰秒:58->0;
- 正闰秒:60->0),所以秒的有效数据范围为0~60。但是系统中其它
- 计时模块没有闰秒的概念,单独在B码模块使用闰秒有可能造成整个计时
- 系统的混乱,所以最终决定将秒的有效数据范围还是限制在0~59,这样
- 当正闰秒出现时,系统时间将是:58->59->0->0-1。初步估计,这种影响
- 在可接受的范围之内。
- 4. 目前在冷火Linux平台上对时误差<8US.(2010-11-23)
- 修改记录:
- */
- /*------------------------------- 头文件 --------------------------------------
- */
- #include "bspconfig.h"
- #include "my_rtc.h"
- #include "rt.h"
- #include "bsp_ccu.h"
- #include "bsp_ustimer.h"
- #include "rt_printf.h"
- #include "rt_types.h"
- #include <sys/mman.h>
- /*------------------------------- 宏定义 --------------------------------------
- */
- #if CFG_BSP_DEBUG
- #define _DEBUG_GPS
- #endif
- #define DTIM_CLOCK_PER_US (CFG_CPU_CLK/2/1000000)
- #define GPS_SIGAL_DIFF 1 //GPS信号宽度误差
- #define GPS_IRIG_CODE_0 0
- #define GPS_IRIG_CODE_1 1
- #define GPS_IRIG_CODE_P 2
- /*------------------------------ 全局变量 -------------------------------------
- */
- extern int g_clock_mode;
- struct timespec g_sys_time;
- static struct rtc_time_t tmp_sys_time;
- //毫秒中断的参考值
- unsigned int g_1s_refence;
- //输入信号是否合法,合法为1,不合法为0
- int g_signal_valid;
- //GPS对时使用的保活计数值
- unsigned int g_keep_alive_gps;
- //处理B码的全局变量
- unsigned int g_irig_old_value;
- unsigned int g_irig_old_interval;
- 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;
- /*------------------------------ 函数声明 -------------------------------------
- */
- int _gps_irig_decode(unsigned char *code,struct rtc_time_t * p_tm );
- void _ms_update_time(void);
- void _gps_capture_isr(void);
- void _gps_1s_isr(void);
- void gps_isr(void);
- /*------------------------------ 外部函数 -------------------------------------
- */
- /******************************************************************************
- 函数名称: gps_init
- 函数版本: 01.01
- 创建作者: ocean
- 创建日期: 2025-11-21
- 函数说明: gps初始化。
- 参数说明: 无
- 返回值: 成功返回0.
- 修改记录:
- */
- int gps_init(void)
- {
- 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_gps_virt_addr: %p %p %x\n", g_gps_virt_addr, g_gps_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)
- {
- 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;
- }
- int gps_get_time(struct timespec *p_ts)
- {
- 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;
-
- //关中断
- rt_irq_save(flags);
- 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);
- p_ts->tv_sec = tv_sec;
- p_ts->tv_nsec = (tv_nsec / 3) * 1000;
- return 0;
- }
- int gps_set_time(struct timespec *p_ts)
- {
- 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.tv_nsec = p_ts->tv_nsec;
- g_sys_time.tv_sec = p_ts->tv_sec;
- 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;
-
- }
- /******************************************************************************
- 函数名称: gps_disable
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2014-12-02
- 函数说明: 禁止GPS输入功能。
- 参数说明: 无
- 返回值: 无.
- 修改记录:
- */
- void gps_disable(void)
- {
- MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) &= ~MCF_DTIM_DTMR_CE_ANY;
- }
- /******************************************************************************
- 函数名称: gps_enable
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2014-12-02
- 函数说明: 使能GPS输入功能。
- 参数说明: 无
- 返回值: 无.
- 修改记录:
- */
- void gps_enable(void)
- {
- MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) |= MCF_DTIM_DTMR_CE_ANY;
- }
- /******************************************************************************
- 函数名称: gps_reset
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-06
- 函数说明: gps对时模块复位。
- 参数说明: 无
- 返回值: 成功返回0.
- 修改记录:
- */
- int gps_reset(void)
- {
- //全局变量清零
- g_signal_valid = 0;
- g_keep_alive_gps = 0;
- g_irig_old_value = 0;
- g_irig_old_interval = 0;
- g_irig_code_index = 0;
-
- 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
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-06
- 函数说明: gps中断处理函数。
- 参数说明: 无
- 返回值: 成功返回0.
- 修改记录:
- */
- void gps_isr(void)
- {
- 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);
- }
- }
-
- }
- /*------------------------------ 内部函数 -------------------------------------
- */
- //闰年判断
- int _is_leap_year(int year)
- {
- if ((((year & 0x3) == 0) && (year % 100 != 0)) ||(year % 400 == 0))
- return 1;
- else
- return 0;
- }
- //日期转换,给出一年中的第几天(从1开始,不是从0开始),算出是这一年的几月几日
- int _days_translate(struct rtc_time_t * pt,int year,int day)
- {
- static int month_last_day[2][13]=
- {
- {0,31,59,90,120,151,181,212,243,273,304,334,365}, //平年
- {0,31,60,91,121,152,182,213,244,274,305,335,366}, //闰年
- };
- int i;
- int *last_day;
-
- if(pt == 0 || day == 0 || day > 366)
- return -1;
-
- last_day = month_last_day[_is_leap_year(year)];
-
- for(i=0;i<13;i++)
- {
- if(day<=last_day[i])
- {
- break;
- }
- }
-
- pt->month = (unsigned char)i;
- pt->day = (unsigned char)(day-last_day[i-1]);
-
- return 0;
- }
- int _gps_irig_decode(unsigned char *code,struct rtc_time_t * p_tm )
- {
- #if 0
- int tmp;
- //检查P码位置
- if( code[0]!=GPS_IRIG_CODE_P
- ||code[9]!=GPS_IRIG_CODE_P
- ||code[19]!=GPS_IRIG_CODE_P
- ||code[29]!=GPS_IRIG_CODE_P
- ||code[39]!=GPS_IRIG_CODE_P
- ||code[49]!=GPS_IRIG_CODE_P
- ||code[59]!=GPS_IRIG_CODE_P
- ||code[69]!=GPS_IRIG_CODE_P
- ||code[79]!=GPS_IRIG_CODE_P
- ||code[89]!=GPS_IRIG_CODE_P)
- return -1;
-
- //秒
- tmp = ((code[8]<<2)+(code[7]<<1)+code[6])*10
- +(code[4]<<3)+(code[3]<<2)+(code[2]<<1)+(code[1]);
- if(tmp>=60)
- return -2;
- p_tm->ms = (unsigned short)(tmp*1000 + p_tm->ms%1000);
-
- //分
- tmp = ((code[17]<<2)+(code[16]<<1)+code[15])*10
- +(code[13]<<3)+(code[12]<<2)+(code[11]<<1)+(code[10]<<0);
- if(tmp>=60)
- return -3;
- p_tm->min=(unsigned char)tmp;
-
- //时
- tmp = ((code[26]<<1)+code[25])*10
- +(code[23]<<3)+(code[22]<<GPS_IRIG_CODE_P)+(code[21]<<1)+(code[20]<<0);
- if(tmp>=24)
- return -4;
- p_tm->hour=(unsigned char)tmp;
- if(g_clock_mode == CLOCK_MODE_GPS_B_YEAR_NONE)
- {
- //不带年的B码对时
- //日
- tmp = ((code[41]<<1)+code[40])*100
- +((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10
- + (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
- if(tmp>366 || tmp == 0)
- return -5;
-
- p_tm->year = tmp_sys_time.year;
- _days_translate(p_tm,p_tm->year + 2000,tmp);
- }
- else if(g_clock_mode == CLOCK_MODE_GPS_B_YEAR)
- {
- //带年的B码对时
- //日
- tmp=((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10+
- (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
- if(tmp>31||tmp==0)
- return -6;
- p_tm->day = (unsigned char)tmp;
-
- //月
- tmp=(code[43]<<3)+(code[42]<<2)+(code[41]<<1)+code[40];
- if(tmp > 12)
- return -7;
- p_tm->month = (unsigned char)tmp;
-
- //年
- tmp=((code[58]<<3)+(code[57]<<2)+(code[56]<<1)+code[55])*10+
- (code[53]<<3)+(code[52]<<2)+(code[51]<<1)+code[50];
- p_tm->year = (unsigned short)tmp;
- }
- else if(g_clock_mode == CLOCK_MODE_GPS_B_2009)
- {
- //年
- tmp=((code[58]<<3)+(code[57]<<2)+(code[56]<<1)+code[55])*10+
- (code[53]<<3)+(code[52]<<2)+(code[51]<<1)+code[50];
- p_tm->year = (unsigned short)tmp;
-
- //日
- tmp = ((code[41]<<1)+code[40])*100
- +((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10
- + (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
- if(tmp>366 || tmp == 0)
- return -8;
-
- _days_translate(p_tm,p_tm->year + 2000,tmp);
-
- }
-
- #endif
- return 0;
- }
- void _ms_update_time(void)
- {
- struct rtc_time_t *pt = &tmp_sys_time;
- int day_flag = 0;
-
- if(pt->ms<60000)
- return;
- pt->ms = 0;
- pt->min++;
- if(pt->min>=60)
- {
- pt->min=0;
- pt->hour++;
- if(pt->hour>=24)
- {
- pt->hour=0;
- pt->day++;
- if(pt->month==2)
- {
- // 2月
- if(pt->day>28)
- {
- if(_is_leap_year(pt->year+2000))
- {
- //闰年 2月29天?
- if(pt->day>29)
- {
- day_flag=1;
- }
- }
- else
- {
- //其他28天
- day_flag=1;
- }
- }
- }
- else
- {
- //非2月
- if(pt->day>30)
- {
- if(pt->month==4||pt->month==6||pt->month==9||pt->month==11)
- {
- day_flag=1;
- }
- }
- if(pt->day>31)
- {
- day_flag=1;
- }
- }
-
- if(day_flag)
- {
- pt->day = 1;
- pt->month++;
- if(pt->month>12)
- {
- pt->month=1;
- pt->year++;
- }
- }
- }
- }
- }
- void _gps_1s_isr(void)
- {
- //unsigned int now;
- //uint32_t flags;
- #if 0
- if(tmp_sys_time.ms%2 == 0)
- {
- // DIO_KOUT6_OFF();
- }
- else
- {
- // DIO_KOUT6_ON();
- }
-
- //计数
- tmp_sys_time.ms ++;
- //输出对时脉冲(10ms,下降沿)
- if((tmp_sys_time.ms%1000) >= 10 )
- {
- //GPIO_GPS_HIGH();
- }
- else if(tmp_sys_time.ms%1000 != 0)
- {
- //GPIO_GPS_LOW();
- }
-
- else
- {
- //tmp_sys_time.ms%1000 == 0的情况
- if(g_clock_mode == CLOCK_MODE_EXT || g_clock_mode == CLOCK_MODE_GPS_MINUTE)
- {
- //当对时模式为外部对时或分对时的时候,在这儿输出下降沿。
- //GPIO_GPS_LOW();
- }
- else if(g_signal_valid == 0)
- {
- //输入信号不合法,在此输出下降沿
- //GPIO_GPS_LOW();
- }
- }
- #endif
- rt_irq_save(flags);
-
- g_sys_time.tv_sec++;
- g_1s_refence += 1000000;
- MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
-
- rt_irq_restore(flags);
-
- //更新系统时间
- //_ms_update_time();
-
- //GPS保活处理
- if(g_keep_alive_gps)
- {
- // 减1s
- g_keep_alive_gps -= 1000;
- }
-
- return;
- }
- void _gps_capture_isr(void)
- {
- #if 0
- unsigned int interval,capture_value,n;
-
- //如果不是GPS对时模式,不进行任何处理
- // if(g_clock_mode == CLOCK_MODE_EXT)
- return;
-
- //得到计数值,并计算和上一次计数器之差,也就是两次中断之间的计数值.
- capture_value = MCF_REG32(MCF_DTIM_DTCR(CFG_DTIM_GPS_CAP));
- interval = (capture_value - g_irig_old_value + 500L)/1000;
-
- //消除干扰信号
- if(interval < 2)
- {
- rt_printf("gps:interval = %d\r\n",interval);
-
- //干扰信号,直接返回
- return;
- }
-
- #if 0
- if(GPIO_GPS_INT_STATUS())
- rt_printf("H:");
- else
- rt_printf("L:");
- rt_printf("%d,%d\r\n",capture_value - g_irig_old_value,capture_value);
- goto __ret;
- #endif
- if(g_clock_mode == CLOCK_MODE_GPS_SECOND)
- {
- //输入信号不为低电平时不进行逻辑判断。
- //注意:目前输入信号经过了两个反相器。
- if(GPIO_GPS_INT_STATUS() == 0)
- {
- goto __ret;
- }
-
- //检查输入信号正负脉冲之和是否为1000ms.
- n = interval + g_irig_old_interval;
- //if( n < 999 || n > 1001)
- if( abs(n - 1000) > GPS_SIGAL_DIFF)
- { //输入信号不正常,重新搜索秒开始位置
- rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
-
- g_signal_valid = 0;
- goto __ret;
- }
-
- //分板对时下降沿
- //GPIO_GPS_LOW();
-
- //修正时间
- tmp_sys_time.ms = (unsigned short)((tmp_sys_time.ms+500)/1000*1000);
- _ms_update_time();
- //修正边沿
- MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
- g_1s_refence = capture_value + 1000000;
- MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
-
- //GPS保活
- g_keep_alive_gps = CLOCK_ALIVE_GPS;
-
- g_signal_valid = 1;
-
- goto __ret;
-
- }
-
- if(g_clock_mode == CLOCK_MODE_GPS_MINUTE)
- {
- //输入信号不为低电平时不进行逻辑判断。
- //注意:目前输入信号经过了两个反相器。
- if(GPIO_GPS_INT_STATUS() == 0)
- {
- goto __ret;
- }
-
- //检查输入信号正负脉冲之和是否为1分钟。
- //由于我们使用的晶体是50ppm的,在一分钟之内可能有3ms的误差,
- //所以我们以5ms作为指标判断。
- n = interval + g_irig_old_interval;
- if( n < (60*1000 - 5) || n > (60*1000 + 5))
- { //输入信号不正常,重新搜索分开始位置
- rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
-
- g_signal_valid = 0;
- goto __ret;;
- }
-
- //分板对时下降沿
- //GPIO_GPS_LOW();
-
- //修正时间
- if(tmp_sys_time.ms > 30000)
- {
- tmp_sys_time.ms = 60000;
- _ms_update_time();
- }
- else
- {
- tmp_sys_time.ms = 0;
- }
-
- //修正边沿
- MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
- g_1s_refence = capture_value + 1000000;
- MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
-
- //GPS保活
- g_keep_alive_gps = CLOCK_ALIVE_GPS + 60000;
- g_signal_valid = 1;
- goto __ret;
- }
-
- //!!!以下为B码对时
- //检查输入信号
- if(abs(interval - 2)> GPS_SIGAL_DIFF && abs(interval - 5) > GPS_SIGAL_DIFF && abs(interval - 8) > GPS_SIGAL_DIFF)
- {
- rt_printf("gps:%d\r\n",interval);
-
- //输入信号不正常,重新搜索秒开始位置
- g_signal_valid = 0;
- g_irig_code_index = 0;
- goto __ret;
-
- }
-
- //输入信号不为低电平时不进行逻辑判断。
- //注意:目前输入信号经过了两个反相器。
- if(GPIO_GPS_INT_STATUS() == 0)
- {
- goto __ret;
- }
-
- //检查输入信号正负脉冲之和是否为10ms。
- if(abs(interval + g_irig_old_interval - 10) > GPS_SIGAL_DIFF)
- { //输入信号不正常,重新搜索秒开始位置
- rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
-
- g_signal_valid = 0;
- g_irig_code_index = 0;
- goto __ret;;
- }
- //如果g_irig_code_index<2,需要搜索秒开始位置
- if(g_irig_code_index <2)
- {
- //如果不是P码,放弃处理,重新搜索。
- if(abs(g_irig_old_interval - 8) > GPS_SIGAL_DIFF)
- {
- g_signal_valid = 0;
- g_irig_code_index = 0;
-
- goto __ret;
- }
-
- //保存P码
- g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_P;
-
-
- if(g_irig_code_index == 1 && g_signal_valid == 1)
- {
- //分板对时下降沿
- //GPIO_GPS_LOW();
-
- //修正时间
- tmp_sys_time.ms = (unsigned short)((tmp_sys_time.ms+500)/1000*1000);
- _ms_update_time();
-
- //修正边沿
- MCF_REG32(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
- g_1s_refence = capture_value + 1000000;
- MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
- }
- goto __ret;
- }
-
- //保存编码
- switch(g_irig_old_interval)
- {
- case 1:
- case 2:
- case 3:
- g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_0;
- break;
- case 4:
- case 5:
- case 6:
- g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_1;
- break;
- case 7:
- case 8:
- case 9:
- g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_P;
- break;
-
- default:
- rt_printf("gps:g_irig_old_interval=%d!\r\n",g_irig_old_interval);
-
- g_signal_valid = 0;
- g_irig_code_index = 0;
- goto __ret;
- break;
- }
-
- //如果接收完时间信息,就开始处理
- if(g_irig_code_index >= 100)
- {
- if(_gps_irig_decode(&g_irig_code[1],&tmp_sys_time) == 0)
- {
- g_signal_valid = 1;
- g_keep_alive_gps = CLOCK_ALIVE_GPS;
- }
- else
- g_signal_valid = 0;
-
- g_irig_code_index = 0;
- }
- __ret:
- g_irig_old_value = capture_value;
- g_irig_old_interval = interval;
- #endif
- }
- /*------------------------------ 测试函数 -------------------------------------
- */
- #ifdef _DEBUG_GPS
- #include "ustimer.h"
- int gps_test(void)
- {
- unsigned int us0,t;
-
- rt_printf("gps_test start...\r\n");
-
- // rt_irq_level(0);
-
- t = 0;
- us0 = ustimer_get_origin();
- // sunxi 20220424 while(1) ;
- while(t < 10)
- {
- // rt_printf("pit(t=%03dsec):g_gps_ms:%06d,diff(g_gps_ms-t*1000):%d!\r\n",t,g_gps_ms,g_gps_ms -t*1000);
- rt_printf("g_sys_time: %04d-%02d-%02d time: %02d:%02d:%05d!\r\n",
- tmp_sys_time.year + 2000,
- tmp_sys_time.month,
- tmp_sys_time.day,
- tmp_sys_time.hour,
- tmp_sys_time.min,
- tmp_sys_time.ms
- );
-
- ustimer_delay_origin(us0,++t*USTIMER_SEC);
- }
-
- rt_printf("gps_test end...\r\n");
-
- return 0;
- }
- #endif
|