1 // Copyright (C) 2022 Beken Corporation
2 //
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 #pragma once
16
17 #include <soc/soc.h>
18 #include "hal_port.h"
19 #include <driver/hal/hal_gpio_types.h>
20 #include "spi_hw.h"
21 #include <driver/hal/hal_spi_types.h>
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 #define SPI_LL_REG_BASE(_spi_unit_id) (SOC_SPI_REG_BASE + _spi_unit_id * 0x1060000)
28
29 /*
30 * config GPIO44~GPIO47 for SPI0
31 */
32 #define SPI0_LL_SCK_PIN GPIO_44
33 #define SPI0_LL_CSN_PIN GPIO_45
34 #define SPI0_LL_MOSI_PIN GPIO_46
35 #define SPI0_LL_MISO_PIN GPIO_47
36
37 //TODO init more
spi_ll_init(spi_hw_t * hw)38 static inline void spi_ll_init(spi_hw_t *hw)
39 {
40 hw->ctrl.tx_fifo_int_level = 0;
41 hw->ctrl.rx_fifo_int_level = 2;
42 }
43
spi_ll_enable(spi_hw_t * hw)44 static inline void spi_ll_enable(spi_hw_t *hw)
45 {
46 hw->ctrl.enable = 1;
47 }
48
spi_ll_disable(spi_hw_t * hw)49 static inline void spi_ll_disable(spi_hw_t *hw)
50 {
51 hw->ctrl.enable = 0;
52 }
53
spi_ll_set_tx_fifo_int_level(spi_hw_t * hw,spi_fifo_int_level level)54 static inline void spi_ll_set_tx_fifo_int_level(spi_hw_t *hw, spi_fifo_int_level level)
55 {
56 hw->ctrl.tx_fifo_int_level = level;
57 }
58
spi_ll_set_rx_fifo_int_level(spi_hw_t * hw,spi_fifo_int_level level)59 static inline void spi_ll_set_rx_fifo_int_level(spi_hw_t *hw, spi_fifo_int_level level)
60 {
61 hw->ctrl.rx_fifo_int_level = level;
62 }
63
spi_ll_get_tx_fifo_int_level(spi_hw_t * hw)64 static inline uint32_t spi_ll_get_tx_fifo_int_level(spi_hw_t *hw)
65 {
66 switch (hw->ctrl.tx_fifo_int_level) {
67 case SPI_FIFO_INT_LEVEL_1:
68 return 1;
69 case SPI_FIFO_INT_LEVEL_16:
70 return 16;
71 case SPI_FIFO_INT_LEVEL_32:
72 return 32;
73 case SPI_FIFO_INT_LEVEL_48:
74 default:
75 return 48;
76 }
77 }
78
spi_ll_get_rx_fifo_int_level(spi_hw_t * hw)79 static inline uint32_t spi_ll_get_rx_fifo_int_level(spi_hw_t *hw)
80 {
81 switch (hw->ctrl.rx_fifo_int_level) {
82 case SPI_FIFO_INT_LEVEL_1:
83 return 1;
84 case SPI_FIFO_INT_LEVEL_16:
85 return 16;
86 case SPI_FIFO_INT_LEVEL_32:
87 return 32;
88 case SPI_FIFO_INT_LEVEL_48:
89 default:
90 return 48;
91 }
92 }
93
spi_ll_enable_tx_underflow_int(spi_hw_t * hw)94 static inline void spi_ll_enable_tx_underflow_int(spi_hw_t *hw)
95 {
96 hw->ctrl.tx_udf_int_en = 1;
97 }
98
spi_ll_disable_tx_underflow_int(spi_hw_t * hw)99 static inline void spi_ll_disable_tx_underflow_int(spi_hw_t *hw)
100 {
101 hw->ctrl.tx_udf_int_en = 0;
102 }
103
spi_ll_enable_rx_overflow_int(spi_hw_t * hw)104 static inline void spi_ll_enable_rx_overflow_int(spi_hw_t *hw)
105 {
106 hw->ctrl.rx_ovf_int_en = 1;
107 }
108
spi_ll_disable_rx_overflow_int(spi_hw_t * hw)109 static inline void spi_ll_disable_rx_overflow_int(spi_hw_t *hw)
110 {
111 hw->ctrl.rx_ovf_int_en = 0;
112 }
113
spi_ll_enable_tx_fifo_int(spi_hw_t * hw)114 static inline void spi_ll_enable_tx_fifo_int(spi_hw_t *hw)
115 {
116 hw->ctrl.tx_fifo_int_en = 1;
117 }
118
spi_ll_disable_tx_fifo_int(spi_hw_t * hw)119 static inline void spi_ll_disable_tx_fifo_int(spi_hw_t *hw)
120 {
121 hw->ctrl.tx_fifo_int_en = 0;
122 }
123
spi_ll_enable_rx_fifo_int(spi_hw_t * hw)124 static inline void spi_ll_enable_rx_fifo_int(spi_hw_t *hw)
125 {
126 hw->ctrl.rx_fifo_int_en = 1;
127 }
128
spi_ll_disable_rx_fifo_int(spi_hw_t * hw)129 static inline void spi_ll_disable_rx_fifo_int(spi_hw_t *hw)
130 {
131 hw->ctrl.rx_fifo_int_en = 0;
132 }
133
spi_ll_set_clk_div(spi_hw_t * hw,uint32_t clk_div)134 static inline void spi_ll_set_clk_div(spi_hw_t *hw, uint32_t clk_div)
135 {
136 hw->ctrl.clk_rate = clk_div & SPI_F_CLK_DIV_M;
137 }
138
spi_ll_enable_slave_release_int(spi_hw_t * hw)139 static inline void spi_ll_enable_slave_release_int(spi_hw_t *hw)
140 {
141 hw->ctrl.slave_release_int_en = 1;
142 }
143
spi_ll_disable_slave_release_int(spi_hw_t * hw)144 static inline void spi_ll_disable_slave_release_int(spi_hw_t *hw)
145 {
146 hw->ctrl.slave_release_int_en = 0;
147 }
148
spi_ll_set_wire_mode(spi_hw_t * hw,spi_wire_mode_t wire_mode)149 static inline void spi_ll_set_wire_mode(spi_hw_t *hw, spi_wire_mode_t wire_mode)
150 {
151 hw->ctrl.wire3_en = wire_mode;
152 }
153
spi_ll_set_bit_width(spi_hw_t * hw,spi_bit_width_t bit_width)154 static inline void spi_ll_set_bit_width(spi_hw_t *hw, spi_bit_width_t bit_width)
155 {
156 hw->ctrl.bit_width = bit_width;
157 }
158
spi_ll_set_first_bit(spi_hw_t * hw,spi_bit_order_t first_bit)159 static inline void spi_ll_set_first_bit(spi_hw_t *hw, spi_bit_order_t first_bit)
160 {
161 hw->ctrl.lsb_first_en = first_bit;
162 }
163
spi_ll_set_cpol(spi_hw_t * hw,spi_polarity_t cpol)164 static inline void spi_ll_set_cpol(spi_hw_t *hw, spi_polarity_t cpol)
165 {
166 hw->ctrl.cpol = cpol;
167 }
168
spi_ll_set_cpha(spi_hw_t * hw,spi_phase_t cpha)169 static inline void spi_ll_set_cpha(spi_hw_t *hw, spi_phase_t cpha)
170 {
171 hw->ctrl.cpha = cpha;
172 }
173
spi_ll_set_role(spi_hw_t * hw,spi_role_t role)174 static inline void spi_ll_set_role(spi_hw_t *hw, spi_role_t role)
175 {
176 hw->ctrl.master_en = role;
177 }
178
spi_ll_set_role_master(spi_hw_t * hw)179 static inline void spi_ll_set_role_master(spi_hw_t *hw)
180 {
181 hw->ctrl.master_en = 1;
182 }
183
spi_ll_set_role_slave(spi_hw_t * hw)184 static inline void spi_ll_set_role_slave(spi_hw_t *hw)
185 {
186 hw->ctrl.master_en = 0;
187 }
188
spi_ll_is_role_master(spi_hw_t * hw)189 static inline bool spi_ll_is_role_master(spi_hw_t *hw)
190 {
191 return !!(hw->ctrl.master_en);
192 }
193
spi_ll_is_role_slave(spi_hw_t * hw)194 static inline bool spi_ll_is_role_slave(spi_hw_t *hw)
195 {
196 return !(hw->ctrl.master_en);
197 }
198
spi_ll_enable_tx(spi_hw_t * hw)199 static inline void spi_ll_enable_tx(spi_hw_t *hw)
200 {
201 hw->cfg.tx_en = 1;
202 }
203
spi_ll_disable_tx(spi_hw_t * hw)204 static inline void spi_ll_disable_tx(spi_hw_t *hw)
205 {
206 hw->cfg.tx_en = 0;
207 }
208
spi_ll_enable_rx(spi_hw_t * hw)209 static inline void spi_ll_enable_rx(spi_hw_t *hw)
210 {
211 hw->cfg.rx_en = 1;
212 }
213
spi_ll_disable_rx(spi_hw_t * hw)214 static inline void spi_ll_disable_rx(spi_hw_t *hw)
215 {
216 hw->cfg.rx_en = 0;
217 }
218
spi_ll_enable_tx_finish_int(spi_hw_t * hw)219 static inline void spi_ll_enable_tx_finish_int(spi_hw_t *hw)
220 {
221 hw->cfg.tx_finish_int_en = 1;
222 }
223
spi_ll_disable_tx_finish_int(spi_hw_t * hw)224 static inline void spi_ll_disable_tx_finish_int(spi_hw_t *hw)
225 {
226 hw->cfg.tx_finish_int_en = 0;
227 }
228
spi_ll_enable_rx_finish_int(spi_hw_t * hw)229 static inline void spi_ll_enable_rx_finish_int(spi_hw_t *hw)
230 {
231 hw->cfg.rx_finish_int_en = 1;
232 }
233
spi_ll_disable_rx_finish_int(spi_hw_t * hw)234 static inline void spi_ll_disable_rx_finish_int(spi_hw_t *hw)
235 {
236 hw->cfg.rx_finish_int_en = 0;
237 }
238
spi_ll_set_tx_trans_len(spi_hw_t * hw,uint32_t len)239 static inline void spi_ll_set_tx_trans_len(spi_hw_t *hw, uint32_t len)
240 {
241 if (hw->ctrl.bit_width == SPI_BIT_WIDTH_16BITS) {
242 len = len / 2;
243 }
244 hw->cfg.tx_trans_len = len & SPI_F_TX_TRANS_LEN_M;
245 }
246
spi_ll_set_rx_trans_len(spi_hw_t * hw,uint32_t len)247 static inline void spi_ll_set_rx_trans_len(spi_hw_t *hw, uint32_t len)
248 {
249 if (hw->ctrl.bit_width == SPI_BIT_WIDTH_16BITS) {
250 len = len / 2;
251 }
252 hw->cfg.rx_trans_len = len & SPI_F_RX_TRANS_LEN_M;
253 }
254
spi_ll_clear_int_status(spi_hw_t * hw)255 static inline void spi_ll_clear_int_status(spi_hw_t *hw)
256 {
257 hw->int_status.tx_fifo_int = 1;
258 hw->int_status.rx_fifo_int = 1;
259 hw->int_status.slave_release_int = 1;
260 hw->int_status.tx_underflow_int = 1;
261 hw->int_status.rx_overflow_int = 1;
262 }
263
spi_ll_clear_slave_release_int_status(spi_hw_t * hw)264 static inline void spi_ll_clear_slave_release_int_status(spi_hw_t *hw)
265 {
266 hw->int_status.slave_release_int = 1;
267 }
268
spi_ll_reset_slave_release_int_status_to_default(spi_hw_t * hw)269 static inline void spi_ll_reset_slave_release_int_status_to_default(spi_hw_t *hw)
270 {
271 hw->int_status.slave_release_int = 0;
272 }
273
spi_ll_clear_tx_underflow_int_status(spi_hw_t * hw)274 static inline void spi_ll_clear_tx_underflow_int_status(spi_hw_t *hw)
275 {
276 hw->int_status.tx_underflow_int = 1;
277 }
278
spi_ll_clear_rx_overflow_int_status(spi_hw_t * hw)279 static inline void spi_ll_clear_rx_overflow_int_status(spi_hw_t *hw)
280 {
281 hw->int_status.rx_overflow_int = 1;
282 }
283
spi_ll_get_interrupt_status(spi_hw_t * hw)284 static inline uint32_t spi_ll_get_interrupt_status(spi_hw_t *hw)
285 {
286 return hw->int_status.v;
287 }
288
spi_ll_clear_interrupt_status(spi_hw_t * hw,uint32_t status)289 static inline void spi_ll_clear_interrupt_status(spi_hw_t *hw, uint32_t status)
290 {
291 hw->int_status.v = status;
292 }
293
spi_ll_is_tx_fifo_wr_ready(spi_hw_t * hw)294 static inline bool spi_ll_is_tx_fifo_wr_ready(spi_hw_t *hw)
295 {
296 return !!(hw->int_status.tx_fifo_wr_ready);
297 }
298
spi_ll_is_rx_fifo_rd_ready(spi_hw_t * hw)299 static inline bool spi_ll_is_rx_fifo_rd_ready(spi_hw_t *hw)
300 {
301 return !!(hw->int_status.rx_fifo_rd_ready);
302 }
303
spi_ll_is_tx_fifo_int_triggered(spi_hw_t * hw)304 static inline bool spi_ll_is_tx_fifo_int_triggered(spi_hw_t *hw)
305 {
306 return !!(hw->int_status.tx_fifo_int);
307 }
308
spi_ll_is_rx_fifo_int_triggered(spi_hw_t * hw)309 static inline bool spi_ll_is_rx_fifo_int_triggered(spi_hw_t *hw)
310 {
311 return !!(hw->int_status.rx_fifo_int);
312 }
313
spi_ll_is_tx_fifo_int_triggered_with_status(spi_hw_t * hw,uint32_t status)314 static inline bool spi_ll_is_tx_fifo_int_triggered_with_status(spi_hw_t *hw, uint32_t status)
315 {
316 return !!(status & BIT(8));
317 }
318
spi_ll_is_rx_fifo_int_triggered_with_status(spi_hw_t * hw,uint32_t status)319 static inline bool spi_ll_is_rx_fifo_int_triggered_with_status(spi_hw_t *hw, uint32_t status)
320 {
321 return !!(status & BIT(9));
322 }
323
spi_ll_is_slave_release_int_triggered(spi_hw_t * hw,uint32_t status)324 static inline bool spi_ll_is_slave_release_int_triggered(spi_hw_t *hw, uint32_t status)
325 {
326 return !!(status & BIT(10));
327 }
328
spi_ll_is_tx_finish_int_triggered(spi_hw_t * hw,uint32_t status)329 static inline bool spi_ll_is_tx_finish_int_triggered(spi_hw_t *hw, uint32_t status)
330 {
331 return !!(status & BIT(13));
332 }
333
spi_ll_is_rx_finish_int_triggered(spi_hw_t * hw,uint32_t status)334 static inline bool spi_ll_is_rx_finish_int_triggered(spi_hw_t *hw, uint32_t status)
335 {
336 return !!(status & BIT(14));
337 }
338
spi_ll_is_rx_overflow_int_triggered(spi_hw_t * hw,uint32_t status)339 static inline bool spi_ll_is_rx_overflow_int_triggered(spi_hw_t *hw, uint32_t status)
340 {
341 return !!(status & BIT(12));
342 }
343
spi_ll_is_tx_underflow_int_triggered(spi_hw_t * hw,uint32_t status)344 static inline bool spi_ll_is_tx_underflow_int_triggered(spi_hw_t *hw, uint32_t status)
345 {
346 return !!(status & BIT(11));
347 }
348
spi_ll_clear_tx_finish_int_status(spi_hw_t * hw)349 static inline void spi_ll_clear_tx_finish_int_status(spi_hw_t *hw)
350 {
351 hw->int_status.tx_finish_int = 1;
352 }
353
spi_ll_clear_rx_finish_int_status(spi_hw_t * hw)354 static inline void spi_ll_clear_rx_finish_int_status(spi_hw_t *hw)
355 {
356 hw->int_status.rx_finish_int = 1;
357 }
358
spi_ll_clear_tx_fifo_int_status(spi_hw_t * hw)359 static inline void spi_ll_clear_tx_fifo_int_status(spi_hw_t *hw)
360 {
361 hw->int_status.tx_fifo_int = 1;
362 }
363
spi_ll_clear_rx_fifo_int_status(spi_hw_t * hw)364 static inline void spi_ll_clear_rx_fifo_int_status(spi_hw_t *hw)
365 {
366 hw->int_status.rx_fifo_int = 1;
367 }
368
spi_ll_clear_tx_fifo(spi_hw_t * hw)369 static inline void spi_ll_clear_tx_fifo(spi_hw_t *hw)
370 {
371 hw->int_status.tx_fifo_clr = 1;
372 }
373
spi_ll_clear_rx_fifo(spi_hw_t * hw)374 static inline void spi_ll_clear_rx_fifo(spi_hw_t *hw)
375 {
376 hw->int_status.rx_fifo_clr = 1;
377 }
378
spi_ll_write_byte(spi_hw_t * hw,uint32_t data)379 static inline void spi_ll_write_byte(spi_hw_t *hw, uint32_t data)
380 {
381 hw->data.fifo_data = data;
382 }
383
spi_ll_read_byte(spi_hw_t * hw)384 static inline uint32_t spi_ll_read_byte(spi_hw_t *hw)
385 {
386 return hw->data.fifo_data;
387 }
388
389 #ifdef __cplusplus
390 }
391 #endif
392
393