1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18 #include "pwm.h"
19
20 dma_config_t pwm_tx_dma_config = {
21 .dst_req_sel = DMA_REQ_PWM_TX, // tx req
22 .src_req_sel = 0,
23 .dst_addr_ctrl = DMA_ADDR_FIX,
24 .src_addr_ctrl = DMA_ADDR_INCREMENT, // increment
25 .dstmode = DMA_HANDSHAKE_MODE, // handshake
26 .srcmode = DMA_NORMAL_MODE,
27 .dstwidth = DMA_CTR_WORD_WIDTH, // must word
28 .srcwidth = DMA_CTR_WORD_WIDTH, // must word
29 .src_burst_size = 0, // must 0
30 .read_num_en = 0,
31 .priority = 0,
32 .write_num_en = 0,
33 .auto_en = 0,
34 };
35
36 /**
37 * @brief This fuction servers to set pin as pwm0
38 * @param[in] pin - selected pin
39 * @return none.
40 */
pwm_set_pin(pwm_pin_e pin)41 void pwm_set_pin(pwm_pin_e pin)
42 {
43 unsigned char val = 0;
44 unsigned char start_bit = (BIT_LOW_BIT(pin & 0xff) % 4) << 1;
45 unsigned char mask = (unsigned char)~BIT_RNG(start_bit, start_bit + 1);
46
47 if (pin == PWM_PWM2_PB7) { // Pad Function Mux:0
48 val = 0;
49 BM_CLR(reg_gpio_pad_mul_sel, BIT(3));
50 } else if ((pin == PWM_PWM0_PB4) || (pin == PWM_PWM4_PD7) || (pin == PWM_PWM2_N_PE6) ||
51 (pin == PWM_PWM3_N_PE7)) { // Pad Function Mux:1
52 val = 1 << (start_bit);
53 } else { // Pad Function Mux:2
54 val = 2 << (start_bit);
55 reg_gpio_pad_mul_sel |= BIT(0);
56 }
57
58 reg_gpio_func_mux(pin) = (reg_gpio_func_mux(pin) & mask) | val;
59 gpio_function_dis(pin);
60 }
61
62 /**
63 * @brief This function servers to configure DMA channel and some configures.
64 * @param[in] chn - to select the DMA channel.
65 * @return none
66 */
pwm_set_dma_config(dma_chn_e chn)67 void pwm_set_dma_config(dma_chn_e chn)
68 {
69 dma_config(chn, &pwm_tx_dma_config);
70 }
71
72 /**
73 * @brief This function servers to configure DMA channel address and length.
74 * @param[in] chn - to select the DMA channel.
75 * @param[in] buf_addr - the address where DMA need to get data from SRAM.
76 * @param[in] len - the length of data in SRAM.
77 * @return none
78 */
pwm_set_dma_buf(dma_chn_e chn,unsigned int buf_addr,unsigned int len)79 void pwm_set_dma_buf(dma_chn_e chn, unsigned int buf_addr, unsigned int len)
80 {
81 dma_set_address(chn, convert_ram_addr_cpu2bus(buf_addr), reg_pwm_data_buf_adr);
82 dma_set_size(chn, len, DMA_WORD_WIDTH);
83 }
84
85 /**
86 * @brief This function servers to enable DMA channel.
87 * @param[in] chn - to select the DMA channel.
88 * @return none
89 */
pwm_ir_dma_mode_start(dma_chn_e chn)90 void pwm_ir_dma_mode_start(dma_chn_e chn)
91 {
92 dma_chn_en(chn);
93 }
94
95 /**
96 * @brief This function servers to configure DMA head node.
97 * @param[in] chn - to select the DMA channel.
98 * @param[in] src_addr - to configure DMA source address.
99 * @param[in] data_len - to configure DMA length.
100 * @param[in] head_of_list - to configure the address of the next node configure.
101 * @return none
102 */
pwm_set_dma_chain_llp(dma_chn_e chn,unsigned short * src_addr,unsigned int data_len,dma_chain_config_t * head_of_list)103 void pwm_set_dma_chain_llp(dma_chn_e chn, unsigned short *src_addr, unsigned int data_len,
104 dma_chain_config_t *head_of_list)
105 {
106 dma_config(chn, &pwm_tx_dma_config);
107 dma_set_address(chn, convert_ram_addr_cpu2bus(src_addr), reg_pwm_data_buf_adr);
108 dma_set_size(chn, data_len, DMA_WORD_WIDTH);
109 reg_dma_llp(chn) = (unsigned int)convert_ram_addr_cpu2bus(head_of_list);
110 }
111
112 /**
113 * @brief This function servers to configure DMA cycle chain node.
114 * @param[in] chn - to select the DMA channel.
115 * @param[in] config_addr - to servers to configure the address of the current node.
116 * @param[in] llponit - to configure the address of the next node configure.
117 * @param[in] src_addr - to configure DMA source address.
118 * @param[in] data_len - to configure DMA length.
119 * @return none
120 */
pwm_set_tx_dma_add_list_element(dma_chn_e chn,dma_chain_config_t * config_addr,dma_chain_config_t * llponit,unsigned short * src_addr,unsigned int data_len)121 void pwm_set_tx_dma_add_list_element(dma_chn_e chn, dma_chain_config_t *config_addr, dma_chain_config_t *llponit,
122 unsigned short *src_addr, unsigned int data_len)
123 {
124 config_addr->dma_chain_ctl = reg_dma_ctrl(chn) | BIT(0);
125 config_addr->dma_chain_src_addr = (unsigned int)convert_ram_addr_cpu2bus(src_addr);
126 config_addr->dma_chain_dst_addr = reg_pwm_data_buf_adr;
127 config_addr->dma_chain_data_len = dma_cal_size(data_len, DMA_WORD_WIDTH);
128 config_addr->dma_chain_llp_ptr = (unsigned int)convert_ram_addr_cpu2bus(llponit);
129 }
130