| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- /**
- ******************************************************************************************************************************
- *
- *@file driver_irtx.c
- *
- *@brief Source file for IR tx driver
- *
- *Copyright (c) 2023, BLUETRUM
- ******************************************************************************************************************************
- **/
- #include "driver_ir.h"
- #include "driver_gpio.h"
- #include "macro.h"
- void ir_clk_init(uint8_t clksel)
- {
- // irrx/irrx clock config
- if ((IR_CLK_OSC32K == clksel) || (IR_CLK_X24M32K == clksel) || (IR_CLK_X24MDIV == clksel)) {
- XOSCCON |= BIT(10); //XOSC24M enable
- CLKCON4 &= ~BIT(26); //xoscrc24m_sel chose XOSC24M
- clk_gate1_cmd(CLK_GATE1_X24M, CLK_EN); //XOSC24M gate open
- if (IR_CLK_OSC32K == clksel) {
- CLKCON1 &= ~BIT(17); // k32_tscsel chose osc32k_p(CLK32K_RTC)
- RTCCON0 |= (BIT(2)); // RTC output clock to core enable
- RTCCON0 &= ~(BIT(19)); // osc core disable
- RTCCON0 = (RTCCON0 & ~(3 << 8)) | (3 << 8); // CLK32K_RTC source select x24mdiv12_rtc(x24m_clkdiv12)
- CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (3 << 13); // clkout sel, osc32k
- } else if (IR_CLK_X24M32K == clksel) {
- CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (2 << 13); // clkout sel, x24m_32K
- } else if (IR_CLK_X24MDIV == clksel) {
- CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (1 << 13); // clkout sel, x24mdiv unvisible,we can check xosc24m
- }
- } else if (IR_CLK_RC32K == clksel) {
- CLKCON0 |= BIT(0); //RC2M enable
- CLKCON0 = (CLKCON0 & ~(0x0f << 13)) | (7 << 13); // clkout sel, rc32k unvisible,we can check rc2m
- }
- //irrx clock select
- CLKCON1 = (CLKCON1 & ~(3 << 4)) | (clksel << 4); // 0:x24m_32k 1:x24m_div_clk 2:osc32k 3:rc32k_clk
- }
- void irtx_clk_init (uint8_t clksel)
- {
- ir_clk_init(clksel);
- clk_gate1_cmd(CLK_GATE1_IRTX, CLK_EN);
- clk_gate2_cmd(CLK_GATE2_IRFLT, CLK_EN);
- }
- /*
- * timing[0] : one [31:16]mark m1 [15:0]space s1
- * timing[1] : zeor [31:16]mark m0 [15:0]space s0
- * timing[2] : start [31:16]1 t1 [15:0]0 t0
- * timing[3] : repteat [31:16]1 r1 [15:0]0 r0
- * timing[4] : IRREPEATCON rt et sy rm
- * timing[5] : IRTXCON o z
- * timing[6] : IRTXLEN l
- */
- const IRTX_timingTypeDef Nec = IRTX_TIMING_NEC;
- const IRTX_timingTypeDef Tc9012 = IRTX_TIMING_TC9012;
- const IRTX_timingTypeDef Rc5 = IRTX_TIMING_RC5;
- const IRTX_timingTypeDef Rc6 = IRTX_TIMING_RC6;
- void irtx_timing_set(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param, const IRTX_timingTypeDef timing)
- {
- double prescale;
- volatile u32 timing_prescale;
- timing_prescale = ir_timing_freq_get(irtx_param->clk_sel);
- prescale = ((double)timing_prescale/1000000);
- irtx_reg->con = BIT(8) * timing.em |
- BIT(5) * timing.o |
- BIT(4) * timing.z |
- BIT(0);
- irtx_reg->otime = BIT(16) * (uint16_t)(timing.m1 * prescale) |
- BIT(0) * (uint16_t)(timing.s1 * prescale);
- irtx_reg->ztime = BIT(16) * (uint16_t)(timing.m0 * prescale) |
- BIT(0) * (uint16_t)(timing.s0 * prescale);
- irtx_reg->stime = BIT(16) * (uint16_t)(timing.t1 * prescale) |
- BIT(0) * (uint16_t)(timing.t0 * prescale);
- irtx_reg->rtime = BIT(16) * (uint16_t)(timing.r1 * prescale) |
- BIT(0) * (uint16_t)(timing.r0 * prescale);
- irtx_reg->rctrl = BIT(13) * (uint32_t)(timing.rt * prescale) |
- BIT(3) * (uint16_t)(timing.et * prescale) |
- BIT(2) * timing.sy |
- BIT(1) * timing.rm;
- irtx_reg->txlen = timing.l;
- }
- void irtx_timing_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- switch(irtx_param->encode_format)
- {
- case IRTX_ENCODE_FORMAT_NEC:
- irtx_timing_set(irtx_reg, irtx_param, Nec);
- break;
- case IRTX_ENCODE_FORMAT_TC9012:
- irtx_timing_set(irtx_reg, irtx_param, Tc9012);
- break;
- case IRTX_ENCODE_FORMAT_RC5:
- irtx_timing_set(irtx_reg, irtx_param, Rc5);
- break;
- case IRTX_ENCODE_FORMAT_RC6:
- irtx_timing_set(irtx_reg, irtx_param, Rc6);
- break;
- default:
- break;
- }
- }
- //edge set 0 to choose fall edge
- void irtx_capture_edge (irtx_typedef *irtx_reg, uint32_t edge)
- {
- if (edge) {
- SETF_REG_IRTXCON_IREDGE_SEL();
- }else {
- CLRF_REG_IRTXCON_IREDGE_SEL();
- }
- }
- void irtx_carrier_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- if (irtx_param->carrier_config.mod_clksel == IRTX_MODE_CLKSEL_3M) {
- CLKCON1 &= ~BIT(9);//1:4m 0:3m
- } else {
- CLKCON1 |= BIT(9);//1:4m 0:3m
- }
- if (irtx_param->carrier_config.carrier_en) {
- SETF_REG_IRTXCON_IRTX_CARRIER_EN();
- SET_REG_IRTXCON_IRCW_LENGTH(irtx_param->carrier_config.ircw_length);
- SET_REG_IRTXCON_IRCW_DUTY(irtx_param->carrier_config.ircw_duty);
- }else {
- CLRF_REG_IRTXCON_IRTX_CARRIER_EN();
- }
- }
- void irtx_dma_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- if (irtx_param->dma_config.rdma_mode == IRTX_DMA_MODE_16BIT) {
- SETF_REG_IRDMACON_IR_RDMA_MODE();
- } else {
- CLRF_REG_IRDMACON_IR_RDMA_MODE();
- }
- if (irtx_param->dma_config.wdma_mode == IRTX_DMA_MODE_16BIT) {
- SETF_REG_IRDMACON_IR_WDMA_MODE();
- } else {
- CLRF_REG_IRDMACON_IR_WDMA_MODE();
- }
- }
- void irtx_data_set (irtx_typedef *irtx_reg, uint32_t code)
- {
- irtx_reg->txdata = code;
- }
- void irtx_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- irtx_data_set(irtx_reg, irtx_param->tx_data);
- irtx_carrier_init(irtx_reg, irtx_param);
- if (IRTX_SYNC_OR_TRAILER_CODE_1 == irtx_param->sync_code) {
- SETF_REG_IRREPEATCON_IRTX_SYC();
- }else {
- CLRF_REG_IRREPEATCON_IRTX_SYC();
- }
- }
- void irtx_set_repeat(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- if (IRTX_KEY_PRESSED == irtx_param->key) {
- SETF_REG_IRREPEATCON_IRTX_KEY();
- }else {
- CLRF_REG_IRREPEATCON_IRTX_KEY();
- }
- }
- void irfilter_set(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- if (IRTX_FILTER_ENABLE == irtx_param->filter_config.filter_en) {
- SETF_REG_IRFLTCON_IRFLT_EN();
- SET_REG_IRFLTCON_IRFLT_LEN(irtx_param->filter_config.filter_len);
- } else {
- CLRF_REG_IRFLTCON_IRFLT_EN();
- }
- }
- //KICK
- inline void irtx_kick_do (void)
- {
- SETF_REG_IRTXCON_IRTX_KST();
- }
- inline void irtx_wait(void)
- {
- while (!GETF_REG_IRTXPEND_IRTX_PND());
- SETF_REG_IRTXPEND_IRTX_PND();
- }
- void irtx_kick_wait(void)
- {
- irtx_kick_do();
- irtx_wait();
- }
- //CAPTURE DMA
- void irtx_capture_dma_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
- {
- irtx_reg->dma_oadr = (uint32_t)buf;
- irtx_reg->dma_osize = len - 1;
- SETF_REG_IRDMACON_IR_WDMA_EN();
- SETF_REG_IRDMACON_IR_WDMA_MODE();
- //SETF_REG_IRDMACON_IR_WDMA_APND_IE();
- }
- void irtx_capture_dma_kick(irtx_typedef *irtx_reg)
- {
- SETF_REG_IRTXCON_IR_CAPEN();
- }
- void irtx_learn_dma_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
- {
- irtx_reg->dma_iadr = (uint32_t)buf;
- irtx_reg->dma_isize = len - 1;
- }
- void irtx_learn_kick(irtx_typedef *irtx_reg)
- {
- //SETF_REG_IRTXCON_IRTXLEN_EN();
- SETF_REG_IRTXCON_IRTX_KST();
- }
- inline void irtx_set_invert(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- if (IRTX_INVERT_OUTPUT_ENABLE == irtx_param->invert_en) {
- SETF_REG_IRTXCON_IRTX_INV();
- }else {
- CLRF_REG_IRTXCON_IRTX_INV();
- }
- }
- /**
- * @brief Set the clock,and clock/rx io init.Set irrx register.
- * @param irrx_reg: irrx register address
- * @param irrx_param: irrx params,include wakup_en/clock/int_en/data_format.
- * @retval None
- */
- void irtx_base_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- irtx_clk_init(irtx_param->clk_sel);
- irtx_timing_init(irtx_reg, irtx_param);
- irfilter_set(irtx_reg, irtx_param);
- irtx_set_invert(irtx_reg, irtx_param);
- irtx_init(irtx_reg, irtx_param);
- irtx_set_repeat(irtx_reg, irtx_param);
- }
- static bool irtx_is_repeat(void)
- {
- bool ret = true;
- if (GETF_REG_IRREPEATCON_IRTX_KEY()) {
- ret = false;
- }
- return ret;
- }
- void irtx_repeat_send(void)
- {
- if (irtx_is_repeat() && GETF_REG_IRFLTCON_IRFLT_EN()) {
- irtx_kick_wait();
- }
- }
- void irtx_send(void)
- {
- irtx_kick_wait();
- }
- void irtx_capture_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- irtx_clk_init(irtx_param->clk_sel);
- irtx_capture_edge(irtx_reg, irtx_param->cap_edge); //edge set 1 to choose rising edge
- }
- void irtx_capture_buf_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
- {
- irtx_capture_dma_init(irtx_reg, buf, len);
- irtx_capture_dma_kick(irtx_reg);
- }
- void irtx_learn_init(irtx_typedef *irtx_reg, const irtx_param_t *irtx_param)
- {
- irtx_clk_init(irtx_param->clk_sel);
- irtx_carrier_init(irtx_reg, irtx_param);
- irtx_dma_init(irtx_reg, irtx_param);
- SETF_REG_IRDMACON_IR_RDMA_EN();
- SETF_REG_IRTXCON_IRTXLEN_EN();
- }
- void irtx_learn_buf_init(irtx_typedef *irtx_reg, void *buf, uint32_t len)
- {
- irtx_learn_dma_init(irtx_reg, buf, len);
- irtx_learn_kick(irtx_reg);
- }
- /**
- * @brief Enable or disable the specified IRTX interrupt.
- * @param isr: Function to be executed for service interruption.
- * @param pr: Priority of service interruption.
- * @param flag_type: specifies the IRTX interrupt sources to be enable or disable.
- * This parameter can be one of the following values:
- * @arg IRTX_FLAG_WDMA_HPND: ir write DMA half interrupt.
- * @arg IRTX_FLAG_WDMA_APND: ir write DMA all interrupt.
- * @arg IRTX_FLAG_RDMA_HPND: ir read DMA half interrupt.
- * @arg IRTX_FLAG_RDMA_APND: ir read DMA all interrupt.
- * @param state: the new state need to config.
- * @retval None
- */
- void irtx_pic_config(isr_t isr, int pr, IRTX_FLAG_TYPEDEF flag_type, FUNCTIONAL_STATE state)
- {
- u32 flag_pending_bit = 0;
- if (flag_type == 0) {
- return;
- }
- if (flag_type & IRTX_FLAG_WDMA_HPND) {
- flag_pending_bit |= BIT_REG_IRDMACON_IR_WDMA_HPND_IE;
- }
- if (flag_type & IRTX_FLAG_WDMA_APND) {
- flag_pending_bit |= BIT_REG_IRDMACON_IR_WDMA_APND_IE;
- }
- if (flag_type & IRTX_FLAG_RDMA_HPND) {
- flag_pending_bit |= BIT_REG_IRDMACON_IR_RDMA_HPND_IE;
- }
- if (flag_type & IRTX_FLAG_RDMA_APND) {
- flag_pending_bit |= BIT_REG_IRDMACON_IR_RDMA_APND_IE;
- }
- if (state != DISABLE) {
- IRTX->dma_con |= flag_pending_bit;
- sys_irq_init(IRQn_IR_QDEC_LEDC, pr, isr);
- } else {
- IRTX->dma_con &= ~flag_pending_bit;
- }
- }
|