• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */