• 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 
16 #include "spi.h"
17 #include <hi_time.h>
18 #include <hi_stdlib.h>
19 #include <hi_isr.h>
20 #include <hi_event.h>
21 #ifdef CONFIG_SPI_DMA_SUPPORT
22 #include <dma.h>
23 #endif
24 
25 spi_ctrl *g_spi_ctrl[SPI_NUM] = { 0 };
26 
spi_check_rx_fifo_empty(hi_u32 reg_base)27 HI_ALWAYS_STAIC_INLINE hi_bool spi_check_rx_fifo_empty(hi_u32 reg_base)
28 {
29     hi_u16 reg_val = 0;
30     hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
31     if (reg_val & MASK_SPI_SR_RNE) {
32         return HI_FALSE;
33     }
34     return HI_TRUE;
35 }
36 
spi_check_busy(hi_u32 reg_base)37 HI_ALWAYS_STAIC_INLINE hi_bool spi_check_busy(hi_u32 reg_base)
38 {
39     hi_u16 reg_val = 0;
40     hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
41     if (reg_val & MASK_SPI_SR_BSY) {
42         return HI_TRUE;
43     }
44     return HI_FALSE;
45 }
46 
spi_check_write_timeout(hi_u32 reg_base)47 HI_ALWAYS_STAIC_INLINE hi_u32 spi_check_write_timeout(hi_u32 reg_base)
48 {
49     hi_u16 reg_val = 0;
50     hi_u32 count = 0;
51     while (count++ < SPI_HOST_TIMEOUT_US) {
52         hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
53         if ((reg_val & MASK_SPI_SR_TFE) && (!(reg_val & MASK_SPI_SR_BSY))) {
54             break;
55         }
56         hi_udelay(1);
57     }
58     if (count >= SPI_HOST_TIMEOUT_US) {
59         spi_process_printf("%s spi transfer wait timeout!", __func__);
60         return HI_ERR_SPI_WRITE_TIMEOUT;
61     }
62     return HI_ERR_SUCCESS;
63 }
64 
65 /* check tx fifo not full */
spi_check_tnf_timeout(hi_u32 reg_base,HI_CONST hi_u32 time_out_us)66 HI_ALWAYS_STAIC_INLINE hi_u32 spi_check_tnf_timeout(hi_u32 reg_base, HI_CONST hi_u32 time_out_us)
67 {
68     hi_u16 reg_val = 0;
69     hi_u32 count = 0;
70     while (count++ < time_out_us) {
71         hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
72         if ((reg_val & MASK_SPI_SR_TNF)) {
73             break;
74         }
75         hi_udelay(1);
76     }
77     if (count >= time_out_us) {
78         if (reg_val & MASK_SPI_SR_TNF) {
79             spi_process_printf("MASK_SPI_SR_TNF\n");
80         }
81         if (reg_val & MASK_SPI_SR_BSY) {
82             spi_process_printf("MASK_SPI_SR_BSY \n");
83         }
84         return HI_ERR_SPI_WRITE_TIMEOUT;
85     }
86     return HI_ERR_SUCCESS;
87 }
88 /* check rx fifo not empty */
spi_check_rne_timeout(hi_u32 reg_base,HI_CONST hi_u32 time_out_us)89 HI_ALWAYS_STAIC_INLINE hi_u32 spi_check_rne_timeout(hi_u32 reg_base, HI_CONST hi_u32 time_out_us)
90 {
91     hi_u16 reg_val = 0;
92     hi_u32 count = 0;
93     while (count++ < time_out_us) {
94         hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
95         if (((reg_val & MASK_SPI_SR_RNE))) {
96             break;
97         }
98         hi_udelay(1);
99     }
100     if (count >= time_out_us) {
101         spi_process_printf("%s timeout!\n", __func__);
102         return HI_ERR_SPI_WRITE_TIMEOUT;
103     }
104     return HI_ERR_SUCCESS;
105 }
106 
107 /*
108  * spi_flush_fifo: flush spi fifo
109  */
spi_flush_fifo(hi_u32 reg_base)110 hi_void spi_flush_fifo(hi_u32 reg_base)
111 {
112     hi_u16 reg_val = 0;
113     hi_u16 fifo_len = (reg_base == HI_SSP0_REG_BASE ? SPI0_FIFO_LEN : SPI1_FIFO_LEN);
114     for (hi_u16 i = 0; i < fifo_len; i++) {
115         hi_reg_read16(reg_base + REG_SPI_SR, reg_val);
116         if (!(reg_val & MASK_SPI_SR_RNE)) {
117             break;
118         }
119         hi_reg_read16(reg_base + REG_SPI_DR, reg_val);
120     }
121 }
122 
spi_disable(spi_ctrl * ctrl)123 hi_void spi_disable(spi_ctrl *ctrl)
124 {
125     hi_u16 reg_val = 0;
126     if (ctrl == NULL) {
127         spi_process_printf("spi_disable para is null \n");
128         return;
129     }
130     if ((ctrl->spi_cfg.is_slave == 0) && spi_check_busy(ctrl->reg_base)) {
131         ctrl->disable_later = HI_TRUE;
132         return;
133     }
134     hi_reg_read16(ctrl->reg_base + REG_SPI_CR1, reg_val);
135     reg_val &= ~(1 << SPI_CR1_ST_BIT_SSE);
136     hi_reg_write16(ctrl->reg_base + REG_SPI_CR1, reg_val);
137 }
138 
spi_enable(spi_ctrl * ctrl)139 static hi_void spi_enable(spi_ctrl *ctrl)
140 {
141     hi_u16 reg_val = 0;
142 
143     hi_reg_read16(ctrl->reg_base + REG_SPI_CR1, reg_val);
144     reg_val |= (1 << SPI_CR1_ST_BIT_SSE);
145     hi_reg_write16(ctrl->reg_base + REG_SPI_CR1, reg_val);
146     ctrl->disable_later = HI_FALSE;
147 }
148 
spi_reset(const spi_ctrl * spi_hw_ctrl)149 hi_void spi_reset(const spi_ctrl *spi_hw_ctrl)
150 {
151     hi_u8 reset_bit;
152     hi_u16 reg_val = 0;
153     hi_u32 int_value;
154     if (spi_hw_ctrl != HI_NULL &&
155         spi_hw_ctrl->reg_base == HI_SSP0_REG_BASE) {
156         reset_bit = CRG_REG_SSP_SRST_REQ_OFFSET;
157     } else {
158         reset_bit = CRG_REG_SSP2_SRST_REQ_OFFSET;
159     }
160     int_value = hi_int_lock();
161     hi_reg_read16(CLDO_CTL_SOFT_RESET_REG, reg_val);
162     reg_val &= (~((hi_u16)(1 << reset_bit)));
163     hi_reg_write16(CLDO_CTL_SOFT_RESET_REG, reg_val);
164     reg_val |= (hi_u16)(1 << reset_bit);
165     hi_reg_write16(CLDO_CTL_SOFT_RESET_REG, reg_val);
166     hi_int_restore(int_value);
167 }
168 
spi_config(const spi_ctrl * spi_hw_ctrl)169 hi_u32 spi_config(const spi_ctrl *spi_hw_ctrl)
170 {
171     spi_inner_cfg inner_cfg = { 0 };
172     if (spi_hw_ctrl == HI_NULL) {
173         return HI_ERR_FAILURE;
174     }
175     if (memcpy_s(&inner_cfg, sizeof(spi_inner_cfg), &spi_hw_ctrl->spi_cfg, sizeof(spi_inner_cfg)) == EOK) {
176         hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_CR0, inner_cfg.cr0);
177         hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_CR1, inner_cfg.cr1);
178         hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_CPSR, inner_cfg.cpsdvsr);
179     } else {
180         return HI_ERR_FAILURE;
181     }
182     return HI_ERR_SUCCESS;
183 }
184 
spi_set_fifo_line(const spi_ctrl * spi_hw_ctrl)185 hi_void spi_set_fifo_line(const spi_ctrl *spi_hw_ctrl)
186 {
187     hi_u16 reg_val;
188     if (spi_hw_ctrl == HI_NULL) {
189         return;
190     }
191     hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
192     reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK << SPI_FIFO_LINE_OFFSET);
193     reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.tx_fifo_line << SPI_FIFO_LINE_OFFSET);
194     hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
195     hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
196     reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK << SPI_FIFO_LINE_OFFSET);
197     reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.rx_fifo_line << SPI_FIFO_LINE_OFFSET);
198     hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
199 }
200 
201 #ifdef CONFIG_SPI_DMA_SUPPORT
spi_set_dma_fifo_line(const spi_ctrl * spi_hw_ctrl)202 hi_void spi_set_dma_fifo_line(const spi_ctrl *spi_hw_ctrl)
203 {
204     hi_u16 reg_val;
205     if (spi_hw_ctrl == HI_NULL) {
206         return;
207     }
208     hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
209     reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK);
210     reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.tx_fifo_dma_line);
211     hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_TXFIFOCR, reg_val);
212     hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
213     reg_val &= ~(hi_u16)(SPI_FIFO_LINE_MASK);
214     reg_val |= (hi_u16)(spi_hw_ctrl->spi_cfg.rx_fifo_dma_line);
215     hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_RXFIFOCR, reg_val);
216 }
217 
dma_write_fifo_callback(hi_u32 irq_type)218 hi_void dma_write_fifo_callback(hi_u32 irq_type)
219 {
220     spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
221     if (irq_type == DMA_INT_TC) {
222         hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_TX_DATA);
223     } else {
224         hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_TX_ERR_DATA);
225     }
226 }
dma_read_fifo_callback(hi_u32 irq_type)227 hi_void dma_read_fifo_callback(hi_u32 irq_type)
228 {
229     spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
230     if (irq_type == DMA_INT_TC) {
231         hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_RX_DATA);
232     } else {
233         hi_event_send(g_spi_ctrl[0]->event_id, HI_EVENT_BIT_DMA_RX_ERR_DATA);
234     }
235 }
dma_write_fifo_callback_spi1(hi_u32 irq_type)236 hi_void dma_write_fifo_callback_spi1(hi_u32 irq_type)
237 {
238     spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
239     if (irq_type == DMA_INT_TC) {
240         hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_TX_DATA);
241     } else {
242         hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_TX_ERR_DATA);
243     }
244 }
dma_read_fifo_callback_spi1(hi_u32 irq_type)245 hi_void dma_read_fifo_callback_spi1(hi_u32 irq_type)
246 {
247     spi_process_printf("This is callback,irq type is %d\r\n", irq_type);
248     if (irq_type == DMA_INT_TC) {
249         hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_RX_DATA);
250     } else {
251         hi_event_send(g_spi_ctrl[1]->event_id, HI_EVENT_BIT_DMA_RX_ERR_DATA);
252     }
253 }
254 
spi_get_rx_dma_burst_size(spi_ctrl * spi_dev_ctrl)255 HI_ALWAYS_STAIC_INLINE hi_u32 spi_get_rx_dma_burst_size(spi_ctrl *spi_dev_ctrl)
256 {
257     spi_hw_cfg *spi_cfg = &(spi_dev_ctrl->spi_cfg);
258     if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
259         return spi_cfg->rx_fifo_dma_line >=
260                 SPI0_RX_FIFO_DMA_WLINE_128 ? DMA_BURST_MSIZE_128 : spi_cfg->rx_fifo_dma_line;
261     } else {
262         return spi_cfg->rx_fifo_dma_line >= SPI1_RX_FIFO_DMA_WLINE_32 ? DMA_BURST_MSIZE_32 : spi_cfg->rx_fifo_dma_line;
263     }
264 }
265 
spi_get_tx_dma_burst_size(spi_ctrl * spi_dev_ctrl)266 HI_ALWAYS_STAIC_INLINE hi_u32 spi_get_tx_dma_burst_size(spi_ctrl *spi_dev_ctrl)
267 {
268     spi_hw_cfg *spi_cfg = &(spi_dev_ctrl->spi_cfg);
269     if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
270         return spi_cfg->tx_fifo_dma_line >= SPI0_TX_FIFO_DMA_WLINE_64 ? DMA_BURST_MSIZE_128 : spi_cfg->tx_fifo_dma_line;
271     } else {
272         return spi_cfg->tx_fifo_dma_line >= SPI1_TX_FIFO_DMA_WLINE_16 ? DMA_BURST_MSIZE_32 : spi_cfg->tx_fifo_dma_line;
273     }
274 }
275 
spi_dma_enable(hi_u32 reg_base,hi_u16 enable_bits)276 hi_void spi_dma_enable(hi_u32 reg_base, hi_u16 enable_bits) /* 使能DMA(按bit操作) */
277 {
278     hi_u16 reg_val = 0;
279     hi_u32 int_save;
280     int_save = hi_int_lock();
281     hi_reg_read16(reg_base + REG_SPI_DMACR, reg_val);
282     reg_val |= enable_bits;
283     hi_reg_write16(reg_base + REG_SPI_DMACR, reg_val);
284     hi_int_restore(int_save);
285     spi_process_printf("dma enable 0x%x 0x%x", reg_base, reg_val);
286 }
287 
spi_dma_disable(hi_u32 reg_base,hi_u16 disable_bits)288 hi_void spi_dma_disable(hi_u32 reg_base, hi_u16 disable_bits) /* 清除DMA使能位(按bit操作) */
289 {
290     hi_u16 reg_val = 0;
291     hi_u32 int_save;
292     int_save = hi_int_lock();
293     hi_reg_read16(reg_base + REG_SPI_DMACR, reg_val);
294     reg_val &= (~disable_bits);
295     hi_reg_write16(reg_base + REG_SPI_DMACR, reg_val);
296     hi_int_restore(int_save);
297 }
298 
spi_dma_transer(hi_u32 tr_type,spi_ctrl * spi_dev_ctrl,uintptr_t addr,hi_u32 tran_len,hi_void (* cb)(hi_u32),hi_u32 * ch_num)299 hi_u32 spi_dma_transer(hi_u32 tr_type, spi_ctrl *spi_dev_ctrl, uintptr_t addr, hi_u32 tran_len,
300                        hi_void (*cb)(hi_u32),
301                        hi_u32 *ch_num)
302 {
303     hi_u32 reg_base = spi_dev_ctrl->reg_base;
304     hi_u32 data_width = WIDTH_BIT8;
305     if (hi_unlikely(spi_dev_ctrl->spi_cfg.data_width > HI_SPI_CFG_DATA_WIDTH_E_8BIT)) {
306         data_width = WIDTH_BIT16;
307     }
308     hi_u8 dma_burst_size;
309     hi_u32 dma_ts;
310     hi_dma_para dma_para;
311     dma_para.tr_type = tr_type;
312     dma_para.src_width = data_width;
313     dma_para.dst_width = data_width;
314     if (tr_type == MEM_TO_SPI) {
315         dma_para.dst_addr = reg_base + REG_SPI_DR;
316         dma_para.src_addr = addr;
317         dma_para.dst_phl = (reg_base == HI_SSP0_REG_BASE) ? SPI0_TX : SPI1_TX;
318         dma_para.src_phl = 0;
319         dma_burst_size = spi_get_tx_dma_burst_size(spi_dev_ctrl);
320     } else {
321         dma_para.dst_addr = addr;
322         dma_para.src_addr = reg_base + REG_SPI_DR;
323         dma_para.dst_phl = 0;
324         dma_para.src_phl = (reg_base == HI_SSP0_REG_BASE) ? SPI0_RX : SPI1_RX;
325         dma_burst_size = spi_get_rx_dma_burst_size(spi_dev_ctrl);
326     }
327     dma_ts = spi_get_transfer_size(dma_burst_size);
328     dma_para.dst_burst_size = (dma_ts > tran_len) ? DMA_BURST_MSIZE_1 : dma_burst_size;
329     dma_para.src_burst_size = (dma_ts > tran_len) ? DMA_BURST_MSIZE_1 : dma_burst_size;
330     dma_para.transfer_size = tran_len;
331     dma_para.cb = cb;
332     return dma_hw_request_transfer(&dma_para, ch_num);
333 }
334 
335 /*
336 ・dma read fifo can used for slave device
337  */
spi_hd_dma_read_fifo(spi_ctrl * spi_dev_ctrl,hi_u32 timeout_ms)338 hi_u32 spi_hd_dma_read_fifo(spi_ctrl *spi_dev_ctrl, hi_u32 timeout_ms)
339 {
340     if (spi_dev_ctrl == HI_NULL) {
341         return HI_ERR_FAILURE;
342     }
343     hi_pvoid read_buf = spi_dev_ctrl->rx_buf.buf;
344     hi_u32 read_pos = spi_dev_ctrl->rx_buf.cur_pos;
345     hi_u32 loop = spi_dev_ctrl->trans_len - spi_dev_ctrl->rx_buf.cur_cnt;
346     hi_u32 ret;
347     hi_u32 event_bit = 0;
348     hi_u32 ch_num = 0xff; /* set invalid value 0xff */
349     if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
350         if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
351             ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u8 *)read_buf + read_pos), loop,
352                                   dma_read_fifo_callback, &ch_num);
353         } else {
354             ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u16 *)read_buf + read_pos), loop,
355                                   dma_read_fifo_callback, &ch_num);
356         }
357     } else {
358         if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
359             ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u8 *)read_buf + read_pos), loop,
360                                   dma_read_fifo_callback_spi1, &ch_num);
361         } else {
362             ret = spi_dma_transer(SPI_TO_MEM, spi_dev_ctrl, (uintptr_t)((hi_u16 *)read_buf + read_pos), loop,
363                                   dma_read_fifo_callback_spi1, &ch_num);
364         }
365     }
366     if (ret != HI_ERR_SUCCESS) {
367         return ret;
368     }
369     ret = hi_event_wait(spi_dev_ctrl->event_id, HI_EVENT_BIT_DMA_RX_DATA, &event_bit, timeout_ms,
370                         HI_EVENT_WAITMODE_OR | HI_EVENT_WAITMODE_CLR);
371     if (event_bit & HI_EVENT_BIT_DMA_RX_ERR_DATA) {
372         spi_process_printf("DMA trans err\n");
373         return HI_ERR_FAILURE;
374     }
375     if (ret == HI_ERR_EVENT_WAIT_TIME_OUT) {
376         hi_dma_ch_close(ch_num);
377         spi_process_printf("read time out\n");
378         return HI_ERR_SPI_WRITE_TIMEOUT;
379     }
380     spi_dev_ctrl->rx_buf.cur_cnt += loop; /* update cur_cnt and read_pos/cur_pos */
381     spi_dev_ctrl->rx_buf.cur_pos += loop;
382     return ret;
383 }
spi_hd_dma_write_fifo(spi_ctrl * spi_dev_ctrl,hi_u32 timeout_ms)384 hi_u32 spi_hd_dma_write_fifo(spi_ctrl *spi_dev_ctrl, hi_u32 timeout_ms)
385 {
386     if (spi_dev_ctrl == NULL) {
387         return HI_ERR_FAILURE;
388     }
389     hi_pvoid write_buf = spi_dev_ctrl->tx_buf.buf;
390     hi_u32 write_pos = spi_dev_ctrl->tx_buf.cur_pos;
391     hi_u32 loop = spi_dev_ctrl->trans_len - spi_dev_ctrl->tx_buf.cur_cnt;
392     hi_u32 ret;
393     hi_u32 event_bit = 0;
394     hi_u32 ch_num = 0xff; /* set invalid value 0xff */
395     if (spi_dev_ctrl->reg_base == HI_SSP0_REG_BASE) {
396         if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
397             ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u8 *)write_buf + write_pos), loop,
398                                   dma_write_fifo_callback, &ch_num);
399         } else {
400             ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u16 *)write_buf + write_pos), loop,
401                                   dma_write_fifo_callback, &ch_num);
402         }
403     } else {
404         if (spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT) {
405             ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u8 *)write_buf + write_pos), loop,
406                                   dma_write_fifo_callback_spi1, &ch_num);
407         } else {
408             ret = spi_dma_transer(MEM_TO_SPI, spi_dev_ctrl, (uintptr_t)((hi_u16 *)write_buf + write_pos), loop,
409                                   dma_write_fifo_callback_spi1, &ch_num);
410         }
411     }
412     if (ret != HI_ERR_SUCCESS) { /* dma fail */
413         return ret;
414     }
415     ret = hi_event_wait(spi_dev_ctrl->event_id, HI_EVENT_BIT_DMA_TX_DATA | HI_EVENT_BIT_DMA_TX_ERR_DATA, &event_bit,
416                         timeout_ms, HI_EVENT_WAITMODE_OR | HI_EVENT_WAITMODE_CLR);
417     if (event_bit & HI_EVENT_BIT_DMA_TX_ERR_DATA) {
418         spi_process_printf("DMA trans err\n");
419         return HI_ERR_FAILURE;
420     }
421     if (ret == HI_ERR_EVENT_WAIT_TIME_OUT) {
422         hi_dma_ch_close(ch_num);
423         spi_process_printf("WRITE time out, ch_num:%d, ret:%x\n", ch_num, ret);
424         return HI_ERR_SPI_WRITE_TIMEOUT;
425     }
426     spi_dev_ctrl->tx_buf.cur_cnt += loop; /* update cur_cnt and read_pos/cur_pos */
427     spi_dev_ctrl->tx_buf.cur_pos += loop;
428     return ret;
429 }
430 #endif
431 
spi_isr_enable(hi_u32 reg_base,hi_u16 enable_bits)432 hi_void spi_isr_enable(hi_u32 reg_base, hi_u16 enable_bits)
433 {
434     hi_u16 reg_val = 0;
435     hi_u32 int_save;
436     int_save = hi_int_lock();
437     hi_reg_read16(reg_base + REG_SPI_IMSC, reg_val);
438     reg_val |= enable_bits;
439     hi_reg_write16(reg_base + REG_SPI_IMSC, reg_val);
440     hi_int_restore(int_save);
441     spi_process_printf("isr enable 0x%x 0x%x", reg_base, reg_val);
442 }
443 
spi_isr_disable(hi_u32 reg_base,hi_u16 disable_bits)444 hi_void spi_isr_disable(hi_u32 reg_base, hi_u16 disable_bits)
445 {
446     hi_u16 reg_val = 0;
447     hi_u32 int_save;
448     int_save = hi_int_lock();
449     hi_reg_read16(reg_base + REG_SPI_IMSC, reg_val);
450     reg_val &= (~disable_bits);
451     hi_reg_write16(reg_base + REG_SPI_IMSC, reg_val);
452     hi_int_restore(int_save);
453 }
spi_isr_clear_cr(hi_u32 reg_base,hi_u16 clear_bit)454 hi_void spi_isr_clear_cr(hi_u32 reg_base, hi_u16 clear_bit)
455 {
456     hi_u16 reg_val = 0;
457     hi_u32 int_save;
458     int_save = hi_int_lock();
459     hi_reg_read16(reg_base + REG_SPI_CR, reg_val);
460     reg_val |= clear_bit;
461     hi_reg_write16(reg_base + REG_SPI_CR, reg_val);
462     hi_int_restore(int_save);
463 }
464 
spi_isr_read_16bits(spi_ctrl * spi_dev_ctrl,hi_bool fifo_irq,hi_u32 loop,hi_pvoid read_buf,hi_u16 increase_step)465 HI_ALWAYS_STAIC_INLINE hi_void spi_isr_read_16bits(spi_ctrl *spi_dev_ctrl, hi_bool fifo_irq, hi_u32 loop,
466                                                    hi_pvoid read_buf, hi_u16 increase_step)
467 {
468     hi_u32 i;
469     hi_u32 reg_base = spi_dev_ctrl->reg_base;
470     hi_u32 read_pos = spi_dev_ctrl->rx_buf.cur_pos;
471     if (fifo_irq) {
472         for (i = 0; i < loop; i++) {
473             *((hi_u16 *)read_buf + read_pos) = (hi_u16)hi_reg_read_val16(reg_base + REG_SPI_DR);
474             read_pos += increase_step;
475         }
476         spi_dev_ctrl->rx_buf.cur_cnt += loop;
477     } else {
478         for (i = 0; i < loop; i++) {
479             if (hi_likely(!spi_check_rx_fifo_empty(reg_base))) {
480                 *((hi_u16 *)read_buf + read_pos) = (hi_u16)hi_reg_read_val16(reg_base + REG_SPI_DR);
481                 read_pos += increase_step;
482                 spi_dev_ctrl->rx_buf.cur_cnt++;
483             } else {
484                 break;
485             }
486         }
487     }
488     spi_dev_ctrl->rx_buf.cur_pos = read_pos;
489 }
490 
spi_isr_read_8bits(spi_ctrl * spi_dev_ctrl,hi_bool fifo_irq,hi_u32 loop,hi_pvoid read_buf,hi_u16 increase_step)491 HI_ALWAYS_STAIC_INLINE hi_void spi_isr_read_8bits(spi_ctrl *spi_dev_ctrl, hi_bool fifo_irq, hi_u32 loop,
492                                                   hi_pvoid read_buf, hi_u16 increase_step)
493 {
494     hi_u32 i;
495     hi_u32 reg_base = spi_dev_ctrl->reg_base;
496     hi_u32 read_pos = spi_dev_ctrl->rx_buf.cur_pos;
497     if (fifo_irq) {
498         for (i = 0; i < loop; i++) {
499             *((hi_u8 *)read_buf + read_pos) = (hi_u8)hi_reg_read_val16(reg_base + REG_SPI_DR);
500             read_pos += increase_step;
501         }
502         spi_dev_ctrl->rx_buf.cur_cnt += loop;
503     } else {
504         for (i = 0; i < loop; i++) {
505             if (hi_likely(!spi_check_rx_fifo_empty(reg_base))) {
506                 *((hi_u8 *)read_buf + read_pos) = (hi_u8)hi_reg_read_val16(reg_base + REG_SPI_DR);
507                 read_pos += increase_step;
508                 spi_dev_ctrl->rx_buf.cur_cnt++;
509             } else {
510                 break;
511             }
512         }
513     }
514     spi_dev_ctrl->rx_buf.cur_pos = read_pos;
515 }
516 
spi_isr_read_fifo(spi_ctrl * spi_dev_ctrl,hi_bool fifo_irq)517 static hi_u16 spi_isr_read_fifo(spi_ctrl *spi_dev_ctrl, hi_bool fifo_irq)
518 {
519     hi_pvoid read_buf = spi_dev_ctrl->rx_buf.buf;
520     hi_u16 fix_data = SPI_UNUSE_DATA;
521     hi_u16 increase_step = 1;
522     hi_u32 loop = hi_min(spi_dev_ctrl->single_len, (spi_dev_ctrl->trans_len - spi_dev_ctrl->rx_buf.cur_cnt));
523     if (read_buf == HI_NULL) {
524         read_buf = &fix_data;
525         increase_step = 0;
526     }
527 
528     if (hi_likely(spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT)) {
529         spi_isr_read_8bits(spi_dev_ctrl, fifo_irq, loop, read_buf, increase_step);
530     } else {
531         spi_isr_read_16bits(spi_dev_ctrl, fifo_irq, loop, read_buf, increase_step);
532     }
533 
534     if (spi_dev_ctrl->rx_buf.cur_cnt >= spi_dev_ctrl->trans_len) {
535         return SPI_INT_BIT_RX_FIFO_WATER_LINE | SPI_INT_BIT_RX_FIFO_TIME_OUT;
536     }
537     return 0;
538 }
539 
spi_isr_write_fifo(spi_ctrl * spi_dev_ctrl)540 static hi_u16 spi_isr_write_fifo(spi_ctrl *spi_dev_ctrl)
541 {
542     hi_pvoid write_buf = spi_dev_ctrl->tx_buf.buf;
543     hi_u32 i;
544     hi_u16 fix_data = SPI_UNUSE_DATA;
545     hi_u16 increase_step = 1;
546     hi_u32 reg_base = spi_dev_ctrl->reg_base;
547     hi_u32 len = spi_dev_ctrl->single_len;
548     hi_u32 write_pos = spi_dev_ctrl->tx_buf.cur_pos;
549     if (write_buf == HI_NULL) {
550         write_buf = &fix_data;
551         increase_step = 0;
552     }
553     if (hi_likely(spi_dev_ctrl->spi_cfg.data_width < HI_SPI_CFG_DATA_WIDTH_E_9BIT)) {
554         for (i = 0; i < len; i++) {
555             spi_process_printf("[wreg8][0x%x]", *((hi_u8 *)write_buf + write_pos));
556             hi_reg_write16(reg_base + REG_SPI_DR, *((hi_u8 *)write_buf + write_pos));
557             write_pos += increase_step;
558         }
559         spi_dev_ctrl->tx_buf.cur_cnt += len;
560     } else {
561         for (i = 0; i < len; i++) {
562             spi_process_printf("[wreg16][0x%x]", *((hi_u16 *)write_buf + write_pos));
563             hi_reg_write16(reg_base + REG_SPI_DR, *((hi_u16 *)write_buf + write_pos));
564             write_pos += increase_step;
565         }
566         spi_dev_ctrl->tx_buf.cur_cnt += len;
567     }
568     spi_dev_ctrl->tx_buf.cur_pos = write_pos;
569     if (spi_dev_ctrl->tx_buf.cur_cnt == spi_dev_ctrl->single_len) {
570         spi_dev_ctrl->tx_buf.cur_cnt = 0;
571         return SPI_INT_BIT_TX_FIFO_WATER_LINE;
572     }
573     return 0;
574 }
575 
spi_isr(spi_ctrl * spi_dev_ctrl)576 hi_void spi_isr(spi_ctrl *spi_dev_ctrl)
577 {
578     if (spi_dev_ctrl == NULL) {
579         spi_process_printf("spi_isr para is null \n");
580         return;
581     }
582     hi_u32 reg_base = spi_dev_ctrl->reg_base;
583     hi_u16 int_val;
584     hi_u32 event_bits = 0;
585     hi_u16 dis_int_bis = 0;
586     hi_u16 clear_int_bits = 0;
587     hi_u32 ret;
588     hi_reg_read16(reg_base + REG_SPI_MIS, int_val);
589     if (int_val & SPI_INT_BIT_TX_FIFO_WATER_LINE) {
590         dis_int_bis |= spi_isr_write_fifo(spi_dev_ctrl);
591         event_bits |= HI_EVENT_BIT_TX_DATA;
592     }
593     if (int_val & SPI_INT_BIT_RX_FIFO_WATER_LINE) {
594         dis_int_bis |= spi_isr_read_fifo(spi_dev_ctrl, HI_TRUE);
595         event_bits |= HI_EVENT_BIT_RX_DATA;
596     }
597     if (int_val & SPI_INT_BIT_RX_FIFO_TIME_OUT) {
598         dis_int_bis |= spi_isr_read_fifo(spi_dev_ctrl, HI_FALSE);
599         event_bits |= HI_EVENT_BIT_RX_DATA;
600         clear_int_bits |= SPI_INT_BIT_RTIC;
601     }
602     if (int_val & SPI_INT_BIT_RX_FIFO_OVER_FLOW) {
603         dis_int_bis |= SPI_INT_BIT_RX_FIFO_OVER_FLOW;
604         event_bits |= HI_EVENT_BIT_RX_FIFO_OVER_FLOW;
605         clear_int_bits |= SPI_INT_BIT_RORIC;
606     }
607     spi_isr_clear_cr(reg_base, clear_int_bits);
608     spi_isr_disable(reg_base, dis_int_bis);
609     if (spi_dev_ctrl->disable_later && !spi_check_busy(reg_base)) {
610         spi_dev_ctrl->disable_later = HI_FALSE;
611     }
612     ret = hi_event_send(spi_dev_ctrl->event_id, event_bits);
613     if (ret != HI_ERR_SUCCESS) {
614         spi_process_printf("spi_isr send sig fail \n");
615     }
616 }
617 
spi_trans_prepare(spi_ctrl * spi_hw_ctrl,spi_trans_attr * trans_attr)618 hi_u32 spi_trans_prepare(spi_ctrl *spi_hw_ctrl, spi_trans_attr *trans_attr)
619 {
620     hi_u32 ret = HI_ERR_SUCCESS;
621     if ((spi_hw_ctrl == NULL) || (trans_attr == NULL)) {
622         return HI_ERR_FAILURE;
623     }
624 
625     if (trans_attr->trans_opt & SPI_OPT_WAIT_SIGNAL) {
626         spi_process_printf("wait_sem\n");
627         ret = hi_sem_wait(spi_hw_ctrl->sem_id, trans_attr->time_out_ms);
628         if (ret != HI_ERR_SUCCESS) {
629             return ret;
630         }
631         trans_attr->trans_opt |= SPI_OPT_TASKED_SIGNAL;
632     }
633     spi_hw_ctrl->transferring = HI_TRUE;
634     if (spi_hw_ctrl->prepare_func) {
635         spi_hw_ctrl->prepare_func();
636     }
637     if (trans_attr->trans_opt & SPI_OPT_ENABLE_SPI) {
638         spi_enable(spi_hw_ctrl);
639     }
640     return ret;
641 }
642 
spi_trans_restore(spi_ctrl * spi_hw_ctrl,const spi_trans_attr * trans_attr)643 hi_void spi_trans_restore(spi_ctrl *spi_hw_ctrl, const spi_trans_attr *trans_attr)
644 {
645     if ((spi_hw_ctrl == NULL) || (trans_attr == NULL)) {
646         return;
647     }
648     if (spi_hw_ctrl->restore_func) {
649         spi_hw_ctrl->restore_func();
650     }
651 
652     if ((trans_attr->trans_opt & SPI_OPT_TASKED_SIGNAL) && (trans_attr->trans_opt & SPI_OPT_FREE_SIGNAL)) {
653         spi_process_printf("free_sem\n");
654         hi_u32 ret = hi_sem_signal(spi_hw_ctrl->sem_id);
655         if (ret != HI_ERR_SUCCESS) {
656             spi_process_printf("free_sem fail\n");
657         }
658     }
659     spi_hw_ctrl->transferring = HI_FALSE;
660 }
661 
spi_transfer_8bits_block(const spi_ctrl * spi_hw_ctrl,hi_u32 options)662 hi_u32 spi_transfer_8bits_block(const spi_ctrl *spi_hw_ctrl, hi_u32 options)
663 {
664     if (spi_hw_ctrl == NULL) {
665         return HI_ERR_FAILURE;
666     }
667     hi_u32 tmp_len, count;
668     hi_u16 value;
669     hi_u8 *tx = (hi_u8 *)spi_hw_ctrl->tx_buf.buf;
670     hi_u8 *rx = (hi_u8 *)spi_hw_ctrl->rx_buf.buf;
671     hi_u32 len = spi_hw_ctrl->trans_len;
672     hi_u16 fifo_len = (spi_hw_ctrl->reg_base == HI_SSP0_REG_BASE ? SPI0_FIFO_LEN : SPI1_FIFO_LEN);
673     hi_bool write_not_fix = ((options & SPI_OPT_SEND_FIX_DATA) == 0);
674     hi_bool read_not_fix = ((options & SPI_OPT_RCV_FIX_DATA) == 0);
675     hi_u32 ret;
676     while (len) {
677         if (len > fifo_len) {
678             tmp_len = fifo_len;
679         } else {
680             tmp_len = len;
681         }
682         len -= tmp_len;
683         /* wirte fifo */
684         count = tmp_len;
685         value = SPI_UNUSE_DATA;
686         while (count) {
687             if (write_not_fix && tx != HI_NULL) {
688                 value = *tx++;
689             }
690             hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
691             count -= 1;
692         }
693         ret = spi_check_write_timeout(spi_hw_ctrl->reg_base);
694         if (ret != HI_ERR_SUCCESS) {
695             return HI_ERR_SPI_WRITE_TIMEOUT;
696         }
697         /* if host device too fast, there be delay 50-100us */
698         /* read fifo */
699         count = tmp_len;
700         while (count) {
701             hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
702             if (read_not_fix && rx != HI_NULL) {
703                 *rx++ = (hi_u8)value;
704             }
705             count -= 1;
706         }
707     }
708     return HI_ERR_SUCCESS;
709 }
710 
711 /*
712  * spi_txrx16: send and receive 16bit data
713  */
spi_transfer_16bits_block(const spi_ctrl * spi_hw_ctrl,hi_u32 options)714 hi_u32 spi_transfer_16bits_block(const spi_ctrl *spi_hw_ctrl, hi_u32 options)
715 {
716     if (spi_hw_ctrl == NULL) {
717         return HI_ERR_FAILURE;
718     }
719     hi_u32 len = spi_hw_ctrl->trans_len;
720     hi_u32 tmp_len;
721     hi_u32 count;
722     hi_u16 *tx = (hi_u16 *)spi_hw_ctrl->tx_buf.buf;
723     hi_u16 *rx = (hi_u16 *)spi_hw_ctrl->rx_buf.buf;
724     hi_u16 value;
725     hi_u16 fifo_len = (spi_hw_ctrl->reg_base == HI_SSP0_REG_BASE ? SPI0_FIFO_LEN : SPI1_FIFO_LEN);
726     hi_bool write_not_fix = ((options & SPI_OPT_SEND_FIX_DATA) == 0);
727     hi_bool read_not_fix = ((options & SPI_OPT_RCV_FIX_DATA) == 0);
728     hi_u32 ret;
729     while (len) {
730         if (len > fifo_len) {
731             tmp_len = fifo_len;
732         } else {
733             tmp_len = len;
734         }
735         len -= tmp_len;
736         /* wirte fifo */
737         count = tmp_len;
738         value = SPI_UNUSE_DATA;
739         while (count) {
740             if (write_not_fix && tx != HI_NULL) {
741                 value = *tx++;
742             }
743             hi_reg_write16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
744             count--;
745         }
746         ret = spi_check_write_timeout(spi_hw_ctrl->reg_base);
747         if (ret != HI_ERR_SUCCESS) {
748             return HI_ERR_SPI_WRITE_TIMEOUT;
749         }
750         /* if host device too fast, there be delay 50-100us */
751         count = tmp_len;
752         while (count) {
753             hi_reg_read16(spi_hw_ctrl->reg_base + REG_SPI_DR, value);
754             if (read_not_fix && rx != HI_NULL) {
755                 *rx++ = value;
756             }
757             count--;
758         }
759     }
760     return HI_ERR_SUCCESS;
761 }
762