1 /*
2  * Copyright (C) 2019 ETH Zurich, University of Bologna
3  * and GreenWaves Technologies
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef HAL_INCLUDE_HAL_SPI_PERIPH_H_
19 #define HAL_INCLUDE_HAL_SPI_PERIPH_H_
20 
21 #include "hal_udma_core_periph.h"
22 
23 /* ----------------------------------------------------------------------------
24    -- SPI Peripheral Access Layer --
25    ---------------------------------------------------------------------------- */
26 
27 /** SPI_Type Register Layout Typedef */
28 typedef struct {
29 	udma_channel_t rx; /**< UDMA RX channels struct. */
30 	udma_channel_t tx; /**< UDMA RX channels struct. */
31 	udma_channel_t cmd; /**< UDMA RX channels struct. */
32 } spi_t;
33 
34 /* ----------------------------------------------------------------------------
35    -- SPI Register Bitfield Access --
36    ---------------------------------------------------------------------------- */
37 
38 /* SPI command fields offset, mask, value definition */
39 /* SPI commands fields offsets */
40 #define SPI_CMD_ID_OFFSET 28
41 
42 /* COMMON definitions */
43 #define SPI_CMD_QPI_ENA		  1
44 #define SPI_CMD_QPI_DIS		  0
45 #define SPI_CMD_LSB_FIRST	  1
46 #define SPI_CMD_MSB_FIRST	  0
47 #define SPI_CMD_4_WORD_PER_TRANSF 2
48 #define SPI_CMD_2_WORD_PER_TRANSF 1
49 #define SPI_CMD_1_WORD_PER_TRANSF 0
50 #define SPI_CMD_DATA_WITDH(val)	  (val)
51 #define SPI_CMD_CMD_SIZE(val)	  (val)
52 
53 /* CFG */
54 #define SPI_CMD_CFG_CLK_DIV_OFFSET 0
55 #define SPI_CMD_CFG_CLK_DIV_WIDTH  8
56 #define SPI_CMD_CFG_CPHA_OFFSET	   8
57 #define SPI_CMD_CFG_CPOL_OFFSET	   9
58 
59 #define SPI_CMD_CFG_CLKDIV(val) (val)
60 #define SPI_CMD_CFG_CPOL_POS	1
61 #define SPI_CMD_CFG_CPOL_NEG	0
62 #define SPI_CMD_CFG_CPHA_STD	1
63 #define SPI_CMD_CFG_CPHA_OPP	0
64 
65 /* SOT */
66 #define SPI_CMD_SOT_CS_OFFSET 0
67 #define SPI_CMD_SOT_CS_WIDTH  2
68 
69 #define SPI_CMD_SOT_CS0 0
70 #define SPI_CMD_SOT_CS1 1
71 #define SPI_CMD_SOT_CS2 2
72 #define SPI_CMD_SOT_CS3 3
73 
74 /* SEND_CMD */
75 #define SPI_CMD_SEND_CMD_CMD_OFFSET  0
76 #define SPI_CMD_SEND_CMD_CMD_WIDTH   16
77 #define SPI_CMD_SEND_CMD_SIZE_OFFSET 16
78 #define SPI_CMD_SEND_CMD_SIZE_WIDTH  4
79 #define SPI_CMD_SEND_CMD_QPI_OFFSET  27
80 
81 /* SEND_CMD */
82 #define SPI_CMD_SEND_BITS_BITS_OFFSET 0
83 #define SPI_CMD_SEND_BITS_BITS_WIDTH  16
84 #define SPI_CMD_SEND_BITS_SIZE_OFFSET 16
85 #define SPI_CMD_SEND_BITS_SIZE_WIDTH  4
86 #define SPI_CMD_SEND_BITS_QPI_OFFSET  27
87 
88 /* SEND_ADDR */
89 #define SPI_CMD_SEND_ADDR_SIZE_OFFSET 16
90 #define SPI_CMD_SEND_ADDR_SIZE_WIDTH  5
91 #define SPI_CMD_SEND_ADDR_QPI_OFFSET  27
92 
93 #define SPI_CMD_SEND_ADDR_VALUE(value) (value)
94 
95 /* SEND_DUMMY */
96 #define SPI_CMD_DUMMY_CYCLE_OFFSET 16
97 #define SPI_CMD_DUMMY_CYCLE_WIDTH  5
98 
99 /* TX_DATA */
100 #define SPI_CMD_TX_DATA_SIZE_OFFSET	 0
101 #define SPI_CMD_TX_DATA_SIZE_WIDTH	 16
102 #define SPI_CMD_TX_DATA_QPI_OFFSET	 27
103 #define SPI_CMD_TX_DATA_WORDTRANS_OFFSET 21
104 #define SPI_CMD_TX_DATA_WORDTRANS_WIDTH	 2
105 #define SPI_CMD_TX_DATA_LSBFIRST_OFFSET	 26
106 #define SPI_CMD_TX_DATA_BITSWORD_OFFSET	 16
107 #define SPI_CMD_TX_DATA_BITSWORD_WIDTH	 5
108 
109 /* RX_DATA */
110 #define SPI_CMD_RX_DATA_SIZE_OFFSET	 0
111 #define SPI_CMD_RX_DATA_SIZE_WIDTH	 16
112 #define SPI_CMD_RX_DATA_QPI_OFFSET	 27
113 #define SPI_CMD_RX_DATA_WORDTRANS_OFFSET 21
114 #define SPI_CMD_RX_DATA_WORDTRANS_WIDTH	 2
115 #define SPI_CMD_RX_DATA_LSBFIRST_OFFSET	 26
116 #define SPI_CMD_RX_DATA_BITSWORD_OFFSET	 16
117 #define SPI_CMD_RX_DATA_BITSWORD_WIDTH	 5
118 
119 /* RPT */
120 #define SPI_CMD_RPT_NB_OFFSET 0
121 #define SPI_CMD_RPT_NB_WIDTH  16
122 
123 /* EOT */
124 #define SPI_CMD_EOT_GEN_EVT_OFFSET 0
125 #define SPI_CMD_EOT_CS_KEEP_OFFSET 1
126 
127 #define SPI_CMD_EOT_EVENT_ENA 1
128 #define SPI_CMD_EOT_EVENT_DIS 0
129 
130 /* WAIT */
131 #define SPI_CMD_WAIT_EVENT_OFFSET 0
132 #define SPI_CMD_WAIT_EVENT_WIDTH  2
133 
134 /* RX_CHECK */
135 #define SPI_CMD_RX_CHECK_VALUE_OFFSET 0
136 #define SPI_CMD_RX_CHECK_VALUE_WIDTH  16
137 
138 #define SPI_CMD_RX_CHECK_SIZE_OFFSET 16
139 #define SPI_CMD_RX_CHECK_SIZE_WIDTH  4
140 
141 #define SPI_CMD_RX_CHECK_MODE_OFFSET 24
142 #define SPI_CMD_RX_CHECK_MODE_WIDTH  2
143 
144 #define SPI_CMD_RX_CHECK_BYTE_ALIGN_OFFSET 26
145 
146 #define SPI_CMD_RX_CHECK_QPI_OFFSET 27
147 
148 #define SPI_CMD_RX_CHECK_MODE_MATCH 0
149 #define SPI_CMD_RX_CHECK_MODE_ONES  1
150 #define SPI_CMD_RX_CHECK_MODE_ZEROS 2
151 #define SPI_CMD_RX_CHECK_MODE_MASK  3
152 
153 /* FULL DUPLEX */
154 #define SPI_CMD_FUL_SIZE_OFFSET	     0
155 #define SPI_CMD_FUL_SIZE_WIDTH	     16
156 #define SPI_CMD_FUL_WORDTRANS_OFFSET 21
157 #define SPI_CMD_FUL_WORDTRANS_WIDTH  2
158 #define SPI_CMD_FUL_LSBFIRST_OFFSET  26
159 #define SPI_CMD_FUL_BITSWORD_OFFSET  16
160 #define SPI_CMD_FUL_BITSWORD_WIDTH   5
161 
162 #define SPI_CMD_SETUP_UC_TXRXEN_OFFSET 27
163 #define SPI_CMD_SETUP_UC_DS_OFFSET     25
164 
165 /* ----------------------------------------------------------------------------
166    -- SPI CMD IDs and macros --
167    ---------------------------------------------------------------------------- */
168 
169 /*! @name CMD_CFG */
170 /* Channel continuous mode:
171   - 1'b0: disable
172   - 1'b1: enable
173   At the end of the buffer the uDMA reloads the address and size and starts a new transfer. */
174 #define UDMA_CORE_CMD_CFG_CONTINOUS_MASK  (0x1)
175 #define UDMA_CORE_CMD_CFG_CONTINOUS_SHIFT (0)
176 #define UDMA_CORE_CMD_CFG_CONTINOUS(val)                                       \
177 	(((uint32_t)(((uint32_t)(val))                                         \
178 		     << UDMA_CORE_CMD_CFG_CONTINOUS_SHIFT)) &                  \
179 	 UDMA_CORE_CMD_CFG_CONTINOUS_MASK)
180 
181 /* Channel transfer size used to increment uDMA buffer address pointer:
182   - 2'b00: +1 (8 bits)
183   - 2'b01: +2 (16 bits)
184   - 2'b10: +4 (32 bits)
185   - 2'b11: +0 */
186 #define UDMA_CORE_CMD_CFG_DATASIZE_MASK	 (0x6)
187 #define UDMA_CORE_CMD_CFG_DATASIZE_SHIFT (1)
188 #define UDMA_CORE_CMD_CFG_DATASIZE(val)                                        \
189 	(((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_DATASIZE_SHIFT)) & \
190 	 UDMA_CORE_CMD_CFG_DATASIZE_MASK)
191 
192 /* Reserved/Not used. */
193 #define UDMA_CORE_CMD_CFG_RESERVED_0_MASK  (0x8)
194 #define UDMA_CORE_CMD_CFG_RESERVED_0_SHIFT (3)
195 #define UDMA_CORE_CMD_CFG_RESERVED_0(val)                                      \
196 	(((uint32_t)(((uint32_t)(val))                                         \
197 		     << UDMA_CORE_CMD_CFG_RESERVED_0_SHIFT)) &                 \
198 	 UDMA_CORE_CMD_CFG_RESERVED_0_MASK)
199 
200 /* Channel enable and start transfer:
201   - 1'b0: disable
202   - 1'b1: enable
203   This signal is used also to queue a transfer if one is already ongoing. */
204 #define UDMA_CORE_CMD_CFG_EN_MASK  (0x10)
205 #define UDMA_CORE_CMD_CFG_EN_SHIFT (4)
206 #define UDMA_CORE_CMD_CFG_EN(val)                                              \
207 	(((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_EN_SHIFT)) &       \
208 	 UDMA_CORE_CMD_CFG_EN_MASK)
209 
210 /* Transfer pending in queue status flag:
211   - 1'b0: no pending transfer in the queue
212   - 1'b1: pending transfer in the queue */
213 #define UDMA_CORE_CMD_CFG_PENDING_MASK	(0x20)
214 #define UDMA_CORE_CMD_CFG_PENDING_SHIFT (5)
215 #define UDMA_CORE_CMD_CFG_PENDING(val)                                         \
216 	(((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_PENDING_SHIFT)) &  \
217 	 UDMA_CORE_CMD_CFG_PENDING_MASK)
218 
219 /* Channel clear and stop transfer:
220   - 1'b0: disable
221   - 1'b1: stop and clear the on-going transfer */
222 #define UDMA_CORE_CMD_CFG_CLR_MASK  (0x20)
223 #define UDMA_CORE_CMD_CFG_CLR_SHIFT (5)
224 #define UDMA_CORE_CMD_CFG_CLR(val)                                             \
225 	(((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_CLR_SHIFT)) &      \
226 	 UDMA_CORE_CMD_CFG_CLR_MASK)
227 
228 /* Reserved/Not used. */
229 #define UDMA_CORE_CMD_CFG_RESERVED_1_MASK  (0xffffff80)
230 #define UDMA_CORE_CMD_CFG_RESERVED_1_SHIFT (7)
231 #define UDMA_CORE_CMD_CFG_RESERVED_1(val)                                      \
232 	(((uint32_t)(((uint32_t)(val))                                         \
233 		     << UDMA_CORE_CMD_CFG_RESERVED_1_SHIFT)) &                 \
234 	 UDMA_CORE_CMD_CFG_RESERVED_1_MASK)
235 
236 /*! @name CMD_INITCFG */
237 /* Reserved/Not used. */
238 #define UDMA_CORE_CMD_INITCFG_RESERVED_0_MASK  (0xffffffff)
239 #define UDMA_CORE_CMD_INITCFG_RESERVED_0_SHIFT (0)
240 #define UDMA_CORE_CMD_INITCFG_RESERVED_0(val)                                  \
241 	(((uint32_t)(((uint32_t)(val))                                         \
242 		     << UDMA_CORE_CMD_INITCFG_RESERVED_0_SHIFT)) &             \
243 	 UDMA_CORE_CMD_INITCFG_RESERVED_0_MASK)
244 
245 #define SPI_CMD_CFG_ID	     0x0 /* Sets the configuration for the SPI Master IP. */
246 #define SPI_CMD_SOT_ID	     0x1 /* Sets the Chip Select (CS). */
247 #define SPI_CMD_SEND_CMD_ID  0x2 /* Transmits a configurable size command. */
248 #define SPI_CMD_SEND_BITS_ID 0x2 /* Transmits a configurable size command. */
249 #define SPI_CMD_SEND_ADDR_ID 0x3 /* Transmits a configurable size address. */
250 #define SPI_CMD_DUMMY_ID                                                       \
251 	0x4 /* Receives a number of dummy bits (not sent to the rx interface). */
252 #define SPI_CMD_WAIT_ID                                                        \
253 	0x5 /* Waits an external event to move to the next instruction. */
254 #define SPI_CMD_TX_DATA_ID 0x6 /* Sends data (max 64Kbits). */
255 #define SPI_CMD_RX_DATA_ID 0x7 /* Receives data (max 64Kbits). */
256 #define SPI_CMD_RPT_ID	   0x8 /* Repeat the next transfer N times. */
257 #define SPI_CMD_EOT_ID	   0x9 /* Clears the Chip Select (CS). */
258 #define SPI_CMD_RPT_END_ID 0xA /* End of the repeat loop command. */
259 #define SPI_CMD_RX_CHECK_ID                                                    \
260 	0xB /* Check up ot 16 bits of data against an expected value. */
261 #define SPI_CMD_FULL_DUPL_ID 0xC /* Activate full duplex mode. */
262 
263 #define SPI_CMD_CFG(clockDiv, cpol, cpha)                                      \
264 	((SPI_CMD_CFG_ID << SPI_CMD_ID_OFFSET) |                               \
265 	 ((cpol) << SPI_CMD_CFG_CPOL_OFFSET) |                                 \
266 	 ((cpha) << SPI_CMD_CFG_CPHA_OFFSET) |                                 \
267 	 ((clockDiv) << SPI_CMD_CFG_CLK_DIV_OFFSET))
268 #define SPI_CMD_SOT(cs)                                                        \
269 	((SPI_CMD_SOT_ID << SPI_CMD_ID_OFFSET) |                               \
270 	 ((cs) << SPI_CMD_SOT_CS_OFFSET))
271 #define SPI_CMD_SEND_CMD(cmd, bits, qpi)                                       \
272 	((SPI_CMD_SEND_CMD_ID << SPI_CMD_ID_OFFSET) |                          \
273 	 ((qpi) << SPI_CMD_SEND_CMD_QPI_OFFSET) |                              \
274 	 (((bits)-1) << SPI_CMD_SEND_CMD_SIZE_OFFSET) | (cmd & 0xFFFF))
275 #define SPI_CMD_SEND_BITS(data, bits, qpi)                                     \
276 	((SPI_CMD_SEND_CMD_ID << SPI_CMD_ID_OFFSET) |                          \
277 	 ((qpi) << SPI_CMD_SEND_CMD_QPI_OFFSET) |                              \
278 	 (((bits)-1) << SPI_CMD_SEND_CMD_SIZE_OFFSET) | (data & 0xFFFF))
279 #define SPI_CMD_DUMMY(cycles)                                                  \
280 	((SPI_CMD_DUMMY_ID << SPI_CMD_ID_OFFSET) |                             \
281 	 (((cycles)-1) << SPI_CMD_DUMMY_CYCLE_OFFSET))
282 
283 #define SPI_CMD_SETUP_UCA(txrxen, ds, addr)                                    \
284 	((SPI_CMD_SETUP_UCA_ID << SPI_CMD_ID_OFFSET) |                         \
285 	 ((txrxen) << SPI_CMD_SETUP_UC_TXRXEN_OFFSET) | ((int)addr & 0xFFFFF))
286 #define SPI_CMD_SETUP_UCS(txrxen, ds, size)                                    \
287 	((SPI_CMD_SETUP_UCS_ID << SPI_CMD_ID_OFFSET) |                         \
288 	 ((txrxen) << SPI_CMD_SETUP_UC_TXRXEN_OFFSET) |                        \
289 	 ((ds) << SPI_CMD_SETUP_UC_DS_OFFSET) | (size & 0xFFFF))
290 
291 #define SPI_CMD_TX_DATA(words, wordstrans, bitsword, qpi, lsbfirst)            \
292 	((SPI_CMD_TX_DATA_ID << SPI_CMD_ID_OFFSET) |                           \
293 	 ((qpi) << SPI_CMD_TX_DATA_QPI_OFFSET) |                               \
294 	 ((wordstrans) << SPI_CMD_TX_DATA_WORDTRANS_OFFSET) |                  \
295 	 ((bitsword - 1) << SPI_CMD_TX_DATA_BITSWORD_OFFSET) |                 \
296 	 (((words)-1) << SPI_CMD_TX_DATA_SIZE_OFFSET) |                        \
297 	 ((lsbfirst) << SPI_CMD_TX_DATA_LSBFIRST_OFFSET))
298 #define SPI_CMD_RX_DATA(words, wordstrans, bitsword, qpi, lsbfirst)            \
299 	((SPI_CMD_RX_DATA_ID << SPI_CMD_ID_OFFSET) |                           \
300 	 ((qpi) << SPI_CMD_RX_DATA_QPI_OFFSET) |                               \
301 	 ((wordstrans) << SPI_CMD_RX_DATA_WORDTRANS_OFFSET) |                  \
302 	 ((bitsword - 1) << SPI_CMD_RX_DATA_BITSWORD_OFFSET) |                 \
303 	 (((words)-1) << SPI_CMD_RX_DATA_SIZE_OFFSET) |                        \
304 	 ((lsbfirst) << SPI_CMD_RX_DATA_LSBFIRST_OFFSET))
305 #define SPI_CMD_RPT(iter)                                                      \
306 	((SPI_CMD_RPT_ID << SPI_CMD_ID_OFFSET) |                               \
307 	 ((iter) << SPI_CMD_RPT_NB_OFFSET))
308 #define SPI_CMD_EOT(evt, cs_keep)                                              \
309 	((SPI_CMD_EOT_ID << SPI_CMD_ID_OFFSET) |                               \
310 	 ((evt) << SPI_CMD_EOT_GEN_EVT_OFFSET) |                               \
311 	 ((cs_keep) << SPI_CMD_EOT_CS_KEEP_OFFSET))
312 
313 #define SPI_CMD_RX_CHECK(mode, bits, value, qpi, byte_align)                   \
314 	((SPI_CMD_RX_CHECK_ID << SPI_CMD_ID_OFFSET) |                          \
315 	 ((value) << SPI_CMD_RX_CHECK_VALUE_OFFSET) |                          \
316 	 ((mode) << SPI_CMD_RX_CHECK_MODE_OFFSET) |                            \
317 	 (((bits)-1) << SPI_CMD_RX_CHECK_SIZE_OFFSET) |                        \
318 	 ((byte_align) << SPI_CMD_RX_CHECK_BYTE_ALIGN_OFFSET) |                \
319 	 ((qpi) << SPI_CMD_RX_CHECK_QPI_OFFSET))
320 
321 #define SPI_CMD_WAIT(event)                                                    \
322 	((SPI_CMD_WAIT_ID << SPI_CMD_ID_OFFSET) |                              \
323 	 ((event) << SPI_CMD_WAIT_EVENT_OFFSET))
324 #define SPI_CMD_RPT_END() ((SPI_CMD_RPT_END_ID << SPI_CMD_ID_OFFSET))
325 #define SPI_CMD_FUL(words, wordstrans, bitsword, lsbfirst)                     \
326 	((SPI_CMD_FUL_ID << SPI_CMD_ID_OFFSET) |                               \
327 	 ((wordstrans) << SPI_CMD_FUL_WORDTRANS_OFFSET) |                      \
328 	 ((bitsword - 1) << SPI_CMD_FUL_BITSWORD_OFFSET) |                     \
329 	 (((words)-1) << SPI_CMD_FUL_SIZE_OFFSET) |                            \
330 	 ((lsbfirst) << SPI_CMD_FUL_LSBFIRST_OFFSET))
331 
332 
333 #endif /* HAL_INCLUDE_HAL_SPI_PERIPH_H_ */
334