1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Description: Provides V151 HAL spi \n
16 *
17 * History: \n
18 * 2022-08-12, Create file. \n
19 */
20 #include <stdbool.h>
21 #include "securec.h"
22 #include "common_def.h"
23 #include "spi_porting.h"
24 #include "hal_spi_v151_regs_op.h"
25 #include "hal_spi_v151.h"
26
27 #define SPI_MINUMUM_CLOCK_IN_MHZ 1
28 #define SPI_MAXIMUM_CLOCK_IN_MHZ 48
29 #define QSPI_MINUMUM_CLOCK_IN_MHZ 1
30 #define QSPI_MAXIMUM_CLOCK_IN_MHZ 96
31
32 #define SPI_MINUMUM_CLK_DIV 2
33 #define SPI_MAXIMUM_CLK_DIV 65534
34 #define spi_mhz_to_hz(x) ((x) * 1000000)
35
36 #define SPI_FRAME_BYTES_1 0x01
37 #define SPI_FRAME_BYTES_4 0x04
38
39 #define QSPI_WAIT_CYCLE_MAX 0x1F
40
41 #define MAX_SPI_GET_RX_LEVEL_RETRY_TIMES 0xFFFF
42 #define SPI_RX_INT_WAIT_TIMES 0xF
43
44 #define hal_spi_trans_bytes_to_word(x) ((((uint32_t)(*(x))) << 24) + (((uint32_t)(*((x) + 1))) << 16) + \
45 (((uint32_t)(*((x) + 2))) << 8) + ((uint32_t)(*((x) + 3))))
46 #define hal_spi_trans_word_31_24_bits_to_byte(x) ((uint8_t)(((x) & 0xff000000) >> 24))
47 #define hal_spi_trans_word_23_16_bits_to_byte(x) ((uint8_t)(((x) & 0xff0000) >> 16))
48 #define hal_spi_trans_word_15_8_bits_to_byte(x) ((uint8_t)(((x) & 0xff00) >> 8))
49 #define hal_spi_trans_word_7_0_bits_to_byte(x) ((uint8_t)((x) & 0xff))
50 #define hal_spi_frame_size_trans_to_frame_bytes(x) (((x) + 1) >> 0x03)
51
52 static hal_spi_callback_t g_hal_spi_callback = NULL;
53 static hal_spi_attr_t g_hal_spi_attrs[SPI_BUS_MAX_NUM] = { 0 };
54 static hal_spi_extra_attr_t g_hal_spi_extra_attrs[SPI_BUS_MAX_NUM] = { 0 };
55 #if defined(CONFIG_SPI_SUPPORT_LPM)
56 #define SPI_BUS_CONFIG_REG_NUM 6
57 #define SPI_GET_MTRC 0
58 #define SPI_GET_TWL 1
59 #define SPI_GET_RWL 2
60 #define SPI_GET_SSEF 3
61 #define SPI_GET_WAITNUM 4
62 #define SPI_GET_NRDF 5
63 static uint32_t g_spi_suspend_regs[SPI_BUS_CONFIG_REG_NUM] = { 0 };
64 #endif
65
hal_spi_check_timeout_by_count(uint32_t * trans_time,uint32_t timeout)66 static bool hal_spi_check_timeout_by_count(uint32_t *trans_time, uint32_t timeout)
67 {
68 (*trans_time)++;
69 return ((*trans_time > timeout) ? true : false);
70 }
71
hal_spi_is_attr_freq_valid(const uint32_t clk_in_mhz,const hal_spi_frame_format_t spi_frame_format)72 static bool hal_spi_is_attr_freq_valid(const uint32_t clk_in_mhz, const hal_spi_frame_format_t spi_frame_format)
73 {
74 if (spi_frame_format == HAL_SPI_FRAME_FORMAT_STANDARD) {
75 if ((clk_in_mhz < SPI_MINUMUM_CLOCK_IN_MHZ) || (clk_in_mhz > SPI_MAXIMUM_CLOCK_IN_MHZ)) {
76 return false;
77 }
78 } else {
79 if ((clk_in_mhz < QSPI_MINUMUM_CLOCK_IN_MHZ) || (clk_in_mhz > QSPI_MAXIMUM_CLOCK_IN_MHZ)) {
80 return false;
81 }
82 }
83 return true;
84 }
85
hal_spi_is_attr_valid(spi_bus_t bus,const hal_spi_attr_t * attr,const hal_spi_extra_attr_t * extra_attr)86 static bool hal_spi_is_attr_valid(spi_bus_t bus, const hal_spi_attr_t *attr, const hal_spi_extra_attr_t *extra_attr)
87 {
88 hal_spi_frame_size_t frame_size = (hal_spi_frame_size_t)attr->frame_size;
89 hal_spi_frame_format_t spi_frame_format = (hal_spi_frame_format_t)attr->spi_frame_format;
90 hal_spi_trans_mode_t tmod = (hal_spi_trans_mode_t)attr->tmod;
91 hal_spi_cfg_frame_format_t frame_format = (hal_spi_cfg_frame_format_t)attr->frame_format;
92 hal_spi_cfg_clk_cpol_t polar = (hal_spi_cfg_clk_cpol_t)attr->clk_polarity;
93 hal_spi_cfg_clk_cpha_t phase = (hal_spi_cfg_clk_cpha_t)attr->clk_phase;
94 hal_spi_cfg_sste_t sste = (hal_spi_cfg_sste_t)attr->sste;
95
96 if (frame_size != HAL_SPI_FRAME_SIZE_8 && frame_size != HAL_SPI_FRAME_SIZE_32) {
97 return false;
98 }
99 if (spi_frame_format >= HAL_SPI_FRAME_FORMAT_MAX_NUM) {
100 return false;
101 }
102 if (spi_frame_format == HAL_SPI_FRAME_FORMAT_QUAD && extra_attr == NULL) {
103 return false;
104 }
105 if (frame_format >= SPI_CFG_FRAME_FORMAT_MAX) {
106 return false;
107 }
108 if (tmod >= HAL_SPI_TRANS_MODE_MAX) {
109 return false;
110 }
111 if (polar >= SPI_CFG_CLK_CPOL_MAX) {
112 return false;
113 }
114 if (phase >= SPI_CFG_CLK_CPHA_MAX) {
115 return false;
116 }
117 if (sste >= SPI_CFG_SSTE_MAX) {
118 return false;
119 }
120
121 /* Only SPI master need to select slave and set clock. */
122 if (attr->is_slave == 0) {
123 if (attr->slave_num > spi_porting_max_slave_select_get(bus) + 1) {
124 return false;
125 }
126 if (hal_spi_is_attr_freq_valid(attr->freq_mhz, spi_frame_format) != true) {
127 return false;
128 }
129 }
130 return true;
131 }
132
hal_spi_get_frame_format(spi_bus_t bus)133 static hal_spi_frame_format_t hal_spi_get_frame_format(spi_bus_t bus)
134 {
135 hal_spi_frame_format_t spi_frame_format = (hal_spi_frame_format_t)hal_spi_v151_spi_ctra_get_enhff(bus);
136 if (spi_frame_format == HAL_SPI_FRAME_FORMAT_OCTAL) {
137 spi_frame_format = g_hal_spi_attrs[bus].spi_frame_format;
138 }
139 return spi_frame_format;
140 }
141
hal_spi_is_busy(spi_bus_t bus,uint32_t timeout)142 static bool hal_spi_is_busy(spi_bus_t bus, uint32_t timeout)
143 {
144 uint32_t trans_time = 0;
145 while (hal_spi_v151_spi_wsr_get_tfe(bus) != 1 || hal_spi_v151_spi_wsr_get_rfne(bus) != 0 ||
146 hal_spi_sr_get_busy(bus) != 0) {
147 if (hal_spi_check_timeout_by_count(&trans_time, timeout)) {
148 return true;
149 }
150 }
151 return false;
152 }
153
hal_spi_config_qspi(spi_bus_t bus,const hal_spi_xfer_qspi_param_t * qspi_param)154 static void hal_spi_config_qspi(spi_bus_t bus, const hal_spi_xfer_qspi_param_t *qspi_param)
155 {
156 hal_spi_ssienr_set_ssi_en(bus, 0);
157 hal_spi_v151_spi_enhctl_set_aaitf(bus, qspi_param->trans_type);
158 hal_spi_v151_spi_enhctl_set_ilen(bus, qspi_param->inst_len);
159 hal_spi_v151_spi_enhctl_set_addrlen(bus, qspi_param->addr_len);
160
161 uint32_t wait_cyc = qspi_param->wait_cycles;
162 if (wait_cyc > QSPI_WAIT_CYCLE_MAX) {
163 wait_cyc = QSPI_WAIT_CYCLE_MAX;
164 }
165 hal_spi_v151_spi_enhctl_set_waitnum(bus, wait_cyc);
166 hal_spi_ssienr_set_ssi_en(bus, 1);
167 }
168
169 #if defined(CONFIG_SPI_SUPPORT_SINGLE_SPI)
hal_spi_config_sspi(spi_bus_t bus,const hal_spi_xfer_sspi_param_t * sspi_param)170 static void hal_spi_config_sspi(spi_bus_t bus, const hal_spi_xfer_sspi_param_t *sspi_param)
171 {
172 spi_porting_set_sspi_mode(bus, true);
173 hal_spi_v151_spi_rsvd_set(bus, sspi_param->wait_cycles);
174 }
175 #endif
176
hal_spi_init_config_spi_frame_format(spi_bus_t bus,hal_spi_frame_format_t spi_frame_format)177 static void hal_spi_init_config_spi_frame_format(spi_bus_t bus, hal_spi_frame_format_t spi_frame_format)
178 {
179 if (spi_frame_format == HAL_SPI_FRAME_FORMAT_STANDARD ||
180 spi_frame_format == HAL_SPI_FRAME_FORMAT_DUAL ||
181 spi_frame_format == HAL_SPI_FRAME_FORMAT_QUAD) {
182 hal_spi_v151_spi_ctra_set_enhff(bus, (uint32_t)spi_frame_format);
183 } else {
184 if (spi_frame_format == HAL_SPI_FRAME_FORMAT_OCTAL ||
185 spi_frame_format == HAL_SPI_FRAME_FORMAT_DOUBLE_OCTAL||
186 spi_frame_format == HAL_SPI_FRAME_FORMAT_SIXT) {
187 hal_spi_v151_spi_ctra_set_enhff(bus, (uint32_t)HAL_SPI_FRAME_FORMAT_OCTAL);
188 }
189 }
190 }
191
hal_spi_init_config_freq(spi_bus_t bus,uint32_t bus_clk,uint32_t clk_in_mhz)192 static void hal_spi_init_config_freq(spi_bus_t bus, uint32_t bus_clk, uint32_t clk_in_mhz)
193 {
194 uint32_t clk_div;
195 clk_div = (uint32_t)(bus_clk / spi_mhz_to_hz(clk_in_mhz));
196 if (clk_div < SPI_MINUMUM_CLK_DIV) {
197 clk_div = SPI_MINUMUM_CLK_DIV;
198 }
199
200 hal_spi_baudr_set_sckdv(bus, clk_div);
201 }
202
hal_spi_init_config_master(spi_bus_t bus,const hal_spi_attr_t * attr,const hal_spi_extra_attr_t * extra_attr)203 static void hal_spi_init_config_master(spi_bus_t bus, const hal_spi_attr_t *attr,
204 const hal_spi_extra_attr_t *extra_attr)
205 {
206 hal_spi_ser_set_ser(bus, (attr->slave_num == 0) ? 0 : bit(attr->slave_num - 1));
207 hal_spi_init_config_freq(bus, attr->bus_clk, attr->freq_mhz);
208 if ((hal_spi_frame_format_t)attr->spi_frame_format == HAL_SPI_FRAME_FORMAT_QUAD) {
209 hal_spi_config_qspi(bus, &extra_attr->qspi_param);
210 }
211 #if defined(CONFIG_SPI_SUPPORT_SINGLE_SPI)
212 if ((hal_spi_cfg_frame_format_t)attr->frame_format == SPI_CFG_FRAME_FORMAT_NS_MICROWIRE) {
213 hal_spi_config_sspi(bus, &extra_attr->sspi_param);
214 }
215 #endif
216 /* Config the number of data frames. */
217 if (attr->ndf > 0) {
218 hal_spi_v151_spi_ctrb_set_nrdf(bus, attr->ndf - 1);
219 } else {
220 hal_spi_v151_spi_ctrb_set_nrdf(bus, 0);
221 }
222 }
223
hal_spi_init_config(spi_bus_t bus,const hal_spi_attr_t * attr,const hal_spi_extra_attr_t * extra_attr)224 static bool hal_spi_init_config(spi_bus_t bus, const hal_spi_attr_t *attr, const hal_spi_extra_attr_t *extra_attr)
225 {
226 if (hal_spi_is_attr_valid(bus, attr, extra_attr) != true) {
227 return false;
228 }
229
230 #if (CONFIG_SPI_NOT_SUPPORT_TEXAS_FORMAT)
231 if (attr->frame_format == SPI_CFG_FRAME_FORMAT_TEXAS_SSP) {
232 return false;
233 }
234 #endif
235
236 /* SPI parameter config */
237 hal_spi_ssienr_set_ssi_en(bus, 0);
238 hal_spi_v151_spi_ctra_set(bus, 0);
239 hal_spi_v151_spi_enhctl_set(bus, 0);
240
241 hal_spi_init_config_spi_frame_format(bus, (hal_spi_frame_format_t)attr->spi_frame_format);
242 hal_spi_v151_spi_ctra_set_prs(bus, (hal_spi_cfg_frame_format_t)attr->frame_format);
243
244 /* Config the clock phase and polarity. */
245 hal_spi_v151_spi_ctra_set_scph(bus, attr->clk_phase);
246 hal_spi_v151_spi_ctra_set_scpol(bus, attr->clk_polarity);
247
248 /* Config the frame size. */
249 hal_spi_v151_spi_ctra_set_dfs32(bus, attr->frame_size);
250 hal_spi_v151_spi_ctra_set_cfs16(bus, attr->frame_size);
251 /* Config the transfer mode and FIFO threshold. */
252 hal_spi_v151_spi_ctra_set_trsm(bus, attr->tmod);
253 if (attr->frame_format == SPI_CFG_FRAME_FORMAT_NS_MICROWIRE && attr->tmod == HAL_SPI_TRANS_MODE_TX) {
254 hal_spi_v151_spi_mcr_set_mtrc(bus, 1);
255 }
256 hal_spi_txftlr_set_tft(bus, CONFIG_SPI_TXFTLR);
257 hal_spi_rxftlr_set_rft(bus, CONFIG_SPI_RXFTLR);
258
259 /* Config slave info and freq in master mode. */
260 if (attr->is_slave == 0) {
261 hal_spi_init_config_master(bus, attr, extra_attr);
262 }
263
264 /* Config slave select toggle enable. */
265 hal_spi_v151_spi_ctra_set_ssn_te(bus, attr->sste);
266
267 /* Enable the SPI and all of the interrupts. */
268 hal_spi_ssienr_set_ssi_en(bus, 1);
269 hal_spi_v151_int_set(bus, SPI_INMAR_REG, 0);
270
271 (void)memcpy_s(&g_hal_spi_attrs[bus], sizeof(hal_spi_attr_t), attr, sizeof(hal_spi_attr_t));
272 (void)memcpy_s(&g_hal_spi_extra_attrs[bus], sizeof(hal_spi_extra_attr_t), extra_attr, sizeof(hal_spi_extra_attr_t));
273
274 return true;
275 }
276
spi_porting_clock_init(uint32_t bus_clk)277 __attribute__((weak)) void spi_porting_clock_init(uint32_t bus_clk)
278 {
279 unused(bus_clk);
280 return;
281 }
282
283 #pragma weak hal_spi_init = hal_spi_v151_init
hal_spi_v151_init(spi_bus_t bus,const hal_spi_attr_t * attr,const hal_spi_extra_attr_t * extra_attr,hal_spi_callback_t callback)284 errcode_t hal_spi_v151_init(spi_bus_t bus, const hal_spi_attr_t *attr,
285 const hal_spi_extra_attr_t *extra_attr, hal_spi_callback_t callback)
286 {
287 if (hal_spi_regs_init() != 0) {
288 return ERRCODE_SPI_REG_ADDR_INVALID;
289 }
290
291 spi_porting_clock_init(attr->bus_clk);
292
293 if (attr->is_slave == 1) {
294 spi_porting_set_device_mode(bus, SPI_MODE_SLAVE);
295 } else {
296 spi_porting_set_device_mode(bus, SPI_MODE_MASTER);
297 }
298
299 g_hal_spi_callback = callback;
300
301 if (hal_spi_init_config(bus, attr, extra_attr) != true) {
302 return ERRCODE_SPI_CONFIG_FAIL;
303 }
304 return ERRCODE_SUCC;
305 }
306
307 #pragma weak hal_spi_deinit = hal_spi_v151_deinit
hal_spi_v151_deinit(spi_bus_t bus)308 errcode_t hal_spi_v151_deinit(spi_bus_t bus)
309 {
310 g_hal_spi_callback = NULL;
311 hal_spi_ssienr_set_ssi_en(bus, 0);
312 return ERRCODE_SUCC;
313 }
314
hal_spi_pack_data_into_fifo(spi_bus_t bus,const uint8_t * data,uint32_t frame_bytes,hal_spi_frame_format_t spi_frame_format)315 static inline void hal_spi_pack_data_into_fifo(spi_bus_t bus, const uint8_t *data, uint32_t frame_bytes,
316 hal_spi_frame_format_t spi_frame_format)
317 {
318 if (frame_bytes == SPI_FRAME_BYTES_1) {
319 hal_spi_dr_set_dr(bus, (uint8_t)(*data));
320 } else { /* SPI_FRAME_BYTES_4 */
321 if (spi_frame_format == HAL_SPI_FRAME_FORMAT_STANDARD) {
322 hal_spi_dr_set_dr(bus, hal_spi_trans_bytes_to_word(data));
323 } else { /* SPI_FRAME_FORMAT_QUAD */
324 hal_spi_dr_set_dr(bus, *(uint32_t *)data);
325 }
326 }
327 }
328
329 #pragma weak hal_spi_write = hal_spi_v151_write
hal_spi_v151_write(spi_bus_t bus,hal_spi_xfer_data_t * data,uint32_t timeout)330 errcode_t hal_spi_v151_write(spi_bus_t bus, hal_spi_xfer_data_t *data, uint32_t timeout)
331 {
332 uint8_t *tx_buff = data->tx_buff;
333 uint32_t frame_bytes = hal_spi_frame_size_trans_to_frame_bytes(hal_spi_v151_spi_ctra_get_dfs32(bus));
334 hal_spi_frame_format_t spi_frame_format = hal_spi_get_frame_format(bus);
335 uint32_t trans_frames = data->tx_bytes / frame_bytes;
336 uint32_t trans_time = 0;
337
338 if (data->tx_bytes % frame_bytes != 0) {
339 return ERRCODE_SPI_INVALID_BYTES;
340 }
341
342 #if defined(CONFIG_SPI_SUPPORT_SINGLE_SPI)
343 if (g_hal_spi_attrs[bus].frame_format == SPI_CFG_FRAME_FORMAT_NS_MICROWIRE) {
344 hal_spi_ssienr_set_ssi_en(bus, 0);
345 if (data->rx_bytes > 0 && data->rx_buff != NULL) {
346 hal_spi_v151_spi_mcr_set_mtrc(bus, 0);
347 hal_spi_v151_spi_ctrb_set_nrdf(bus, (uint32_t)(data->rx_bytes / frame_bytes) - 1);
348 } else {
349 hal_spi_v151_spi_mcr_set_mtrc(bus, 1);
350 }
351 hal_spi_ssienr_set_ssi_en(bus, 1);
352 }
353 #endif
354
355 if (unlikely(spi_porting_get_device_mode(bus) == SPI_MODE_MASTER &&
356 spi_frame_format == HAL_SPI_FRAME_FORMAT_QUAD)) {
357 /* qspi mode: send cmd and register addr */
358 if (hal_spi_v151_spi_enhctl_get_ilen(bus) != 0) {
359 hal_spi_dr_set_dr(bus, data->cmd);
360 }
361 if (hal_spi_v151_spi_enhctl_get_addrlen(bus) != 0) {
362 hal_spi_dr_set_dr(bus, data->addr);
363 }
364 }
365
366 if (tx_buff == NULL) {
367 trans_frames = 0;
368 }
369 while (trans_frames > 0) {
370 if (hal_spi_v151_spi_wsr_get_tfnf(bus) != 0) {
371 hal_spi_pack_data_into_fifo(bus, tx_buff, frame_bytes, spi_frame_format);
372 tx_buff += frame_bytes;
373 trans_frames--;
374 }
375
376 if (hal_spi_check_timeout_by_count(&trans_time, timeout)) {
377 return ERRCODE_SPI_TIMEOUT;
378 }
379 }
380
381 return ERRCODE_SUCC;
382 }
383
hal_spi_pack_data_outof_fifo(spi_bus_t bus,uint8_t * data,uint32_t frame_bytes,hal_spi_frame_format_t spi_frame_format)384 static void hal_spi_pack_data_outof_fifo(spi_bus_t bus, uint8_t *data, uint32_t frame_bytes,
385 hal_spi_frame_format_t spi_frame_format)
386 {
387 if (frame_bytes == SPI_FRAME_BYTES_1) {
388 *data = (uint8_t)hal_spi_dr_get_dr(bus);
389 } else { /* SPI_FRAME_BYTES_4 */
390 if (spi_frame_format == HAL_SPI_FRAME_FORMAT_STANDARD) {
391 uint32_t data_read = hal_spi_dr_get_dr(bus);
392 (*(data + 0)) = hal_spi_trans_word_31_24_bits_to_byte(data_read); /* 0: TRANS_WORD 31-24 */
393 (*(data + 1)) = hal_spi_trans_word_23_16_bits_to_byte(data_read); /* 1: TRANS_WORD 23-16 */
394 (*(data + 2)) = hal_spi_trans_word_15_8_bits_to_byte(data_read); /* 2: TRANS_WORD 15-8 */
395 (*(data + 3)) = hal_spi_trans_word_7_0_bits_to_byte(data_read); /* 3: TRANS_WORD 7-0 */
396 } else {
397 *(uint32_t *)data = hal_spi_dr_get_dr(bus);
398 }
399 }
400 }
401
hal_spi_read_rx_mode_prepare(spi_bus_t bus)402 static bool hal_spi_read_rx_mode_prepare(spi_bus_t bus)
403 {
404 uint32_t wait_time = 0;
405 if (spi_porting_get_device_mode(bus) == SPI_MODE_MASTER &&
406 hal_spi_v151_spi_ctra_get_trsm(bus) == HAL_SPI_TRANS_MODE_RX) {
407 hal_spi_dr_set_dr(bus, 0); /* 解决主机读场景时,先任意写一个数据拉低CS发出时钟信号。 */
408
409 while (hal_spi_rxflr_get_rxtfl(bus) == 0) {
410 if (hal_spi_check_timeout_by_count(&wait_time, MAX_SPI_GET_RX_LEVEL_RETRY_TIMES)) {
411 return false;
412 }
413 }
414 }
415
416 return true;
417 }
418
419 #pragma weak hal_spi_read = hal_spi_v151_read
hal_spi_v151_read(spi_bus_t bus,hal_spi_xfer_data_t * data,uint32_t timeout)420 errcode_t hal_spi_v151_read(spi_bus_t bus, hal_spi_xfer_data_t *data, uint32_t timeout)
421 {
422 uint8_t *rx_buff = data->rx_buff;
423 uint32_t frame_bytes = hal_spi_frame_size_trans_to_frame_bytes(hal_spi_v151_spi_ctra_get_dfs32(bus));
424 hal_spi_frame_format_t spi_frame_format = hal_spi_get_frame_format(bus);
425 uint32_t trans_frames = data->rx_bytes / frame_bytes;
426 uint32_t trans_time = 0;
427 uint32_t timeout_tmp = (timeout == 0) ? SPI_RX_INT_WAIT_TIMES : timeout;
428
429 if (data->rx_bytes % frame_bytes != 0) {
430 return ERRCODE_SPI_INVALID_BYTES;
431 }
432
433 while (trans_frames > 0) {
434 if (hal_spi_v151_spi_wsr_get_rffe(bus) == 1) {
435 return ERRCODE_SPI_RX_FIFO_FULL;
436 }
437
438 if ((timeout != 0) && (!hal_spi_read_rx_mode_prepare(bus))) {
439 return ERRCODE_SPI_TIMEOUT;
440 }
441
442 uint32_t rx_level = hal_spi_rxflr_get_rxtfl(bus);
443 while (rx_level > 0) {
444 if (timeout == 0) {
445 trans_time = 0;
446 }
447 hal_spi_pack_data_outof_fifo(bus, rx_buff, frame_bytes, spi_frame_format);
448 rx_buff += frame_bytes;
449 trans_frames--;
450 rx_level--;
451 if (trans_frames == 0) {
452 break;
453 }
454 }
455
456 if (hal_spi_check_timeout_by_count(&trans_time, timeout_tmp)) {
457 if (timeout == 0) {
458 data->rx_bytes = trans_frames * frame_bytes;
459 return ERRCODE_SUCC;
460 }
461 return ERRCODE_SPI_TIMEOUT;
462 }
463 }
464
465 if (timeout == 0) {
466 data->rx_bytes = trans_frames * frame_bytes;
467 }
468 return ERRCODE_SUCC;
469 }
470
hal_spi_ctrl_set_attr(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)471 static errcode_t hal_spi_ctrl_set_attr(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
472 {
473 unused(id);
474
475 hal_spi_attr_t *attr = (hal_spi_attr_t *)param;
476
477 hal_spi_ssienr_set_ssi_en(bus, 0);
478 hal_spi_init_config_spi_frame_format(bus, (hal_spi_frame_format_t)attr->spi_frame_format);
479
480 /* Config the clock phase and polarity. */
481 hal_spi_v151_spi_ctra_set_scph(bus, attr->clk_phase);
482 hal_spi_v151_spi_ctra_set_scpol(bus, attr->clk_polarity);
483
484 /* Config the frame size. */
485 hal_spi_v151_spi_ctra_set_dfs32(bus, attr->frame_size);
486
487 /* Config the transfer mode. */
488 if (attr->frame_format == SPI_CFG_FRAME_FORMAT_NS_MICROWIRE) {
489 if (attr->tmod == HAL_SPI_TRANS_MODE_TX) {
490 hal_spi_v151_spi_mcr_set_mtrc(bus, 1);
491 } else {
492 hal_spi_v151_spi_mcr_set_mtrc(bus, 0);
493 }
494 }
495 hal_spi_v151_spi_ctra_set_trsm(bus, attr->tmod);
496
497 /* Config the number of data frames. */
498 if (attr->ndf > 0) {
499 hal_spi_v151_spi_ctrb_set_nrdf(bus, attr->ndf - 1);
500 } else {
501 hal_spi_v151_spi_ctrb_set_nrdf(bus, 0);
502 }
503
504 /* Config slave info and freq in master mode. */
505 if (attr->is_slave == 0) {
506 hal_spi_ser_set_ser(bus, (attr->slave_num == 0) ? 0 : bit(attr->slave_num - 1));
507 hal_spi_init_config_freq(bus, attr->bus_clk, attr->freq_mhz);
508 }
509
510 /* Config slave select toggle enable. */
511 hal_spi_v151_spi_ctra_set_ssn_te(bus, attr->sste);
512
513 hal_spi_ssienr_set_ssi_en(bus, 1);
514
515 (void)memcpy_s(&g_hal_spi_attrs[bus], sizeof(hal_spi_attr_t), attr, sizeof(hal_spi_attr_t));
516
517 return ERRCODE_SUCC;
518 }
519
hal_spi_ctrl_get_attr(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)520 static errcode_t hal_spi_ctrl_get_attr(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
521 {
522 unused(id);
523
524 hal_spi_attr_t *attr = (hal_spi_attr_t *)param;
525
526 (void)memcpy_s(attr, sizeof(hal_spi_attr_t), &g_hal_spi_attrs[bus], sizeof(hal_spi_attr_t));
527
528 return ERRCODE_SUCC;
529 }
530
hal_spi_ctrl_set_extra_attr(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)531 static errcode_t hal_spi_ctrl_set_extra_attr(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
532 {
533 unused(id);
534
535 hal_spi_extra_attr_t *extra_attr = (hal_spi_extra_attr_t *)param;
536
537 if (hal_spi_get_frame_format(bus) != HAL_SPI_FRAME_FORMAT_QUAD) {
538 return ERRCODE_SPI_MODE_MISMATCH;
539 }
540
541 hal_spi_config_qspi(bus, &extra_attr->qspi_param);
542
543 (void)memcpy_s(&g_hal_spi_extra_attrs[bus], sizeof(hal_spi_extra_attr_t), extra_attr, sizeof(hal_spi_extra_attr_t));
544
545 return ERRCODE_SUCC;
546 }
547
hal_spi_ctrl_get_extra_attr(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)548 static errcode_t hal_spi_ctrl_get_extra_attr(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
549 {
550 unused(id);
551
552 hal_spi_extra_attr_t *extra_attr = (hal_spi_extra_attr_t *)param;
553
554 (void)memcpy_s(extra_attr, sizeof(hal_spi_extra_attr_t), &g_hal_spi_extra_attrs[bus], sizeof(hal_spi_extra_attr_t));
555
556 return ERRCODE_SUCC;
557 }
558
hal_spi_ctrl_select_slave(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)559 static errcode_t hal_spi_ctrl_select_slave(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
560 {
561 unused(id);
562
563 if (hal_spi_is_busy(bus, CONFIG_SPI_MAX_TIMEOUT)) {
564 return ERRCODE_SPI_TIMEOUT;
565 }
566 uint32_t slave = (uint32_t)param;
567 hal_spi_ser_set_ser(bus, slave);
568 g_hal_spi_attrs[bus].slave_num = slave + 1;
569
570 return ERRCODE_SUCC;
571 }
572
573 #if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1)
hal_spi_ctrl_set_dma_cfg(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)574 static errcode_t hal_spi_ctrl_set_dma_cfg(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
575 {
576 unused(id);
577
578 hal_spi_dma_cfg_param_t *data = (hal_spi_dma_cfg_param_t *)param;
579 hal_spi_v151_spi_dcr_set_tden(bus, (uint32_t)data->is_enable);
580 hal_spi_dmacr_set_rdmae(bus, (uint32_t)data->is_enable);
581 hal_spi_v151_spi_dtdl_data_set_dl(bus, data->dma_tx_level);
582 hal_spi_dmardlr_set_dmardl(bus, data->dma_rx_level);
583
584 return ERRCODE_SUCC;
585 }
586
hal_spi_ctrl_get_dma_data_addr(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)587 static errcode_t hal_spi_ctrl_get_dma_data_addr(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
588 {
589 unused(id);
590
591 uint32_t *addr = (uint32_t *)param;
592 *addr = (uint32_t)(uintptr_t)(&(spis_v151_regs(bus)->spi_drnm[0]));
593
594 return ERRCODE_SUCC;
595 }
596 #endif /* CONFIG_SPI_SUPPORT_DMA */
597
598 #if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1)
hal_spi_ctrl_en_rxfi_int(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)599 static errcode_t hal_spi_ctrl_en_rxfi_int(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
600 {
601 unused(id);
602
603 uint32_t en = (uint32_t)param;
604 hal_spi_v151_spi_inmar_set_rffis(bus, en);
605 return ERRCODE_SUCC;
606 }
607
hal_spi_ctrl_check_rx_fifo_empty(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)608 static errcode_t hal_spi_ctrl_check_rx_fifo_empty(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
609 {
610 unused(id);
611
612 bool *rx_fifo_empty = (bool *)param;
613 if (hal_spi_v151_spi_wsr_get_rfne(bus) == 0) {
614 *rx_fifo_empty = true;
615 } else {
616 *rx_fifo_empty = false;
617 }
618 return ERRCODE_SUCC;
619 }
620
hal_spi_ctrl_en_txei_int(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)621 static errcode_t hal_spi_ctrl_en_txei_int(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
622 {
623 unused(id);
624
625 uint32_t en = (uint32_t)param;
626 hal_spi_v151_spi_inmar_set_tfeis(bus, en);
627 return ERRCODE_SUCC;
628 }
629
hal_spi_ctrl_check_tx_fifo_full(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)630 static errcode_t hal_spi_ctrl_check_tx_fifo_full(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
631 {
632 unused(id);
633
634 bool *tx_fifo_full = (bool *)param;
635 if (hal_spi_v151_spi_wsr_get_tfnf(bus) == 0) {
636 *tx_fifo_full = true;
637 } else {
638 *tx_fifo_full = false;
639 }
640 return ERRCODE_SUCC;
641 }
642 #endif /* CONFIG_SPI_SUPPORT_SLAVE */
643
hal_spi_ctrl_check_fifo_busy(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)644 static errcode_t hal_spi_ctrl_check_fifo_busy(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
645 {
646 unused(id);
647 uint32_t timeout = (uint32_t)param;
648 uint32_t trans_time = 0;
649
650 while (hal_spi_v151_spi_wsr_get_tfe(bus) != 1 || hal_spi_sr_get_busy(bus) != 0) {
651 if (hal_spi_check_timeout_by_count(&trans_time, timeout)) {
652 return ERRCODE_SPI_TIMEOUT;
653 }
654 }
655
656 return ERRCODE_SUCC;
657 }
658
659 #if defined(CONFIG_SPI_SUPPORT_LPM) && (CONFIG_SPI_SUPPORT_LPM == 1)
hal_spi_ctrl_suspend(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)660 static errcode_t hal_spi_ctrl_suspend(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
661 {
662 unused(id);
663 unused(param);
664 g_spi_suspend_regs[SPI_GET_MTRC] = hal_spi_v151_spi_mcr_get_mtrc(bus);
665 g_spi_suspend_regs[SPI_GET_TWL] = hal_spi_v151_spi_twlr_get_twl(bus);
666 g_spi_suspend_regs[SPI_GET_RWL] = hal_spi_v151_spi_rwlr_get_rwl(bus);
667 if (g_hal_spi_attrs[bus].is_slave == 0) {
668 g_spi_suspend_regs[SPI_GET_SSEF] = hal_spi_v151_spi_slenr_get_ssef(bus);
669 if ((hal_spi_frame_format_t)g_hal_spi_attrs[bus].spi_frame_format == HAL_SPI_FRAME_FORMAT_QUAD) {
670 g_spi_suspend_regs[SPI_GET_WAITNUM] = hal_spi_v151_spi_enhctl_get_waitnum(bus);
671 }
672 g_spi_suspend_regs[SPI_GET_NRDF] = hal_spi_v151_spi_ctrb_get_nrdf(bus);
673 }
674 return ERRCODE_SUCC;
675 }
676
hal_spi_ctrl_resume(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)677 static errcode_t hal_spi_ctrl_resume(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
678 {
679 unused(id);
680 unused(param);
681 if (g_hal_spi_attrs[bus].is_slave == 1) {
682 spi_porting_set_device_mode(bus, 1);
683 } else {
684 spi_porting_set_device_mode(bus, 0);
685 }
686 /* SPI parameter config */
687 hal_spi_ssienr_set_ssi_en(bus, 0);
688 hal_spi_v151_spi_ctra_set(bus, 0);
689 hal_spi_v151_spi_enhctl_set(bus, 0);
690
691 hal_spi_init_config_spi_frame_format(bus, (hal_spi_frame_format_t)g_hal_spi_attrs[bus].spi_frame_format);
692 hal_spi_v151_spi_ctra_set_prs(bus, (hal_spi_cfg_frame_format_t)g_hal_spi_attrs[bus].frame_format);
693
694 /* Config the clock phase and polarity. */
695 hal_spi_v151_spi_ctra_set_scph(bus, g_hal_spi_attrs[bus].clk_phase);
696 hal_spi_v151_spi_ctra_set_scpol(bus, g_hal_spi_attrs[bus].clk_polarity);
697
698 /* Config the frame size. */
699 hal_spi_v151_spi_ctra_set_dfs32(bus, g_hal_spi_attrs[bus].frame_size);
700 hal_spi_v151_spi_ctra_set_cfs16(bus, g_hal_spi_attrs[bus].frame_size);
701 /* Config the transfer mode and FIFO threshold. */
702 hal_spi_v151_spi_ctra_set_trsm(bus, g_hal_spi_attrs[bus].tmod);
703 hal_spi_v151_spi_mcr_set_mtrc(bus, g_spi_suspend_regs[SPI_GET_MTRC]);
704 hal_spi_txftlr_set_tft(bus, g_spi_suspend_regs[SPI_GET_TWL]);
705 hal_spi_rxftlr_set_rft(bus, g_spi_suspend_regs[SPI_GET_RWL]);
706
707 /* Config slave info and freq in master mode. */
708 if (g_hal_spi_attrs[bus].is_slave == 0) {
709 hal_spi_ser_set_ser(bus, g_spi_suspend_regs[SPI_GET_SSEF]);
710 hal_spi_init_config_freq(bus, g_hal_spi_attrs[bus].bus_clk, g_hal_spi_attrs[bus].freq_mhz);
711 if ((hal_spi_frame_format_t)g_hal_spi_attrs[bus].spi_frame_format == HAL_SPI_FRAME_FORMAT_QUAD) {
712 hal_spi_ssienr_set_ssi_en(bus, 0);
713 hal_spi_v151_spi_enhctl_set_aaitf(bus, g_hal_spi_extra_attrs[bus].qspi_param.trans_type);
714 hal_spi_v151_spi_enhctl_set_ilen(bus, g_hal_spi_extra_attrs[bus].qspi_param.inst_len);
715 hal_spi_v151_spi_enhctl_set_addrlen(bus, g_hal_spi_extra_attrs[bus].qspi_param.addr_len);
716 hal_spi_v151_spi_enhctl_set_waitnum(bus, g_spi_suspend_regs[SPI_GET_WAITNUM]);
717 hal_spi_ssienr_set_ssi_en(bus, 1);
718 }
719 #if defined(CONFIG_SPI_SUPPORT_SINGLE_SPI)
720 if ((hal_spi_cfg_frame_format_t)g_hal_spi_attrs[bus].frame_format == SPI_CFG_FRAME_FORMAT_NS_MICROWIRE) {
721 spi_porting_set_sspi_mode(bus, true);
722 hal_spi_v151_spi_rsvd_set(bus, g_hal_spi_extra_attrs[bus].sspi_param.wait_cycles);
723 }
724 #endif
725 hal_spi_v151_spi_ctrb_set_nrdf(bus, g_spi_suspend_regs[SPI_GET_NRDF]);
726 }
727
728 /* Config slave select toggle enable. */
729 hal_spi_v151_spi_ctra_set_ssn_te(bus, g_hal_spi_attrs[bus].sste);
730
731 /* Enable the SPI and all of the interrupts. */
732 hal_spi_ssienr_set_ssi_en(bus, 1);
733 hal_spi_v151_int_set(bus, SPI_INMAR_REG, 0);
734 return ERRCODE_SUCC;
735 }
736 #endif
737
hal_spi_ctrl_set_tmod(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)738 static errcode_t hal_spi_ctrl_set_tmod(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
739 {
740 unused(id);
741 #if defined(CONFIG_SPI_SUPPORT_SINGLE_SPI)
742 if (spi_porting_is_sspi_mode(bus)) {
743 return ERRCODE_SUCC;
744 }
745 #endif /* SPI_SUPPORT_SINGLE_SPI */
746 if (hal_spi_sr_get_busy(bus) == 1) {
747 return ERRCODE_SPI_BUSY;
748 }
749 hal_spi_attr_t *attr = (hal_spi_attr_t *)param;
750 hal_spi_ssienr_set_ssi_en(bus, 0);
751 hal_spi_v151_spi_ctra_set_trsm(bus, attr->tmod);
752 if (attr->tmod >= HAL_SPI_TRANS_MODE_RX) {
753 /* 仅在RX Only和EEPROM模式下配置。 */
754 hal_spi_v151_spi_ctrb_set_nrdf(bus, attr->ndf - 1);
755 }
756 hal_spi_ssienr_set_ssi_en(bus, 1);
757 g_hal_spi_attrs[bus].tmod = attr->tmod;
758 return ERRCODE_SUCC;
759 }
760
761 static const hal_spi_ctrl_t g_hal_spi_ctrl_func_array[SPI_CTRL_MAX] = {
762 hal_spi_ctrl_set_attr, /* SPI_CTRL_SET_ATTR */
763 hal_spi_ctrl_get_attr, /* SPI_CTRL_GET_ATTR */
764 hal_spi_ctrl_set_extra_attr, /* SPI_CTRL_SET_EXTRA_ATTR */
765 hal_spi_ctrl_get_extra_attr, /* SPI_CTRL_GET_EXTRA_ATTR */
766 hal_spi_ctrl_select_slave, /* SPI_CTRL_SELECT_SLAVE */
767 hal_spi_ctrl_check_fifo_busy, /* SPI_CTRL_CHECK_FIFO_BUSY */
768 #if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1)
769 hal_spi_ctrl_set_dma_cfg, /* SPI_CTRL_SET_DMA_CFG */
770 hal_spi_ctrl_get_dma_data_addr, /* SPI_CTRL_GET_DMA_DATA_ADDR */
771 #endif /* CONFIG_SPI_SUPPORT_DMA */
772 #if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1)
773 hal_spi_ctrl_en_rxfi_int, /* SPI_CTRL_EN_RXFI_INT */
774 hal_spi_ctrl_check_rx_fifo_empty, /* SPI_CTRL_CHECK_RX_FIFO_EMPTY */
775 hal_spi_ctrl_en_txei_int, /* SPI_CTRL_EN_TXEI_INT */
776 hal_spi_ctrl_check_tx_fifo_full, /* SPI_CTRL_CHECK_TX_FIFO_FULL */
777 NULL, /* SPI_CTRL_EN_MULTI_MASTER_ERR_INT */
778 #endif /* CONFIG_SPI_SUPPORT_SLAVE */
779 #if defined(CONFIG_SPI_SUPPORT_LPM) && (CONFIG_SPI_SUPPORT_LPM == 1)
780 hal_spi_ctrl_suspend,
781 hal_spi_ctrl_resume,
782 #endif /* CONFIG_SPI_SUPPORT_LPM */
783 hal_spi_ctrl_set_tmod, /* SPI_CTRL_SET_TMOD */
784 };
785
786 #pragma weak hal_spi_ctrl = hal_spi_v151_ctrl
hal_spi_v151_ctrl(spi_bus_t bus,hal_spi_ctrl_id_t id,uintptr_t param)787 errcode_t hal_spi_v151_ctrl(spi_bus_t bus, hal_spi_ctrl_id_t id, uintptr_t param)
788 {
789 return g_hal_spi_ctrl_func_array[id](bus, id, param);
790 }
791
792 #if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1)
hal_spi_v151_irq_handler(spi_bus_t bus)793 void hal_spi_v151_irq_handler(spi_bus_t bus)
794 {
795 if (!g_hal_spi_callback) {
796 return;
797 }
798
799 if (hal_spi_v151_int_get_rffis(bus, SPI_INSR_REG) == 1) {
800 g_hal_spi_callback(bus, SPI_EVT_RX_FULL_ISR, 0);
801 }
802 if (hal_spi_v151_int_get_rfufis(bus, SPI_INSR_REG) == 1) {
803 g_hal_spi_callback(bus, SPI_EVT_RX_UNDERFLOW_ISR, 0);
804 }
805 if (hal_spi_v151_int_get_rfofis(bus, SPI_INSR_REG) == 1) {
806 g_hal_spi_callback(bus, SPI_EVT_RX_OVERFLOW_ISR, 0);
807 }
808 if (hal_spi_v151_int_get_tfeis(bus, SPI_INSR_REG) == 1) {
809 g_hal_spi_callback(bus, SPI_EVT_TX_EMPTY_ISR, 0);
810 }
811 if (hal_spi_v151_int_get_tfofis(bus, SPI_INSR_REG) == 1) {
812 g_hal_spi_callback(bus, SPI_EVT_TX_OVERFLOW_ISR, 0);
813 }
814 hal_spi_v151_icr_set_any(bus);
815 }
816 #endif /* CONFIG_SPI_SUPPORT_SLAVE */