driver_irtx.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /**
  2. ******************************************************************************************************************************
  3. *
  4. *@file driver_irtx.c
  5. *
  6. *@brief Source file for IR tx driver
  7. *
  8. *Copyright (c) 2023, BLUETRUM
  9. ******************************************************************************************************************************
  10. **/
  11. #include "driver_ir.h"
  12. #include "driver_gpio.h"
  13. #include "macro.h"
  14. void ir_clk_init(uint8_t clksel)
  15. {
  16. // irrx/irrx clock config
  17. if ((IR_CLK_OSC32K == clksel) || (IR_CLK_X24M32K == clksel) || (IR_CLK_X24MDIV == clksel)) {
  18. XOSCCON |= BIT(10); //XOSC24M enable
  19. CLKCON4 &= ~BIT(26); //xoscrc24m_sel chose XOSC24M
  20. clk_gate1_cmd(CLK_GATE1_X24M, CLK_EN); //XOSC24M gate open
  21. if (IR_CLK_OSC32K == clksel) {
  22. CLKCON1 &= ~BIT(17); // k32_tscsel chose osc32k_p(CLK32K_RTC)
  23. RTCCON0 |= (BIT(2)); // RTC output clock to core enable
  24. RTCCON0 &= ~(BIT(19)); // osc core disable
  25. RTCCON0 = (RTCCON0 & ~(3 << 8)) | (3 << 8); // CLK32K_RTC source select x24mdiv12_rtc(x24m_clkdiv12)
  26. CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (3 << 13); // clkout sel, osc32k
  27. } else if (IR_CLK_X24M32K == clksel) {
  28. CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (2 << 13); // clkout sel, x24m_32K
  29. } else if (IR_CLK_X24MDIV == clksel) {
  30. CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (1 << 13); // clkout sel, x24mdiv unvisible,we can check xosc24m
  31. }
  32. } else if (IR_CLK_RC32K == clksel) {
  33. CLKCON0 |= BIT(0); //RC2M enable
  34. CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (7 << 13); // clkout sel, rc32k unvisible,we can check rc2m
  35. }
  36. //irrx clock select
  37. CLKCON1 = (CLKCON1 & ~(3 << 4)) | (clksel << 4); // 0:x24m_32k 1:x24m_div_clk 2:osc32k 3:rc32k_clk
  38. }
  39. void irtx_clk_init (uint8_t clksel)
  40. {
  41. ir_clk_init(clksel);
  42. clk_gate1_cmd(CLK_GATE1_IRTX, CLK_EN);
  43. clk_gate2_cmd(CLK_GATE2_IRFLT, CLK_EN);
  44. }
  45. /*
  46. * timing[0] : one [31:16]mark m1 [15:0]space s1
  47. * timing[1] : zeor [31:16]mark m0 [15:0]space s0
  48. * timing[2] : start [31:16]1 t1 [15:0]0 t0
  49. * timing[3] : repteat [31:16]1 r1 [15:0]0 r0
  50. * timing[4] : IRREPEATCON rt et sy rm
  51. * timing[5] : IRTXCON o z
  52. * timing[6] : IRTXLEN l
  53. */
  54. const IRTX_timingTypeDef Nec = IRTX_TIMING_NEC;
  55. const IRTX_timingTypeDef Tc9012 = IRTX_TIMING_TC9012;
  56. const IRTX_timingTypeDef Rc5 = IRTX_TIMING_RC5;
  57. const IRTX_timingTypeDef Rc6 = IRTX_TIMING_RC6;
  58. void irtx_timing_set(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param, const IRTX_timingTypeDef timing)
  59. {
  60. double prescale;
  61. volatile u32 timing_prescale;
  62. timing_prescale = ir_timing_freq_get(irtx_param->clk_sel);
  63. prescale = ((double)timing_prescale/1000000);
  64. irtx_reg->con = BIT(8) * timing.em |
  65. BIT(5) * timing.o |
  66. BIT(4) * timing.z |
  67. BIT(0);
  68. irtx_reg->otime = BIT(16) * (uint16_t)(timing.m1 * prescale) |
  69. BIT(0) * (uint16_t)(timing.s1 * prescale);
  70. irtx_reg->ztime = BIT(16) * (uint16_t)(timing.m0 * prescale) |
  71. BIT(0) * (uint16_t)(timing.s0 * prescale);
  72. irtx_reg->stime = BIT(16) * (uint16_t)(timing.t1 * prescale) |
  73. BIT(0) * (uint16_t)(timing.t0 * prescale);
  74. irtx_reg->rtime = BIT(16) * (uint16_t)(timing.r1 * prescale) |
  75. BIT(0) * (uint16_t)(timing.r0 * prescale);
  76. irtx_reg->rctrl = BIT(13) * (uint32_t)(timing.rt * prescale) |
  77. BIT(3) * (uint16_t)(timing.et * prescale) |
  78. BIT(2) * timing.sy |
  79. BIT(1) * timing.rm;
  80. irtx_reg->txlen = timing.l;
  81. }
  82. void irtx_timing_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  83. {
  84. switch(irtx_param->encode_format)
  85. {
  86. case IRTX_ENCODE_FORMAT_NEC:
  87. irtx_timing_set(irtx_reg, irtx_param, Nec);
  88. break;
  89. case IRTX_ENCODE_FORMAT_TC9012:
  90. irtx_timing_set(irtx_reg, irtx_param, Tc9012);
  91. break;
  92. case IRTX_ENCODE_FORMAT_RC5:
  93. irtx_timing_set(irtx_reg, irtx_param, Rc5);
  94. break;
  95. case IRTX_ENCODE_FORMAT_RC6:
  96. irtx_timing_set(irtx_reg, irtx_param, Rc6);
  97. break;
  98. default:
  99. break;
  100. }
  101. }
  102. //edge set 0 to choose fall edge
  103. void irtx_capture_edge (irtx_typedef *irtx_reg, uint32_t edge)
  104. {
  105. if (edge) {
  106. SETF_REG_IRTXCON_IREDGE_SEL();
  107. }else {
  108. CLRF_REG_IRTXCON_IREDGE_SEL();
  109. }
  110. }
  111. void irtx_carrier_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  112. {
  113. if (irtx_param->carrier_config.mod_clksel == IRTX_MODE_CLKSEL_3M) {
  114. CLKCON1 &= ~BIT(9);//1:4m 0:3m
  115. } else {
  116. CLKCON1 |= BIT(9);//1:4m 0:3m
  117. }
  118. if (irtx_param->carrier_config.carrier_en) {
  119. SETF_REG_IRTXCON_IRTX_CARRIER_EN();
  120. SET_REG_IRTXCON_IRCW_LENGTH(irtx_param->carrier_config.ircw_length);
  121. SET_REG_IRTXCON_IRCW_DUTY(irtx_param->carrier_config.ircw_duty);
  122. }else {
  123. CLRF_REG_IRTXCON_IRTX_CARRIER_EN();
  124. }
  125. }
  126. void irtx_dma_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  127. {
  128. if (irtx_param->dma_config.rdma_mode == IRTX_DMA_MODE_16BIT) {
  129. SETF_REG_IRDMACON_IR_RDMA_MODE();
  130. } else {
  131. CLRF_REG_IRDMACON_IR_RDMA_MODE();
  132. }
  133. if (irtx_param->dma_config.wdma_mode == IRTX_DMA_MODE_16BIT) {
  134. SETF_REG_IRDMACON_IR_WDMA_MODE();
  135. } else {
  136. CLRF_REG_IRDMACON_IR_WDMA_MODE();
  137. }
  138. }
  139. void irtx_data_set (irtx_typedef *irtx_reg, uint32_t code)
  140. {
  141. irtx_reg->txdata = code;
  142. }
  143. void irtx_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  144. {
  145. irtx_data_set(irtx_reg, irtx_param->tx_data);
  146. irtx_carrier_init(irtx_reg, irtx_param);
  147. if (IRTX_SYNC_OR_TRAILER_CODE_1 == irtx_param->sync_code) {
  148. SETF_REG_IRREPEATCON_IRTX_SYC();
  149. }else {
  150. CLRF_REG_IRREPEATCON_IRTX_SYC();
  151. }
  152. }
  153. void irtx_set_repeat(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  154. {
  155. if (IRTX_KEY_PRESSED == irtx_param->key) {
  156. SETF_REG_IRREPEATCON_IRTX_KEY();
  157. }else {
  158. CLRF_REG_IRREPEATCON_IRTX_KEY();
  159. }
  160. }
  161. void irfilter_set(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  162. {
  163. if (IRTX_FILTER_ENABLE == irtx_param->filter_config.filter_en) {
  164. SETF_REG_IRFLTCON_IRFLT_EN();
  165. SET_REG_IRFLTCON_IRFLT_LEN(irtx_param->filter_config.filter_len);
  166. } else {
  167. CLRF_REG_IRFLTCON_IRFLT_EN();
  168. }
  169. }
  170. //KICK
  171. inline void irtx_kick_do (void)
  172. {
  173. SETF_REG_IRTXCON_IRTX_KST();
  174. }
  175. inline void irtx_wait(void)
  176. {
  177. while (!GETF_REG_IRTXPEND_IRTX_PND());
  178. SETF_REG_IRTXPEND_IRTX_PND();
  179. }
  180. void irtx_kick_wait(void)
  181. {
  182. irtx_kick_do();
  183. irtx_wait();
  184. }
  185. //CAPTURE DMA
  186. void irtx_capture_dma_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
  187. {
  188. irtx_reg->dma_oadr = (uint32_t)buf;
  189. irtx_reg->dma_osize = len - 1;
  190. SETF_REG_IRDMACON_IR_WDMA_EN();
  191. SETF_REG_IRDMACON_IR_WDMA_MODE();
  192. //SETF_REG_IRDMACON_IR_WDMA_APND_IE();
  193. }
  194. void irtx_capture_dma_kick(irtx_typedef *irtx_reg)
  195. {
  196. SETF_REG_IRTXCON_IR_CAPEN();
  197. }
  198. void irtx_learn_dma_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
  199. {
  200. irtx_reg->dma_iadr = (uint32_t)buf;
  201. irtx_reg->dma_isize = len - 1;
  202. }
  203. void irtx_learn_kick(irtx_typedef *irtx_reg)
  204. {
  205. //SETF_REG_IRTXCON_IRTXLEN_EN();
  206. SETF_REG_IRTXCON_IRTX_KST();
  207. }
  208. inline void irtx_set_invert(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  209. {
  210. if (IRTX_INVERT_OUTPUT_ENABLE == irtx_param->invert_en) {
  211. SETF_REG_IRTXCON_IRTX_INV();
  212. }else {
  213. CLRF_REG_IRTXCON_IRTX_INV();
  214. }
  215. }
  216. /**
  217. * @brief Set the clock,and clock/rx io init.Set irrx register.
  218. * @param irrx_reg: irrx register address
  219. * @param irrx_param: irrx params,include wakup_en/clock/int_en/data_format.
  220. * @retval None
  221. */
  222. void irtx_base_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  223. {
  224. irtx_clk_init(irtx_param->clk_sel);
  225. irtx_timing_init(irtx_reg, irtx_param);
  226. irfilter_set(irtx_reg, irtx_param);
  227. irtx_set_invert(irtx_reg, irtx_param);
  228. irtx_init(irtx_reg, irtx_param);
  229. irtx_set_repeat(irtx_reg, irtx_param);
  230. }
  231. static bool irtx_is_repeat(void)
  232. {
  233. bool ret = true;
  234. if (GETF_REG_IRREPEATCON_IRTX_KEY()) {
  235. ret = false;
  236. }
  237. return ret;
  238. }
  239. void irtx_repeat_send(void)
  240. {
  241. if (irtx_is_repeat() && GETF_REG_IRFLTCON_IRFLT_EN()) {
  242. irtx_kick_wait();
  243. }
  244. }
  245. void irtx_send(void)
  246. {
  247. irtx_kick_wait();
  248. }
  249. void irtx_capture_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  250. {
  251. irtx_clk_init(irtx_param->clk_sel);
  252. irtx_capture_edge(irtx_reg, irtx_param->cap_edge); //edge set 1 to choose rising edge
  253. }
  254. void irtx_capture_buf_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
  255. {
  256. irtx_capture_dma_init(irtx_reg, buf, len);
  257. irtx_capture_dma_kick(irtx_reg);
  258. }
  259. void irtx_learn_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
  260. {
  261. irtx_clk_init(irtx_param->clk_sel);
  262. irtx_carrier_init(irtx_reg, irtx_param);
  263. irtx_dma_init(irtx_reg, irtx_param);
  264. SETF_REG_IRDMACON_IR_RDMA_EN();
  265. SETF_REG_IRTXCON_IRTXLEN_EN();
  266. }
  267. void irtx_learn_buf_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
  268. {
  269. irtx_learn_dma_init(irtx_reg, buf, len);
  270. irtx_learn_kick(irtx_reg);
  271. }
  272. /**
  273. * @brief Enable or disable the specified IRTX interrupt.
  274. * @param isr: Function to be executed for service interruption.
  275. * @param pr: Priority of service interruption.
  276. * @param flag_type: specifies the IRTX interrupt sources to be enable or disable.
  277. * This parameter can be one of the following values:
  278. * @arg IRTX_FLAG_WDMA_HPND: ir write DMA half interrupt.
  279. * @arg IRTX_FLAG_WDMA_APND: ir write DMA all interrupt.
  280. * @arg IRTX_FLAG_RDMA_HPND: ir read DMA half interrupt.
  281. * @arg IRTX_FLAG_RDMA_APND: ir read DMA all interrupt.
  282. * @param state: the new state need to config.
  283. * @retval None
  284. */
  285. void irtx_pic_config(isr_t isr, int pr, IRTX_FLAG_TYPEDEF flag_type, FUNCTIONAL_STATE state)
  286. {
  287. u32 flag_pending_bit = 0;
  288. if (flag_type == 0) {
  289. return;
  290. }
  291. if (flag_type & IRTX_FLAG_WDMA_HPND) {
  292. flag_pending_bit |= BIT_REG_IRDMACON_IR_WDMA_HPND_IE;
  293. }
  294. if (flag_type & IRTX_FLAG_WDMA_APND) {
  295. flag_pending_bit |= BIT_REG_IRDMACON_IR_WDMA_APND_IE;
  296. }
  297. if (flag_type & IRTX_FLAG_RDMA_HPND) {
  298. flag_pending_bit |= BIT_REG_IRDMACON_IR_RDMA_HPND_IE;
  299. }
  300. if (flag_type & IRTX_FLAG_RDMA_APND) {
  301. flag_pending_bit |= BIT_REG_IRDMACON_IR_RDMA_APND_IE;
  302. }
  303. if (state != DISABLE) {
  304. IRTX->dma_con |= flag_pending_bit;
  305. sys_irq_init(IRQn_IR_QDEC_LEDC, pr, isr);
  306. } else {
  307. IRTX->dma_con &= ~flag_pending_bit;
  308. }
  309. }