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