1 /**
2   *********************************************************************************
3   *
4   * @file    ald_pis.c
5   * @brief   PIS module driver.
6   *
7   * @version V1.0
8   * @date    27 Nov 2019
9   * @author  AE Team
10   * @note
11   *          Change Logs:
12   *          Date            Author          Notes
13   *          27 Nov 2019     AE Team         The first version
14   *
15   * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
16   *
17   * SPDX-License-Identifier: Apache-2.0
18   *
19   * Licensed under the Apache License, Version 2.0 (the License); you may
20   * not use this file except in compliance with the License.
21   * You may obtain a copy of the License at
22   *
23   * www.apache.org/licenses/LICENSE-2.0
24   *
25   * Unless required by applicable law or agreed to in writing, software
26   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
27   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28   * See the License for the specific language governing permissions and
29   * limitations under the License.
30   **********************************************************************************
31   */
32 
33 #include "ald_conf.h"
34 
35 /** @addtogroup ES32FXXX_ALD
36   * @{
37   */
38 
39 /** @defgroup PIS PIS
40   * @brief PIS module driver
41   * @{
42   */
43 #ifdef ALD_PIS
44 
45 /** @defgroup PIS_Public_Functions PIS Public Functions
46   * @{
47   */
48 
49 /** @defgroup PIS_Public_Functions_Group1 Initialization functions
50   * @brief Initialization and Configuration functions
51   * @{
52   */
53 
54 /**
55   * @brief  Create the PIS mode according to the specified parameters in
56   *         the pis_handle_t and create the associated handle.
57   * @param  hperh: Pointer to a pis_handle_t structure that contains
58   *         the configuration information for the specified PIS module.
59   * @retval Status, see @ref ald_status_t.
60   */
ald_pis_create(pis_handle_t * hperh)61 ald_status_t ald_pis_create(pis_handle_t *hperh)
62 {
63 	if (hperh == NULL)
64 		return ERROR;
65 
66 	assert_param(IS_PIS_SRC(hperh->init.producer_src));
67 	assert_param(IS_PIS_TRIG(hperh->init.consumer_trig));
68 	assert_param(IS_PIS_CLOCK(hperh->init.producer_clk));
69 	assert_param(IS_PIS_CLOCK(hperh->init.consumer_clk));
70 	assert_param(IS_PIS_EDGE(hperh->init.producer_edge));
71 	assert_param(IS_PIS_SIGNAL_MODE(hperh->init.producer_signal));
72 
73 	__LOCK(hperh);
74 	hperh->perh = PIS;
75 
76 	/* get location of consumer in channel and position of con0/con1
77 	 * accord to comsumer_trig information */
78 	hperh->consumer_ch  = (pis_ch_t)(hperh->init.consumer_trig & 0x0F);
79 	hperh->consumer_con = (pis_con_t)((hperh->init.consumer_trig >> 4) & 0x0F);
80 	hperh->consumer_pos = (1U << (uint32_t)((hperh->init.consumer_trig >> 8) & 0xFF));
81 
82 	if (hperh->perh->CH_CON[hperh->consumer_ch] != 0) {
83 		__UNLOCK(hperh);
84 		return BUSY;
85 	}
86 
87 	MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SRCS_MSK, ((hperh->init.producer_src) >> 4) << PIS_CH0_CON_SRCS_POSS);
88 	MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_MSIGS_MSK, ((hperh->init.producer_src) & 0xf) << PIS_CH0_CON_MSIGS_POSS);
89 
90 	if (hperh->init.producer_clk == hperh->init.consumer_clk) {
91 		MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, PIS_SYN_DIRECT << PIS_CH0_CON_SYNCSEL_POSS);
92 		MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_PULCK_MSK, (hperh->init.consumer_clk) << PIS_CH0_CON_PULCK_POSS);
93 	}
94 	else {
95 		if (hperh->init.producer_signal == PIS_OUT_LEVEL) {
96 			if (hperh->init.consumer_clk == PIS_CLK_PCLK1)
97 				MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, PIS_SYN_LEVEL_ASY_APB1 << PIS_CH0_CON_SYNCSEL_POSS);
98 			if (hperh->init.consumer_clk == PIS_CLK_PCLK2)
99 				MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, PIS_SYN_LEVEL_ASY_APB2 << PIS_CH0_CON_SYNCSEL_POSS);
100 			if (hperh->init.consumer_clk == PIS_CLK_SYS)
101 				MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, PIS_SYN_LEVEL_ASY_AHB << PIS_CH0_CON_SYNCSEL_POSS);
102 		}
103 
104 		if (hperh->init.producer_signal == PIS_OUT_PULSE) {
105 			if (hperh->init.consumer_clk == PIS_CLK_PCLK1)
106 				MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, PIS_SYN_PULSE_ASY_APB1 << PIS_CH0_CON_SYNCSEL_POSS);
107 			if (hperh->init.consumer_clk == PIS_CLK_PCLK2)
108 				MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, PIS_SYN_PULSE_ASY_APB2 << PIS_CH0_CON_SYNCSEL_POSS);
109 			if (hperh->init.consumer_clk == PIS_CLK_SYS)
110 				MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, PIS_SYN_PULSE_ASY_AHB << PIS_CH0_CON_SYNCSEL_POSS);
111 		}
112 	}
113 
114 	MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_PULCK_MSK, hperh->init.consumer_clk << PIS_CH0_CON_PULCK_POSS);
115 	MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_EDGS_MSK, hperh->init.producer_edge << PIS_CH0_CON_EDGS_POSS);
116 	hperh->check_info = hperh->perh->CH_CON[hperh->consumer_ch];
117 
118 	/* enable consumer bit, switch pin of consumer */
119 	if (hperh->init.input_chan == PIS_CHAN_INPUT) {
120 		switch (hperh->consumer_con) {
121 		case PIS_CON_0:
122 			PIS->TAR_CON0 |= hperh->consumer_pos;
123 			break;
124 		case PIS_CON_1:
125 			PIS->TAR_CON1 |= hperh->consumer_pos;
126 			break;
127 		default:
128 			break;
129 		}
130 	}
131 
132 	__UNLOCK(hperh);
133 	return OK;
134 }
135 
136 /**
137   * @brief  Destroy the PIS mode according to the specified parameters in
138   *         the pis_init_t and create the associated handle.
139   * @param  hperh: Pointer to a pis_handle_t structure that contains
140   *         the configuration information for the specified PIS module.
141   * @retval Status, see @ref ald_status_t.
142   */
ald_pis_destroy(pis_handle_t * hperh)143 ald_status_t ald_pis_destroy(pis_handle_t *hperh)
144 {
145 	assert_param(IS_PIS(hperh->perh));
146 
147 	if (hperh->check_info != hperh->perh->CH_CON[hperh->consumer_ch])
148 		return ERROR;
149 
150 	__LOCK(hperh);
151 
152 	CLEAR_BIT(PIS->CH_OER, (1U << (uint32_t)hperh->consumer_ch));
153 	WRITE_REG(hperh->perh->CH_CON[hperh->consumer_ch], 0x0);
154 
155 	switch (hperh->consumer_con) {
156 	case PIS_CON_0:
157 		PIS->TAR_CON0 &= ~(hperh->consumer_pos);
158 		break;
159 	case PIS_CON_1:
160 		PIS->TAR_CON1 &= ~(hperh->consumer_pos);
161 		break;
162 	default:
163 		break;
164 	}
165 
166 	hperh->state = PIS_STATE_RESET;
167 	__UNLOCK(hperh);
168 
169 	return OK;
170 }
171 /**
172   * @}
173   */
174 
175 /** @defgroup PIS_Public_Functions_Group2 Operation functions
176   * @brief PIS output enable or disable functions
177   * @{
178   */
179 
180 /**
181   * @brief  Start the PIS output function.
182   * @param  hperh: Pointer to a pis_handle_t structure that contains
183   *         the configuration information for the specified PIS module.
184   * @param  ch: The PIS channel enable output
185   *	    This parameter can be one of the following values:
186   *		@arg PIS_OUT_CH_0
187   *		@arg PIS_OUT_CH_1
188   *		@arg PIS_OUT_CH_2
189   *		@arg PIS_OUT_CH_3
190   * @retval Status, see @ref ald_status_t.
191   */
ald_pis_output_start(pis_handle_t * hperh,pis_out_ch_t ch)192 ald_status_t ald_pis_output_start(pis_handle_t *hperh, pis_out_ch_t ch)
193 {
194 	assert_param(IS_PIS(hperh->perh));
195 	assert_param(IS_PIS_OUPUT_CH(ch));
196 	__LOCK(hperh);
197 	SET_BIT(PIS->CH_OER, (1 << (uint32_t)ch));
198 	__UNLOCK(hperh);
199 
200 	return OK;
201 }
202 
203 /**
204   * @brief  Stop the PIS output function.
205   * @param  hperh: Pointer to a pis_handle_t structure that contains
206   *         the configuration information for the specified PIS module.
207   * @param  ch: The PIS channel disable output
208   *	    This parameter can be one of the following values:
209   *		@arg PIS_OUT_CH_0
210   *		@arg PIS_OUT_CH_1
211   *		@arg PIS_OUT_CH_2
212   *		@arg PIS_OUT_CH_3
213   * @retval Status, see @ref ald_status_t.
214   */
ald_pis_output_stop(pis_handle_t * hperh,pis_out_ch_t ch)215 ald_status_t ald_pis_output_stop(pis_handle_t *hperh, pis_out_ch_t ch)
216 {
217 	assert_param(IS_PIS(hperh->perh));
218 	assert_param(IS_PIS_OUPUT_CH(ch));
219 	__LOCK(hperh);
220 	CLEAR_BIT(PIS->CH_OER, (1 << (uint32_t)ch));
221 	__UNLOCK(hperh);
222 
223 	return OK;
224 }
225 /**
226   * @}
227   */
228 
229 /** @defgroup PIS_Public_Functions_Group3 Peripheral State and Errors functions
230   *  @brief   PIS State and Errors functions
231   * @{
232   */
233 
234 /**
235   * @brief  Returns the PIS state.
236   * @param  hperh: Pointer to a pis_handle_t structure that contains
237   *         the configuration information for the specified PIS module.
238   * @retval ALD state
239   */
ald_pis_get_state(pis_handle_t * hperh)240 pis_state_t ald_pis_get_state(pis_handle_t *hperh)
241 {
242 	assert_param(IS_PIS(hperh->perh));
243 	return hperh->state;
244 }
245 
246 /**
247   * @}
248   */
249 
250 /** @defgroup PIS_Public_Functions_Group4 modulate output functions
251   *  @brief   PIS modulate output signal functions
252   * @{
253   */
254 
255 /**
256   * @brief  Config the PIS modulate signal function
257   * @param  hperh: Pointer to a pis_handle_t structure that contains
258   *         the configuration information for the specified PIS module.
259   * @param  config: Pointer to a pis_modulate_config_t structure that
260   *         contains the selected target (UART0,UART1,UART2,UART3 or
261   *         LPUART0) how to modulate the target output signal.
262   * @retval Status, see @ref ald_status_t.
263   */
ald_pis_modu_config(pis_handle_t * hperh,pis_modulate_config_t * config)264 ald_status_t ald_pis_modu_config(pis_handle_t *hperh, pis_modulate_config_t *config)
265 {
266 	assert_param(IS_PIS(hperh->perh));
267 	assert_param(IS_PIS_MODU_TARGET(config->target));
268 	assert_param(IS_PIS_MODU_LEVEL(config->level));
269 	assert_param(IS_PIS_MODU_SRC(config->src));
270 	assert_param(IS_PIS_MODU_CHANNEL(config->channel));
271 	__LOCK(hperh);
272 
273 	switch (config->target) {
274 	case PIS_UART0_TX:
275 		MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_UART0_TXMCR_TXMLVLS_MSK, config->level << PIS_UART0_TXMCR_TXMLVLS_POS);
276 		MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_UART0_TXMCR_TXMSS_MSK, config->src << PIS_UART0_TXMCR_TXMSS_POSS);
277 		MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_UART0_TXMCR_TXSIGS_MSK, config->channel << PIS_UART0_TXMCR_TXSIGS_POSS);
278 		break;
279 
280 	case PIS_UART1_TX:
281 		MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_UART1_TXMCR_TXMLVLS_MSK, config->level << PIS_UART1_TXMCR_TXMLVLS_POS);
282 		MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_UART1_TXMCR_TXMSS_MSK, config->src << PIS_UART1_TXMCR_TXMSS_POSS);
283 		MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_UART1_TXMCR_TXSIGS_MSK, config->channel << PIS_UART1_TXMCR_TXSIGS_POSS);
284 		break;
285 
286 	case PIS_UART2_TX:
287 		MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_UART2_TXMCR_TXMLVLS_MSK, config->level << PIS_UART2_TXMCR_TXMLVLS_POS);
288 		MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_UART2_TXMCR_TXMSS_MSK, config->src << PIS_UART2_TXMCR_TXMSS_POSS);
289 		MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_UART2_TXMCR_TXSIGS_MSK, config->channel << PIS_UART2_TXMCR_TXSIGS_POSS);
290 		break;
291 
292 	case PIS_UART3_TX:
293 		MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_UART3_TXMCR_TXMLVLS_MSK, config->level << PIS_UART3_TXMCR_TXMLVLS_POS);
294 		MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_UART3_TXMCR_TXMSS_MSK, config->src << PIS_UART3_TXMCR_TXMSS_POSS);
295 		MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_UART3_TXMCR_TXSIGS_MSK, config->channel << PIS_UART3_TXMCR_TXSIGS_POSS);
296 		break;
297 
298 	case PIS_LPUART0_TX:
299 		MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_LPUART0_TXMCR_TXMLVLS_MSK, config->level << PIS_LPUART0_TXMCR_TXMLVLS_POS);
300 		MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_LPUART0_TXMCR_TXMSS_MSK, config->src << PIS_LPUART0_TXMCR_TXMSS_POSS);
301 		MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_LPUART0_TXMCR_TXSIGS_MSK, config->channel << PIS_LPUART0_TXMCR_TXSIGS_POSS);
302 		break;
303 
304 	default:
305 		break;
306 	}
307 
308 	__UNLOCK(hperh);
309 	return OK;
310 }
311 /**
312   * @}
313   */
314 /**
315   * @}
316   */
317 #endif /* ALD_PIS */
318 /**
319   * @}
320   */
321 /**
322   * @}
323   */
324