gps.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: rt_gps.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2008-06-04
  7. 功能说明: GPS时钟模块驱动程序。
  8. 其它说明: 1. GPS卫星同步时钟只保证整秒时PR上升沿的精度(一般1us之内),
  9. 其它bit的上升沿精度并不保证。
  10. 2. GPS接收模块只给出秒脉冲和串口数据。
  11. 3. 使用B码对时的时候,B码给的数据中可能包含闰秒(负闰秒:58->0;
  12. 正闰秒:60->0),所以秒的有效数据范围为0~60。但是系统中其它
  13. 计时模块没有闰秒的概念,单独在B码模块使用闰秒有可能造成整个计时
  14. 系统的混乱,所以最终决定将秒的有效数据范围还是限制在0~59,这样
  15. 当正闰秒出现时,系统时间将是:58->59->0->0-1。初步估计,这种影响
  16. 在可接受的范围之内。
  17. 4. 目前在冷火Linux平台上对时误差<8US.(2010-11-23)
  18. 修改记录:
  19. */
  20. /*------------------------------- 头文件 --------------------------------------
  21. */
  22. #include "bspconfig.h"
  23. #include "my_rtc.h"
  24. #include "rt.h"
  25. #include "bsp_ccu.h"
  26. #include "bsp_ustimer.h"
  27. #include "rt_printf.h"
  28. #include "rt_types.h"
  29. #include <sys/mman.h>
  30. /*------------------------------- 宏定义 --------------------------------------
  31. */
  32. #if CFG_BSP_DEBUG
  33. #define _DEBUG_GPS
  34. #endif
  35. #define DTIM_CLOCK_PER_US (CFG_CPU_CLK/2/1000000)
  36. #define GPS_SIGAL_DIFF 1 //GPS信号宽度误差
  37. #define GPS_IRIG_CODE_0 0
  38. #define GPS_IRIG_CODE_1 1
  39. #define GPS_IRIG_CODE_P 2
  40. /*------------------------------ 全局变量 -------------------------------------
  41. */
  42. extern int g_clock_mode;
  43. struct timespec g_sys_time;
  44. static struct rtc_time_t tmp_sys_time;
  45. //毫秒中断的参考值
  46. unsigned int g_1s_refence;
  47. //输入信号是否合法,合法为1,不合法为0
  48. int g_signal_valid;
  49. //GPS对时使用的保活计数值
  50. unsigned int g_keep_alive_gps;
  51. //处理B码的全局变量
  52. unsigned int g_irig_old_value;
  53. unsigned int g_irig_old_interval;
  54. unsigned int g_irig_code_index;
  55. unsigned char g_irig_code[100];
  56. int g_gps_fd = -1;
  57. unsigned g_gps_mapped_size;
  58. void *g_gps_map_base, *g_gps_virt_addr;
  59. /*------------------------------ 函数声明 -------------------------------------
  60. */
  61. int _gps_irig_decode(unsigned char *code,struct rtc_time_t * p_tm );
  62. void _ms_update_time(void);
  63. void _gps_capture_isr(void);
  64. void _gps_1s_isr(void);
  65. void gps_isr(void);
  66. /*------------------------------ 外部函数 -------------------------------------
  67. */
  68. /******************************************************************************
  69. 函数名称: gps_init
  70. 函数版本: 01.01
  71. 创建作者: ocean
  72. 创建日期: 2025-11-21
  73. 函数说明: gps初始化。
  74. 参数说明: 无
  75. 返回值: 成功返回0.
  76. 修改记录:
  77. */
  78. int gps_init(void)
  79. {
  80. struct timespec ts;
  81. struct rtc_time_t ct;
  82. void *temp_ccu_base, *temp_virt_l_base, *temp_virt_h_base, *temp_virt_ctl_base, *temp_virt_irq_base;
  83. unsigned long read_result;
  84. off_t target;
  85. unsigned page_size, offset_in_page;
  86. unsigned width = 8 * sizeof(int);
  87. target = TIMER_BASE;
  88. // 获取页面大小
  89. g_gps_mapped_size = page_size = sysconf(_SC_PAGESIZE);
  90. offset_in_page = (unsigned)target & (page_size - 1);
  91. if (offset_in_page + width > page_size) {
  92. /* This access spans pages.
  93. * Must map two pages to make it possible: */
  94. g_gps_mapped_size *= 2;
  95. }
  96. g_gps_fd = open("/dev/mem", O_RDWR | O_SYNC);
  97. if (g_gps_fd < 0)
  98. {
  99. printf("open(/dev/mem) failed.\n");
  100. return -1;
  101. }
  102. fflush(stdout);
  103. 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));
  104. if (g_gps_map_base == (void *)-1)
  105. {
  106. printf ("NULL pointer!\n");
  107. }
  108. else
  109. {
  110. printf ("BSP gps map Successfull!\n");
  111. }
  112. fflush(stdout);
  113. g_gps_virt_addr = (char*)g_gps_map_base + offset_in_page;
  114. // printf("g_gps_virt_addr: %p %p %x\n", g_gps_virt_addr, g_gps_map_base, offset_in_page);
  115. // Init timer ccu clock
  116. /* set TMR3 clock source to HOSC, 8 pre-division */
  117. temp_ccu_base = g_ccu_map_base + 0x080C;
  118. read_result = *(volatile u_int32_t*)(temp_ccu_base);
  119. read_result &= ~(0x01 << 24);
  120. read_result |= (1 << 31) | 3;
  121. *(volatile u_int32_t*)(temp_ccu_base) = read_result;
  122. // Enable timer3
  123. /* set timer intervalue */
  124. temp_virt_l_base = (char*)g_gps_map_base + 0x84;
  125. temp_virt_h_base = (char*)g_gps_map_base + 0x8C;
  126. *(volatile u_int32_t*)(temp_virt_l_base) = 3000000;
  127. *(volatile u_int32_t*)(temp_virt_h_base) = 0x0;
  128. /* set mode to auto reload */
  129. temp_virt_ctl_base = (char*)g_gps_map_base + 0x80;
  130. read_result = *(volatile u_int32_t*)(temp_virt_ctl_base);
  131. read_result &= TIMER_CTL_PERIODIC;
  132. *(volatile u_int32_t*)(temp_virt_ctl_base) = (read_result | TIMER_CTL_AUTORELOAD | TIMER_CTL_ENABLE);
  133. /* Enable timer interrupt */
  134. temp_virt_irq_base = (char*)g_gps_map_base + 0x00;
  135. read_result = *(volatile u_int32_t*)(temp_virt_irq_base);
  136. *(volatile u_int32_t*)(temp_virt_irq_base) = (read_result | TIMER_IRQ_EN(3));
  137. /* Get linux system current time */
  138. clock_gettime(CLOCK_REALTIME, &ts);
  139. timespec_to_rtc(ts, &ct, 1);
  140. if(ct.hour>=24||ct.min>=60||ct.month>12||ct.day>31||ct.day==0||ct.month==0) // 读取系统时钟错误
  141. {
  142. /* Reset linux system time */
  143. ct.year = 8;
  144. ct.month = 8;
  145. ct.day = 8;
  146. ct.hour = 8;
  147. ct.min = 8;
  148. rtc_to_timespec(&ct, &ts);
  149. rt_printf("gps read system date data error!!!");
  150. }
  151. g_sys_time.tv_sec = ts.tv_sec;
  152. g_sys_time.tv_nsec = ts.tv_nsec;
  153. return 0;
  154. }
  155. int gps_exit(void)
  156. {
  157. unsigned long read_result;
  158. void *temp_virt_ctl_base;
  159. if (g_gps_fd >= 0)
  160. {
  161. close(g_gps_fd);
  162. g_gps_fd = -1;
  163. }
  164. temp_virt_ctl_base = (char*)g_gps_map_base + 0x80;
  165. read_result = *(volatile u_int32_t*)(temp_virt_ctl_base);
  166. read_result &= ~(TIMER_CTL_ENABLE);
  167. *(volatile u_int32_t*)(temp_virt_ctl_base) = (read_result);
  168. if (munmap(g_gps_map_base, g_gps_mapped_size) == -1) {
  169. printf("munmap failed!");
  170. return -1;
  171. }
  172. return 0;
  173. }
  174. int gps_get_time(struct timespec *p_ts)
  175. {
  176. unsigned long flags;
  177. register long tv_sec,tv_nsec;
  178. unsigned long read_result;
  179. void *temp_virt_cvl_base, *temp_virt_irq_base;
  180. //检查参数
  181. if(p_ts == 0)
  182. return -1;
  183. //关中断
  184. rt_irq_save(flags);
  185. tv_sec = g_sys_time.tv_sec;
  186. temp_virt_cvl_base = (char*)g_gps_map_base + 0x88;
  187. temp_virt_irq_base = (char*)g_gps_map_base + 0x04;
  188. // read_result = *(volatile u_int32_t*)(temp_virt_cvl_base);
  189. tv_nsec = 3000000 - (*(volatile u_int32_t*)(temp_virt_cvl_base));
  190. if (((*(volatile u_int32_t*)(temp_virt_irq_base)) & (1 << 3)) != 0)
  191. {
  192. tv_sec += 1;
  193. tv_nsec = 3000000 - (*(volatile u_int32_t*)(temp_virt_cvl_base));
  194. }
  195. //恢复中断级别
  196. rt_irq_restore(flags);
  197. p_ts->tv_sec = tv_sec;
  198. p_ts->tv_nsec = (tv_nsec / 3) * 1000;
  199. return 0;
  200. }
  201. int gps_set_time(struct timespec *p_ts)
  202. {
  203. unsigned int flags;
  204. unsigned long tmp;
  205. void *temp_virt_cvl_base, *temp_virt_irq_base;
  206. if (!p_ts) {
  207. return -1;
  208. }
  209. rt_irq_save(flags);
  210. g_sys_time.tv_nsec = p_ts->tv_nsec;
  211. g_sys_time.tv_sec = p_ts->tv_sec;
  212. tmp = 3000000 - ((g_sys_time.tv_nsec / 1000) * 3);
  213. if (tmp > 3000000)
  214. tmp = 3000000;
  215. temp_virt_cvl_base = (char*)g_gps_map_base + 0x88;
  216. *(volatile u_int32_t*)(temp_virt_cvl_base) = tmp;
  217. // ((TIMER_TypeDef *) g_timer_base)->TMR3_CVH_REG = 0x0;
  218. rt_irq_restore(flags);
  219. return 0;
  220. }
  221. /******************************************************************************
  222. 函数名称: gps_disable
  223. 函数版本: 01.01
  224. 创建作者:
  225. 创建日期: 2014-12-02
  226. 函数说明: 禁止GPS输入功能。
  227. 参数说明: 无
  228. 返回值: 无.
  229. 修改记录:
  230. */
  231. void gps_disable(void)
  232. {
  233. MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) &= ~MCF_DTIM_DTMR_CE_ANY;
  234. }
  235. /******************************************************************************
  236. 函数名称: gps_enable
  237. 函数版本: 01.01
  238. 创建作者:
  239. 创建日期: 2014-12-02
  240. 函数说明: 使能GPS输入功能。
  241. 参数说明: 无
  242. 返回值: 无.
  243. 修改记录:
  244. */
  245. void gps_enable(void)
  246. {
  247. MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) |= MCF_DTIM_DTMR_CE_ANY;
  248. }
  249. /******************************************************************************
  250. 函数名称: gps_reset
  251. 函数版本: 01.01
  252. 创建作者: sunxi
  253. 创建日期: 2008-08-06
  254. 函数说明: gps对时模块复位。
  255. 参数说明: 无
  256. 返回值: 成功返回0.
  257. 修改记录:
  258. */
  259. int gps_reset(void)
  260. {
  261. //全局变量清零
  262. g_signal_valid = 0;
  263. g_keep_alive_gps = 0;
  264. g_irig_old_value = 0;
  265. g_irig_old_interval = 0;
  266. g_irig_code_index = 0;
  267. return 0;
  268. }
  269. /******************************************************************************
  270. 函数名称: gps_pulse_isr
  271. 函数版本: 01.01
  272. 创建作者: ocean
  273. 创建日期: 2023-11-24
  274. 函数说明: gps脉冲中断
  275. 参数说明: 无
  276. 返回值: 成功返回0.
  277. 修改记录:
  278. */
  279. void gps_pulse_isr(void *data)
  280. {
  281. unsigned int flags;
  282. rt_irq_save(flags);
  283. g_sys_time.tv_sec++;
  284. rt_irq_restore(flags);
  285. }
  286. /******************************************************************************
  287. 函数名称: gps_isr
  288. 函数版本: 01.01
  289. 创建作者: sunxi
  290. 创建日期: 2008-08-06
  291. 函数说明: gps中断处理函数。
  292. 参数说明: 无
  293. 返回值: 成功返回0.
  294. 修改记录:
  295. */
  296. void gps_isr(void)
  297. {
  298. void *temp_virt_cvl_base, *temp_virt_irq_base;
  299. // clear irq flags
  300. if (g_gps_map_base) {
  301. temp_virt_irq_base = (char*)g_gps_map_base + 0x04;
  302. if (((*(volatile u_int32_t*)(temp_virt_irq_base)) & (1 << 3)) != 0)
  303. {
  304. gps_pulse_isr(NULL);
  305. *(volatile u_int32_t*)(temp_virt_irq_base) = (1 << 3);
  306. }
  307. }
  308. }
  309. /*------------------------------ 内部函数 -------------------------------------
  310. */
  311. //闰年判断
  312. int _is_leap_year(int year)
  313. {
  314. if ((((year & 0x3) == 0) && (year % 100 != 0)) ||(year % 400 == 0))
  315. return 1;
  316. else
  317. return 0;
  318. }
  319. //日期转换,给出一年中的第几天(从1开始,不是从0开始),算出是这一年的几月几日
  320. int _days_translate(struct rtc_time_t * pt,int year,int day)
  321. {
  322. static int month_last_day[2][13]=
  323. {
  324. {0,31,59,90,120,151,181,212,243,273,304,334,365}, //平年
  325. {0,31,60,91,121,152,182,213,244,274,305,335,366}, //闰年
  326. };
  327. int i;
  328. int *last_day;
  329. if(pt == 0 || day == 0 || day > 366)
  330. return -1;
  331. last_day = month_last_day[_is_leap_year(year)];
  332. for(i=0;i<13;i++)
  333. {
  334. if(day<=last_day[i])
  335. {
  336. break;
  337. }
  338. }
  339. pt->month = (unsigned char)i;
  340. pt->day = (unsigned char)(day-last_day[i-1]);
  341. return 0;
  342. }
  343. int _gps_irig_decode(unsigned char *code,struct rtc_time_t * p_tm )
  344. {
  345. #if 0
  346. int tmp;
  347. //检查P码位置
  348. if( code[0]!=GPS_IRIG_CODE_P
  349. ||code[9]!=GPS_IRIG_CODE_P
  350. ||code[19]!=GPS_IRIG_CODE_P
  351. ||code[29]!=GPS_IRIG_CODE_P
  352. ||code[39]!=GPS_IRIG_CODE_P
  353. ||code[49]!=GPS_IRIG_CODE_P
  354. ||code[59]!=GPS_IRIG_CODE_P
  355. ||code[69]!=GPS_IRIG_CODE_P
  356. ||code[79]!=GPS_IRIG_CODE_P
  357. ||code[89]!=GPS_IRIG_CODE_P)
  358. return -1;
  359. //秒
  360. tmp = ((code[8]<<2)+(code[7]<<1)+code[6])*10
  361. +(code[4]<<3)+(code[3]<<2)+(code[2]<<1)+(code[1]);
  362. if(tmp>=60)
  363. return -2;
  364. p_tm->ms = (unsigned short)(tmp*1000 + p_tm->ms%1000);
  365. //分
  366. tmp = ((code[17]<<2)+(code[16]<<1)+code[15])*10
  367. +(code[13]<<3)+(code[12]<<2)+(code[11]<<1)+(code[10]<<0);
  368. if(tmp>=60)
  369. return -3;
  370. p_tm->min=(unsigned char)tmp;
  371. //时
  372. tmp = ((code[26]<<1)+code[25])*10
  373. +(code[23]<<3)+(code[22]<<GPS_IRIG_CODE_P)+(code[21]<<1)+(code[20]<<0);
  374. if(tmp>=24)
  375. return -4;
  376. p_tm->hour=(unsigned char)tmp;
  377. if(g_clock_mode == CLOCK_MODE_GPS_B_YEAR_NONE)
  378. {
  379. //不带年的B码对时
  380. //日
  381. tmp = ((code[41]<<1)+code[40])*100
  382. +((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10
  383. + (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
  384. if(tmp>366 || tmp == 0)
  385. return -5;
  386. p_tm->year = tmp_sys_time.year;
  387. _days_translate(p_tm,p_tm->year + 2000,tmp);
  388. }
  389. else if(g_clock_mode == CLOCK_MODE_GPS_B_YEAR)
  390. {
  391. //带年的B码对时
  392. //日
  393. tmp=((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10+
  394. (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
  395. if(tmp>31||tmp==0)
  396. return -6;
  397. p_tm->day = (unsigned char)tmp;
  398. //月
  399. tmp=(code[43]<<3)+(code[42]<<2)+(code[41]<<1)+code[40];
  400. if(tmp > 12)
  401. return -7;
  402. p_tm->month = (unsigned char)tmp;
  403. //年
  404. tmp=((code[58]<<3)+(code[57]<<2)+(code[56]<<1)+code[55])*10+
  405. (code[53]<<3)+(code[52]<<2)+(code[51]<<1)+code[50];
  406. p_tm->year = (unsigned short)tmp;
  407. }
  408. else if(g_clock_mode == CLOCK_MODE_GPS_B_2009)
  409. {
  410. //年
  411. tmp=((code[58]<<3)+(code[57]<<2)+(code[56]<<1)+code[55])*10+
  412. (code[53]<<3)+(code[52]<<2)+(code[51]<<1)+code[50];
  413. p_tm->year = (unsigned short)tmp;
  414. //日
  415. tmp = ((code[41]<<1)+code[40])*100
  416. +((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10
  417. + (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
  418. if(tmp>366 || tmp == 0)
  419. return -8;
  420. _days_translate(p_tm,p_tm->year + 2000,tmp);
  421. }
  422. #endif
  423. return 0;
  424. }
  425. void _ms_update_time(void)
  426. {
  427. struct rtc_time_t *pt = &tmp_sys_time;
  428. int day_flag = 0;
  429. if(pt->ms<60000)
  430. return;
  431. pt->ms = 0;
  432. pt->min++;
  433. if(pt->min>=60)
  434. {
  435. pt->min=0;
  436. pt->hour++;
  437. if(pt->hour>=24)
  438. {
  439. pt->hour=0;
  440. pt->day++;
  441. if(pt->month==2)
  442. {
  443. // 2月
  444. if(pt->day>28)
  445. {
  446. if(_is_leap_year(pt->year+2000))
  447. {
  448. //闰年 2月29天?
  449. if(pt->day>29)
  450. {
  451. day_flag=1;
  452. }
  453. }
  454. else
  455. {
  456. //其他28天
  457. day_flag=1;
  458. }
  459. }
  460. }
  461. else
  462. {
  463. //非2月
  464. if(pt->day>30)
  465. {
  466. if(pt->month==4||pt->month==6||pt->month==9||pt->month==11)
  467. {
  468. day_flag=1;
  469. }
  470. }
  471. if(pt->day>31)
  472. {
  473. day_flag=1;
  474. }
  475. }
  476. if(day_flag)
  477. {
  478. pt->day = 1;
  479. pt->month++;
  480. if(pt->month>12)
  481. {
  482. pt->month=1;
  483. pt->year++;
  484. }
  485. }
  486. }
  487. }
  488. }
  489. void _gps_1s_isr(void)
  490. {
  491. //unsigned int now;
  492. //uint32_t flags;
  493. #if 0
  494. if(tmp_sys_time.ms%2 == 0)
  495. {
  496. // DIO_KOUT6_OFF();
  497. }
  498. else
  499. {
  500. // DIO_KOUT6_ON();
  501. }
  502. //计数
  503. tmp_sys_time.ms ++;
  504. //输出对时脉冲(10ms,下降沿)
  505. if((tmp_sys_time.ms%1000) >= 10 )
  506. {
  507. //GPIO_GPS_HIGH();
  508. }
  509. else if(tmp_sys_time.ms%1000 != 0)
  510. {
  511. //GPIO_GPS_LOW();
  512. }
  513. else
  514. {
  515. //tmp_sys_time.ms%1000 == 0的情况
  516. if(g_clock_mode == CLOCK_MODE_EXT || g_clock_mode == CLOCK_MODE_GPS_MINUTE)
  517. {
  518. //当对时模式为外部对时或分对时的时候,在这儿输出下降沿。
  519. //GPIO_GPS_LOW();
  520. }
  521. else if(g_signal_valid == 0)
  522. {
  523. //输入信号不合法,在此输出下降沿
  524. //GPIO_GPS_LOW();
  525. }
  526. }
  527. #endif
  528. rt_irq_save(flags);
  529. g_sys_time.tv_sec++;
  530. g_1s_refence += 1000000;
  531. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  532. rt_irq_restore(flags);
  533. //更新系统时间
  534. //_ms_update_time();
  535. //GPS保活处理
  536. if(g_keep_alive_gps)
  537. {
  538. // 减1s
  539. g_keep_alive_gps -= 1000;
  540. }
  541. return;
  542. }
  543. void _gps_capture_isr(void)
  544. {
  545. #if 0
  546. unsigned int interval,capture_value,n;
  547. //如果不是GPS对时模式,不进行任何处理
  548. // if(g_clock_mode == CLOCK_MODE_EXT)
  549. return;
  550. //得到计数值,并计算和上一次计数器之差,也就是两次中断之间的计数值.
  551. capture_value = MCF_REG32(MCF_DTIM_DTCR(CFG_DTIM_GPS_CAP));
  552. interval = (capture_value - g_irig_old_value + 500L)/1000;
  553. //消除干扰信号
  554. if(interval < 2)
  555. {
  556. rt_printf("gps:interval = %d\r\n",interval);
  557. //干扰信号,直接返回
  558. return;
  559. }
  560. #if 0
  561. if(GPIO_GPS_INT_STATUS())
  562. rt_printf("H:");
  563. else
  564. rt_printf("L:");
  565. rt_printf("%d,%d\r\n",capture_value - g_irig_old_value,capture_value);
  566. goto __ret;
  567. #endif
  568. if(g_clock_mode == CLOCK_MODE_GPS_SECOND)
  569. {
  570. //输入信号不为低电平时不进行逻辑判断。
  571. //注意:目前输入信号经过了两个反相器。
  572. if(GPIO_GPS_INT_STATUS() == 0)
  573. {
  574. goto __ret;
  575. }
  576. //检查输入信号正负脉冲之和是否为1000ms.
  577. n = interval + g_irig_old_interval;
  578. //if( n < 999 || n > 1001)
  579. if( abs(n - 1000) > GPS_SIGAL_DIFF)
  580. { //输入信号不正常,重新搜索秒开始位置
  581. rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
  582. g_signal_valid = 0;
  583. goto __ret;
  584. }
  585. //分板对时下降沿
  586. //GPIO_GPS_LOW();
  587. //修正时间
  588. tmp_sys_time.ms = (unsigned short)((tmp_sys_time.ms+500)/1000*1000);
  589. _ms_update_time();
  590. //修正边沿
  591. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  592. g_1s_refence = capture_value + 1000000;
  593. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  594. //GPS保活
  595. g_keep_alive_gps = CLOCK_ALIVE_GPS;
  596. g_signal_valid = 1;
  597. goto __ret;
  598. }
  599. if(g_clock_mode == CLOCK_MODE_GPS_MINUTE)
  600. {
  601. //输入信号不为低电平时不进行逻辑判断。
  602. //注意:目前输入信号经过了两个反相器。
  603. if(GPIO_GPS_INT_STATUS() == 0)
  604. {
  605. goto __ret;
  606. }
  607. //检查输入信号正负脉冲之和是否为1分钟。
  608. //由于我们使用的晶体是50ppm的,在一分钟之内可能有3ms的误差,
  609. //所以我们以5ms作为指标判断。
  610. n = interval + g_irig_old_interval;
  611. if( n < (60*1000 - 5) || n > (60*1000 + 5))
  612. { //输入信号不正常,重新搜索分开始位置
  613. rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
  614. g_signal_valid = 0;
  615. goto __ret;;
  616. }
  617. //分板对时下降沿
  618. //GPIO_GPS_LOW();
  619. //修正时间
  620. if(tmp_sys_time.ms > 30000)
  621. {
  622. tmp_sys_time.ms = 60000;
  623. _ms_update_time();
  624. }
  625. else
  626. {
  627. tmp_sys_time.ms = 0;
  628. }
  629. //修正边沿
  630. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  631. g_1s_refence = capture_value + 1000000;
  632. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  633. //GPS保活
  634. g_keep_alive_gps = CLOCK_ALIVE_GPS + 60000;
  635. g_signal_valid = 1;
  636. goto __ret;
  637. }
  638. //!!!以下为B码对时
  639. //检查输入信号
  640. if(abs(interval - 2)> GPS_SIGAL_DIFF && abs(interval - 5) > GPS_SIGAL_DIFF && abs(interval - 8) > GPS_SIGAL_DIFF)
  641. {
  642. rt_printf("gps:%d\r\n",interval);
  643. //输入信号不正常,重新搜索秒开始位置
  644. g_signal_valid = 0;
  645. g_irig_code_index = 0;
  646. goto __ret;
  647. }
  648. //输入信号不为低电平时不进行逻辑判断。
  649. //注意:目前输入信号经过了两个反相器。
  650. if(GPIO_GPS_INT_STATUS() == 0)
  651. {
  652. goto __ret;
  653. }
  654. //检查输入信号正负脉冲之和是否为10ms。
  655. if(abs(interval + g_irig_old_interval - 10) > GPS_SIGAL_DIFF)
  656. { //输入信号不正常,重新搜索秒开始位置
  657. rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
  658. g_signal_valid = 0;
  659. g_irig_code_index = 0;
  660. goto __ret;;
  661. }
  662. //如果g_irig_code_index<2,需要搜索秒开始位置
  663. if(g_irig_code_index <2)
  664. {
  665. //如果不是P码,放弃处理,重新搜索。
  666. if(abs(g_irig_old_interval - 8) > GPS_SIGAL_DIFF)
  667. {
  668. g_signal_valid = 0;
  669. g_irig_code_index = 0;
  670. goto __ret;
  671. }
  672. //保存P码
  673. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_P;
  674. if(g_irig_code_index == 1 && g_signal_valid == 1)
  675. {
  676. //分板对时下降沿
  677. //GPIO_GPS_LOW();
  678. //修正时间
  679. tmp_sys_time.ms = (unsigned short)((tmp_sys_time.ms+500)/1000*1000);
  680. _ms_update_time();
  681. //修正边沿
  682. MCF_REG32(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  683. g_1s_refence = capture_value + 1000000;
  684. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  685. }
  686. goto __ret;
  687. }
  688. //保存编码
  689. switch(g_irig_old_interval)
  690. {
  691. case 1:
  692. case 2:
  693. case 3:
  694. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_0;
  695. break;
  696. case 4:
  697. case 5:
  698. case 6:
  699. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_1;
  700. break;
  701. case 7:
  702. case 8:
  703. case 9:
  704. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_P;
  705. break;
  706. default:
  707. rt_printf("gps:g_irig_old_interval=%d!\r\n",g_irig_old_interval);
  708. g_signal_valid = 0;
  709. g_irig_code_index = 0;
  710. goto __ret;
  711. break;
  712. }
  713. //如果接收完时间信息,就开始处理
  714. if(g_irig_code_index >= 100)
  715. {
  716. if(_gps_irig_decode(&g_irig_code[1],&tmp_sys_time) == 0)
  717. {
  718. g_signal_valid = 1;
  719. g_keep_alive_gps = CLOCK_ALIVE_GPS;
  720. }
  721. else
  722. g_signal_valid = 0;
  723. g_irig_code_index = 0;
  724. }
  725. __ret:
  726. g_irig_old_value = capture_value;
  727. g_irig_old_interval = interval;
  728. #endif
  729. }
  730. /*------------------------------ 测试函数 -------------------------------------
  731. */
  732. #ifdef _DEBUG_GPS
  733. #include "ustimer.h"
  734. int gps_test(void)
  735. {
  736. unsigned int us0,t;
  737. rt_printf("gps_test start...\r\n");
  738. // rt_irq_level(0);
  739. t = 0;
  740. us0 = ustimer_get_origin();
  741. // sunxi 20220424 while(1) ;
  742. while(t < 10)
  743. {
  744. // 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);
  745. rt_printf("g_sys_time: %04d-%02d-%02d time: %02d:%02d:%05d!\r\n",
  746. tmp_sys_time.year + 2000,
  747. tmp_sys_time.month,
  748. tmp_sys_time.day,
  749. tmp_sys_time.hour,
  750. tmp_sys_time.min,
  751. tmp_sys_time.ms
  752. );
  753. ustimer_delay_origin(us0,++t*USTIMER_SEC);
  754. }
  755. rt_printf("gps_test end...\r\n");
  756. return 0;
  757. }
  758. #endif