]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Cyclone_V_SoC_DK/Altera_Code/HardwareLibrary/alt_spi.c
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Demo / CORTEX_A9_Cyclone_V_SoC_DK / Altera_Code / HardwareLibrary / alt_spi.c
1 /******************************************************************************\r
2  *\r
3  * Copyright 2013 Altera Corporation. All Rights Reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions are met:\r
7  *\r
8  * 1. Redistributions of source code must retain the above copyright notice,\r
9  * this list of conditions and the following disclaimer.\r
10  *\r
11  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
12  * this list of conditions and the following disclaimer in the documentation\r
13  * and/or other materials provided with the distribution.\r
14  *\r
15  * 3. The name of the author may not be used to endorse or promote products\r
16  * derived from this software without specific prior written permission.\r
17  *\r
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR\r
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO\r
21  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
27  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28  *\r
29  ******************************************************************************/\r
30 \r
31 #include "alt_spi.h"\r
32 #include "alt_reset_manager.h"\r
33 #include "socal/alt_rstmgr.h"\r
34 \r
35 // Timeout for reset manager\r
36 #define  ALT_SPI_RESET_TMO_INIT      8192\r
37 \r
38 // Maximum value of SPI Clock Divider\r
39 #define  ALT_SPI_MAX_CLK_DIV         65534\r
40 // Minimum value of SPI Clock Divider\r
41 #define  ALT_SPI_MIN_CLK_DIV         2\r
42 // Timeout for waiting interrupt\r
43 #define  ALT_SPI_TMO_WAITER          2500000\r
44 \r
45 /////\r
46 \r
47 #define MIN(a, b) ((a) < (b) ? (a) : (b))\r
48 #define MAX(a, b) ((a) > (b) ? (a) : (b))\r
49 \r
50 /////\r
51 \r
52 //\r
53 // Check whether spi space is correct.\r
54 //\r
55 static ALT_STATUS_CODE alt_spi_checking(ALT_SPI_DEV_t * spi_dev)\r
56 \r
57 {\r
58     if (!spi_dev)\r
59     {\r
60         //Incorrect pointer\r
61         return ALT_E_FALSE;\r
62     }\r
63 \r
64     if (   spi_dev->location != (void *)ALT_SPI_SPIS0\r
65         && spi_dev->location != (void *)ALT_SPI_SPIS1\r
66         && spi_dev->location != (void *)ALT_SPI_SPIM0\r
67         && spi_dev->location != (void *)ALT_SPI_SPIM1)\r
68     {\r
69         // Incorrect device\r
70         return ALT_E_FALSE;\r
71     }\r
72 \r
73     \r
74     return ALT_E_TRUE;\r
75 }\r
76 \r
77 //\r
78 // Initialize the specified SPI controller instance for use and return a device\r
79 // handle referencing it.\r
80 //\r
81 ALT_STATUS_CODE alt_spi_init(const ALT_SPI_CTLR_t spi,\r
82                              ALT_SPI_DEV_t * spi_dev)\r
83 \r
84 {\r
85     if (!spi_dev || spi == 0)\r
86     {\r
87         return ALT_E_BAD_ARG;\r
88     }\r
89 \r
90     //Save spi start address to the instance\r
91     spi_dev->location = (void *)spi;\r
92     \r
93     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
94     {\r
95         return ALT_E_BAD_ARG;\r
96     }\r
97 \r
98     if (alt_clk_is_enabled(ALT_CLK_SPI_M) != ALT_E_TRUE)\r
99     {\r
100         return ALT_E_BAD_CLK;\r
101     }\r
102 \r
103     // Define operation mode\r
104     if  (   spi_dev->location == (void *)ALT_SPI_SPIM0\r
105          || spi_dev->location == (void *)ALT_SPI_SPIM1)\r
106     {\r
107         spi_dev->op_mode = ALT_SPI_OP_MODE_MASTER;\r
108     }\r
109     else if (   spi_dev->location == (void *)ALT_SPI_SPIS0\r
110              || spi_dev->location == (void *)ALT_SPI_SPIS1)\r
111     {\r
112         spi_dev->op_mode = ALT_SPI_OP_MODE_SLAVE;\r
113     }\r
114 \r
115     /////\r
116 \r
117     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
118 \r
119     if (status == ALT_E_SUCCESS)\r
120     {\r
121         // Get spi clock frequence\r
122         status = alt_clk_freq_get(ALT_CLK_SPI_M, &spi_dev->clock_freq);\r
123     }\r
124 \r
125     // Reset spi module\r
126     if (status == ALT_E_SUCCESS)\r
127     {\r
128         status = alt_spi_reset(spi_dev);\r
129     }\r
130 \r
131     return status;\r
132 }\r
133 \r
134 //\r
135 // Reset spi module by reset manager\r
136 //\r
137 static ALT_STATUS_CODE alt_spi_rstmgr_set(ALT_SPI_DEV_t * spi_dev)\r
138 {\r
139     uint32_t rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;\r
140 \r
141     // Assert the appropriate SPI module reset signal via the Reset Manager Peripheral Reset register.\r
142     switch ((ALT_SPI_CTLR_t)spi_dev->location)\r
143     {\r
144     case ALT_SPI_SPIM0:\r
145         rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;\r
146         break;\r
147     case ALT_SPI_SPIM1:\r
148         rst_mask = ALT_RSTMGR_PERMODRST_SPIM1_SET_MSK;\r
149         break;\r
150     case ALT_SPI_SPIS0:\r
151         rst_mask = ALT_RSTMGR_PERMODRST_SPIS0_SET_MSK;\r
152         break;\r
153     case ALT_SPI_SPIS1:\r
154         rst_mask = ALT_RSTMGR_PERMODRST_SPIS1_SET_MSK;\r
155         break;\r
156     default:\r
157         return ALT_E_BAD_ARG;\r
158     }\r
159 \r
160     alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);\r
161 \r
162     return ALT_E_SUCCESS;\r
163 }\r
164 \r
165 //\r
166 // Reset spi module by reset manager\r
167 //\r
168 static ALT_STATUS_CODE alt_spi_rstmgr_strobe(ALT_SPI_DEV_t * spi_dev)\r
169 {\r
170     uint32_t rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;\r
171 \r
172     // Assert the appropriate SPI module reset signal via the Reset Manager Peripheral Reset register.\r
173     switch ((ALT_SPI_CTLR_t)spi_dev->location)\r
174     {\r
175     case ALT_SPI_SPIM0:\r
176         rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;\r
177         break;\r
178     case ALT_SPI_SPIM1:\r
179         rst_mask = ALT_RSTMGR_PERMODRST_SPIM1_SET_MSK;\r
180         break;\r
181     case ALT_SPI_SPIS0:\r
182         rst_mask = ALT_RSTMGR_PERMODRST_SPIS0_SET_MSK;\r
183         break;\r
184     case ALT_SPI_SPIS1:\r
185         rst_mask = ALT_RSTMGR_PERMODRST_SPIS1_SET_MSK;\r
186         break;\r
187     default:\r
188         return ALT_E_BAD_ARG;\r
189     }\r
190 \r
191     alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);\r
192 \r
193     volatile uint32_t timeout = ALT_SPI_RESET_TMO_INIT;\r
194 \r
195     // Wait while spi modure is reseting\r
196     while (timeout--)\r
197         ;\r
198 \r
199     // Deassert the appropriate SPI module reset signal via the Reset Manager Peripheral Reset register.\r
200     alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);\r
201 \r
202     return ALT_E_SUCCESS;\r
203 }\r
204 \r
205 //\r
206 // Reset spi module\r
207 //\r
208 ALT_STATUS_CODE alt_spi_reset(ALT_SPI_DEV_t * spi_dev)\r
209 {\r
210 \r
211     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
212     {\r
213         return ALT_E_BAD_ARG;\r
214     }\r
215 \r
216     ALT_STATUS_CODE    status = ALT_E_SUCCESS;\r
217     bool already_enabled = (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE);\r
218 \r
219     if (already_enabled)\r
220     {\r
221         // Temporarily disable controller\r
222         status = alt_spi_disable(spi_dev);\r
223         if (status != ALT_E_SUCCESS)\r
224         {\r
225             return status;\r
226         }\r
227     }\r
228     \r
229     // Reset spi module by reset manager\r
230     alt_spi_rstmgr_strobe(spi_dev);\r
231 \r
232     // Reset the last target address cache.\r
233     spi_dev->last_slave_mask = 0xffffffff;\r
234     spi_dev->last_transfer_mode = (uint32_t)(-1);\r
235 \r
236     if (already_enabled)\r
237     {\r
238         // Re-enable controller\r
239         status = alt_spi_enable(spi_dev);\r
240     }\r
241 \r
242     return status;\r
243 }\r
244 \r
245 \r
246 //\r
247 // Uninitialize the SPI controller referenced by the spi_dev handle.\r
248 //\r
249 ALT_STATUS_CODE alt_spi_uninit(ALT_SPI_DEV_t * spi_dev)\r
250 {\r
251     ALT_STATUS_CODE    status = ALT_E_SUCCESS;\r
252     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
253     {\r
254         return ALT_E_BAD_ARG;\r
255     }\r
256 \r
257     // Disable spi controller\r
258     status = alt_spi_disable(spi_dev);\r
259     if (status != ALT_E_SUCCESS)\r
260     {\r
261         return status;\r
262     }\r
263 \r
264     // Reset spi module by reset manager\r
265     alt_spi_rstmgr_set(spi_dev);\r
266 \r
267     return status;\r
268 }\r
269 \r
270 \r
271 //\r
272 // Enables the SPI controller.\r
273 //\r
274 ALT_STATUS_CODE alt_spi_enable(ALT_SPI_DEV_t * spi_dev)\r
275 {\r
276     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
277     {\r
278         return ALT_E_BAD_ARG;\r
279     }\r
280 \r
281     switch (spi_dev->op_mode)\r
282     {\r
283     case ALT_SPI_OP_MODE_MASTER:\r
284         alt_setbits_word(ALT_SPIM_SPIENR_ADDR(spi_dev->location),\r
285                          ALT_SPIM_SPIENR_SPI_EN_SET_MSK);\r
286         break;\r
287     case ALT_SPI_OP_MODE_SLAVE:\r
288         alt_setbits_word(ALT_SPIS_SPIENR_ADDR(spi_dev->location),\r
289                          ALT_SPIS_SPIENR_SPI_EN_SET_MSK);\r
290         break;\r
291     }\r
292     \r
293     return ALT_E_SUCCESS;\r
294 }\r
295 \r
296 //\r
297 // Disables the SPI controller\r
298 //\r
299 ALT_STATUS_CODE alt_spi_disable(ALT_SPI_DEV_t * spi_dev)\r
300 {\r
301     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
302     {\r
303         return ALT_E_BAD_ARG;\r
304     }\r
305 \r
306     // If spi controller is enabled, return with sucess\r
307     if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)\r
308     {\r
309         return ALT_E_SUCCESS;\r
310     }\r
311   \r
312     // Else clear enable bit of spi_enable register\r
313     switch (spi_dev->op_mode)\r
314     {\r
315     case ALT_SPI_OP_MODE_MASTER:\r
316         alt_clrbits_word(ALT_SPIM_SPIENR_ADDR(spi_dev->location),\r
317                          ALT_SPIM_SPIENR_SPI_EN_SET_MSK);\r
318         break;\r
319     case ALT_SPI_OP_MODE_SLAVE:\r
320         alt_clrbits_word(ALT_SPIS_SPIENR_ADDR(spi_dev->location),\r
321                          ALT_SPIS_SPIENR_SPI_EN_SET_MSK);\r
322         break;\r
323     }\r
324 \r
325     // Clear interrapts mask and clear interrupt status\r
326     alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_ALL);\r
327     alt_spi_int_clear(spi_dev, ALT_SPI_STATUS_ALL);\r
328 \r
329     return ALT_E_SUCCESS;\r
330 }\r
331 \r
332 //\r
333 // Check whether spi controller is enable\r
334 //\r
335 ALT_STATUS_CODE alt_spi_is_enabled(ALT_SPI_DEV_t * spi_dev)\r
336 {\r
337     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
338     {\r
339         return ALT_E_BAD_ARG;\r
340     }\r
341 \r
342     ALT_STATUS_CODE en_status = ALT_E_FALSE;\r
343     switch (spi_dev->op_mode)\r
344     {\r
345     case ALT_SPI_OP_MODE_MASTER:\r
346         en_status = ALT_SPIM_SPIENR_SPI_EN_GET(alt_read_word(ALT_SPIM_SPIENR_ADDR(spi_dev->location)));\r
347         break;\r
348     case ALT_SPI_OP_MODE_SLAVE:\r
349         en_status = ALT_SPIS_SPIENR_SPI_EN_GET(alt_read_word(ALT_SPIS_SPIENR_ADDR(spi_dev->location)));\r
350         break;\r
351     }\r
352     return en_status;\r
353 }\r
354 \r
355 ALT_STATUS_CODE alt_spi_is_busy(ALT_SPI_DEV_t *spi_dev)\r
356 \r
357 {\r
358     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
359     {\r
360         return ALT_E_BAD_ARG;\r
361     }\r
362    \r
363     switch (spi_dev->op_mode)\r
364     {\r
365     case ALT_SPI_OP_MODE_MASTER:\r
366         if (ALT_SPIM_SR_BUSY_GET(alt_read_word(ALT_SPIM_SR_ADDR(spi_dev->location))))\r
367         {\r
368             return ALT_E_TRUE;\r
369         }\r
370         break;\r
371     case ALT_SPI_OP_MODE_SLAVE:\r
372         if (ALT_SPIS_SR_BUSY_GET(alt_read_word(ALT_SPIS_SR_ADDR(spi_dev->location))))\r
373         {\r
374             return ALT_E_TRUE;\r
375         }\r
376         break;\r
377     }\r
378    \r
379     return ALT_E_FALSE;\r
380 }\r
381 \r
382 //\r
383 // Get config parameters from appropriate registers.\r
384 //\r
385 ALT_STATUS_CODE alt_spi_config_get(ALT_SPI_DEV_t *spi_dev,\r
386                                    ALT_SPI_CONFIG_t* cfg)\r
387 {\r
388     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)\r
389     {\r
390         return ALT_E_BAD_ARG;\r
391     }\r
392 \r
393     uint32_t cfg_register;\r
394     switch (spi_dev->op_mode)\r
395     {\r
396     case ALT_SPI_OP_MODE_MASTER:\r
397         cfg_register = alt_read_word(ALT_SPIM_CTLR0_ADDR(spi_dev->location));\r
398       \r
399         cfg->frame_size    = (ALT_SPI_DFS_t)ALT_SPIM_CTLR0_DFS_GET(cfg_register);\r
400         cfg->frame_format  = (ALT_SPI_FRF_t)ALT_SPIM_CTLR0_FRF_GET(cfg_register);\r
401         cfg->clk_phase     = (ALT_SPI_SCPH_t)ALT_SPIM_CTLR0_SCPH_GET(cfg_register);\r
402         cfg->clk_polarity  = (ALT_SPI_SCPOL_t)ALT_SPIM_CTLR0_SCPOL_GET(cfg_register);\r
403         cfg->transfer_mode = (ALT_SPI_TMOD_t)ALT_SPIM_CTLR0_TMOD_GET(cfg_register);\r
404         cfg->loopback_mode = (bool)ALT_SPIM_CTLR0_SRL_GET(cfg_register);\r
405         break;\r
406     case ALT_SPI_OP_MODE_SLAVE:\r
407         cfg_register       = alt_read_word(ALT_SPIS_CTLR0_ADDR(spi_dev->location));\r
408 \r
409         cfg->frame_size    = (ALT_SPI_DFS_t)ALT_SPIS_CTLR0_DFS_GET(cfg_register);\r
410         cfg->frame_format  = (ALT_SPI_FRF_t)ALT_SPIS_CTLR0_FRF_GET(cfg_register);\r
411         cfg->clk_phase     = (ALT_SPI_SCPH_t)ALT_SPIS_CTLR0_SCPH_GET(cfg_register);\r
412         cfg->clk_polarity  = (ALT_SPI_SCPOL_t)ALT_SPIS_CTLR0_SCPOL_GET(cfg_register);\r
413         cfg->transfer_mode = (ALT_SPI_TMOD_t)ALT_SPIS_CTLR0_TMOD_GET(cfg_register);\r
414         cfg->slave_output_enable = (bool)ALT_SPIS_CTLR0_SLV_OE_GET(cfg_register);\r
415         cfg->loopback_mode = (bool)ALT_SPIS_CTLR0_SRL_GET(cfg_register);\r
416         break;\r
417     }\r
418     return ALT_E_SUCCESS;\r
419 }\r
420 \r
421 //\r
422 // Set config parameters to appropriate registers.\r
423 //\r
424 ALT_STATUS_CODE alt_spi_config_set(ALT_SPI_DEV_t *spi_dev,\r
425                                    const ALT_SPI_CONFIG_t* cfg)\r
426 {\r
427     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
428 \r
429     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
430     {\r
431         return ALT_E_ERROR;\r
432     }\r
433 \r
434     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)\r
435     {\r
436         return ALT_E_BAD_ARG;\r
437     }\r
438 \r
439     if (cfg->frame_size < ALT_SPI_DFS_4BIT ||cfg->frame_size > ALT_SPI_DFS_16BIT\r
440         || cfg->frame_format > ALT_SPI_FRF_MICROWIRE || cfg->clk_polarity > ALT_SPI_SCPOL_INACTIVE_HIGH\r
441         || cfg->clk_phase > ALT_SPI_SCPH_TOGGLE_START)\r
442     {\r
443         return ALT_E_ARG_RANGE;\r
444     }\r
445 \r
446     // Set config parameters to appropriate registers\r
447     uint32_t cfg_register;\r
448     uint32_t cfg_mask;\r
449     switch (spi_dev->op_mode)\r
450     {\r
451     case ALT_SPI_OP_MODE_MASTER:\r
452         cfg_register = ALT_SPIM_CTLR0_DFS_SET(cfg->frame_size)\r
453                      | ALT_SPIM_CTLR0_FRF_SET(cfg->frame_format)\r
454                      | ALT_SPIM_CTLR0_SCPH_SET(cfg->clk_phase)\r
455                      | ALT_SPIM_CTLR0_SCPOL_SET(cfg->clk_polarity)\r
456                      | ALT_SPIM_CTLR0_TMOD_SET(cfg->transfer_mode)\r
457                      | ALT_SPIM_CTLR0_SRL_SET(cfg->loopback_mode);\r
458 \r
459         cfg_mask     = ALT_SPIM_CTLR0_DFS_SET_MSK\r
460                      | ALT_SPIM_CTLR0_FRF_SET_MSK\r
461                      | ALT_SPIM_CTLR0_SCPH_SET_MSK\r
462                      | ALT_SPIM_CTLR0_SCPOL_SET_MSK\r
463                      | ALT_SPIM_CTLR0_TMOD_SET_MSK\r
464                      | ALT_SPIM_CTLR0_SRL_SET_MSK;\r
465                        \r
466         alt_replbits_word(ALT_SPIM_CTLR0_ADDR(spi_dev->location), cfg_mask, cfg_register);\r
467         break;\r
468     case ALT_SPI_OP_MODE_SLAVE:\r
469 \r
470     cfg_register     = ALT_SPIS_CTLR0_DFS_SET(cfg->frame_size)\r
471                      | ALT_SPIS_CTLR0_FRF_SET(cfg->frame_format)\r
472                      | ALT_SPIS_CTLR0_SCPH_SET(cfg->clk_phase)\r
473                      | ALT_SPIS_CTLR0_SCPOL_SET(cfg->clk_polarity)\r
474                      | ALT_SPIS_CTLR0_TMOD_SET(cfg->transfer_mode)\r
475                      | ALT_SPIS_CTLR0_SLV_OE_SET(cfg->slave_output_enable)\r
476                      | ALT_SPIS_CTLR0_SRL_SET(cfg->loopback_mode);\r
477 \r
478         cfg_mask     = ALT_SPIS_CTLR0_DFS_SET_MSK\r
479                      | ALT_SPIS_CTLR0_FRF_SET_MSK\r
480                      | ALT_SPIS_CTLR0_SCPH_SET_MSK\r
481                      | ALT_SPIS_CTLR0_SCPOL_SET_MSK\r
482                      | ALT_SPIS_CTLR0_TMOD_SET_MSK\r
483                      | ALT_SPIS_CTLR0_SLV_OE_SET_MSK\r
484                      | ALT_SPIS_CTLR0_SRL_SET_MSK;\r
485                        \r
486         alt_replbits_word(ALT_SPIS_CTLR0_ADDR(spi_dev->location), cfg_mask, cfg_register);\r
487         break;\r
488     }\r
489 \r
490     spi_dev->last_transfer_mode = cfg->transfer_mode;\r
491 \r
492     return status;\r
493 \r
494 }\r
495 \r
496 //\r
497 // Get config parameters from appropriate registers for microwire mode.\r
498 //\r
499 ALT_STATUS_CODE alt_spi_mw_config_get(ALT_SPI_DEV_t *spi_dev,\r
500                                       ALT_SPI_MW_CONFIG_t* cfg)\r
501 {\r
502     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)\r
503     {\r
504         return ALT_E_BAD_ARG;\r
505     }\r
506 \r
507     uint32_t cfg_register, mwcr_register;\r
508     switch (spi_dev->op_mode)\r
509     {\r
510     case ALT_SPI_OP_MODE_MASTER:\r
511         cfg_register           = alt_read_word(ALT_SPIM_CTLR0_ADDR(spi_dev->location));\r
512         mwcr_register          = alt_read_word(ALT_SPIM_MWCR_ADDR(spi_dev->location));\r
513         \r
514         cfg->ctl_frame_size    = ALT_SPIM_CTLR0_DFS_GET(cfg_register);\r
515         cfg->mode              = (ALT_SPI_MW_MODE_t)ALT_SPIM_MWCR_MWMOD_GET(mwcr_register);\r
516         cfg->dir               = (ALT_SPI_MW_DIR_t)ALT_SPIM_MWCR_MDD_GET(mwcr_register);\r
517         cfg->handshake_enabled = ALT_SPIM_MWCR_MHS_GET(mwcr_register);\r
518         break;\r
519     case ALT_SPI_OP_MODE_SLAVE:\r
520         cfg_register          = alt_read_word(ALT_SPIS_CTLR0_ADDR(spi_dev->location));\r
521         mwcr_register         = alt_read_word(ALT_SPIS_MWCR_ADDR(spi_dev->location));\r
522         \r
523         cfg->ctl_frame_size = ALT_SPIS_CTLR0_DFS_GET(cfg_register);\r
524         cfg->mode             = (ALT_SPI_MW_MODE_t)ALT_SPIS_MWCR_MWMOD_GET(mwcr_register);\r
525         cfg->dir              = (ALT_SPI_MW_DIR_t)ALT_SPIS_MWCR_MDD_GET(mwcr_register);\r
526         break;\r
527     }\r
528     return ALT_E_SUCCESS;\r
529 }\r
530 \r
531 //\r
532 // Set config parameters to appropriate registers for microwire mode.\r
533 //\r
534 ALT_STATUS_CODE alt_spi_mw_config_set(ALT_SPI_DEV_t *spi_dev,\r
535                                       const ALT_SPI_MW_CONFIG_t* cfg)\r
536 {\r
537     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
538 \r
539     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
540     {\r
541         return ALT_E_ERROR;\r
542     }\r
543 \r
544     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)\r
545     {\r
546         return ALT_E_BAD_ARG;\r
547     }\r
548 \r
549     if (cfg->ctl_frame_size > ALT_SPI_MW_CTL_FRAME_SIZE_MAX\r
550         || cfg->mode > ALT_SPI_MW_SEQUENTIAL || cfg->dir > ALT_SPI_MW_DIR_TX)\r
551     {\r
552         return ALT_E_ARG_RANGE;\r
553     }\r
554 \r
555     // Set config parameters to appropriate registers\r
556     uint32_t mwcr_register;\r
557     uint32_t mwcr_mask;\r
558     switch (spi_dev->op_mode)\r
559     {\r
560     case ALT_SPI_OP_MODE_MASTER:\r
561         mwcr_register = ALT_SPIM_MWCR_MWMOD_SET(cfg->mode)\r
562                       | ALT_SPIM_MWCR_MDD_SET(cfg->dir)\r
563                       | ALT_SPIM_MWCR_MHS_SET(cfg->handshake_enabled);\r
564 \r
565         mwcr_mask     = ALT_SPIM_MWCR_MWMOD_SET_MSK\r
566                       | ALT_SPIM_MWCR_MDD_SET_MSK\r
567                       | ALT_SPIM_MWCR_MHS_SET_MSK;\r
568                         \r
569         alt_replbits_word(ALT_SPIM_MWCR_ADDR(spi_dev->location), mwcr_mask, mwcr_register);\r
570         alt_replbits_word(ALT_SPIM_CTLR0_ADDR(spi_dev->location), \r
571                           ALT_SPIM_CTLR0_DFS_SET_MSK,\r
572                           ALT_SPIM_CTLR0_DFS_SET(cfg->ctl_frame_size));\r
573         break;\r
574     case ALT_SPI_OP_MODE_SLAVE:\r
575         mwcr_register = ALT_SPIS_MWCR_MWMOD_SET(cfg->mode)\r
576                       | ALT_SPIS_MWCR_MDD_SET(cfg->dir);\r
577 \r
578         mwcr_mask     = ALT_SPIS_MWCR_MWMOD_SET_MSK\r
579                       | ALT_SPIS_MWCR_MDD_SET_MSK;\r
580                         \r
581         alt_replbits_word(ALT_SPIS_MWCR_ADDR(spi_dev->location), mwcr_mask, mwcr_register);\r
582         alt_replbits_word(ALT_SPIS_CTLR0_ADDR(spi_dev->location), \r
583                           ALT_SPIS_CTLR0_DFS_SET_MSK,\r
584                           ALT_SPIS_CTLR0_DFS_SET(cfg->ctl_frame_size));\r
585         break;\r
586     }\r
587 \r
588     return status;\r
589 \r
590 }\r
591 \r
592 //\r
593 // Disable the specified SPI controller slave select output lines..\r
594 //\r
595 ALT_STATUS_CODE alt_spi_slave_select_disable(ALT_SPI_DEV_t *spi_dev,\r
596                                              const uint32_t mask)\r
597 {\r
598     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
599 \r
600     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
601     {\r
602         return ALT_E_ERROR;\r
603     }\r
604 \r
605     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
606     {\r
607         return ALT_E_BAD_ARG;\r
608     }\r
609 \r
610     if (mask > ALT_SPI_SLAVE_MASK_ALL)\r
611     {\r
612         return ALT_E_BAD_ARG;\r
613     }\r
614 \r
615     switch (spi_dev->op_mode)\r
616     {\r
617     case ALT_SPI_OP_MODE_MASTER:\r
618         alt_clrbits_word(ALT_SPIM_SER_ADDR(spi_dev->location), mask);\r
619         break;\r
620     case ALT_SPI_OP_MODE_SLAVE:\r
621         status = ALT_E_ERROR;\r
622         break;\r
623     }\r
624 \r
625     return status;\r
626 }\r
627 \r
628 //\r
629 // Enable the specified SPI controller slave select output lines.\r
630 //\r
631 ALT_STATUS_CODE alt_spi_slave_select_enable(ALT_SPI_DEV_t *spi_dev,\r
632                                             const uint32_t mask)\r
633 {\r
634     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
635 \r
636     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
637     {\r
638         return ALT_E_ERROR;\r
639     }\r
640 \r
641     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
642     {\r
643         return ALT_E_BAD_ARG;\r
644     }\r
645 \r
646     if (mask > ALT_SPI_SLAVE_MASK_ALL)\r
647     {\r
648         return ALT_E_BAD_ARG;\r
649     }\r
650 \r
651     switch (spi_dev->op_mode)\r
652     {\r
653     case ALT_SPI_OP_MODE_MASTER:\r
654         alt_setbits_word(ALT_SPIM_SER_ADDR(spi_dev->location), mask);\r
655         break;\r
656     case ALT_SPI_OP_MODE_SLAVE:\r
657         status = ALT_E_ERROR;\r
658         break;\r
659     }\r
660 \r
661     return status;\r
662 }\r
663 \r
664 //\r
665 // Get the configured baud rate divider value for the specified SPI controller\r
666 //\r
667 ALT_STATUS_CODE alt_spi_divider_get(ALT_SPI_DEV_t *spi_dev, uint32_t *div)\r
668 {\r
669     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
670     {\r
671         return ALT_E_BAD_ARG;\r
672     }\r
673 \r
674     switch (spi_dev->op_mode)\r
675     {\r
676     case ALT_SPI_OP_MODE_MASTER:\r
677         *div = ALT_SPIM_BAUDR_SCKDV_GET(alt_read_word(ALT_SPIM_BAUDR_ADDR(spi_dev->location)));\r
678         break;\r
679     case ALT_SPI_OP_MODE_SLAVE:\r
680     default:\r
681         return ALT_E_ERROR;\r
682     }\r
683 \r
684     return ALT_E_SUCCESS;\r
685 }\r
686 \r
687 //\r
688 // Set the baud rate divider to configure the generated sclk_out frequency\r
689 //\r
690 ALT_STATUS_CODE alt_spi_divider_set(ALT_SPI_DEV_t *spi_dev, const uint32_t div)\r
691 {\r
692     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
693     {\r
694         return ALT_E_BAD_ARG;\r
695     }\r
696 \r
697     if (spi_dev->op_mode != ALT_SPI_OP_MODE_MASTER)\r
698     {\r
699         return ALT_E_ERROR;\r
700     }\r
701 \r
702     if (div < ALT_SPI_MIN_CLK_DIV || div > ALT_SPI_MAX_CLK_DIV)\r
703     {\r
704         return ALT_E_BAD_ARG;\r
705     }\r
706 \r
707     /////\r
708 \r
709     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
710     bool already_enabled = (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE);\r
711 \r
712     if (already_enabled)\r
713     {\r
714         // Temporarily disable controller\r
715         status = alt_spi_disable(spi_dev);\r
716         if (status != ALT_E_SUCCESS)\r
717         {\r
718             return status;\r
719         }\r
720     }\r
721 \r
722     alt_replbits_word(ALT_SPIM_BAUDR_ADDR(spi_dev->location),\r
723                       ALT_SPIM_BAUDR_SCKDV_SET_MSK,\r
724                       ALT_SPIM_BAUDR_SCKDV_SET(div));\r
725 \r
726     if (already_enabled)\r
727     {\r
728         // Re-enable controller\r
729         status = alt_spi_enable(spi_dev);\r
730     }\r
731 \r
732     return status;\r
733 }\r
734 \r
735     \r
736 //\r
737 // Get the configured baud rate divider value for the specified SPI controller\r
738 //\r
739 ALT_STATUS_CODE alt_spi_baud_rate_get(ALT_SPI_DEV_t *spi_dev, uint32_t *div)\r
740 {\r
741     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
742     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !div)\r
743     {\r
744         return ALT_E_BAD_ARG;\r
745     }\r
746 \r
747     switch (spi_dev->op_mode)\r
748     {\r
749     case ALT_SPI_OP_MODE_MASTER:\r
750         *div = ALT_SPIM_BAUDR_SCKDV_GET(alt_read_word(ALT_SPIM_BAUDR_ADDR(spi_dev->location)));\r
751         break;\r
752     case ALT_SPI_OP_MODE_SLAVE:\r
753         status = ALT_E_ERROR;\r
754         break;\r
755     }\r
756 \r
757     return status;\r
758 }\r
759     \r
760 //\r
761 // Set the baud rate divider to configure the generated sclk_out frequency\r
762 //\r
763 ALT_STATUS_CODE alt_spi_baud_rate_set(ALT_SPI_DEV_t *spi_dev, const uint32_t div)\r
764 {\r
765     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
766 \r
767     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
768     {\r
769         return ALT_E_ERROR;\r
770     }\r
771 \r
772     if (alt_spi_checking(spi_dev) == ALT_E_FALSE )\r
773     {\r
774         return ALT_E_BAD_ARG;\r
775     }\r
776 \r
777     switch (spi_dev->op_mode)\r
778     {\r
779     case ALT_SPI_OP_MODE_MASTER:\r
780         if(div < ALT_SPI_MIN_CLK_DIV || div > ALT_SPI_MAX_CLK_DIV)\r
781         {\r
782             status = ALT_E_BAD_ARG;\r
783             break;\r
784         }\r
785         alt_replbits_word(ALT_SPIM_BAUDR_ADDR(spi_dev->location), \r
786                           ALT_SPIM_BAUDR_SCKDV_SET_MSK,\r
787                           ALT_SPIM_BAUDR_SCKDV_SET(div));\r
788         break;\r
789     case ALT_SPI_OP_MODE_SLAVE:\r
790         status = ALT_E_ERROR;\r
791         break;\r
792     }\r
793 \r
794     return status;\r
795 \r
796 }\r
797 \r
798 //\r
799 // Return bus speed by configuration of spi controller for master mode.\r
800 //\r
801 ALT_STATUS_CODE alt_spi_speed_get(ALT_SPI_DEV_t * spi_dev,\r
802                                   uint32_t * speed_in_hz)\r
803 {\r
804     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
805     {\r
806         return ALT_E_BAD_ARG;\r
807     }\r
808 \r
809     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
810 \r
811     uint32_t div;\r
812 \r
813     status = alt_spi_divider_get(spi_dev, &div);\r
814     if (status != ALT_E_SUCCESS)\r
815     {\r
816         return status;\r
817     }\r
818  \r
819     if (div < ALT_SPI_MIN_CLK_DIV || div > ALT_SPI_MAX_CLK_DIV)\r
820     {\r
821         return ALT_E_BAD_ARG;\r
822     }\r
823         \r
824     //<speed, Hz> = <internal clock> / <lcount>\r
825     *speed_in_hz = spi_dev->clock_freq / div;\r
826 \r
827     return ALT_E_SUCCESS;\r
828 }\r
829 \r
830 //\r
831 // Fill struct with configuration of spi controller for master mode by bus speed\r
832 //\r
833 ALT_STATUS_CODE alt_spi_speed_set(ALT_SPI_DEV_t * spi_dev,\r
834                                   uint32_t speed_in_hz)\r
835 \r
836 {\r
837     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
838     {\r
839         return ALT_E_BAD_ARG;\r
840     }\r
841 \r
842     // If speed is not standard or fast return range error\r
843     if (speed_in_hz > spi_dev->clock_freq || speed_in_hz == 0)\r
844     {\r
845         return ALT_E_ARG_RANGE;\r
846     }\r
847 \r
848     //<lcount> = <internal clock> / <speed, Hz>\r
849     uint32_t div = spi_dev->clock_freq / speed_in_hz;\r
850 \r
851     return alt_spi_divider_set(spi_dev, div);\r
852 }\r
853 \r
854 //\r
855 // Fill struct with configuration of spi controller for master mode by bus speed\r
856 //\r
857 ALT_STATUS_CODE alt_spi_speed_to_divider(ALT_SPI_DEV_t * spi_dev, \r
858                                          uint32_t speed_in_hz, \r
859                                          uint32_t * div)\r
860     \r
861 {\r
862     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !div)\r
863     {\r
864         return ALT_E_BAD_ARG;\r
865     }\r
866 \r
867     // If speed is not standard or fast return range error\r
868     if (speed_in_hz > spi_dev->clock_freq || speed_in_hz == 0)\r
869     {\r
870         return ALT_E_ARG_RANGE;\r
871     }\r
872     \r
873     // <lcount> = <internal clock> / <speed, Hz>\r
874     *div = spi_dev->clock_freq / speed_in_hz;\r
875 \r
876     return ALT_E_SUCCESS;\r
877 }\r
878 \r
879 //\r
880 // Return bus speed by configuration of spi controller for master mode.\r
881 //\r
882 ALT_STATUS_CODE alt_spi_divider_to_speed(ALT_SPI_DEV_t * spi_dev, \r
883                                          uint32_t * speed_in_hz, \r
884                                          const uint32_t * div)\r
885 {\r
886     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !div)\r
887     {\r
888         return ALT_E_BAD_ARG;\r
889     }\r
890 \r
891     if (*div < ALT_SPI_MIN_CLK_DIV || *div > ALT_SPI_MAX_CLK_DIV)\r
892     {\r
893         return ALT_E_BAD_ARG;\r
894     }\r
895     \r
896     // <speed, Hz> = <internal clock> / <lcount>\r
897     *speed_in_hz = spi_dev->clock_freq / *div;\r
898 \r
899     return ALT_E_SUCCESS;\r
900 }\r
901 \r
902 //\r
903 // Get the current number of data frames configured for the SPI controller.\r
904 //\r
905 ALT_STATUS_CODE alt_spi_num_data_frames_get(ALT_SPI_DEV_t *spi_dev, uint32_t *num_data_frames)\r
906 {\r
907     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
908     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !num_data_frames)\r
909     {\r
910         return ALT_E_BAD_ARG;\r
911     }\r
912 \r
913     switch (spi_dev->op_mode)\r
914     {\r
915     case ALT_SPI_OP_MODE_MASTER:\r
916         *num_data_frames = ALT_SPIM_CTLR1_NDF_GET(alt_read_word(ALT_SPIM_CTLR1_ADDR(spi_dev->location)));\r
917         break;\r
918     case ALT_SPI_OP_MODE_SLAVE:\r
919         status = ALT_E_ERROR;\r
920         break;\r
921     }\r
922 \r
923     return status;\r
924 }\r
925    \r
926 //\r
927 // Set the number of data frames configured for the SPI controller.\r
928 //\r
929 ALT_STATUS_CODE alt_spi_num_data_frames_set(ALT_SPI_DEV_t *spi_dev, const uint32_t num_data_frames)\r
930 {\r
931     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
932 \r
933     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
934     {\r
935         return ALT_E_ERROR;\r
936     }\r
937 \r
938     if (alt_spi_checking(spi_dev) == ALT_E_FALSE )\r
939     {\r
940         return ALT_E_BAD_ARG;\r
941     }\r
942 \r
943     switch (spi_dev->op_mode)\r
944     {\r
945     case ALT_SPI_OP_MODE_MASTER:\r
946         if(num_data_frames & ALT_SPIM_CTLR1_NDF_CLR_MSK)\r
947         {\r
948             status = ALT_E_BAD_ARG;\r
949             break;\r
950         }\r
951         alt_replbits_word(ALT_SPIM_CTLR1_ADDR(spi_dev->location), \r
952                           ALT_SPIM_CTLR1_NDF_SET_MSK,\r
953                           ALT_SPIM_CTLR1_NDF_SET(num_data_frames));\r
954         break;\r
955     case ALT_SPI_OP_MODE_SLAVE:\r
956         status = ALT_E_ERROR;\r
957         break;\r
958     }\r
959 \r
960     return status;\r
961 \r
962 }\r
963 \r
964 //\r
965 // Returns the current SPI controller interrupt status conditions.\r
966 //\r
967 ALT_STATUS_CODE alt_spi_int_status_get(ALT_SPI_DEV_t *spi_dev,\r
968                                        uint32_t *status)\r
969 {\r
970     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !status)\r
971     {\r
972         return ALT_E_BAD_ARG;\r
973     }\r
974 \r
975     switch (spi_dev->op_mode)\r
976     {\r
977     case ALT_SPI_OP_MODE_MASTER:\r
978         *status = alt_read_word(ALT_SPIM_ISR_ADDR(spi_dev->location));\r
979         break;\r
980     case ALT_SPI_OP_MODE_SLAVE:\r
981         *status = alt_read_word(ALT_SPIS_ISR_ADDR(spi_dev->location));\r
982         break;\r
983     }\r
984 \r
985     return ALT_E_SUCCESS;\r
986 }\r
987 \r
988 //\r
989 // Returns the SPI controller raw interrupt status conditions irrespective of\r
990 // the interrupt status condition enablement state.\r
991 //\r
992 ALT_STATUS_CODE alt_spi_int_raw_status_get(ALT_SPI_DEV_t *spi_dev,\r
993                                            uint32_t *status)\r
994 {\r
995     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !status)\r
996     {\r
997         return ALT_E_BAD_ARG;\r
998     }\r
999 \r
1000     switch (spi_dev->op_mode)\r
1001     {\r
1002     case ALT_SPI_OP_MODE_MASTER:\r
1003         *status = alt_read_word(ALT_SPIM_RISR_ADDR(spi_dev->location));\r
1004         break;\r
1005     case ALT_SPI_OP_MODE_SLAVE:\r
1006         *status = alt_read_word(ALT_SPIS_RISR_ADDR(spi_dev->location));\r
1007         break;\r
1008     }\r
1009 \r
1010     return ALT_E_SUCCESS;\r
1011 }\r
1012 \r
1013 //\r
1014 // Clears the specified SPI controller interrupt status conditions identified\r
1015 // in the mask (for slave mode).\r
1016 //\r
1017 static ALT_STATUS_CODE alt_spi_slave_int_clear(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)\r
1018 {\r
1019     if (mask == ALT_SPI_STATUS_ALL)\r
1020     {\r
1021         alt_read_word(ALT_SPIS_ICR_ADDR(spi_dev->location));\r
1022         return ALT_E_SUCCESS;\r
1023     }\r
1024     \r
1025     // For different status clear different register\r
1026     if (mask & ALT_SPI_STATUS_TXOI)\r
1027     {\r
1028         alt_read_word(ALT_SPIS_TXOICR_ADDR(spi_dev->location));\r
1029     } \r
1030     if (mask & ALT_SPI_STATUS_RXOI)\r
1031     {\r
1032         alt_read_word(ALT_SPIS_RXOICR_ADDR(spi_dev->location));\r
1033     }\r
1034     if (mask & ALT_SPI_STATUS_RXUI)\r
1035     {\r
1036         alt_read_word(ALT_SPIS_RXUICR_ADDR(spi_dev->location));\r
1037     }\r
1038 \r
1039     return ALT_E_SUCCESS;\r
1040 }\r
1041 \r
1042 //\r
1043 // Clears the specified SPI controller interrupt status conditions identified\r
1044 // in the mask (for master mode).\r
1045 //\r
1046 static ALT_STATUS_CODE alt_spi_master_int_clear(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)\r
1047 {\r
1048     if (mask == ALT_SPI_STATUS_ALL)\r
1049     {\r
1050         alt_read_word(ALT_SPIM_ICR_ADDR(spi_dev->location));\r
1051         return ALT_E_SUCCESS;\r
1052     }\r
1053     \r
1054     // For different status clear different register\r
1055     if (mask & ALT_SPI_STATUS_TXOI)\r
1056     {\r
1057         alt_read_word(ALT_SPIM_TXOICR_ADDR(spi_dev->location));\r
1058     }\r
1059     if (mask & ALT_SPI_STATUS_RXOI)\r
1060     {\r
1061         alt_read_word(ALT_SPIM_RXOICR_ADDR(spi_dev->location));\r
1062     }\r
1063     if (mask & ALT_SPI_STATUS_RXUI)\r
1064     {\r
1065         alt_read_word(ALT_SPIM_RXUICR_ADDR(spi_dev->location));\r
1066     }\r
1067 \r
1068     return ALT_E_SUCCESS;\r
1069 }\r
1070 \r
1071 //\r
1072 // Clears the specified SPI controller interrupt status conditions identified\r
1073 // in the mask.\r
1074 //\r
1075 ALT_STATUS_CODE alt_spi_int_clear(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)\r
1076 {\r
1077     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1078     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1079     {\r
1080         return ALT_E_BAD_ARG;\r
1081     }\r
1082 \r
1083     switch (spi_dev->op_mode)\r
1084     {\r
1085     case ALT_SPI_OP_MODE_MASTER:\r
1086         status = alt_spi_master_int_clear(spi_dev, mask);\r
1087         break;\r
1088     case ALT_SPI_OP_MODE_SLAVE:\r
1089         status = alt_spi_slave_int_clear(spi_dev, mask);\r
1090         break;\r
1091     }\r
1092     return status;\r
1093 }\r
1094 \r
1095 //\r
1096 // Disable the specified SPI controller interrupt status conditions identified in\r
1097 // the mask.\r
1098 //\r
1099 ALT_STATUS_CODE alt_spi_int_disable(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)\r
1100 {\r
1101     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1102     {\r
1103         return ALT_E_BAD_ARG;\r
1104     }\r
1105 \r
1106     switch (spi_dev->op_mode)\r
1107     {\r
1108     case ALT_SPI_OP_MODE_MASTER:\r
1109         alt_clrbits_word(ALT_SPIM_IMR_ADDR(spi_dev->location), mask);\r
1110         break;\r
1111     case ALT_SPI_OP_MODE_SLAVE:\r
1112         alt_clrbits_word(ALT_SPIS_IMR_ADDR(spi_dev->location), mask);\r
1113         break;\r
1114     }\r
1115 \r
1116     return ALT_E_SUCCESS;\r
1117 }\r
1118 \r
1119 //\r
1120 // Enable the specified SPI controller interrupt status conditions identified in\r
1121 // the mask.\r
1122 //\r
1123 ALT_STATUS_CODE alt_spi_int_enable(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)\r
1124 {\r
1125     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1126     {\r
1127         return ALT_E_BAD_ARG;\r
1128     }\r
1129 \r
1130     switch (spi_dev->op_mode)\r
1131     {\r
1132     case ALT_SPI_OP_MODE_MASTER:\r
1133         alt_setbits_word(ALT_SPIM_IMR_ADDR(spi_dev->location), mask);\r
1134         break;\r
1135     case ALT_SPI_OP_MODE_SLAVE:\r
1136         alt_setbits_word(ALT_SPIS_IMR_ADDR(spi_dev->location), mask);\r
1137         break;\r
1138     }\r
1139 \r
1140     return ALT_E_SUCCESS;\r
1141 }\r
1142 \r
1143 //\r
1144 // Returns ALT_E_TRUE when the receive FIFO is empty.\r
1145 //\r
1146 ALT_STATUS_CODE alt_spi_rx_fifo_is_empty(ALT_SPI_DEV_t *spi_dev)\r
1147 {\r
1148     ALT_STATUS_CODE status = ALT_E_FALSE;\r
1149     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1150     {\r
1151         return ALT_E_BAD_ARG;\r
1152     }\r
1153 \r
1154     switch (spi_dev->op_mode)\r
1155     {\r
1156     case ALT_SPI_OP_MODE_MASTER:\r
1157         if (ALT_SPIM_SR_RFNE_GET(alt_read_word(ALT_SPIM_SR_ADDR(spi_dev->location))) == ALT_SPIM_SR_RFNE_E_EMPTY)\r
1158         {\r
1159             status = ALT_E_TRUE;\r
1160         }\r
1161         break;\r
1162     case ALT_SPI_OP_MODE_SLAVE:\r
1163         if (ALT_SPIS_SR_RFNE_GET(alt_read_word(ALT_SPIS_SR_ADDR(spi_dev->location))) == ALT_SPIS_SR_RFNE_E_EMPTY)\r
1164         {\r
1165             status =  ALT_E_TRUE;\r
1166         }\r
1167         break;\r
1168     }\r
1169     return status;\r
1170 }\r
1171 \r
1172 //\r
1173 // Returns ALT_E_TRUE when the receive FIFO is completely full.\r
1174 //\r
1175 ALT_STATUS_CODE alt_spi_rx_fifo_is_full(ALT_SPI_DEV_t *spi_dev)\r
1176 {\r
1177     ALT_STATUS_CODE status = ALT_E_FALSE;\r
1178     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1179     {\r
1180         return ALT_E_BAD_ARG;\r
1181     }\r
1182 \r
1183     switch (spi_dev->op_mode)\r
1184     {\r
1185     case ALT_SPI_OP_MODE_MASTER:\r
1186         if (ALT_SPIM_SR_RFF_GET(alt_read_word(ALT_SPIM_SR_ADDR(spi_dev->location))) == ALT_SPIM_SR_RFF_E_FULL)\r
1187         {\r
1188             status = ALT_E_TRUE;\r
1189         }\r
1190         break;\r
1191     case ALT_SPI_OP_MODE_SLAVE:\r
1192         if (ALT_SPIS_SR_RFF_GET(alt_read_word(ALT_SPIS_SR_ADDR(spi_dev->location))) == ALT_SPIS_SR_RFF_E_FULL)\r
1193         {\r
1194             status = ALT_E_TRUE;\r
1195         }\r
1196         break;\r
1197     }\r
1198     return status;\r
1199 }\r
1200 \r
1201 //\r
1202 // Returns the number of valid entries in the receive FIFO.\r
1203 //\r
1204 ALT_STATUS_CODE alt_spi_rx_fifo_level_get(ALT_SPI_DEV_t *spi_dev,\r
1205                                           uint32_t *num_entries)\r
1206 {\r
1207     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !num_entries)\r
1208     {\r
1209         return ALT_E_BAD_ARG;\r
1210     }\r
1211 \r
1212     switch (spi_dev->op_mode)\r
1213     {\r
1214     case ALT_SPI_OP_MODE_MASTER:\r
1215         *num_entries = ALT_SPIM_RXFLR_RXTFL_GET(alt_read_word(ALT_SPIM_RXFLR_ADDR(spi_dev->location)));\r
1216         break;\r
1217     case ALT_SPI_OP_MODE_SLAVE:\r
1218         *num_entries = ALT_SPIS_RXFLR_RXTFL_GET(alt_read_word(ALT_SPIS_RXFLR_ADDR(spi_dev->location)));\r
1219         break;\r
1220     }\r
1221 \r
1222     return ALT_E_SUCCESS;\r
1223 \r
1224 }\r
1225 \r
1226 //\r
1227 // Gets the current receive FIFO threshold level value.\r
1228 //\r
1229 ALT_STATUS_CODE alt_spi_rx_fifo_threshold_get(ALT_SPI_DEV_t *spi_dev,\r
1230                                               uint8_t *threshold)\r
1231 {\r
1232     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !threshold)\r
1233     {\r
1234         return ALT_E_BAD_ARG;\r
1235     }\r
1236 \r
1237     switch (spi_dev->op_mode)\r
1238     {\r
1239     case ALT_SPI_OP_MODE_MASTER:\r
1240         *threshold = ALT_SPIM_RXFTLR_RFT_GET(alt_read_word(ALT_SPIM_RXFTLR_ADDR(spi_dev->location)));\r
1241         break;\r
1242     case ALT_SPI_OP_MODE_SLAVE:\r
1243         *threshold = ALT_SPIS_RXFTLR_RFT_GET(alt_read_word(ALT_SPIS_RXFTLR_ADDR(spi_dev->location)));\r
1244         break;\r
1245     }\r
1246 \r
1247     return ALT_E_SUCCESS;\r
1248 \r
1249 }\r
1250 \r
1251 //\r
1252 // Sets the current receive FIFO threshold level value.\r
1253 //\r
1254 ALT_STATUS_CODE alt_spi_rx_fifo_threshold_set(ALT_SPI_DEV_t *spi_dev,\r
1255                                               const uint8_t threshold)\r
1256 {\r
1257     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1258 \r
1259     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
1260     {\r
1261         return ALT_E_ERROR;\r
1262     }\r
1263 \r
1264     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1265     {\r
1266         return ALT_E_BAD_ARG;\r
1267     }\r
1268 \r
1269     switch (spi_dev->op_mode)\r
1270     {\r
1271     case ALT_SPI_OP_MODE_MASTER:\r
1272         alt_replbits_word(ALT_SPIM_RXFTLR_ADDR(spi_dev->location), \r
1273                           ALT_SPIM_RXFTLR_RFT_SET_MSK,\r
1274                           ALT_SPIM_RXFTLR_RFT_SET(threshold));\r
1275         \r
1276         break;\r
1277     case ALT_SPI_OP_MODE_SLAVE:\r
1278         alt_replbits_word(ALT_SPIS_RXFTLR_ADDR(spi_dev->location), \r
1279                           ALT_SPIS_RXFTLR_RFT_SET_MSK,\r
1280                           ALT_SPIS_RXFTLR_RFT_SET(threshold));\r
1281         \r
1282         break;\r
1283     }\r
1284 \r
1285     return status;\r
1286 }\r
1287 \r
1288 //\r
1289 // Returns ALT_E_TRUE when the transmit FIFO is empty.\r
1290 //\r
1291 ALT_STATUS_CODE alt_spi_tx_fifo_is_empty(ALT_SPI_DEV_t *spi_dev)\r
1292 {\r
1293     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1294     {\r
1295         return ALT_E_BAD_ARG;\r
1296     }\r
1297 \r
1298     switch (spi_dev->op_mode)\r
1299     {\r
1300     case ALT_SPI_OP_MODE_MASTER:\r
1301         if (ALT_SPIM_SR_TFE_GET(alt_read_word(ALT_SPIM_SR_ADDR(spi_dev->location))) == ALT_SPIM_SR_TFE_E_EMPTY)\r
1302         {\r
1303             return ALT_E_TRUE;\r
1304         }\r
1305         break;\r
1306     case ALT_SPI_OP_MODE_SLAVE:\r
1307         if (ALT_SPIS_SR_TFE_GET(alt_read_word(ALT_SPIS_SR_ADDR(spi_dev->location))) == ALT_SPIS_SR_TFE_E_EMPTY)\r
1308         {\r
1309             return ALT_E_TRUE;\r
1310         }\r
1311         break;\r
1312     }\r
1313 \r
1314     return ALT_E_FALSE;\r
1315 }\r
1316 \r
1317 //\r
1318 // Returns ALT_E_TRUE when the transmit FIFO is completely full.\r
1319 //\r
1320 ALT_STATUS_CODE alt_spi_tx_fifo_is_full(ALT_SPI_DEV_t *spi_dev)\r
1321 {\r
1322     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1323     {\r
1324         return ALT_E_BAD_ARG;\r
1325     }\r
1326 \r
1327     switch (spi_dev->op_mode)\r
1328     {\r
1329     case ALT_SPI_OP_MODE_MASTER:\r
1330         if (ALT_SPIM_SR_TFNF_GET(alt_read_word(ALT_SPIM_SR_ADDR(spi_dev->location))) == ALT_SPIM_SR_TFNF_E_FULL)\r
1331         {\r
1332             return ALT_E_TRUE;\r
1333         }\r
1334         break;\r
1335     case ALT_SPI_OP_MODE_SLAVE:\r
1336         if (ALT_SPIS_SR_TFNF_GET(alt_read_word(ALT_SPIS_SR_ADDR(spi_dev->location))) == ALT_SPIS_SR_TFNF_E_FULL)\r
1337         {\r
1338             return ALT_E_TRUE;\r
1339         }\r
1340         break;\r
1341     }\r
1342 \r
1343     return ALT_E_FALSE;\r
1344 }\r
1345 \r
1346 //\r
1347 // Returns the number of valid entries in the transmit FIFO.\r
1348 //\r
1349 ALT_STATUS_CODE alt_spi_tx_fifo_level_get(ALT_SPI_DEV_t *spi_dev,\r
1350                                           uint32_t *num_entries)\r
1351 {\r
1352     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !num_entries)\r
1353     {\r
1354         return ALT_E_BAD_ARG;\r
1355     }\r
1356 \r
1357     switch (spi_dev->op_mode)\r
1358     {\r
1359     case ALT_SPI_OP_MODE_MASTER:\r
1360         *num_entries = ALT_SPIM_TXFLR_TXTFL_GET(alt_read_word(ALT_SPIM_TXFLR_ADDR(spi_dev->location)));\r
1361         break;\r
1362     case ALT_SPI_OP_MODE_SLAVE:\r
1363         *num_entries = ALT_SPIS_TXFLR_TXTFL_GET(alt_read_word(ALT_SPIS_TXFLR_ADDR(spi_dev->location)));\r
1364         break;\r
1365     }\r
1366 \r
1367     return ALT_E_SUCCESS;\r
1368 \r
1369 }\r
1370 \r
1371 \r
1372 //\r
1373 // Sets the current transmit FIFO threshold level value.\r
1374 //\r
1375 ALT_STATUS_CODE alt_spi_tx_fifo_threshold_get(ALT_SPI_DEV_t *spi_dev,\r
1376                                               uint8_t *threshold)\r
1377 {\r
1378     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !threshold)\r
1379     {\r
1380         return ALT_E_BAD_ARG;\r
1381     }\r
1382 \r
1383     switch (spi_dev->op_mode)\r
1384     {\r
1385     case ALT_SPI_OP_MODE_MASTER:\r
1386         *threshold = ALT_SPIM_TXFTLR_TFT_GET(alt_read_word(ALT_SPIM_TXFTLR_ADDR(spi_dev->location)));\r
1387         break;\r
1388     case ALT_SPI_OP_MODE_SLAVE:\r
1389         *threshold = ALT_SPIS_TXFTLR_TFT_GET(alt_read_word(ALT_SPIS_TXFTLR_ADDR(spi_dev->location)));\r
1390         break;\r
1391     }\r
1392 \r
1393     return ALT_E_SUCCESS;\r
1394 \r
1395 }\r
1396 \r
1397 //\r
1398 // Sets the current transmit FIFO threshold level value.\r
1399 //\r
1400 ALT_STATUS_CODE alt_spi_tx_fifo_threshold_set(ALT_SPI_DEV_t *spi_dev,\r
1401                                               const uint8_t threshold)\r
1402 {\r
1403     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1404 \r
1405     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
1406     {\r
1407         return ALT_E_ERROR;\r
1408     }\r
1409 \r
1410     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1411     {\r
1412         return ALT_E_BAD_ARG;\r
1413     }\r
1414 \r
1415     switch (spi_dev->op_mode)\r
1416     {\r
1417     case ALT_SPI_OP_MODE_MASTER:\r
1418         alt_replbits_word(ALT_SPIM_TXFTLR_ADDR(spi_dev->location), \r
1419                           ALT_SPIM_TXFTLR_TFT_SET_MSK,\r
1420                           ALT_SPIM_TXFTLR_TFT_SET(threshold));\r
1421         break;\r
1422     case ALT_SPI_OP_MODE_SLAVE:\r
1423         alt_replbits_word(ALT_SPIS_TXFTLR_ADDR(spi_dev->location), \r
1424                           ALT_SPIS_TXFTLR_TFT_SET_MSK,\r
1425                           ALT_SPIS_TXFTLR_TFT_SET(threshold));\r
1426         break;\r
1427     }\r
1428 \r
1429     return status;\r
1430 }\r
1431 \r
1432 //\r
1433 // Get the configured Rx sample delay value.\r
1434 //\r
1435 ALT_STATUS_CODE alt_spi_rx_sample_delay_get(ALT_SPI_DEV_t *spi_dev, uint32_t *delay)\r
1436 {\r
1437     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1438     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !delay)\r
1439     {\r
1440         return ALT_E_BAD_ARG;\r
1441     }\r
1442 \r
1443     switch (spi_dev->op_mode)\r
1444     {\r
1445     case ALT_SPI_OP_MODE_MASTER:\r
1446         *delay = ALT_SPIM_RX_SMPL_DLY_RSD_GET(alt_read_word(ALT_SPIM_RX_SMPL_DLY_ADDR(spi_dev->location)));\r
1447         break;\r
1448     case ALT_SPI_OP_MODE_SLAVE:\r
1449         status = ALT_E_ERROR;\r
1450         break;\r
1451     }\r
1452 \r
1453     return status;\r
1454 }\r
1455 \r
1456 //\r
1457 // Set the configured Rx sample delay value.\r
1458 //\r
1459 ALT_STATUS_CODE alt_spi_rx_sample_delay_set(ALT_SPI_DEV_t *spi_dev, const uint32_t delay)\r
1460 {\r
1461     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1462 \r
1463     if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)\r
1464     {\r
1465         return ALT_E_ERROR;\r
1466     }\r
1467 \r
1468     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1469     {\r
1470         return ALT_E_BAD_ARG;\r
1471     }\r
1472 \r
1473     switch (spi_dev->op_mode)\r
1474     {\r
1475     case ALT_SPI_OP_MODE_MASTER:\r
1476         if(delay & ALT_SPIM_RX_SMPL_DLY_RSD_CLR_MSK)\r
1477         {\r
1478             status = ALT_E_BAD_ARG;\r
1479             break;\r
1480         }\r
1481         alt_replbits_word(ALT_SPIM_RX_SMPL_DLY_ADDR(spi_dev->location), \r
1482                           ALT_SPIM_RX_SMPL_DLY_RSD_SET_MSK,\r
1483                           ALT_SPIM_RX_SMPL_DLY_RSD_SET(delay));\r
1484         break;\r
1485     case ALT_SPI_OP_MODE_SLAVE:\r
1486         status = ALT_E_ERROR;\r
1487         break;\r
1488     }\r
1489 \r
1490     return status;\r
1491 }\r
1492 \r
1493 //\r
1494 // Disable the transmit (Tx) FIFO DMA channel.\r
1495 //\r
1496 ALT_STATUS_CODE alt_spi_dma_tx_disable(ALT_SPI_DEV_t *spi_dev)\r
1497 {\r
1498     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1499     {\r
1500         return ALT_E_BAD_ARG;\r
1501     }\r
1502 \r
1503     // Else clear enable bit of spi_enable register\r
1504     switch (spi_dev->op_mode)\r
1505     {\r
1506     case ALT_SPI_OP_MODE_MASTER:\r
1507         alt_clrbits_word(ALT_SPIM_DMACR_ADDR(spi_dev->location), \r
1508                          ALT_SPIM_DMACR_TDMAE_SET_MSK);\r
1509         break;\r
1510     case ALT_SPI_OP_MODE_SLAVE:\r
1511         alt_clrbits_word(ALT_SPIS_DMACR_ADDR(spi_dev->location), \r
1512                          ALT_SPIS_DMACR_TDMAE_SET_MSK);\r
1513         break;\r
1514     }\r
1515 \r
1516     return ALT_E_SUCCESS;\r
1517 }\r
1518 \r
1519 //\r
1520 // Enable and set the transmit data level for the transmit (Tx) FIFO DMA channel.\r
1521 //\r
1522 ALT_STATUS_CODE alt_spi_dma_tx_enable(ALT_SPI_DEV_t *spi_dev, const uint32_t level)\r
1523 {\r
1524     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1525 \r
1526     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1527     {\r
1528         return ALT_E_BAD_ARG;\r
1529     }\r
1530 \r
1531     switch (spi_dev->op_mode)\r
1532     {\r
1533     case ALT_SPI_OP_MODE_MASTER:\r
1534         alt_setbits_word(ALT_SPIM_DMACR_ADDR(spi_dev->location),\r
1535                          ALT_SPIM_DMACR_TDMAE_SET_MSK);\r
1536         if(level & ALT_SPIM_DMATDLR_DMATDL_CLR_MSK)\r
1537         {\r
1538             status = ALT_E_BAD_ARG;\r
1539             break;\r
1540         }\r
1541         alt_replbits_word(ALT_SPIM_DMATDLR_ADDR(spi_dev->location), \r
1542                           ALT_SPIM_DMATDLR_DMATDL_SET_MSK,\r
1543                           ALT_SPIM_DMATDLR_DMATDL_SET(level));\r
1544         break;\r
1545     case ALT_SPI_OP_MODE_SLAVE:\r
1546         if(level & ALT_SPIS_DMATDLR_DMATDL_CLR_MSK)\r
1547         {\r
1548             status = ALT_E_BAD_ARG;\r
1549             break;\r
1550         }\r
1551         alt_setbits_word( ALT_SPIS_DMACR_ADDR(spi_dev->location),\r
1552                           ALT_SPIS_DMACR_TDMAE_SET_MSK);\r
1553         alt_replbits_word(ALT_SPIS_DMATDLR_ADDR(spi_dev->location), \r
1554                           ALT_SPIS_DMATDLR_DMATDL_SET_MSK,\r
1555                           ALT_SPIS_DMATDLR_DMATDL_SET(level));\r
1556         break;\r
1557     }\r
1558     \r
1559     return status;\r
1560 }\r
1561 \r
1562 //\r
1563 // Disable the receive (Rx) FIFO DMA channel.\r
1564 //\r
1565 ALT_STATUS_CODE alt_spi_dma_rx_disable(ALT_SPI_DEV_t *spi_dev)\r
1566 {\r
1567     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1568     {\r
1569         return ALT_E_BAD_ARG;\r
1570     }\r
1571 \r
1572     // Else clear enable bit of spi_enable register\r
1573     switch (spi_dev->op_mode)\r
1574     {\r
1575     case ALT_SPI_OP_MODE_MASTER:\r
1576         alt_clrbits_word(ALT_SPIM_DMACR_ADDR(spi_dev->location), \r
1577                          ALT_SPIM_DMACR_RDMAE_SET_MSK);\r
1578         break;\r
1579     case ALT_SPI_OP_MODE_SLAVE:\r
1580         alt_clrbits_word(ALT_SPIS_DMACR_ADDR(spi_dev->location), \r
1581                          ALT_SPIS_DMACR_RDMAE_SET_MSK);\r
1582         break;\r
1583     }\r
1584 \r
1585     return ALT_E_SUCCESS;\r
1586 }\r
1587 \r
1588 //\r
1589 // Enable and set the receive data level for the receive (Rx) FIFO DMA channel.\r
1590 //\r
1591 ALT_STATUS_CODE alt_spi_dma_rx_enable(ALT_SPI_DEV_t *spi_dev, const uint32_t level)\r
1592 {\r
1593     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1594 \r
1595     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1596     {\r
1597         return ALT_E_BAD_ARG;\r
1598     }\r
1599 \r
1600     switch (spi_dev->op_mode)\r
1601     {\r
1602     case ALT_SPI_OP_MODE_MASTER:\r
1603         alt_setbits_word( ALT_SPIM_DMACR_ADDR(spi_dev->location),\r
1604                           ALT_SPIM_DMACR_RDMAE_SET_MSK);\r
1605         if(level & ALT_SPIM_DMARDLR_DMARDL_CLR_MSK)\r
1606         {\r
1607             status = ALT_E_BAD_ARG;\r
1608             break;\r
1609         }\r
1610         alt_replbits_word(ALT_SPIM_DMARDLR_ADDR(spi_dev->location), \r
1611                           ALT_SPIM_DMARDLR_DMARDL_SET_MSK,\r
1612                           ALT_SPIM_DMARDLR_DMARDL_SET(level));\r
1613         break;\r
1614     case ALT_SPI_OP_MODE_SLAVE:\r
1615         if(level & ALT_SPIS_DMARDLR_DMARDL_CLR_MSK)\r
1616         {\r
1617             status = ALT_E_BAD_ARG;\r
1618             break;\r
1619         }\r
1620         alt_setbits_word( ALT_SPIS_DMACR_ADDR(spi_dev->location),\r
1621                           ALT_SPIS_DMACR_RDMAE_SET_MSK);\r
1622         alt_replbits_word(ALT_SPIS_DMARDLR_ADDR(spi_dev->location), \r
1623                           ALT_SPIS_DMARDLR_DMARDL_SET_MSK,\r
1624                           ALT_SPIS_DMARDLR_DMARDL_SET(level));\r
1625         break;\r
1626     }\r
1627     \r
1628     return status;\r
1629 }\r
1630 \r
1631 //\r
1632 // Reads a data frame from the receive (Rx) FIFO.\r
1633 //\r
1634 ALT_STATUS_CODE alt_spi_rx_fifo_deq(ALT_SPI_DEV_t *spi_dev, uint16_t *data)\r
1635 {\r
1636     if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !data)\r
1637     {\r
1638         return ALT_E_BAD_ARG;\r
1639     }\r
1640 \r
1641     if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)\r
1642     {\r
1643         return ALT_E_ERROR;\r
1644     }\r
1645 \r
1646     switch (spi_dev->op_mode)\r
1647     {\r
1648     case ALT_SPI_OP_MODE_MASTER:\r
1649         *data = (ALT_SPIM_DR_DR_GET(alt_read_word(ALT_SPIM_DR_ADDR(spi_dev->location))));\r
1650         break;\r
1651     case ALT_SPI_OP_MODE_SLAVE:\r
1652         *data = (ALT_SPIS_DR_DR_GET(alt_read_word(ALT_SPIS_DR_ADDR(spi_dev->location))));\r
1653         break;\r
1654     }\r
1655 \r
1656     return ALT_E_SUCCESS;\r
1657 }\r
1658 \r
1659 //\r
1660 // Writes a data frame to the transmit (Tx) FIFO for transmittal.\r
1661 //\r
1662 ALT_STATUS_CODE alt_spi_tx_fifo_enq(ALT_SPI_DEV_t *spi_dev, const uint16_t data)\r
1663 {\r
1664     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1665     {\r
1666         return ALT_E_BAD_ARG;\r
1667     }\r
1668 \r
1669     if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)\r
1670     {\r
1671         return ALT_E_ERROR;\r
1672     }\r
1673 \r
1674     switch (spi_dev->op_mode)\r
1675     {\r
1676     case ALT_SPI_OP_MODE_MASTER:\r
1677         alt_write_word(ALT_SPIM_DR_ADDR(spi_dev->location), ALT_SPIM_DR_DR_SET(data));\r
1678         break;\r
1679     case ALT_SPI_OP_MODE_SLAVE:\r
1680         alt_write_word(ALT_SPIS_DR_ADDR(spi_dev->location), ALT_SPIS_DR_DR_SET(data));\r
1681         break;\r
1682     }\r
1683 \r
1684     return ALT_E_SUCCESS;\r
1685 }\r
1686 \r
1687 //\r
1688 // This function writes a single data byte to the transmit FIFO. \r
1689 //\r
1690 static ALT_STATUS_CODE alt_spi_transmit_error_handler(ALT_SPI_DEV_t *spi_dev, ALT_STATUS_CODE *err_status)\r
1691 {\r
1692     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
1693     uint32_t int_status = 0;\r
1694 \r
1695     status = alt_spi_int_raw_status_get(spi_dev, &int_status);\r
1696 \r
1697     if (status == ALT_E_TRUE && int_status != 0)\r
1698     {\r
1699         if(int_status \r
1700             & (ALT_SPI_STATUS_TXOI\r
1701                 | ALT_SPI_STATUS_RXOI\r
1702                 | ALT_SPI_STATUS_RXUI))\r
1703         {\r
1704             *err_status = ALT_E_BUF_OVF;\r
1705         }\r
1706     }\r
1707 \r
1708     return status;\r
1709 }\r
1710 \r
1711 //\r
1712 // Write or read bulk of data form master mode\r
1713 //\r
1714 static ALT_STATUS_CODE alt_spi_master_transfer_helper(ALT_SPI_DEV_t *spi_dev, \r
1715                                                       size_t data_send,\r
1716                                                       size_t data_recv,\r
1717                                                       const uint16_t * tx_buf, \r
1718                                                       uint16_t * rx_buf)\r
1719 {\r
1720     ALT_STATUS_CODE    status  = ALT_E_SUCCESS;\r
1721 \r
1722     const uint16_t * buffer_tx = tx_buf;\r
1723     uint16_t * buffer_rx       = rx_buf;\r
1724     uint32_t timeout           = MAX(data_send, data_recv) * 10000;\r
1725     \r
1726     while (data_send > 0 || data_recv > 0)\r
1727     {\r
1728         // Error handling\r
1729         ALT_STATUS_CODE err_status = 0;\r
1730         status = alt_spi_transmit_error_handler(spi_dev, &err_status);\r
1731     \r
1732         if (status != ALT_E_SUCCESS)\r
1733         {\r
1734             break;\r
1735         }\r
1736     \r
1737         if (err_status != ALT_E_SUCCESS)\r
1738         {\r
1739             status = err_status;\r
1740             break;\r
1741         }\r
1742     \r
1743         // Top up the TX FIFO with sending data\r
1744     \r
1745         if (data_send > 0)\r
1746         {\r
1747             uint32_t level = 0;\r
1748             status = alt_spi_tx_fifo_level_get(spi_dev, &level);\r
1749             if (status != ALT_E_SUCCESS)\r
1750             {\r
1751                 break;\r
1752             }\r
1753     \r
1754             uint32_t space = ALT_SPI_TX_FIFO_NUM_ENTRIES - level;\r
1755     \r
1756             space = MIN(data_send, space);\r
1757     \r
1758             for (uint32_t i = 0; i < space; ++i)\r
1759             {\r
1760                 alt_write_word(ALT_SPIM_DR_ADDR(spi_dev->location), ALT_SPIM_DR_DR_SET(*buffer_tx));\r
1761                 ++buffer_tx;\r
1762             }\r
1763     \r
1764             data_send -= space;\r
1765         }\r
1766     \r
1767         // Read out the resulting received data as they come in.\r
1768     \r
1769         if (data_recv > 0)\r
1770         {\r
1771             uint32_t level = 0;\r
1772             status = alt_spi_rx_fifo_level_get(spi_dev, &level);\r
1773             if (status != ALT_E_SUCCESS)\r
1774             {\r
1775                 break;\r
1776             }\r
1777     \r
1778             if (level == 0)\r
1779             {\r
1780                 timeout--;\r
1781                 if (timeout == 0)\r
1782                 {\r
1783                     status = ALT_E_TMO;\r
1784                     break;\r
1785                 }\r
1786             }\r
1787     \r
1788             level = MIN(data_recv, level);\r
1789     \r
1790             for (uint32_t i = 0; i < level; ++i)\r
1791             {\r
1792                 uint32_t data_read = alt_read_word(ALT_SPIM_DR_ADDR(spi_dev->location));\r
1793                 *buffer_rx = (ALT_SPIM_DR_DR_GET(data_read));\r
1794                 //printf("data %x\n", (unsigned int)data_read);\r
1795                 ++buffer_rx;\r
1796             }\r
1797     \r
1798             data_recv -= level;\r
1799         }\r
1800     }\r
1801 \r
1802     return status;\r
1803 }\r
1804 \r
1805 //\r
1806 // This function performs a master SPI/SSP serial master transfer operations (use by all transfer functions).\r
1807 //\r
1808 static ALT_STATUS_CODE alt_spi_master_transfer(ALT_SPI_DEV_t *spi_dev, \r
1809                                                const uint32_t slave_select,\r
1810                                                const size_t num_frames,\r
1811                                                const uint16_t * tx_buf, \r
1812                                                uint16_t * rx_buf,\r
1813                                                ALT_SPI_TMOD_t transfer_mode,\r
1814                                                const uint8_t opcode,\r
1815                                                const uint32_t eeprom_addr)\r
1816 {\r
1817     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
1818     {\r
1819         return ALT_E_BAD_ARG;\r
1820     }\r
1821 \r
1822     if (spi_dev->op_mode == ALT_SPI_OP_MODE_SLAVE)\r
1823     {\r
1824         return ALT_E_ERROR;\r
1825     }\r
1826     \r
1827     if (num_frames == 0) \r
1828     {\r
1829         return ALT_E_SUCCESS;\r
1830     }\r
1831 \r
1832     ALT_STATUS_CODE    status = ALT_E_SUCCESS;\r
1833 \r
1834     if(alt_spi_is_busy(spi_dev) == ALT_E_TRUE)\r
1835     {\r
1836         return ALT_E_ERROR;\r
1837     }\r
1838 \r
1839     // Checking necessity to update slave mask\r
1840     if (slave_select != spi_dev->last_slave_mask)\r
1841     {\r
1842         status = alt_spi_disable(spi_dev);\r
1843         if (status != ALT_E_SUCCESS)\r
1844         {\r
1845             return status;\r
1846         }\r
1847         // Update slave select mask\r
1848         alt_spi_slave_select_disable(spi_dev, ALT_SPI_SLAVE_MASK_ALL);\r
1849         status = alt_spi_slave_select_enable(spi_dev, slave_select);\r
1850         if (status != ALT_E_SUCCESS)\r
1851         {\r
1852             return status;\r
1853         }\r
1854 \r
1855         spi_dev->last_slave_mask = slave_select;\r
1856     }\r
1857 \r
1858     // Checking necessity to update transfer mode\r
1859     if (transfer_mode != spi_dev->last_transfer_mode)\r
1860     {\r
1861         status = alt_spi_disable(spi_dev);\r
1862         if (status != ALT_E_SUCCESS)\r
1863         {\r
1864             return status;\r
1865         }\r
1866         // Update transfer mode\r
1867         alt_replbits_word(ALT_SPIM_CTLR0_ADDR(spi_dev->location),\r
1868                           ALT_SPIM_CTLR0_TMOD_SET_MSK,\r
1869                           ALT_SPIM_CTLR0_TMOD_SET(transfer_mode));\r
1870         spi_dev->last_transfer_mode = transfer_mode;\r
1871     }\r
1872     \r
1873     if (transfer_mode == ALT_SPI_TMOD_RX || transfer_mode == ALT_SPI_TMOD_EEPROM)\r
1874     {\r
1875         status = alt_spi_disable(spi_dev);\r
1876         if (status != ALT_E_SUCCESS)\r
1877         {\r
1878             return status;\r
1879         }\r
1880         // Set number of data frames for read\r
1881         status = alt_spi_num_data_frames_set(spi_dev, num_frames - 1);\r
1882         if (status != ALT_E_SUCCESS)\r
1883         {\r
1884             return status;\r
1885         }\r
1886     }\r
1887 \r
1888     // Clear interrupt status and disable interrupt mask\r
1889     alt_spi_int_clear(spi_dev, ALT_SPI_STATUS_ALL);\r
1890     alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_ALL);\r
1891 \r
1892     if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)\r
1893     {\r
1894         status = alt_spi_enable(spi_dev);\r
1895         if (status != ALT_E_SUCCESS)\r
1896         {\r
1897             return status;\r
1898         }\r
1899     }\r
1900     \r
1901     //Enable abort and TXFIFO empty interrupt status\r
1902     alt_spi_int_enable(spi_dev, ALT_SPI_STATUS_RXOI | \r
1903                                 ALT_SPI_STATUS_RXUI | \r
1904                                 ALT_SPI_STATUS_TXOI);\r
1905 \r
1906     // This SPI controller requires that a read issue be performed for each byte requested.\r
1907     // Read issue takes space in the TX FIFO, which may asynchronously handling a previous request.\r
1908     \r
1909     uint32_t data_send = 0;\r
1910     uint32_t data_recv = 0;\r
1911     \r
1912     if (transfer_mode == ALT_SPI_TMOD_TX || transfer_mode == ALT_SPI_TMOD_TXRX)\r
1913     {\r
1914         data_send = num_frames;\r
1915     }\r
1916     \r
1917     if (transfer_mode == ALT_SPI_TMOD_RX   || \r
1918         transfer_mode == ALT_SPI_TMOD_TXRX ||\r
1919         transfer_mode == ALT_SPI_TMOD_EEPROM)\r
1920     {\r
1921         data_recv = num_frames;\r
1922     }\r
1923     \r
1924     if (transfer_mode == ALT_SPI_TMOD_EEPROM)\r
1925     {\r
1926         //Send opcode and eeprom address\r
1927         alt_write_word(ALT_SPIM_DR_ADDR(spi_dev->location), ALT_SPIM_DR_DR_SET(opcode));\r
1928         alt_write_word(ALT_SPIM_DR_ADDR(spi_dev->location), ALT_SPIM_DR_DR_SET(((eeprom_addr & 0xFF00) >> 8)));\r
1929         alt_write_word(ALT_SPIM_DR_ADDR(spi_dev->location), ALT_SPIM_DR_DR_SET(eeprom_addr & 0xFF));\r
1930     }\r
1931     if (transfer_mode == ALT_SPI_TMOD_RX)\r
1932     {\r
1933         //Activate rx transfer\r
1934         alt_spi_tx_fifo_enq(spi_dev, 0);\r
1935     }\r
1936     \r
1937     // Write or read bulk of data\r
1938     status = alt_spi_master_transfer_helper(spi_dev,\r
1939                                             data_send, data_recv,\r
1940                                             tx_buf,  \r
1941                                             rx_buf);\r
1942 \r
1943     // Need reset for set spi bus in idle state\r
1944     if(status == ALT_E_TMO)\r
1945         alt_spi_reset(spi_dev);\r
1946 \r
1947     // Mask all interrupts\r
1948     alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_ALL);\r
1949 \r
1950     return status;\r
1951 }\r
1952 \r
1953 //\r
1954 // This function performs a master SPI/SSP serial transmit and receive transfer.\r
1955 //\r
1956 ALT_STATUS_CODE alt_spi_master_tx_rx_transfer(ALT_SPI_DEV_t *spi_dev, \r
1957                                               const uint32_t slave_select,\r
1958                                               const size_t num_frames,\r
1959                                               const uint16_t * tx_buf, \r
1960                                               uint16_t * rx_buf)\r
1961 {\r
1962     return alt_spi_master_transfer(spi_dev, \r
1963                                    slave_select, \r
1964                                    num_frames,\r
1965                                    tx_buf, \r
1966                                    rx_buf, \r
1967                                    ALT_SPI_TMOD_TXRX, \r
1968                                    0, 0);\r
1969 }\r
1970 \r
1971 //\r
1972 // This function performs a master SPI/SSP serial transmit only transfer.\r
1973 //\r
1974 ALT_STATUS_CODE alt_spi_master_tx_transfer(ALT_SPI_DEV_t *spi_dev, \r
1975                                            const uint32_t slave_select,\r
1976                                            const size_t num_frames,\r
1977                                            const uint16_t * tx_buf)\r
1978 {\r
1979     return alt_spi_master_transfer(spi_dev, \r
1980                                    slave_select, \r
1981                                    num_frames,\r
1982                                    tx_buf, NULL, \r
1983                                    ALT_SPI_TMOD_TX, \r
1984                                    0, 0);\r
1985 }\r
1986 \r
1987 //\r
1988 // This function performs a master SPI/SSP serial receive only transfer.\r
1989 //\r
1990 ALT_STATUS_CODE alt_spi_master_rx_transfer(ALT_SPI_DEV_t *spi_dev, \r
1991                                            const uint32_t slave_select,\r
1992                                            const size_t num_frames,\r
1993                                            uint16_t * rx_buf)\r
1994 {\r
1995     return alt_spi_master_transfer(spi_dev, \r
1996                                    slave_select, \r
1997                                    num_frames,\r
1998                                    NULL, \r
1999                                    rx_buf, \r
2000                                    ALT_SPI_TMOD_RX, \r
2001                                    0, 0);\r
2002 }\r
2003 \r
2004 //\r
2005 // This function performs a master SPI EEPROM read transfer.\r
2006 //\r
2007 ALT_STATUS_CODE alt_spi_master_eeprom_transfer(ALT_SPI_DEV_t *spi_dev, \r
2008                                                const uint32_t slave_select,\r
2009                                                const uint8_t opcode,\r
2010                                                const uint16_t eeprom_addr,\r
2011                                                const size_t num_frames,\r
2012                                                uint16_t * rx_buf)\r
2013 {\r
2014     return alt_spi_master_transfer(spi_dev, \r
2015                                    slave_select, \r
2016                                    num_frames,\r
2017                                    NULL, \r
2018                                    rx_buf, \r
2019                                    ALT_SPI_TMOD_EEPROM, \r
2020                                    opcode, \r
2021                                    eeprom_addr);\r
2022 }\r
2023 \r
2024 //\r
2025 // Write or read bulk of data form slave mode\r
2026 //\r
2027 static ALT_STATUS_CODE alt_spi_slave_transfer_helper(ALT_SPI_DEV_t *spi_dev, \r
2028                                               size_t data_send,\r
2029                                               size_t data_recv,\r
2030                                               const uint16_t * tx_buf, \r
2031                                               uint16_t * rx_buf)\r
2032 {\r
2033     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
2034 \r
2035     const uint16_t * buffer_tx = tx_buf;\r
2036     uint16_t * buffer_rx = rx_buf;\r
2037     uint32_t timeout = MAX(data_send, data_recv) * 10000;\r
2038     \r
2039     while (data_send > 0 || data_recv > 0)\r
2040     {\r
2041         // Error handling\r
2042         ALT_STATUS_CODE err_status = 0;\r
2043         status = alt_spi_transmit_error_handler(spi_dev, &err_status);\r
2044     \r
2045         if (status != ALT_E_SUCCESS)\r
2046         {\r
2047             break;\r
2048         }\r
2049     \r
2050         if (err_status != ALT_E_SUCCESS)\r
2051         {\r
2052             status = err_status;\r
2053             break;\r
2054         }\r
2055     \r
2056         // Read out the resulting received data as they come in.\r
2057         \r
2058         if (data_recv > 0)\r
2059         {\r
2060             uint32_t level = 0;\r
2061             status = alt_spi_rx_fifo_level_get(spi_dev, &level);\r
2062             if (status != ALT_E_SUCCESS)\r
2063             {\r
2064                 break;\r
2065             }\r
2066         \r
2067             if (level == 0)\r
2068             {\r
2069                 if (--timeout == 0)\r
2070                 {\r
2071                     status = ALT_E_TMO;\r
2072                     break;\r
2073                 }\r
2074             }\r
2075         \r
2076             level = MIN(data_recv, level);\r
2077         \r
2078             for (uint32_t i = 0; i < level; ++i)\r
2079             {\r
2080                 *buffer_rx = (ALT_SPIS_DR_DR_GET(alt_read_word(ALT_SPIS_DR_ADDR(spi_dev->location))));\r
2081                 ++buffer_rx;\r
2082             }\r
2083         \r
2084             data_recv -= level;\r
2085         }\r
2086 \r
2087         // Top up the TX FIFO with sending data\r
2088         \r
2089         if (data_send > 0)\r
2090         {\r
2091             uint32_t level = 0;\r
2092             status = alt_spi_tx_fifo_level_get(spi_dev, &level);\r
2093             if (status != ALT_E_SUCCESS)\r
2094             {\r
2095                 break;\r
2096             }\r
2097     \r
2098             uint32_t space = ALT_SPI_TX_FIFO_NUM_ENTRIES - level;\r
2099     \r
2100             space = MIN(data_send, space);\r
2101     \r
2102             for (uint32_t i = 0; i < space; ++i)\r
2103             {\r
2104                 alt_write_word(ALT_SPIS_DR_ADDR(spi_dev->location), ALT_SPIS_DR_DR_SET(*buffer_tx));\r
2105                 ++buffer_tx;\r
2106             }\r
2107     \r
2108             data_send -= space;\r
2109         }\r
2110     \r
2111     }\r
2112 \r
2113     return status;\r
2114 }\r
2115 //\r
2116 // This function performs a slave SPI/SSP serial slave transfer.\r
2117 //\r
2118 static ALT_STATUS_CODE alt_spi_slave_transfer(ALT_SPI_DEV_t *spi_dev, \r
2119                                               const uint16_t * tx_buf, \r
2120                                               uint16_t * rx_buf,\r
2121                                               const size_t buf_len,\r
2122                                               ALT_SPI_TMOD_t transfer_mode)\r
2123 {\r
2124     if (alt_spi_checking(spi_dev) == ALT_E_FALSE)\r
2125     {\r
2126         return ALT_E_BAD_ARG;\r
2127     }\r
2128 \r
2129     if (spi_dev->op_mode == ALT_SPI_OP_MODE_MASTER)\r
2130     {\r
2131         return ALT_E_ERROR;\r
2132     }\r
2133     \r
2134     if (buf_len == 0) \r
2135     {\r
2136         return ALT_E_SUCCESS;\r
2137     }\r
2138 \r
2139     if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)\r
2140     {\r
2141         return ALT_E_ERROR;\r
2142     }\r
2143     \r
2144     ALT_STATUS_CODE status = ALT_E_SUCCESS;\r
2145 \r
2146     // Clear interrupt status and disable interrupt mask\r
2147     alt_spi_int_clear(  spi_dev,ALT_SPI_STATUS_ALL);\r
2148     alt_spi_int_disable(spi_dev,ALT_SPI_STATUS_ALL);\r
2149     // Enable abort and TXFIFO empty interrupt status\r
2150     alt_spi_int_enable( spi_dev,ALT_SPI_STATUS_RXOI | \r
2151                                 ALT_SPI_STATUS_RXUI | \r
2152                                 ALT_SPI_STATUS_TXOI);\r
2153 \r
2154     // This SPI controller requires that a read issue be performed for each byte requested.\r
2155     // Read issue takes space in the TX FIFO, which may asynchronously handling a previous request.\r
2156     \r
2157     uint32_t data_send = 0;\r
2158     uint32_t data_recv = 0;\r
2159     \r
2160     if (transfer_mode == ALT_SPI_TMOD_TX || transfer_mode == ALT_SPI_TMOD_TXRX)\r
2161     {\r
2162         data_send = buf_len;\r
2163     }\r
2164     \r
2165     if (transfer_mode == ALT_SPI_TMOD_RX || transfer_mode == ALT_SPI_TMOD_TXRX)\r
2166     {\r
2167         data_recv = buf_len;\r
2168     }\r
2169     \r
2170     // Write or read bulk of data\r
2171     status = alt_spi_slave_transfer_helper(spi_dev, \r
2172                                            data_send, \r
2173                                            data_recv,\r
2174                                            tx_buf, \r
2175                                            rx_buf);\r
2176 \r
2177     // Need reset for set spi bus in idle state\r
2178     if(status == ALT_E_TMO)\r
2179         alt_spi_reset(spi_dev);\r
2180 \r
2181     // Mask all interrupts\r
2182     alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_ALL);\r
2183 \r
2184     return status;\r
2185 \r
2186 }\r
2187 \r
2188 //\r
2189 // This function performs a slave SPI/SSP serial transmit and receive transfer.\r
2190 //\r
2191 ALT_STATUS_CODE alt_spi_slave_tx_rx_transfer(ALT_SPI_DEV_t *spi_dev, \r
2192                                              const uint16_t * tx_buf, \r
2193                                              uint16_t * rx_buf,\r
2194                                              const size_t buf_len)\r
2195 {\r
2196     return alt_spi_slave_transfer(spi_dev, \r
2197                                   tx_buf, \r
2198                                   rx_buf, \r
2199                                   buf_len, \r
2200                                   ALT_SPI_TMOD_TXRX);\r
2201 }\r
2202 \r
2203 //\r
2204 // This function performs a slave SPI/SSP serial transmit only transfer.\r
2205 //\r
2206 ALT_STATUS_CODE alt_spi_slave_tx_transfer(ALT_SPI_DEV_t *spi_dev, \r
2207                                           const uint16_t * tx_buf,\r
2208                                           const size_t buf_len)\r
2209 {\r
2210     alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_RXFI);\r
2211     return alt_spi_slave_transfer(spi_dev, \r
2212                                   tx_buf, \r
2213                                   NULL, \r
2214                                   buf_len, \r
2215                                   ALT_SPI_TMOD_TXRX);\r
2216 }\r
2217 \r
2218 //\r
2219 // This function performs a slave SPI/SSP serial receive only transfer.\r
2220 //\r
2221 ALT_STATUS_CODE alt_spi_slave_rx_transfer(ALT_SPI_DEV_t *spi_dev, \r
2222                                           uint16_t * rx_buf,\r
2223                                           const size_t buf_len)\r
2224 {\r
2225     alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_TXEI);\r
2226     return alt_spi_slave_transfer(spi_dev, \r
2227                                   NULL, \r
2228                                   rx_buf, \r
2229                                   buf_len, \r
2230                                   ALT_SPI_TMOD_TXRX);\r
2231 }\r
2232 \r