gps.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  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. // sunxi 20220408 #include "mcf5441x_gpio.h"
  26. //#include "linux/math64.h"
  27. /*------------------------------- 宏定义 --------------------------------------
  28. */
  29. #if CFG_BSP_DEBUG
  30. #define _DEBUG_GPS
  31. #endif
  32. #define DTIM_CLOCK_PER_US (CFG_CPU_CLK/2/1000000)
  33. #define GPS_SIGAL_DIFF 1 //GPS信号宽度误差
  34. #define GPS_IRIG_CODE_0 0
  35. #define GPS_IRIG_CODE_1 1
  36. #define GPS_IRIG_CODE_P 2
  37. /*------------------------------ 全局变量 -------------------------------------
  38. */
  39. extern int g_clock_mode;
  40. struct timespec g_sys_time;
  41. static struct rtc_time_t tmp_sys_time;
  42. //毫秒中断的参考值
  43. unsigned int g_1s_refence;
  44. //输入信号是否合法,合法为1,不合法为0
  45. int g_signal_valid;
  46. //GPS对时使用的保活计数值
  47. unsigned int g_keep_alive_gps;
  48. //处理B码的全局变量
  49. unsigned int g_irig_old_value;
  50. unsigned int g_irig_old_interval;
  51. unsigned int g_irig_code_index;
  52. unsigned char g_irig_code[100];
  53. /*------------------------------ 函数声明 -------------------------------------
  54. */
  55. int _gps_irig_decode(unsigned char *code,struct rtc_time_t * p_tm );
  56. void _ms_update_time(void);
  57. void _gps_capture_isr(void);
  58. void _gps_1s_isr(void);
  59. void gps_isr(void);
  60. /*------------------------------ 外部函数 -------------------------------------
  61. */
  62. /******************************************************************************
  63. 函数名称: gps_init
  64. 函数版本: 01.01
  65. 创建作者: sunxi
  66. 创建日期: 2008-08-06
  67. 函数说明: gps初始化。
  68. 参数说明: 无
  69. 返回值: 成功返回0.
  70. 修改记录:
  71. */
  72. int gps_init(void)
  73. {
  74. //设置GPIO
  75. //GPIO_GPS_INT_INIT(); //对时输入
  76. //GPIO_GPS_INIT(); //对时输出
  77. //以下设置输入捕获定时器
  78. //设置DTIM扩展模式寄存器。
  79. MCF_REG08(MCF_DTIM_DTXMR(CFG_DTIM_GPS_CAP)) = 0;
  80. //设置DTIM模式寄存器。定时器时钟源为1M,所以定时器分辨率为1us。
  81. //32位计数值的计数周期为4294.967296s(大于1.1小时),
  82. MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) = (unsigned short)(0
  83. | MCF_DTIM_DTMR_RST //允许定时器
  84. | MCF_DTIM_DTMR_CLK_DIV1 //输入clock除1
  85. // | MCF_DTIM_DTMR_FRR //自由运行模式(free run)
  86. | MCF_DTIM_DTMR_ORRI //当参考计数值到达后,产生DMA或中断
  87. // | MCF_DTIM_DTMR_OM //输出模式为低脉冲模式
  88. // | MCF_DTIM_DTMR_CE_ANY //上升沿和下降沿都捕获
  89. | MCF_DTIM_DTMR_PS(DTIM_CLOCK_PER_US - 1));//将定时器clock周期设为1us。
  90. //不清零,因为内核中使用了该定时器
  91. //清除计数值
  92. //MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP)) = 0;
  93. //清除中断
  94. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_CAP | MCF_DTIM_DTER_REF;
  95. //申请实时中断
  96. rt_request_irq(CFG_DTIM_VECTOR_BEGIN + CFG_DTIM_GPS_CAP,CFG_INT_LEVEL_CLOCK,gps_isr,"gps_isr_cap");
  97. //设置参考值
  98. g_1s_refence = MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP)) + 1000000;
  99. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  100. return 0;
  101. }
  102. int gps_exit(void)
  103. {
  104. // MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) = 0; //和内核ustimer共用定时器,不能关闭
  105. rt_free_irq(CFG_DTIM_VECTOR_BEGIN + CFG_DTIM_GPS_CAP);
  106. return 0;
  107. }
  108. int gps_get_time(struct timespec *p_ts)
  109. {
  110. //register long tv_sec,tv_nsec;
  111. //uint32_t flags;
  112. //unsigned int dtcn,dtrr,ref;
  113. //检查参数
  114. if(p_ts == 0)
  115. return -1;
  116. #if 0
  117. //关中断
  118. rt_irq_save(flags);
  119. dtrr=g_1s_refence;
  120. dtcn=MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP));
  121. //得到当前时间
  122. tv_sec = g_sys_time.tv_sec;
  123. //恢复中断级别
  124. rt_irq_restore(flags);
  125. ref = dtrr - 1000000;
  126. tv_nsec = (dtcn - ref)*1000;
  127. while(tv_nsec > 1000000000)
  128. {
  129. tv_sec++;
  130. tv_nsec -= 1000000000;
  131. }
  132. p_ts->tv_sec = tv_sec;
  133. p_ts->tv_nsec = tv_nsec;
  134. #else
  135. struct timeval tv;
  136. gettimeofday(&tv,NULL);
  137. p_ts->tv_sec = tv.tv_sec + 8*60*60;
  138. p_ts->tv_nsec = tv.tv_usec * 1000;
  139. #endif
  140. return 0;
  141. }
  142. int gps_set_time(struct timespec *p_ts)
  143. {
  144. // register long tv_sec,tv_nsec;
  145. //uint32_t flags;
  146. //检查参数
  147. if(p_ts == 0)
  148. return -1;
  149. //关中断
  150. rt_irq_save(flags);
  151. g_sys_time = *p_ts;
  152. //(**1**)
  153. g_1s_refence = MCF_REG32(MCF_DTIM_DTCN(CFG_DTIM_GPS_CAP)) + (1000000000 - p_ts->tv_nsec)/1000;
  154. //为了防止边界中断问题,这里让MCF_DTIM_DTCN和MCF_DTIM_DTRR的差值人为加多100us,
  155. //加多100us后,会导致定时中断推迟100us的产生,但不影响时间的正确获取.
  156. //(**2**)
  157. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence+100;
  158. //如果参考中断标志产生,清除中断
  159. if (MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP))& MCF_DTIM_DTER_REF)
  160. {
  161. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  162. }
  163. //恢复中断级别
  164. rt_irq_restore(flags);
  165. return 0;
  166. }
  167. /******************************************************************************
  168. 函数名称: gps_disable
  169. 函数版本: 01.01
  170. 创建作者:
  171. 创建日期: 2014-12-02
  172. 函数说明: 禁止GPS输入功能。
  173. 参数说明: 无
  174. 返回值: 无.
  175. 修改记录:
  176. */
  177. void gps_disable(void)
  178. {
  179. MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) &= ~MCF_DTIM_DTMR_CE_ANY;
  180. }
  181. /******************************************************************************
  182. 函数名称: gps_enable
  183. 函数版本: 01.01
  184. 创建作者:
  185. 创建日期: 2014-12-02
  186. 函数说明: 使能GPS输入功能。
  187. 参数说明: 无
  188. 返回值: 无.
  189. 修改记录:
  190. */
  191. void gps_enable(void)
  192. {
  193. MCF_REG16(MCF_DTIM_DTMR(CFG_DTIM_GPS_CAP)) |= MCF_DTIM_DTMR_CE_ANY;
  194. }
  195. /******************************************************************************
  196. 函数名称: gps_reset
  197. 函数版本: 01.01
  198. 创建作者: sunxi
  199. 创建日期: 2008-08-06
  200. 函数说明: gps对时模块复位。
  201. 参数说明: 无
  202. 返回值: 成功返回0.
  203. 修改记录:
  204. */
  205. int gps_reset(void)
  206. {
  207. //全局变量清零
  208. g_signal_valid = 0;
  209. g_keep_alive_gps = 0;
  210. g_irig_old_value = 0;
  211. g_irig_old_interval = 0;
  212. g_irig_code_index = 0;
  213. return 0;
  214. }
  215. /******************************************************************************
  216. 函数名称: gps_isr
  217. 函数版本: 01.01
  218. 创建作者: sunxi
  219. 创建日期: 2008-08-06
  220. 函数说明: gps中断处理函数。
  221. 参数说明: 无
  222. 返回值: 成功返回0.
  223. 修改记录:
  224. */
  225. void gps_isr(void)
  226. {
  227. // rt_printf("gps_isr\n\r");
  228. //毫秒中断
  229. if(MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) & MCF_DTIM_DTER_REF)
  230. {
  231. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  232. _gps_1s_isr();
  233. }
  234. //捕获中断
  235. if(MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) & MCF_DTIM_DTER_CAP)
  236. {
  237. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_CAP;
  238. timespec_to_rtc(g_sys_time, &tmp_sys_time, 1);
  239. _gps_capture_isr();
  240. rtc_to_timespec(&tmp_sys_time, &g_sys_time);
  241. }
  242. }
  243. /*------------------------------ 内部函数 -------------------------------------
  244. */
  245. //闰年判断
  246. int _is_leap_year(int year)
  247. {
  248. if ((((year & 0x3) == 0) && (year % 100 != 0)) ||(year % 400 == 0))
  249. return 1;
  250. else
  251. return 0;
  252. }
  253. //日期转换,给出一年中的第几天(从1开始,不是从0开始),算出是这一年的几月几日
  254. int _days_translate(struct rtc_time_t * pt,int year,int day)
  255. {
  256. static int month_last_day[2][13]=
  257. {
  258. {0,31,59,90,120,151,181,212,243,273,304,334,365}, //平年
  259. {0,31,60,91,121,152,182,213,244,274,305,335,366}, //闰年
  260. };
  261. int i;
  262. int *last_day;
  263. if(pt == 0 || day == 0 || day > 366)
  264. return -1;
  265. last_day = month_last_day[_is_leap_year(year)];
  266. for(i=0;i<13;i++)
  267. {
  268. if(day<=last_day[i])
  269. {
  270. break;
  271. }
  272. }
  273. pt->month = (unsigned char)i;
  274. pt->day = (unsigned char)(day-last_day[i-1]);
  275. return 0;
  276. }
  277. int _gps_irig_decode(unsigned char *code,struct rtc_time_t * p_tm )
  278. {
  279. #if 0
  280. int tmp;
  281. //检查P码位置
  282. if( code[0]!=GPS_IRIG_CODE_P
  283. ||code[9]!=GPS_IRIG_CODE_P
  284. ||code[19]!=GPS_IRIG_CODE_P
  285. ||code[29]!=GPS_IRIG_CODE_P
  286. ||code[39]!=GPS_IRIG_CODE_P
  287. ||code[49]!=GPS_IRIG_CODE_P
  288. ||code[59]!=GPS_IRIG_CODE_P
  289. ||code[69]!=GPS_IRIG_CODE_P
  290. ||code[79]!=GPS_IRIG_CODE_P
  291. ||code[89]!=GPS_IRIG_CODE_P)
  292. return -1;
  293. //秒
  294. tmp = ((code[8]<<2)+(code[7]<<1)+code[6])*10
  295. +(code[4]<<3)+(code[3]<<2)+(code[2]<<1)+(code[1]);
  296. if(tmp>=60)
  297. return -2;
  298. p_tm->ms = (unsigned short)(tmp*1000 + p_tm->ms%1000);
  299. //分
  300. tmp = ((code[17]<<2)+(code[16]<<1)+code[15])*10
  301. +(code[13]<<3)+(code[12]<<2)+(code[11]<<1)+(code[10]<<0);
  302. if(tmp>=60)
  303. return -3;
  304. p_tm->min=(unsigned char)tmp;
  305. //时
  306. tmp = ((code[26]<<1)+code[25])*10
  307. +(code[23]<<3)+(code[22]<<GPS_IRIG_CODE_P)+(code[21]<<1)+(code[20]<<0);
  308. if(tmp>=24)
  309. return -4;
  310. p_tm->hour=(unsigned char)tmp;
  311. if(g_clock_mode == CLOCK_MODE_GPS_B_YEAR_NONE)
  312. {
  313. //不带年的B码对时
  314. //日
  315. tmp = ((code[41]<<1)+code[40])*100
  316. +((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10
  317. + (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
  318. if(tmp>366 || tmp == 0)
  319. return -5;
  320. p_tm->year = tmp_sys_time.year;
  321. _days_translate(p_tm,p_tm->year + 2000,tmp);
  322. }
  323. else if(g_clock_mode == CLOCK_MODE_GPS_B_YEAR)
  324. {
  325. //带年的B码对时
  326. //日
  327. tmp=((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10+
  328. (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
  329. if(tmp>31||tmp==0)
  330. return -6;
  331. p_tm->day = (unsigned char)tmp;
  332. //月
  333. tmp=(code[43]<<3)+(code[42]<<2)+(code[41]<<1)+code[40];
  334. if(tmp > 12)
  335. return -7;
  336. p_tm->month = (unsigned char)tmp;
  337. //年
  338. tmp=((code[58]<<3)+(code[57]<<2)+(code[56]<<1)+code[55])*10+
  339. (code[53]<<3)+(code[52]<<2)+(code[51]<<1)+code[50];
  340. p_tm->year = (unsigned short)tmp;
  341. }
  342. else if(g_clock_mode == CLOCK_MODE_GPS_B_2009)
  343. {
  344. //年
  345. tmp=((code[58]<<3)+(code[57]<<2)+(code[56]<<1)+code[55])*10+
  346. (code[53]<<3)+(code[52]<<2)+(code[51]<<1)+code[50];
  347. p_tm->year = (unsigned short)tmp;
  348. //日
  349. tmp = ((code[41]<<1)+code[40])*100
  350. +((code[38]<<3)+(code[37]<<2)+(code[36]<<1)+code[35])*10
  351. + (code[33]<<3)+(code[32]<<2)+(code[31]<<1)+code[30];
  352. if(tmp>366 || tmp == 0)
  353. return -8;
  354. _days_translate(p_tm,p_tm->year + 2000,tmp);
  355. }
  356. #endif
  357. return 0;
  358. }
  359. void _ms_update_time(void)
  360. {
  361. struct rtc_time_t *pt = &tmp_sys_time;
  362. int day_flag = 0;
  363. if(pt->ms<60000)
  364. return;
  365. pt->ms = 0;
  366. pt->min++;
  367. if(pt->min>=60)
  368. {
  369. pt->min=0;
  370. pt->hour++;
  371. if(pt->hour>=24)
  372. {
  373. pt->hour=0;
  374. pt->day++;
  375. if(pt->month==2)
  376. {
  377. // 2月
  378. if(pt->day>28)
  379. {
  380. if(_is_leap_year(pt->year+2000))
  381. {
  382. //闰年 2月29天?
  383. if(pt->day>29)
  384. {
  385. day_flag=1;
  386. }
  387. }
  388. else
  389. {
  390. //其他28天
  391. day_flag=1;
  392. }
  393. }
  394. }
  395. else
  396. {
  397. //非2月
  398. if(pt->day>30)
  399. {
  400. if(pt->month==4||pt->month==6||pt->month==9||pt->month==11)
  401. {
  402. day_flag=1;
  403. }
  404. }
  405. if(pt->day>31)
  406. {
  407. day_flag=1;
  408. }
  409. }
  410. if(day_flag)
  411. {
  412. pt->day = 1;
  413. pt->month++;
  414. if(pt->month>12)
  415. {
  416. pt->month=1;
  417. pt->year++;
  418. }
  419. }
  420. }
  421. }
  422. }
  423. void _gps_1s_isr(void)
  424. {
  425. //unsigned int now;
  426. //uint32_t flags;
  427. #if 0
  428. if(tmp_sys_time.ms%2 == 0)
  429. {
  430. // DIO_KOUT6_OFF();
  431. }
  432. else
  433. {
  434. // DIO_KOUT6_ON();
  435. }
  436. //计数
  437. tmp_sys_time.ms ++;
  438. //输出对时脉冲(10ms,下降沿)
  439. if((tmp_sys_time.ms%1000) >= 10 )
  440. {
  441. //GPIO_GPS_HIGH();
  442. }
  443. else if(tmp_sys_time.ms%1000 != 0)
  444. {
  445. //GPIO_GPS_LOW();
  446. }
  447. else
  448. {
  449. //tmp_sys_time.ms%1000 == 0的情况
  450. if(g_clock_mode == CLOCK_MODE_EXT || g_clock_mode == CLOCK_MODE_GPS_MINUTE)
  451. {
  452. //当对时模式为外部对时或分对时的时候,在这儿输出下降沿。
  453. //GPIO_GPS_LOW();
  454. }
  455. else if(g_signal_valid == 0)
  456. {
  457. //输入信号不合法,在此输出下降沿
  458. //GPIO_GPS_LOW();
  459. }
  460. }
  461. #endif
  462. rt_irq_save(flags);
  463. g_sys_time.tv_sec++;
  464. g_1s_refence += 1000000;
  465. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  466. rt_irq_restore(flags);
  467. //更新系统时间
  468. //_ms_update_time();
  469. //GPS保活处理
  470. if(g_keep_alive_gps)
  471. {
  472. // 减1s
  473. g_keep_alive_gps -= 1000;
  474. }
  475. return;
  476. }
  477. void _gps_capture_isr(void)
  478. {
  479. #if 0
  480. unsigned int interval,capture_value,n;
  481. //如果不是GPS对时模式,不进行任何处理
  482. // if(g_clock_mode == CLOCK_MODE_EXT)
  483. return;
  484. //得到计数值,并计算和上一次计数器之差,也就是两次中断之间的计数值.
  485. capture_value = MCF_REG32(MCF_DTIM_DTCR(CFG_DTIM_GPS_CAP));
  486. interval = (capture_value - g_irig_old_value + 500L)/1000;
  487. //消除干扰信号
  488. if(interval < 2)
  489. {
  490. rt_printf("gps:interval = %d\r\n",interval);
  491. //干扰信号,直接返回
  492. return;
  493. }
  494. #if 0
  495. if(GPIO_GPS_INT_STATUS())
  496. rt_printf("H:");
  497. else
  498. rt_printf("L:");
  499. rt_printf("%d,%d\r\n",capture_value - g_irig_old_value,capture_value);
  500. goto __ret;
  501. #endif
  502. if(g_clock_mode == CLOCK_MODE_GPS_SECOND)
  503. {
  504. //输入信号不为低电平时不进行逻辑判断。
  505. //注意:目前输入信号经过了两个反相器。
  506. if(GPIO_GPS_INT_STATUS() == 0)
  507. {
  508. goto __ret;
  509. }
  510. //检查输入信号正负脉冲之和是否为1000ms.
  511. n = interval + g_irig_old_interval;
  512. //if( n < 999 || n > 1001)
  513. if( abs(n - 1000) > GPS_SIGAL_DIFF)
  514. { //输入信号不正常,重新搜索秒开始位置
  515. rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
  516. g_signal_valid = 0;
  517. goto __ret;
  518. }
  519. //分板对时下降沿
  520. //GPIO_GPS_LOW();
  521. //修正时间
  522. tmp_sys_time.ms = (unsigned short)((tmp_sys_time.ms+500)/1000*1000);
  523. _ms_update_time();
  524. //修正边沿
  525. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  526. g_1s_refence = capture_value + 1000000;
  527. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  528. //GPS保活
  529. g_keep_alive_gps = CLOCK_ALIVE_GPS;
  530. g_signal_valid = 1;
  531. goto __ret;
  532. }
  533. if(g_clock_mode == CLOCK_MODE_GPS_MINUTE)
  534. {
  535. //输入信号不为低电平时不进行逻辑判断。
  536. //注意:目前输入信号经过了两个反相器。
  537. if(GPIO_GPS_INT_STATUS() == 0)
  538. {
  539. goto __ret;
  540. }
  541. //检查输入信号正负脉冲之和是否为1分钟。
  542. //由于我们使用的晶体是50ppm的,在一分钟之内可能有3ms的误差,
  543. //所以我们以5ms作为指标判断。
  544. n = interval + g_irig_old_interval;
  545. if( n < (60*1000 - 5) || n > (60*1000 + 5))
  546. { //输入信号不正常,重新搜索分开始位置
  547. rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
  548. g_signal_valid = 0;
  549. goto __ret;;
  550. }
  551. //分板对时下降沿
  552. //GPIO_GPS_LOW();
  553. //修正时间
  554. if(tmp_sys_time.ms > 30000)
  555. {
  556. tmp_sys_time.ms = 60000;
  557. _ms_update_time();
  558. }
  559. else
  560. {
  561. tmp_sys_time.ms = 0;
  562. }
  563. //修正边沿
  564. MCF_REG08(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  565. g_1s_refence = capture_value + 1000000;
  566. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  567. //GPS保活
  568. g_keep_alive_gps = CLOCK_ALIVE_GPS + 60000;
  569. g_signal_valid = 1;
  570. goto __ret;
  571. }
  572. //!!!以下为B码对时
  573. //检查输入信号
  574. if(abs(interval - 2)> GPS_SIGAL_DIFF && abs(interval - 5) > GPS_SIGAL_DIFF && abs(interval - 8) > GPS_SIGAL_DIFF)
  575. {
  576. rt_printf("gps:%d\r\n",interval);
  577. //输入信号不正常,重新搜索秒开始位置
  578. g_signal_valid = 0;
  579. g_irig_code_index = 0;
  580. goto __ret;
  581. }
  582. //输入信号不为低电平时不进行逻辑判断。
  583. //注意:目前输入信号经过了两个反相器。
  584. if(GPIO_GPS_INT_STATUS() == 0)
  585. {
  586. goto __ret;
  587. }
  588. //检查输入信号正负脉冲之和是否为10ms。
  589. if(abs(interval + g_irig_old_interval - 10) > GPS_SIGAL_DIFF)
  590. { //输入信号不正常,重新搜索秒开始位置
  591. rt_printf("gps:%d,%d\r\n",interval,g_irig_old_interval);
  592. g_signal_valid = 0;
  593. g_irig_code_index = 0;
  594. goto __ret;;
  595. }
  596. //如果g_irig_code_index<2,需要搜索秒开始位置
  597. if(g_irig_code_index <2)
  598. {
  599. //如果不是P码,放弃处理,重新搜索。
  600. if(abs(g_irig_old_interval - 8) > GPS_SIGAL_DIFF)
  601. {
  602. g_signal_valid = 0;
  603. g_irig_code_index = 0;
  604. goto __ret;
  605. }
  606. //保存P码
  607. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_P;
  608. if(g_irig_code_index == 1 && g_signal_valid == 1)
  609. {
  610. //分板对时下降沿
  611. //GPIO_GPS_LOW();
  612. //修正时间
  613. tmp_sys_time.ms = (unsigned short)((tmp_sys_time.ms+500)/1000*1000);
  614. _ms_update_time();
  615. //修正边沿
  616. MCF_REG32(MCF_DTIM_DTER(CFG_DTIM_GPS_CAP)) = MCF_DTIM_DTER_REF;
  617. g_1s_refence = capture_value + 1000000;
  618. MCF_REG32(MCF_DTIM_DTRR(CFG_DTIM_GPS_CAP)) = g_1s_refence;
  619. }
  620. goto __ret;
  621. }
  622. //保存编码
  623. switch(g_irig_old_interval)
  624. {
  625. case 1:
  626. case 2:
  627. case 3:
  628. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_0;
  629. break;
  630. case 4:
  631. case 5:
  632. case 6:
  633. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_1;
  634. break;
  635. case 7:
  636. case 8:
  637. case 9:
  638. g_irig_code[g_irig_code_index++] = GPS_IRIG_CODE_P;
  639. break;
  640. default:
  641. rt_printf("gps:g_irig_old_interval=%d!\r\n",g_irig_old_interval);
  642. g_signal_valid = 0;
  643. g_irig_code_index = 0;
  644. goto __ret;
  645. break;
  646. }
  647. //如果接收完时间信息,就开始处理
  648. if(g_irig_code_index >= 100)
  649. {
  650. if(_gps_irig_decode(&g_irig_code[1],&tmp_sys_time) == 0)
  651. {
  652. g_signal_valid = 1;
  653. g_keep_alive_gps = CLOCK_ALIVE_GPS;
  654. }
  655. else
  656. g_signal_valid = 0;
  657. g_irig_code_index = 0;
  658. }
  659. __ret:
  660. g_irig_old_value = capture_value;
  661. g_irig_old_interval = interval;
  662. #endif
  663. }
  664. /*------------------------------ 测试函数 -------------------------------------
  665. */
  666. #ifdef _DEBUG_GPS
  667. #include "ustimer.h"
  668. int gps_test(void)
  669. {
  670. unsigned int us0,t;
  671. rt_printf("gps_test start...\r\n");
  672. // rt_irq_level(0);
  673. t = 0;
  674. us0 = ustimer_get_origin();
  675. // sunxi 20220424 while(1) ;
  676. while(t < 10)
  677. {
  678. // 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);
  679. rt_printf("g_sys_time: %04d-%02d-%02d time: %02d:%02d:%05d!\r\n",
  680. tmp_sys_time.year + 2000,
  681. tmp_sys_time.month,
  682. tmp_sys_time.day,
  683. tmp_sys_time.hour,
  684. tmp_sys_time.min,
  685. tmp_sys_time.ms
  686. );
  687. ustimer_delay_origin(us0,++t*USTIMER_SEC);
  688. }
  689. rt_printf("gps_test end...\r\n");
  690. return 0;
  691. }
  692. #endif