1 /******************************************************************************
\r
3 * Copyright 2013 Altera Corporation. All Rights Reserved.
\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
8 * 1. Redistributions of source code must retain the above copyright notice,
\r
9 * this list of conditions and the following disclaimer.
\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
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
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
29 ******************************************************************************/
\r
31 #include "alt_spi.h"
\r
32 #include "alt_reset_manager.h"
\r
33 #include "socal/alt_rstmgr.h"
\r
35 // Timeout for reset manager
\r
36 #define ALT_SPI_RESET_TMO_INIT 8192
\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
47 #define MIN(a, b) ((a) < (b) ? (a) : (b))
\r
48 #define MAX(a, b) ((a) > (b) ? (a) : (b))
\r
53 // Check whether spi space is correct.
\r
55 static ALT_STATUS_CODE alt_spi_checking(ALT_SPI_DEV_t * spi_dev)
\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
78 // Initialize the specified SPI controller instance for use and return a device
\r
79 // handle referencing it.
\r
81 ALT_STATUS_CODE alt_spi_init(const ALT_SPI_CTLR_t spi,
\r
82 ALT_SPI_DEV_t * spi_dev)
\r
85 if (!spi_dev || spi == 0)
\r
87 return ALT_E_BAD_ARG;
\r
90 //Save spi start address to the instance
\r
91 spi_dev->location = (void *)spi;
\r
93 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
95 return ALT_E_BAD_ARG;
\r
98 if (alt_clk_is_enabled(ALT_CLK_SPI_M) != ALT_E_TRUE)
\r
100 return ALT_E_BAD_CLK;
\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
107 spi_dev->op_mode = ALT_SPI_OP_MODE_MASTER;
\r
109 else if ( spi_dev->location == (void *)ALT_SPI_SPIS0
\r
110 || spi_dev->location == (void *)ALT_SPI_SPIS1)
\r
112 spi_dev->op_mode = ALT_SPI_OP_MODE_SLAVE;
\r
117 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
119 if (status == ALT_E_SUCCESS)
\r
121 // Get spi clock frequence
\r
122 status = alt_clk_freq_get(ALT_CLK_SPI_M, &spi_dev->clock_freq);
\r
125 // Reset spi module
\r
126 if (status == ALT_E_SUCCESS)
\r
128 status = alt_spi_reset(spi_dev);
\r
135 // Reset spi module by reset manager
\r
137 static ALT_STATUS_CODE alt_spi_rstmgr_set(ALT_SPI_DEV_t * spi_dev)
\r
139 uint32_t rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;
\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
144 case ALT_SPI_SPIM0:
\r
145 rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;
\r
147 case ALT_SPI_SPIM1:
\r
148 rst_mask = ALT_RSTMGR_PERMODRST_SPIM1_SET_MSK;
\r
150 case ALT_SPI_SPIS0:
\r
151 rst_mask = ALT_RSTMGR_PERMODRST_SPIS0_SET_MSK;
\r
153 case ALT_SPI_SPIS1:
\r
154 rst_mask = ALT_RSTMGR_PERMODRST_SPIS1_SET_MSK;
\r
157 return ALT_E_BAD_ARG;
\r
160 alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
\r
162 return ALT_E_SUCCESS;
\r
166 // Reset spi module by reset manager
\r
168 static ALT_STATUS_CODE alt_spi_rstmgr_strobe(ALT_SPI_DEV_t * spi_dev)
\r
170 uint32_t rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;
\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
175 case ALT_SPI_SPIM0:
\r
176 rst_mask = ALT_RSTMGR_PERMODRST_SPIM0_SET_MSK;
\r
178 case ALT_SPI_SPIM1:
\r
179 rst_mask = ALT_RSTMGR_PERMODRST_SPIM1_SET_MSK;
\r
181 case ALT_SPI_SPIS0:
\r
182 rst_mask = ALT_RSTMGR_PERMODRST_SPIS0_SET_MSK;
\r
184 case ALT_SPI_SPIS1:
\r
185 rst_mask = ALT_RSTMGR_PERMODRST_SPIS1_SET_MSK;
\r
188 return ALT_E_BAD_ARG;
\r
191 alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, rst_mask);
\r
193 volatile uint32_t timeout = ALT_SPI_RESET_TMO_INIT;
\r
195 // Wait while spi modure is reseting
\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
202 return ALT_E_SUCCESS;
\r
206 // Reset spi module
\r
208 ALT_STATUS_CODE alt_spi_reset(ALT_SPI_DEV_t * spi_dev)
\r
211 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
213 return ALT_E_BAD_ARG;
\r
216 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
217 bool already_enabled = (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE);
\r
219 if (already_enabled)
\r
221 // Temporarily disable controller
\r
222 status = alt_spi_disable(spi_dev);
\r
223 if (status != ALT_E_SUCCESS)
\r
229 // Reset spi module by reset manager
\r
230 alt_spi_rstmgr_strobe(spi_dev);
\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
236 if (already_enabled)
\r
238 // Re-enable controller
\r
239 status = alt_spi_enable(spi_dev);
\r
247 // Uninitialize the SPI controller referenced by the spi_dev handle.
\r
249 ALT_STATUS_CODE alt_spi_uninit(ALT_SPI_DEV_t * spi_dev)
\r
251 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
252 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
254 return ALT_E_BAD_ARG;
\r
257 // Disable spi controller
\r
258 status = alt_spi_disable(spi_dev);
\r
259 if (status != ALT_E_SUCCESS)
\r
264 // Reset spi module by reset manager
\r
265 alt_spi_rstmgr_set(spi_dev);
\r
272 // Enables the SPI controller.
\r
274 ALT_STATUS_CODE alt_spi_enable(ALT_SPI_DEV_t * spi_dev)
\r
276 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
278 return ALT_E_BAD_ARG;
\r
281 switch (spi_dev->op_mode)
\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
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
293 return ALT_E_SUCCESS;
\r
297 // Disables the SPI controller
\r
299 ALT_STATUS_CODE alt_spi_disable(ALT_SPI_DEV_t * spi_dev)
\r
301 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
303 return ALT_E_BAD_ARG;
\r
306 // If spi controller is enabled, return with sucess
\r
307 if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)
\r
309 return ALT_E_SUCCESS;
\r
312 // Else clear enable bit of spi_enable register
\r
313 switch (spi_dev->op_mode)
\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
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
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
329 return ALT_E_SUCCESS;
\r
333 // Check whether spi controller is enable
\r
335 ALT_STATUS_CODE alt_spi_is_enabled(ALT_SPI_DEV_t * spi_dev)
\r
337 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
339 return ALT_E_BAD_ARG;
\r
342 ALT_STATUS_CODE en_status = ALT_E_FALSE;
\r
343 switch (spi_dev->op_mode)
\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
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
355 ALT_STATUS_CODE alt_spi_is_busy(ALT_SPI_DEV_t *spi_dev)
\r
358 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
360 return ALT_E_BAD_ARG;
\r
363 switch (spi_dev->op_mode)
\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
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
379 return ALT_E_FALSE;
\r
383 // Get config parameters from appropriate registers.
\r
385 ALT_STATUS_CODE alt_spi_config_get(ALT_SPI_DEV_t *spi_dev,
\r
386 ALT_SPI_CONFIG_t* cfg)
\r
388 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)
\r
390 return ALT_E_BAD_ARG;
\r
393 uint32_t cfg_register;
\r
394 switch (spi_dev->op_mode)
\r
396 case ALT_SPI_OP_MODE_MASTER:
\r
397 cfg_register = alt_read_word(ALT_SPIM_CTLR0_ADDR(spi_dev->location));
\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
406 case ALT_SPI_OP_MODE_SLAVE:
\r
407 cfg_register = alt_read_word(ALT_SPIS_CTLR0_ADDR(spi_dev->location));
\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
418 return ALT_E_SUCCESS;
\r
422 // Set config parameters to appropriate registers.
\r
424 ALT_STATUS_CODE alt_spi_config_set(ALT_SPI_DEV_t *spi_dev,
\r
425 const ALT_SPI_CONFIG_t* cfg)
\r
427 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
429 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
431 return ALT_E_ERROR;
\r
434 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)
\r
436 return ALT_E_BAD_ARG;
\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
443 return ALT_E_ARG_RANGE;
\r
446 // Set config parameters to appropriate registers
\r
447 uint32_t cfg_register;
\r
449 switch (spi_dev->op_mode)
\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
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
466 alt_replbits_word(ALT_SPIM_CTLR0_ADDR(spi_dev->location), cfg_mask, cfg_register);
\r
468 case ALT_SPI_OP_MODE_SLAVE:
\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
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
486 alt_replbits_word(ALT_SPIS_CTLR0_ADDR(spi_dev->location), cfg_mask, cfg_register);
\r
490 spi_dev->last_transfer_mode = cfg->transfer_mode;
\r
497 // Get config parameters from appropriate registers for microwire mode.
\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
502 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)
\r
504 return ALT_E_BAD_ARG;
\r
507 uint32_t cfg_register, mwcr_register;
\r
508 switch (spi_dev->op_mode)
\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
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
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
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
528 return ALT_E_SUCCESS;
\r
532 // Set config parameters to appropriate registers for microwire mode.
\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
537 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
539 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
541 return ALT_E_ERROR;
\r
544 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !cfg)
\r
546 return ALT_E_BAD_ARG;
\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
552 return ALT_E_ARG_RANGE;
\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
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
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
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
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
578 mwcr_mask = ALT_SPIS_MWCR_MWMOD_SET_MSK
\r
579 | ALT_SPIS_MWCR_MDD_SET_MSK;
\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
593 // Disable the specified SPI controller slave select output lines..
\r
595 ALT_STATUS_CODE alt_spi_slave_select_disable(ALT_SPI_DEV_t *spi_dev,
\r
596 const uint32_t mask)
\r
598 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
600 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
602 return ALT_E_ERROR;
\r
605 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
607 return ALT_E_BAD_ARG;
\r
610 if (mask > ALT_SPI_SLAVE_MASK_ALL)
\r
612 return ALT_E_BAD_ARG;
\r
615 switch (spi_dev->op_mode)
\r
617 case ALT_SPI_OP_MODE_MASTER:
\r
618 alt_clrbits_word(ALT_SPIM_SER_ADDR(spi_dev->location), mask);
\r
620 case ALT_SPI_OP_MODE_SLAVE:
\r
621 status = ALT_E_ERROR;
\r
629 // Enable the specified SPI controller slave select output lines.
\r
631 ALT_STATUS_CODE alt_spi_slave_select_enable(ALT_SPI_DEV_t *spi_dev,
\r
632 const uint32_t mask)
\r
634 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
636 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
638 return ALT_E_ERROR;
\r
641 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
643 return ALT_E_BAD_ARG;
\r
646 if (mask > ALT_SPI_SLAVE_MASK_ALL)
\r
648 return ALT_E_BAD_ARG;
\r
651 switch (spi_dev->op_mode)
\r
653 case ALT_SPI_OP_MODE_MASTER:
\r
654 alt_setbits_word(ALT_SPIM_SER_ADDR(spi_dev->location), mask);
\r
656 case ALT_SPI_OP_MODE_SLAVE:
\r
657 status = ALT_E_ERROR;
\r
665 // Get the configured baud rate divider value for the specified SPI controller
\r
667 ALT_STATUS_CODE alt_spi_divider_get(ALT_SPI_DEV_t *spi_dev, uint32_t *div)
\r
669 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
671 return ALT_E_BAD_ARG;
\r
674 switch (spi_dev->op_mode)
\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
679 case ALT_SPI_OP_MODE_SLAVE:
\r
681 return ALT_E_ERROR;
\r
684 return ALT_E_SUCCESS;
\r
688 // Set the baud rate divider to configure the generated sclk_out frequency
\r
690 ALT_STATUS_CODE alt_spi_divider_set(ALT_SPI_DEV_t *spi_dev, const uint32_t div)
\r
692 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
694 return ALT_E_BAD_ARG;
\r
697 if (spi_dev->op_mode != ALT_SPI_OP_MODE_MASTER)
\r
699 return ALT_E_ERROR;
\r
702 if (div < ALT_SPI_MIN_CLK_DIV || div > ALT_SPI_MAX_CLK_DIV)
\r
704 return ALT_E_BAD_ARG;
\r
709 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
710 bool already_enabled = (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE);
\r
712 if (already_enabled)
\r
714 // Temporarily disable controller
\r
715 status = alt_spi_disable(spi_dev);
\r
716 if (status != ALT_E_SUCCESS)
\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
726 if (already_enabled)
\r
728 // Re-enable controller
\r
729 status = alt_spi_enable(spi_dev);
\r
737 // Get the configured baud rate divider value for the specified SPI controller
\r
739 ALT_STATUS_CODE alt_spi_baud_rate_get(ALT_SPI_DEV_t *spi_dev, uint32_t *div)
\r
741 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
742 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !div)
\r
744 return ALT_E_BAD_ARG;
\r
747 switch (spi_dev->op_mode)
\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
752 case ALT_SPI_OP_MODE_SLAVE:
\r
753 status = ALT_E_ERROR;
\r
761 // Set the baud rate divider to configure the generated sclk_out frequency
\r
763 ALT_STATUS_CODE alt_spi_baud_rate_set(ALT_SPI_DEV_t *spi_dev, const uint32_t div)
\r
765 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
767 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
769 return ALT_E_ERROR;
\r
772 if (alt_spi_checking(spi_dev) == ALT_E_FALSE )
\r
774 return ALT_E_BAD_ARG;
\r
777 switch (spi_dev->op_mode)
\r
779 case ALT_SPI_OP_MODE_MASTER:
\r
780 if(div < ALT_SPI_MIN_CLK_DIV || div > ALT_SPI_MAX_CLK_DIV)
\r
782 status = ALT_E_BAD_ARG;
\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
789 case ALT_SPI_OP_MODE_SLAVE:
\r
790 status = ALT_E_ERROR;
\r
799 // Return bus speed by configuration of spi controller for master mode.
\r
801 ALT_STATUS_CODE alt_spi_speed_get(ALT_SPI_DEV_t * spi_dev,
\r
802 uint32_t * speed_in_hz)
\r
804 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
806 return ALT_E_BAD_ARG;
\r
809 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
813 status = alt_spi_divider_get(spi_dev, &div);
\r
814 if (status != ALT_E_SUCCESS)
\r
819 if (div < ALT_SPI_MIN_CLK_DIV || div > ALT_SPI_MAX_CLK_DIV)
\r
821 return ALT_E_BAD_ARG;
\r
824 //<speed, Hz> = <internal clock> / <lcount>
\r
825 *speed_in_hz = spi_dev->clock_freq / div;
\r
827 return ALT_E_SUCCESS;
\r
831 // Fill struct with configuration of spi controller for master mode by bus speed
\r
833 ALT_STATUS_CODE alt_spi_speed_set(ALT_SPI_DEV_t * spi_dev,
\r
834 uint32_t speed_in_hz)
\r
837 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
839 return ALT_E_BAD_ARG;
\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
845 return ALT_E_ARG_RANGE;
\r
848 //<lcount> = <internal clock> / <speed, Hz>
\r
849 uint32_t div = spi_dev->clock_freq / speed_in_hz;
\r
851 return alt_spi_divider_set(spi_dev, div);
\r
855 // Fill struct with configuration of spi controller for master mode by bus speed
\r
857 ALT_STATUS_CODE alt_spi_speed_to_divider(ALT_SPI_DEV_t * spi_dev,
\r
858 uint32_t speed_in_hz,
\r
862 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !div)
\r
864 return ALT_E_BAD_ARG;
\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
870 return ALT_E_ARG_RANGE;
\r
873 // <lcount> = <internal clock> / <speed, Hz>
\r
874 *div = spi_dev->clock_freq / speed_in_hz;
\r
876 return ALT_E_SUCCESS;
\r
880 // Return bus speed by configuration of spi controller for master mode.
\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
886 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !div)
\r
888 return ALT_E_BAD_ARG;
\r
891 if (*div < ALT_SPI_MIN_CLK_DIV || *div > ALT_SPI_MAX_CLK_DIV)
\r
893 return ALT_E_BAD_ARG;
\r
896 // <speed, Hz> = <internal clock> / <lcount>
\r
897 *speed_in_hz = spi_dev->clock_freq / *div;
\r
899 return ALT_E_SUCCESS;
\r
903 // Get the current number of data frames configured for the SPI controller.
\r
905 ALT_STATUS_CODE alt_spi_num_data_frames_get(ALT_SPI_DEV_t *spi_dev, uint32_t *num_data_frames)
\r
907 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
908 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !num_data_frames)
\r
910 return ALT_E_BAD_ARG;
\r
913 switch (spi_dev->op_mode)
\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
918 case ALT_SPI_OP_MODE_SLAVE:
\r
919 status = ALT_E_ERROR;
\r
927 // Set the number of data frames configured for the SPI controller.
\r
929 ALT_STATUS_CODE alt_spi_num_data_frames_set(ALT_SPI_DEV_t *spi_dev, const uint32_t num_data_frames)
\r
931 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
933 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
935 return ALT_E_ERROR;
\r
938 if (alt_spi_checking(spi_dev) == ALT_E_FALSE )
\r
940 return ALT_E_BAD_ARG;
\r
943 switch (spi_dev->op_mode)
\r
945 case ALT_SPI_OP_MODE_MASTER:
\r
946 if(num_data_frames & ALT_SPIM_CTLR1_NDF_CLR_MSK)
\r
948 status = ALT_E_BAD_ARG;
\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
955 case ALT_SPI_OP_MODE_SLAVE:
\r
956 status = ALT_E_ERROR;
\r
965 // Returns the current SPI controller interrupt status conditions.
\r
967 ALT_STATUS_CODE alt_spi_int_status_get(ALT_SPI_DEV_t *spi_dev,
\r
970 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !status)
\r
972 return ALT_E_BAD_ARG;
\r
975 switch (spi_dev->op_mode)
\r
977 case ALT_SPI_OP_MODE_MASTER:
\r
978 *status = alt_read_word(ALT_SPIM_ISR_ADDR(spi_dev->location));
\r
980 case ALT_SPI_OP_MODE_SLAVE:
\r
981 *status = alt_read_word(ALT_SPIS_ISR_ADDR(spi_dev->location));
\r
985 return ALT_E_SUCCESS;
\r
989 // Returns the SPI controller raw interrupt status conditions irrespective of
\r
990 // the interrupt status condition enablement state.
\r
992 ALT_STATUS_CODE alt_spi_int_raw_status_get(ALT_SPI_DEV_t *spi_dev,
\r
995 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !status)
\r
997 return ALT_E_BAD_ARG;
\r
1000 switch (spi_dev->op_mode)
\r
1002 case ALT_SPI_OP_MODE_MASTER:
\r
1003 *status = alt_read_word(ALT_SPIM_RISR_ADDR(spi_dev->location));
\r
1005 case ALT_SPI_OP_MODE_SLAVE:
\r
1006 *status = alt_read_word(ALT_SPIS_RISR_ADDR(spi_dev->location));
\r
1010 return ALT_E_SUCCESS;
\r
1014 // Clears the specified SPI controller interrupt status conditions identified
\r
1015 // in the mask (for slave mode).
\r
1017 static ALT_STATUS_CODE alt_spi_slave_int_clear(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)
\r
1019 if (mask == ALT_SPI_STATUS_ALL)
\r
1021 alt_read_word(ALT_SPIS_ICR_ADDR(spi_dev->location));
\r
1022 return ALT_E_SUCCESS;
\r
1025 // For different status clear different register
\r
1026 if (mask & ALT_SPI_STATUS_TXOI)
\r
1028 alt_read_word(ALT_SPIS_TXOICR_ADDR(spi_dev->location));
\r
1030 if (mask & ALT_SPI_STATUS_RXOI)
\r
1032 alt_read_word(ALT_SPIS_RXOICR_ADDR(spi_dev->location));
\r
1034 if (mask & ALT_SPI_STATUS_RXUI)
\r
1036 alt_read_word(ALT_SPIS_RXUICR_ADDR(spi_dev->location));
\r
1039 return ALT_E_SUCCESS;
\r
1043 // Clears the specified SPI controller interrupt status conditions identified
\r
1044 // in the mask (for master mode).
\r
1046 static ALT_STATUS_CODE alt_spi_master_int_clear(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)
\r
1048 if (mask == ALT_SPI_STATUS_ALL)
\r
1050 alt_read_word(ALT_SPIM_ICR_ADDR(spi_dev->location));
\r
1051 return ALT_E_SUCCESS;
\r
1054 // For different status clear different register
\r
1055 if (mask & ALT_SPI_STATUS_TXOI)
\r
1057 alt_read_word(ALT_SPIM_TXOICR_ADDR(spi_dev->location));
\r
1059 if (mask & ALT_SPI_STATUS_RXOI)
\r
1061 alt_read_word(ALT_SPIM_RXOICR_ADDR(spi_dev->location));
\r
1063 if (mask & ALT_SPI_STATUS_RXUI)
\r
1065 alt_read_word(ALT_SPIM_RXUICR_ADDR(spi_dev->location));
\r
1068 return ALT_E_SUCCESS;
\r
1072 // Clears the specified SPI controller interrupt status conditions identified
\r
1075 ALT_STATUS_CODE alt_spi_int_clear(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)
\r
1077 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1078 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1080 return ALT_E_BAD_ARG;
\r
1083 switch (spi_dev->op_mode)
\r
1085 case ALT_SPI_OP_MODE_MASTER:
\r
1086 status = alt_spi_master_int_clear(spi_dev, mask);
\r
1088 case ALT_SPI_OP_MODE_SLAVE:
\r
1089 status = alt_spi_slave_int_clear(spi_dev, mask);
\r
1096 // Disable the specified SPI controller interrupt status conditions identified in
\r
1099 ALT_STATUS_CODE alt_spi_int_disable(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)
\r
1101 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1103 return ALT_E_BAD_ARG;
\r
1106 switch (spi_dev->op_mode)
\r
1108 case ALT_SPI_OP_MODE_MASTER:
\r
1109 alt_clrbits_word(ALT_SPIM_IMR_ADDR(spi_dev->location), mask);
\r
1111 case ALT_SPI_OP_MODE_SLAVE:
\r
1112 alt_clrbits_word(ALT_SPIS_IMR_ADDR(spi_dev->location), mask);
\r
1116 return ALT_E_SUCCESS;
\r
1120 // Enable the specified SPI controller interrupt status conditions identified in
\r
1123 ALT_STATUS_CODE alt_spi_int_enable(ALT_SPI_DEV_t *spi_dev, const uint32_t mask)
\r
1125 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1127 return ALT_E_BAD_ARG;
\r
1130 switch (spi_dev->op_mode)
\r
1132 case ALT_SPI_OP_MODE_MASTER:
\r
1133 alt_setbits_word(ALT_SPIM_IMR_ADDR(spi_dev->location), mask);
\r
1135 case ALT_SPI_OP_MODE_SLAVE:
\r
1136 alt_setbits_word(ALT_SPIS_IMR_ADDR(spi_dev->location), mask);
\r
1140 return ALT_E_SUCCESS;
\r
1144 // Returns ALT_E_TRUE when the receive FIFO is empty.
\r
1146 ALT_STATUS_CODE alt_spi_rx_fifo_is_empty(ALT_SPI_DEV_t *spi_dev)
\r
1148 ALT_STATUS_CODE status = ALT_E_FALSE;
\r
1149 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1151 return ALT_E_BAD_ARG;
\r
1154 switch (spi_dev->op_mode)
\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
1159 status = ALT_E_TRUE;
\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
1165 status = ALT_E_TRUE;
\r
1173 // Returns ALT_E_TRUE when the receive FIFO is completely full.
\r
1175 ALT_STATUS_CODE alt_spi_rx_fifo_is_full(ALT_SPI_DEV_t *spi_dev)
\r
1177 ALT_STATUS_CODE status = ALT_E_FALSE;
\r
1178 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1180 return ALT_E_BAD_ARG;
\r
1183 switch (spi_dev->op_mode)
\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
1188 status = ALT_E_TRUE;
\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
1194 status = ALT_E_TRUE;
\r
1202 // Returns the number of valid entries in the receive FIFO.
\r
1204 ALT_STATUS_CODE alt_spi_rx_fifo_level_get(ALT_SPI_DEV_t *spi_dev,
\r
1205 uint32_t *num_entries)
\r
1207 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !num_entries)
\r
1209 return ALT_E_BAD_ARG;
\r
1212 switch (spi_dev->op_mode)
\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
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
1222 return ALT_E_SUCCESS;
\r
1227 // Gets the current receive FIFO threshold level value.
\r
1229 ALT_STATUS_CODE alt_spi_rx_fifo_threshold_get(ALT_SPI_DEV_t *spi_dev,
\r
1230 uint8_t *threshold)
\r
1232 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !threshold)
\r
1234 return ALT_E_BAD_ARG;
\r
1237 switch (spi_dev->op_mode)
\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
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
1247 return ALT_E_SUCCESS;
\r
1252 // Sets the current receive FIFO threshold level value.
\r
1254 ALT_STATUS_CODE alt_spi_rx_fifo_threshold_set(ALT_SPI_DEV_t *spi_dev,
\r
1255 const uint8_t threshold)
\r
1257 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1259 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
1261 return ALT_E_ERROR;
\r
1264 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1266 return ALT_E_BAD_ARG;
\r
1269 switch (spi_dev->op_mode)
\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
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
1289 // Returns ALT_E_TRUE when the transmit FIFO is empty.
\r
1291 ALT_STATUS_CODE alt_spi_tx_fifo_is_empty(ALT_SPI_DEV_t *spi_dev)
\r
1293 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1295 return ALT_E_BAD_ARG;
\r
1298 switch (spi_dev->op_mode)
\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
1303 return ALT_E_TRUE;
\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
1309 return ALT_E_TRUE;
\r
1314 return ALT_E_FALSE;
\r
1318 // Returns ALT_E_TRUE when the transmit FIFO is completely full.
\r
1320 ALT_STATUS_CODE alt_spi_tx_fifo_is_full(ALT_SPI_DEV_t *spi_dev)
\r
1322 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1324 return ALT_E_BAD_ARG;
\r
1327 switch (spi_dev->op_mode)
\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
1332 return ALT_E_TRUE;
\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
1338 return ALT_E_TRUE;
\r
1343 return ALT_E_FALSE;
\r
1347 // Returns the number of valid entries in the transmit FIFO.
\r
1349 ALT_STATUS_CODE alt_spi_tx_fifo_level_get(ALT_SPI_DEV_t *spi_dev,
\r
1350 uint32_t *num_entries)
\r
1352 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !num_entries)
\r
1354 return ALT_E_BAD_ARG;
\r
1357 switch (spi_dev->op_mode)
\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
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
1367 return ALT_E_SUCCESS;
\r
1373 // Sets the current transmit FIFO threshold level value.
\r
1375 ALT_STATUS_CODE alt_spi_tx_fifo_threshold_get(ALT_SPI_DEV_t *spi_dev,
\r
1376 uint8_t *threshold)
\r
1378 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !threshold)
\r
1380 return ALT_E_BAD_ARG;
\r
1383 switch (spi_dev->op_mode)
\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
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
1393 return ALT_E_SUCCESS;
\r
1398 // Sets the current transmit FIFO threshold level value.
\r
1400 ALT_STATUS_CODE alt_spi_tx_fifo_threshold_set(ALT_SPI_DEV_t *spi_dev,
\r
1401 const uint8_t threshold)
\r
1403 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1405 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
1407 return ALT_E_ERROR;
\r
1410 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1412 return ALT_E_BAD_ARG;
\r
1415 switch (spi_dev->op_mode)
\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
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
1433 // Get the configured Rx sample delay value.
\r
1435 ALT_STATUS_CODE alt_spi_rx_sample_delay_get(ALT_SPI_DEV_t *spi_dev, uint32_t *delay)
\r
1437 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1438 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !delay)
\r
1440 return ALT_E_BAD_ARG;
\r
1443 switch (spi_dev->op_mode)
\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
1448 case ALT_SPI_OP_MODE_SLAVE:
\r
1449 status = ALT_E_ERROR;
\r
1457 // Set the configured Rx sample delay value.
\r
1459 ALT_STATUS_CODE alt_spi_rx_sample_delay_set(ALT_SPI_DEV_t *spi_dev, const uint32_t delay)
\r
1461 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1463 if (alt_spi_is_enabled(spi_dev) == ALT_E_TRUE)
\r
1465 return ALT_E_ERROR;
\r
1468 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1470 return ALT_E_BAD_ARG;
\r
1473 switch (spi_dev->op_mode)
\r
1475 case ALT_SPI_OP_MODE_MASTER:
\r
1476 if(delay & ALT_SPIM_RX_SMPL_DLY_RSD_CLR_MSK)
\r
1478 status = ALT_E_BAD_ARG;
\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
1485 case ALT_SPI_OP_MODE_SLAVE:
\r
1486 status = ALT_E_ERROR;
\r
1494 // Disable the transmit (Tx) FIFO DMA channel.
\r
1496 ALT_STATUS_CODE alt_spi_dma_tx_disable(ALT_SPI_DEV_t *spi_dev)
\r
1498 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1500 return ALT_E_BAD_ARG;
\r
1503 // Else clear enable bit of spi_enable register
\r
1504 switch (spi_dev->op_mode)
\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
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
1516 return ALT_E_SUCCESS;
\r
1520 // Enable and set the transmit data level for the transmit (Tx) FIFO DMA channel.
\r
1522 ALT_STATUS_CODE alt_spi_dma_tx_enable(ALT_SPI_DEV_t *spi_dev, const uint32_t level)
\r
1524 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1526 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1528 return ALT_E_BAD_ARG;
\r
1531 switch (spi_dev->op_mode)
\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
1538 status = ALT_E_BAD_ARG;
\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
1545 case ALT_SPI_OP_MODE_SLAVE:
\r
1546 if(level & ALT_SPIS_DMATDLR_DMATDL_CLR_MSK)
\r
1548 status = ALT_E_BAD_ARG;
\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
1563 // Disable the receive (Rx) FIFO DMA channel.
\r
1565 ALT_STATUS_CODE alt_spi_dma_rx_disable(ALT_SPI_DEV_t *spi_dev)
\r
1567 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1569 return ALT_E_BAD_ARG;
\r
1572 // Else clear enable bit of spi_enable register
\r
1573 switch (spi_dev->op_mode)
\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
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
1585 return ALT_E_SUCCESS;
\r
1589 // Enable and set the receive data level for the receive (Rx) FIFO DMA channel.
\r
1591 ALT_STATUS_CODE alt_spi_dma_rx_enable(ALT_SPI_DEV_t *spi_dev, const uint32_t level)
\r
1593 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1595 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1597 return ALT_E_BAD_ARG;
\r
1600 switch (spi_dev->op_mode)
\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
1607 status = ALT_E_BAD_ARG;
\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
1614 case ALT_SPI_OP_MODE_SLAVE:
\r
1615 if(level & ALT_SPIS_DMARDLR_DMARDL_CLR_MSK)
\r
1617 status = ALT_E_BAD_ARG;
\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
1632 // Reads a data frame from the receive (Rx) FIFO.
\r
1634 ALT_STATUS_CODE alt_spi_rx_fifo_deq(ALT_SPI_DEV_t *spi_dev, uint16_t *data)
\r
1636 if (alt_spi_checking(spi_dev) == ALT_E_FALSE || !data)
\r
1638 return ALT_E_BAD_ARG;
\r
1641 if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)
\r
1643 return ALT_E_ERROR;
\r
1646 switch (spi_dev->op_mode)
\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
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
1656 return ALT_E_SUCCESS;
\r
1660 // Writes a data frame to the transmit (Tx) FIFO for transmittal.
\r
1662 ALT_STATUS_CODE alt_spi_tx_fifo_enq(ALT_SPI_DEV_t *spi_dev, const uint16_t data)
\r
1664 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1666 return ALT_E_BAD_ARG;
\r
1669 if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)
\r
1671 return ALT_E_ERROR;
\r
1674 switch (spi_dev->op_mode)
\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
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
1684 return ALT_E_SUCCESS;
\r
1688 // This function writes a single data byte to the transmit FIFO.
\r
1690 static ALT_STATUS_CODE alt_spi_transmit_error_handler(ALT_SPI_DEV_t *spi_dev, ALT_STATUS_CODE *err_status)
\r
1692 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1693 uint32_t int_status = 0;
\r
1695 status = alt_spi_int_raw_status_get(spi_dev, &int_status);
\r
1697 if (status == ALT_E_TRUE && int_status != 0)
\r
1700 & (ALT_SPI_STATUS_TXOI
\r
1701 | ALT_SPI_STATUS_RXOI
\r
1702 | ALT_SPI_STATUS_RXUI))
\r
1704 *err_status = ALT_E_BUF_OVF;
\r
1712 // Write or read bulk of data form master mode
\r
1714 static ALT_STATUS_CODE alt_spi_master_transfer_helper(ALT_SPI_DEV_t *spi_dev,
\r
1717 const uint16_t * tx_buf,
\r
1718 uint16_t * rx_buf)
\r
1720 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\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
1726 while (data_send > 0 || data_recv > 0)
\r
1729 ALT_STATUS_CODE err_status = 0;
\r
1730 status = alt_spi_transmit_error_handler(spi_dev, &err_status);
\r
1732 if (status != ALT_E_SUCCESS)
\r
1737 if (err_status != ALT_E_SUCCESS)
\r
1739 status = err_status;
\r
1743 // Top up the TX FIFO with sending data
\r
1745 if (data_send > 0)
\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
1754 uint32_t space = ALT_SPI_TX_FIFO_NUM_ENTRIES - level;
\r
1756 space = MIN(data_send, space);
\r
1758 for (uint32_t i = 0; i < space; ++i)
\r
1760 alt_write_word(ALT_SPIM_DR_ADDR(spi_dev->location), ALT_SPIM_DR_DR_SET(*buffer_tx));
\r
1764 data_send -= space;
\r
1767 // Read out the resulting received data as they come in.
\r
1769 if (data_recv > 0)
\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
1783 status = ALT_E_TMO;
\r
1788 level = MIN(data_recv, level);
\r
1790 for (uint32_t i = 0; i < level; ++i)
\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
1798 data_recv -= level;
\r
1806 // This function performs a master SPI/SSP serial master transfer operations (use by all transfer functions).
\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
1817 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
1819 return ALT_E_BAD_ARG;
\r
1822 if (spi_dev->op_mode == ALT_SPI_OP_MODE_SLAVE)
\r
1824 return ALT_E_ERROR;
\r
1827 if (num_frames == 0)
\r
1829 return ALT_E_SUCCESS;
\r
1832 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\r
1834 if(alt_spi_is_busy(spi_dev) == ALT_E_TRUE)
\r
1836 return ALT_E_ERROR;
\r
1839 // Checking necessity to update slave mask
\r
1840 if (slave_select != spi_dev->last_slave_mask)
\r
1842 status = alt_spi_disable(spi_dev);
\r
1843 if (status != ALT_E_SUCCESS)
\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
1855 spi_dev->last_slave_mask = slave_select;
\r
1858 // Checking necessity to update transfer mode
\r
1859 if (transfer_mode != spi_dev->last_transfer_mode)
\r
1861 status = alt_spi_disable(spi_dev);
\r
1862 if (status != ALT_E_SUCCESS)
\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
1873 if (transfer_mode == ALT_SPI_TMOD_RX || transfer_mode == ALT_SPI_TMOD_EEPROM)
\r
1875 status = alt_spi_disable(spi_dev);
\r
1876 if (status != ALT_E_SUCCESS)
\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
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
1892 if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)
\r
1894 status = alt_spi_enable(spi_dev);
\r
1895 if (status != ALT_E_SUCCESS)
\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
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
1909 uint32_t data_send = 0;
\r
1910 uint32_t data_recv = 0;
\r
1912 if (transfer_mode == ALT_SPI_TMOD_TX || transfer_mode == ALT_SPI_TMOD_TXRX)
\r
1914 data_send = num_frames;
\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
1921 data_recv = num_frames;
\r
1924 if (transfer_mode == ALT_SPI_TMOD_EEPROM)
\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
1931 if (transfer_mode == ALT_SPI_TMOD_RX)
\r
1933 //Activate rx transfer
\r
1934 alt_spi_tx_fifo_enq(spi_dev, 0);
\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
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
1947 // Mask all interrupts
\r
1948 alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_ALL);
\r
1954 // This function performs a master SPI/SSP serial transmit and receive transfer.
\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
1962 return alt_spi_master_transfer(spi_dev,
\r
1967 ALT_SPI_TMOD_TXRX,
\r
1972 // This function performs a master SPI/SSP serial transmit only transfer.
\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
1979 return alt_spi_master_transfer(spi_dev,
\r
1988 // This function performs a master SPI/SSP serial receive only transfer.
\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
1995 return alt_spi_master_transfer(spi_dev,
\r
2005 // This function performs a master SPI EEPROM read transfer.
\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
2014 return alt_spi_master_transfer(spi_dev,
\r
2019 ALT_SPI_TMOD_EEPROM,
\r
2025 // Write or read bulk of data form slave mode
\r
2027 static ALT_STATUS_CODE alt_spi_slave_transfer_helper(ALT_SPI_DEV_t *spi_dev,
\r
2030 const uint16_t * tx_buf,
\r
2031 uint16_t * rx_buf)
\r
2033 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\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
2039 while (data_send > 0 || data_recv > 0)
\r
2042 ALT_STATUS_CODE err_status = 0;
\r
2043 status = alt_spi_transmit_error_handler(spi_dev, &err_status);
\r
2045 if (status != ALT_E_SUCCESS)
\r
2050 if (err_status != ALT_E_SUCCESS)
\r
2052 status = err_status;
\r
2056 // Read out the resulting received data as they come in.
\r
2058 if (data_recv > 0)
\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
2069 if (--timeout == 0)
\r
2071 status = ALT_E_TMO;
\r
2076 level = MIN(data_recv, level);
\r
2078 for (uint32_t i = 0; i < level; ++i)
\r
2080 *buffer_rx = (ALT_SPIS_DR_DR_GET(alt_read_word(ALT_SPIS_DR_ADDR(spi_dev->location))));
\r
2084 data_recv -= level;
\r
2087 // Top up the TX FIFO with sending data
\r
2089 if (data_send > 0)
\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
2098 uint32_t space = ALT_SPI_TX_FIFO_NUM_ENTRIES - level;
\r
2100 space = MIN(data_send, space);
\r
2102 for (uint32_t i = 0; i < space; ++i)
\r
2104 alt_write_word(ALT_SPIS_DR_ADDR(spi_dev->location), ALT_SPIS_DR_DR_SET(*buffer_tx));
\r
2108 data_send -= space;
\r
2116 // This function performs a slave SPI/SSP serial slave transfer.
\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
2124 if (alt_spi_checking(spi_dev) == ALT_E_FALSE)
\r
2126 return ALT_E_BAD_ARG;
\r
2129 if (spi_dev->op_mode == ALT_SPI_OP_MODE_MASTER)
\r
2131 return ALT_E_ERROR;
\r
2134 if (buf_len == 0)
\r
2136 return ALT_E_SUCCESS;
\r
2139 if (alt_spi_is_enabled(spi_dev) == ALT_E_FALSE)
\r
2141 return ALT_E_ERROR;
\r
2144 ALT_STATUS_CODE status = ALT_E_SUCCESS;
\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
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
2157 uint32_t data_send = 0;
\r
2158 uint32_t data_recv = 0;
\r
2160 if (transfer_mode == ALT_SPI_TMOD_TX || transfer_mode == ALT_SPI_TMOD_TXRX)
\r
2162 data_send = buf_len;
\r
2165 if (transfer_mode == ALT_SPI_TMOD_RX || transfer_mode == ALT_SPI_TMOD_TXRX)
\r
2167 data_recv = buf_len;
\r
2170 // Write or read bulk of data
\r
2171 status = alt_spi_slave_transfer_helper(spi_dev,
\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
2181 // Mask all interrupts
\r
2182 alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_ALL);
\r
2189 // This function performs a slave SPI/SSP serial transmit and receive transfer.
\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
2196 return alt_spi_slave_transfer(spi_dev,
\r
2200 ALT_SPI_TMOD_TXRX);
\r
2204 // This function performs a slave SPI/SSP serial transmit only transfer.
\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
2210 alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_RXFI);
\r
2211 return alt_spi_slave_transfer(spi_dev,
\r
2215 ALT_SPI_TMOD_TXRX);
\r
2219 // This function performs a slave SPI/SSP serial receive only transfer.
\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
2225 alt_spi_int_disable(spi_dev, ALT_SPI_STATUS_TXEI);
\r
2226 return alt_spi_slave_transfer(spi_dev,
\r
2230 ALT_SPI_TMOD_TXRX);
\r