irflt.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #include "asm/includes.h"
  2. #include "asm/irflt.h"
  3. #include "timer.h"
  4. #include "generic/gpio.h"
  5. #define ir_log log_d
  6. //红外定时器定义
  7. #define IR_TIMER TIMER3
  8. #define IR_IRQ_TIME_IDX IRQ_TIME3_IDX
  9. #define IR_TIME_REG JL_TIMER3
  10. #define IR_INTPUTCHANNEL 7
  11. #define IRFLT_INTPUTCHANNEL_SEL(x) SFR(JL_IOMAP->CON1, 4, 3, x)
  12. IR_CODE ir_code; ///<红外遥控信息
  13. static u8 cmp_start = 0;
  14. static const u16 timer_div[] = {
  15. /*0000*/ 1,
  16. /*0001*/ 4,
  17. /*0010*/ 16,
  18. /*0011*/ 64,
  19. /*0100*/ 2,
  20. /*0101*/ 8,
  21. /*0110*/ 32,
  22. /*0111*/ 128,
  23. /*1000*/ 256,
  24. /*1001*/ 4 * 256,
  25. /*1010*/ 16 * 256,
  26. /*1011*/ 64 * 256,
  27. /*1100*/ 2 * 256,
  28. /*1101*/ 8 * 256,
  29. /*1110*/ 32 * 256,
  30. /*1111*/ 128 * 256,
  31. };
  32. /*----------------------------------------------------------------------------*/
  33. /**@brief time1红外中断服务函数
  34. @param void
  35. @param void
  36. @return void
  37. @note void timer1_ir_isr(void)
  38. */
  39. /*----------------------------------------------------------------------------*/
  40. ___interrupt
  41. void timer_ir_isr(void)
  42. {
  43. IR_TIME_REG->CON |= BIT(14);
  44. u16 bCap1 = IR_TIME_REG->PRD;
  45. IR_TIME_REG->CNT = 0;
  46. u8 cap = bCap1 / ir_code.timer_pad;
  47. ir_code.boverflow = 0;
  48. if (cmp_start < 3) {
  49. return;
  50. }
  51. /* putchar('0' + (cap/10)); */
  52. /* putchar('0' + (cap%10)); */
  53. if (cap <= 1) {
  54. ir_code.wData >>= 1;
  55. ir_code.bState++;
  56. } else if (cap == 2) {
  57. ir_code.wData >>= 1;
  58. ir_code.wData |= 0x8000;
  59. ir_code.bState++;
  60. }
  61. if (ir_code.bState == 16) {
  62. ir_code.wUserCode = ir_code.wData;
  63. }
  64. if (ir_code.bState == 33) {
  65. ir_code.bState = 1;
  66. }
  67. }
  68. /*----------------------------------------------------------------------------*/
  69. /**@brief ir按键初始化
  70. @param void
  71. @param void
  72. @return void
  73. @note void set_ir_clk(void)
  74. ((cnt - 1)* 分频数)/lsb_clk = 1ms
  75. */
  76. /*----------------------------------------------------------------------------*/
  77. #define TIMER_UNIT_MS 1
  78. #define MAX_TIME_CNT 0x07ff //分频准确范围,更具实际情况调整
  79. #define MIN_TIME_CNT 0x0030
  80. void set_ir_clk(void)
  81. {
  82. u32 prd_cnt;
  83. u8 index;
  84. u32 app_timer_clk = 24000000;
  85. for (index = 0; index < (sizeof(timer_div) / sizeof(timer_div[0])); index++) {
  86. prd_cnt = TIMER_UNIT_MS * (app_timer_clk / 1000) / timer_div[index];
  87. if (prd_cnt > MIN_TIME_CNT && prd_cnt < MAX_TIME_CNT) {
  88. break;
  89. }
  90. }
  91. ir_code.timer_pad = prd_cnt;
  92. cmp_start = 0;
  93. if (IR_IRQ_TIME_IDX == IRQ_TIME3_IDX) {
  94. bit_clr_ie(IRQ_TIME3_IDX);
  95. }
  96. request_irq(IR_IRQ_TIME_IDX, 3, timer_ir_isr, 0);
  97. IR_TIME_REG->CON = ((6 << 10) | (index << 4) | BIT(2) | BIT(1) | BIT(0));
  98. }
  99. /*----------------------------------------------------------------------------*/
  100. /**@brief 获取ir按键值
  101. @param void
  102. @param void
  103. @return void
  104. @note void get_irkey_value(void)
  105. */
  106. /*----------------------------------------------------------------------------*/
  107. u8 get_irflt_value(void)
  108. {
  109. u8 tkey = 0xff;
  110. if (ir_code.bState != 32) {
  111. return tkey;
  112. }
  113. if ((((u8 *)&ir_code.wData)[0] ^ ((u8 *)&ir_code.wData)[1]) == 0xff) {
  114. tkey = (u8)ir_code.wData;
  115. } else {
  116. ir_code.bState = 0;
  117. }
  118. return tkey;
  119. }
  120. static u8 ir_io_level = 0;
  121. static u8 ir_io = 0;
  122. void ir_input_io_sel(u8 port)
  123. {
  124. ir_io = port;
  125. IRFLT_INTPUTCHANNEL_SEL(IR_INTPUTCHANNEL);
  126. gpio_set_fun_input_port(port, PFI_GP_ICH0 + IR_INTPUTCHANNEL * 4);
  127. gpio_set_direction(port, 1);
  128. gpio_set_die(port, 1);
  129. gpio_set_pull_up(port, 1);
  130. gpio_set_pull_down(port, 0);
  131. }
  132. void ir_output_timer_sel()
  133. {
  134. }
  135. static void ir_timeout(void *priv)
  136. {
  137. ir_code.boverflow++;
  138. if (ir_code.boverflow > 56) { //56*2ms ~= 112ms
  139. ir_code.boverflow = 56;
  140. ir_code.bState = 0;
  141. }
  142. cmp_start ++;
  143. if (cmp_start > 3) {
  144. cmp_start = 3;
  145. }
  146. }
  147. void ir_timeout_set(void)
  148. {
  149. sys_s_hi_timer_add(NULL, ir_timeout, 2); //2ms
  150. }
  151. static u8 ir_io_sus = 0;
  152. u8 ir_io_suspend(void)
  153. {
  154. if (ir_io_sus) {
  155. return 1;
  156. }
  157. if (ir_code.boverflow < 7) { //14ms内,红外接收有可能在忙碌
  158. return 1;
  159. }
  160. ir_io_level = gpio_read(ir_io);
  161. IR_TIME_REG->CON |= BIT(14);
  162. IR_TIME_REG->CON &= ~(0b11 << 0);
  163. ir_io_sus = 1;
  164. return 0;
  165. }
  166. u8 ir_io_resume(void)
  167. {
  168. if (!ir_io_sus) {
  169. return 0;
  170. }
  171. ir_io_sus = 0;
  172. gpio_set_direction(ir_io, 1);
  173. gpio_set_die(ir_io, 1);
  174. gpio_set_pull_up(ir_io, 1);
  175. gpio_set_pull_down(ir_io, 0);
  176. delay(10);
  177. if ((ir_io_level) && (ir_io_level != (gpio_read(ir_io)))) {
  178. ir_code.boverflow = 0;
  179. }
  180. cmp_start = 0;
  181. IR_TIME_REG->CNT = 0;
  182. IR_TIME_REG->CON |= BIT(14);
  183. IR_TIME_REG->CON |= (0b11 << 0);
  184. return 0;
  185. }
  186. void irflt_config()
  187. {
  188. JL_IR->RFLT_CON = 0;
  189. /* JL_IR->RFLT_CON |= BIT(7); //256 div */
  190. /* JL_IR->RFLT_CON |= BIT(3); //osc 24m */
  191. JL_IR->RFLT_CON |= BIT(7) | BIT(4); //512 div
  192. JL_IR->RFLT_CON |= BIT(3) | BIT(2); //PLL_48m(兼容省晶振)
  193. JL_IR->RFLT_CON |= BIT(0); //irflt enable
  194. set_ir_clk();
  195. }
  196. void log_irflt_info()
  197. {
  198. ir_log("IOMC0 = 0x%x", JL_IOMAP->CON0);
  199. ir_log("IOMC1 = 0x%x", JL_IOMAP->CON1);
  200. ir_log("RFLT_CON = 0x%x", JL_IR->RFLT_CON);
  201. ir_log("IR_TIME_REG = 0x%x", IR_TIME_REG->CON);
  202. }