gps.c 23 KB

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