pit.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: pit.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2008-06-25
  7. 功能说明: 可编程中断定时器程序。
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "bsp.h"
  14. #include "rt.h"
  15. #include "head.h"
  16. /*------------------------------- 宏定义 --------------------------------------
  17. */
  18. /*------------------------------ 全局变量 -------------------------------------
  19. */
  20. unsigned int g_count_156us;
  21. FN_PIT_CALLBACK g_pit_callback_5ms;
  22. FN_PIT_CALLBACK g_pit_callback_156us;
  23. struct rt_stat g_stat_156us;
  24. struct rt_stat g_stat_5ms;
  25. void pit_156us_isr(void);
  26. void pit_5ms_isr(void);
  27. //void pit_250us_isr(void); // sunxi 20190425 added
  28. int pit_500us_isr(int irq, void *data);
  29. /*------------------------------ 外部函数 -------------------------------------
  30. */
  31. /******************************************************************************
  32. 函数名称: pit_init
  33. 函数版本: 01.01
  34. 创建作者: sunxi
  35. 创建日期: 2008-06-25
  36. 函数说明: pit初始化。目前使用PIT0产生1ms中断。
  37. 参数说明: 无
  38. 返回值: 无
  39. 修改记录:
  40. */
  41. int pit_init(void)
  42. {
  43. #if 0
  44. //PIT3,采样中断
  45. // 允许ADC时钟(PIT3 CD35)
  46. MCF_PMM_PPMCR0 = CFG_PIT_CD_BEGIN + CFG_PIT_SAMPLE;
  47. //设置控制寄存器
  48. MCF_PIT3_PCSR = 0
  49. | MCF_PIT_PCSR_EN //允许
  50. | MCF_PIT_PCSR_RLD //自动重装
  51. | MCF_PIT_PCSR_PIF //清除中断标志
  52. | MCF_PIT_PCSR_PIE //允许中断
  53. // | MCF_PIT_PCSR_OVW //允许重写
  54. | MCF_PIT_PCSR_PRE(0); //分频值为1,使用CFG_SYSTEM_CLOCK_KHZ/2频率。
  55. //设置定时周期。
  56. MCF_PIT3_PMR = (unsigned short)(PIT_PERIOD_156US - 1); //一分频下必须再减一(十六分频下不需要)
  57. // 申请实时中断
  58. rt_request_irq(CFG_PIT_VECTOR_BEGIN+CFG_PIT_SAMPLE,CFG_INT_LEVEL_PIT,pit_156us_isr,"pit_156us_isr");
  59. //PIT2,5MS中断
  60. // 允许ADC时钟(PIT2 CD34)
  61. MCF_PMM_PPMCR0 = CFG_PIT_CD_BEGIN + CFG_PIT_5MS;
  62. //设置控制寄存器
  63. MCF_PIT2_PCSR = 0
  64. | MCF_PIT_PCSR_EN //允许
  65. | MCF_PIT_PCSR_RLD //自动重装
  66. | MCF_PIT_PCSR_PIF //清除中断标志
  67. | MCF_PIT_PCSR_PIE //允许中断
  68. // | MCF_PIT_PCSR_OVW //允许重写
  69. | MCF_PIT_PCSR_PRE(4); //分频值为16,使用CFG_SYSTEM_CLOCK_KHZ/2/16频率。
  70. //设置定时周期。
  71. MCF_PIT2_PMR = (unsigned short)(PIT_PERIOD_5MS);
  72. // 申请实时中断
  73. rt_request_irq(CFG_PIT_VECTOR_BEGIN+CFG_PIT_5MS,CFG_INT_LEVEL_5MS,pit_5ms_isr,"pit_5ms_isr");
  74. pit_stat_reset();
  75. #endif
  76. return 0;
  77. }
  78. int pit_exit(void)
  79. {
  80. rt_free_irq(CFG_PIT_VECTOR_BEGIN+CFG_PIT_5MS); // 释放5ms中断
  81. rt_free_irq(CFG_PIT_VECTOR_BEGIN+CFG_PIT_SAMPLE); // 释放156us中断
  82. return 0;
  83. }
  84. /******************************************************************************
  85. 函数名称: pit_regester_callback
  86. 函数版本: 01.01
  87. 创建作者: sunxi
  88. 创建日期: 2011-04-22
  89. 函数说明: 登记PIT的定时回调函数。
  90. 参数说明:
  91. period_us: 定时周期,以us为单位。
  92. fn: 回调函数。
  93. 返回值: 成功返回0,失败返回负数。
  94. 修改记录:
  95. */
  96. int pit_regester_callback(int period_us,FN_PIT_CALLBACK fn)
  97. {
  98. switch(period_us)
  99. {
  100. case 5000:
  101. g_pit_callback_5ms = fn;
  102. break;
  103. case 156:
  104. g_pit_callback_156us = fn;
  105. break;
  106. default:
  107. return -1;
  108. }
  109. return 0;
  110. }
  111. /******************************************************************************
  112. 函数名称: pit_156us_period_set
  113. 函数版本: 01.01
  114. 创建作者: sunxi
  115. 创建日期: 2012-12-05
  116. 函数说明: 通过测得的线路频率,修改采样周期。
  117. 参数说明:
  118. hz: 通过测频电路测得的线路频率。Q16定点数。
  119. 返回值: 成功返回0,失败返回负数。
  120. 修改记录:
  121. */
  122. int pit_156us_period_set(float hz)
  123. {
  124. unsigned short pmr;
  125. hz *= CFG_ADC_DOTS_PER_PERIOD*4;// 128点采样
  126. // 根据公式计算pmr。
  127. pmr = (unsigned short)rt_round((CFG_CPU_CLK/2)/hz);
  128. pmr -= 2;
  129. //设置定时周期。
  130. // MCF_PIT3_PMR = pmr;
  131. //rt_printf("pit_156us_period:hz=%s,pmr=0x%04x\r\n",q16_to_str(hz/128),pmr);
  132. return 0;
  133. }
  134. /******************************************************************************
  135. 函数名称: pit_5ms_isr
  136. 函数版本: 01.01
  137. 创建作者: sunxi
  138. 创建日期: 2008-06-25
  139. 函数说明: pit0中断服务程序。
  140. 参数说明: 无
  141. 返回值: 无
  142. 修改记录:
  143. */
  144. void pit_5ms_isr(void)
  145. {
  146. // 统计中断延时
  147. // rt_stat_in(&g_stat_5ms,(uint32_t)(PIT_PERIOD_5MS - MCF_PIT2_PCNTR));
  148. // 先清除中断
  149. // MCF_PIT2_PCSR |= MCF_PIT_PCSR_PIF;
  150. //5ms主回调函数
  151. if(g_pit_callback_5ms)
  152. {
  153. g_pit_callback_5ms(0);
  154. }
  155. //软件狗喂狗
  156. watchdog_feed_protect();
  157. }
  158. /******************************************************************************
  159. 函数名称: pit_156us_isr
  160. 函数版本: 01.01
  161. 创建作者: sunxi
  162. 创建日期: 2011-04-22
  163. 函数说明: pit1中断服务程序。
  164. 参数说明: 无
  165. 返回值: 无
  166. 修改记录:
  167. */
  168. //extern struct rt_irq_node g_rt_irq_list[RT_IRQS_NUM];
  169. void dido_soe_gen(void);
  170. void pit_156us_isr(void)
  171. {
  172. #if 0
  173. int mod;
  174. uint32_t count;
  175. uint32_t us0;
  176. count = (uint32_t)(MCF_PIT3_PMR - MCF_PIT3_PCNTR);
  177. rt_stat_in(&g_stat_156us,count);
  178. us0 = ustimer_get_origin();
  179. // 先清除中断。
  180. MCF_PIT3_PCSR |= MCF_PIT_PCSR_PIF;
  181. //根据g_count_156us统一计算mod和is625us,保证两者的同步。
  182. mod = (int)(g_count_156us &0x03);
  183. // is625us = (mod == 0x03) ? 1:0;
  184. //调用ADC中断处理函数
  185. adc_isr(mod);
  186. // SOE发生器
  187. dido_soe_gen();
  188. // 遥信扫描
  189. dido_di_poll();
  190. //回调156us应用处理函数
  191. if (g_pit_callback_156us != NULL)
  192. {
  193. g_pit_callback_156us(mod);
  194. }
  195. //计数器加一。
  196. g_count_156us++;
  197. // 喂ADC看门狗
  198. watchdog_feed_adc();
  199. // 由于针对采样中断的入口进行了优化,所以将时间统计放在这儿。
  200. rt_stat_in(&g_rt_irq_list[CFG_PIT_VECTOR_BEGIN+3].stat,ustimer_get_duration(us0));
  201. #endif
  202. }
  203. int pit_stat_reset(void)
  204. {
  205. rt_stat_init(&g_stat_156us,"pit_156us_isr(8ns)");
  206. rt_stat_init(&g_stat_5ms,"pit_5ms_isr(128ns)");
  207. return 0;
  208. }
  209. int pit_stat_printf(void)
  210. {
  211. rt_printf("\r\n[实时中断延时统计(单位:见各行)]\r\n");
  212. rt_stat_printf(&g_stat_156us);
  213. rt_stat_printf(&g_stat_5ms);
  214. return 0;
  215. }
  216. int pit_500us_isr(int irq, void *data)
  217. {
  218. // 清除中断标志
  219. //MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF;
  220. //goose_timer_handle();
  221. return 0;
  222. }
  223. /*------------------------------ 测试函数 -------------------------------------
  224. */
  225. //#ifdef CFG_BSP_DEBUG
  226. #if 0
  227. #include "ustimer.h"
  228. int pit_test(void)
  229. {
  230. uint32_t t,t0;
  231. t=0;
  232. t0 = ustimer_get_origin();
  233. sti(0);
  234. while(1)
  235. {
  236. rt_printf("pit(t=%04d):5ms:%06d,156us:%08d,[156us-t*6400:%d],[5ms-t*200:%d]!\r\n",
  237. t,
  238. g_count_5ms,
  239. g_count_156us,
  240. g_count_156us -t*6400,
  241. g_count_5ms -t*200);
  242. watchdog_feed_software_5s();
  243. t++;
  244. ustimer_delay_origin(t0,t*USTIMER_SEC);
  245. }
  246. }
  247. #endif
  248. /*------------------------------ 文件结束 -------------------------------------
  249. */