1 /*
2 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33 //*****************************************************************************
34 //
35 // spi.c
36 //
37 // Driver for the SPI.
38 //
39 //*****************************************************************************
40
41 //*****************************************************************************
42 //
43 //! \addtogroup SPI_Serial_Peripheral_Interface_api
44 //! @{
45 //
46 //*****************************************************************************
47
48
49 #include "inc/hw_ints.h"
50 #include "inc/hw_types.h"
51 #include "inc/hw_memmap.h"
52 #include "inc/hw_mcspi.h"
53 #include "inc/hw_apps_config.h"
54 #include "interrupt.h"
55 #include "spi.h"
56
57
58 //*****************************************************************************
59 //
60 // A mapping of SPI base address to interupt number.
61 //
62 //*****************************************************************************
63 static const unsigned long g_ppulSPIIntMap[][3] =
64 {
65 { SSPI_BASE, INT_SSPI }, // Shared SPI
66 { GSPI_BASE, INT_GSPI }, // Generic SPI
67 { LSPI_BASE, INT_LSPI }, // LINK SPI
68 };
69
70 //*****************************************************************************
71 //
72 // A mapping of SPI base address to DMA done interrupt mask bit(s).
73 //
74 //*****************************************************************************
75 static const unsigned long g_ulSPIDmaMaskMap[][2]=
76 {
77 {SSPI_BASE,APPS_CONFIG_DMA_DONE_INT_MASK_SHSPI_WR_DMA_DONE_INT_MASK},
78 {LSPI_BASE,APPS_CONFIG_DMA_DONE_INT_MASK_HOSTSPI_WR_DMA_DONE_INT_MASK},
79 {GSPI_BASE,APPS_CONFIG_DMA_DONE_INT_MASK_APPS_SPI_WR_DMA_DONE_INT_MASK},
80 };
81
82 //*****************************************************************************
83 //
84 //! \internal
85 //! Transfer bytes over SPI channel
86 //!
87 //! \param ulBase is the base address of SPI module
88 //! \param ucDout is the pointer to Tx data buffer or 0.
89 //! \param ucDin is pointer to Rx data buffer or 0
90 //! \param ulCount is the size of data in bytes.
91 //!
92 //! This function transfers \e ulCount bytes of data over SPI channel.
93 //!
94 //! The function will not return until data has been transmitted
95 //!
96 //! \return Returns 0 on success, -1 otherwise.
97 //
98 //*****************************************************************************
SPITransfer8(unsigned long ulBase,unsigned char * ucDout,unsigned char * ucDin,unsigned long ulCount,unsigned long ulFlags)99 static long SPITransfer8(unsigned long ulBase, unsigned char *ucDout,
100 unsigned char *ucDin, unsigned long ulCount,
101 unsigned long ulFlags)
102 {
103 unsigned long ulReadReg;
104 unsigned long ulWriteReg;
105 unsigned long ulStatReg;
106 unsigned long ulOutIncr;
107 unsigned long ulInIncr;
108 unsigned long ulTxDummy;
109 unsigned long ulRxDummy;
110
111 //
112 // Initialize the variables
113 //
114 ulOutIncr = 1;
115 ulInIncr = 1;
116
117 //
118 // Check if output buffer pointer is 0
119 //
120 if(ucDout == 0)
121 {
122 ulOutIncr = 0;
123 ulTxDummy = 0xFFFFFFFF;
124 ucDout = (unsigned char *)&ulTxDummy;
125 }
126
127 //
128 // Check if input buffer pointer is 0
129 //
130 if(ucDin == 0)
131 {
132 ulInIncr = 0;
133 ucDin = (unsigned char *)&ulRxDummy;
134 }
135
136 //
137 // Load the register addresses.
138 //
139 ulReadReg = (ulBase + MCSPI_O_RX0);
140 ulWriteReg = (ulBase + MCSPI_O_TX0);
141 ulStatReg = (ulBase + MCSPI_O_CH0STAT);
142
143 //
144 // Enable CS based on Flag
145 //
146 if( ulFlags & SPI_CS_ENABLE)
147 {
148 HWREG( ulBase + MCSPI_O_CH0CONF) |= MCSPI_CH0CONF_FORCE;
149 }
150
151 while(ulCount)
152 {
153 //
154 // Wait for space in output register/FIFO.
155 //
156 while( !(HWREG(ulStatReg) & MCSPI_CH0STAT_TXS) )
157 {
158 }
159
160 //
161 // Write the data
162 //
163 HWREG(ulWriteReg) = *ucDout;
164
165 //
166 // Wait for data in input register/FIFO.
167 //
168 while( !( HWREG(ulStatReg) & MCSPI_CH0STAT_RXS) )
169 {
170 }
171
172 //
173 // Read the data
174 //
175 *ucDin = HWREG(ulReadReg);
176
177 //
178 // Increment pointers.
179 //
180 ucDout = ucDout + ulOutIncr;
181 ucDin = ucDin + ulInIncr;
182
183 //
184 // Decrement the count.
185 //
186 ulCount--;
187 }
188
189 //
190 // Disable CS based on Flag
191 //
192 if( ulFlags & SPI_CS_DISABLE)
193 {
194 HWREG( ulBase + MCSPI_O_CH0CONF) &= ~MCSPI_CH0CONF_FORCE;
195 }
196
197 return 0;
198 }
199
200 //*****************************************************************************
201 //
202 //! \internal
203 //! Transfer half-words over SPI channel
204 //!
205 //! \param ulBase is the base address of SPI module
206 //! \param usDout is the pointer to Tx data buffer or 0.
207 //! \param usDin is pointer to Rx data buffer or 0
208 //! \param ulCount is the size of data in bytes.
209 //!
210 //! This function transfers \e ulCount bytes of data over SPI channel. Since
211 //! the API sends a half-word at a time \e ulCount should be a multiple
212 //! of two.
213 //!
214 //! The function will not return until data has been transmitted
215 //!
216 //! \return Returns 0 on success, -1 otherwise.
217 //
218 //*****************************************************************************
SPITransfer16(unsigned long ulBase,unsigned short * usDout,unsigned short * usDin,unsigned long ulCount,unsigned long ulFlags)219 static long SPITransfer16(unsigned long ulBase, unsigned short *usDout,
220 unsigned short *usDin, unsigned long ulCount,
221 unsigned long ulFlags)
222 {
223 unsigned long ulReadReg;
224 unsigned long ulWriteReg;
225 unsigned long ulStatReg;
226 unsigned long ulOutIncr;
227 unsigned long ulInIncr;
228 unsigned long ulTxDummy;
229 unsigned long ulRxDummy;
230
231 //
232 // Initialize the variables.
233 //
234 ulOutIncr = 1;
235 ulInIncr = 1;
236
237 //
238 // Check if count is multiple of half-word
239 //
240 if(ulCount%2)
241 {
242 return -1;
243 }
244
245 //
246 // Compute number of half words.
247 //
248 ulCount = ulCount/2;
249
250 //
251 // Check if output buffer pointer is 0
252 //
253 if(usDout == 0)
254 {
255 ulOutIncr = 0;
256 ulTxDummy = 0xFFFFFFFF;
257 usDout = (unsigned short *)&ulTxDummy;
258 }
259
260 //
261 // Check if input buffer pointer is 0
262 //
263 if(usDin == 0)
264 {
265 ulInIncr = 0;
266 usDin = (unsigned short *)&ulRxDummy;
267 }
268
269 //
270 // Load the register addresses.
271 //
272 ulReadReg = (ulBase + MCSPI_O_RX0);
273 ulWriteReg = (ulBase + MCSPI_O_TX0);
274 ulStatReg = (ulBase + MCSPI_O_CH0STAT);
275
276 //
277 // Enable CS based on Flag
278 //
279 if( ulFlags & SPI_CS_ENABLE)
280 {
281 HWREG( ulBase + MCSPI_O_CH0CONF) |= MCSPI_CH0CONF_FORCE;
282 }
283
284 while(ulCount)
285 {
286 //
287 // Wait for space in output register/FIFO.
288 //
289 while( !(HWREG(ulStatReg) & MCSPI_CH0STAT_TXS) )
290 {
291 }
292
293 //
294 // Write the data
295 //
296 HWREG(ulWriteReg) = *usDout;
297
298 //
299 // Wait for data in input register/FIFO.
300 //
301 while( !( HWREG(ulStatReg) & MCSPI_CH0STAT_RXS) )
302 {
303 }
304
305 //
306 // Read the data
307 //
308 *usDin = HWREG(ulReadReg);
309
310 //
311 // Increment pointers.
312 //
313 usDout = usDout + ulOutIncr;
314 usDin = usDin + ulInIncr;
315
316 //
317 // Decrement the count.
318 //
319 ulCount--;
320 }
321
322 //
323 // Disable CS based on Flag
324 //
325 if( ulFlags & SPI_CS_DISABLE)
326 {
327 HWREG( ulBase + MCSPI_O_CH0CONF) &= ~MCSPI_CH0CONF_FORCE;
328 }
329
330 return 0;
331 }
332
333 //*****************************************************************************
334 //
335 //! \internal
336 //! Transfer words over SPI channel
337 //!
338 //! \param ulBase is the base address of SPI module
339 //! \param ulDout is the pointer to Tx data buffer or 0.
340 //! \param ulDin is pointer to Rx data buffer or 0
341 //! \param ulCount is the size of data in bytes.
342 //!
343 //! This function transfers \e ulCount bytes of data over SPI channel. Since
344 //! the API sends a word at a time \e ulCount should be a multiple of four.
345 //!
346 //! The function will not return until data has been transmitted
347 //!
348 //! \return Returns 0 on success, -1 otherwise.
349 //
350 //*****************************************************************************
SPITransfer32(unsigned long ulBase,unsigned long * ulDout,unsigned long * ulDin,unsigned long ulCount,unsigned long ulFlags)351 static long SPITransfer32(unsigned long ulBase, unsigned long *ulDout,
352 unsigned long *ulDin, unsigned long ulCount,
353 unsigned long ulFlags)
354 {
355 unsigned long ulReadReg;
356 unsigned long ulWriteReg;
357 unsigned long ulStatReg;
358 unsigned long ulOutIncr;
359 unsigned long ulInIncr;
360 unsigned long ulTxDummy;
361 unsigned long ulRxDummy;
362
363 //
364 // Initialize the variables.
365 //
366 ulOutIncr = 1;
367 ulInIncr = 1;
368
369 //
370 // Check if count is multiple of word
371 //
372 if(ulCount%4)
373 {
374 return -1;
375 }
376
377 //
378 // Compute the number of words to be transferd
379 //
380 ulCount = ulCount/4;
381
382 //
383 // Check if output buffer pointer is 0
384 //
385 if(ulDout == 0)
386 {
387 ulOutIncr = 0;
388 ulTxDummy = 0xFFFFFFFF;
389 ulDout = &ulTxDummy;
390 }
391
392 //
393 // Check if input buffer pointer is 0
394 //
395 if(ulDin == 0)
396 {
397 ulInIncr = 0;
398 ulDin = &ulRxDummy;
399 }
400
401
402 //
403 // Load the register addresses.
404 //
405 ulReadReg = (ulBase + MCSPI_O_RX0);
406 ulWriteReg = (ulBase + MCSPI_O_TX0);
407 ulStatReg = (ulBase + MCSPI_O_CH0STAT);
408
409 //
410 // Enable CS based on Flag
411 //
412 if( ulFlags & SPI_CS_ENABLE)
413 {
414 HWREG( ulBase + MCSPI_O_CH0CONF) |= MCSPI_CH0CONF_FORCE;
415 }
416
417 while(ulCount)
418 {
419 //
420 // Wait for space in output register/FIFO.
421 //
422 while( !(HWREG(ulStatReg) & MCSPI_CH0STAT_TXS) )
423 {
424 }
425
426 //
427 // Write the data
428 //
429 HWREG(ulWriteReg) = *ulDout;
430
431 //
432 // Wait for data in input register/FIFO.
433 //
434 while( !( HWREG(ulStatReg) & MCSPI_CH0STAT_RXS) )
435 {
436 }
437
438 //
439 // Read the data
440 //
441 *ulDin = HWREG(ulReadReg);
442
443 //
444 // Increment pointers.
445 //
446 ulDout = ulDout + ulOutIncr;
447 ulDin = ulDin + ulInIncr;
448
449 //
450 // Decrement the count.
451 //
452 ulCount--;
453 }
454
455 //
456 // Disable CS based on Flag
457 //
458 if( ulFlags & SPI_CS_DISABLE)
459 {
460 HWREG( ulBase + MCSPI_O_CH0CONF) &= ~MCSPI_CH0CONF_FORCE;
461 }
462
463 return 0;
464 }
465
466 //*****************************************************************************
467 //
468 //! \internal
469 //! Gets the SPI interrupt number.
470 //!
471 //! \param ulBase is the base address of the SPI module
472 //!
473 //! Given a SPI base address, returns the corresponding interrupt number.
474 //!
475 //! \return Returns a SPI interrupt number, or -1 if \e ulBase is invalid.
476 //
477 //*****************************************************************************
478 static long
SPIIntNumberGet(unsigned long ulBase)479 SPIIntNumberGet(unsigned long ulBase)
480 {
481 unsigned long ulIdx;
482
483 //
484 // Loop through the table that maps SPI base addresses to interrupt
485 // numbers.
486 //
487 for(ulIdx = 0; ulIdx < (sizeof(g_ppulSPIIntMap) /
488 sizeof(g_ppulSPIIntMap[0])); ulIdx++)
489 {
490 //
491 // See if this base address matches.
492 //
493 if(g_ppulSPIIntMap[ulIdx][0] == ulBase)
494 {
495 //
496 // Return the corresponding interrupt number.
497 //
498 return(g_ppulSPIIntMap[ulIdx][1]);
499 }
500 }
501
502 //
503 // The base address could not be found, so return an error.
504 //
505 return(-1);
506 }
507
508 //*****************************************************************************
509 //
510 //! \internal
511 //! Gets the SPI DMA interrupt mask bit.
512 //!
513 //! \param ulBase is the base address of the SPI module
514 //!
515 //! Given a SPI base address, DMA interrupt mask bit.
516 //!
517 //! \return Returns a DMA interrupt mask bit, or -1 if \e ulBase is invalid.
518 //
519 //*****************************************************************************
520 static long
SPIDmaMaskGet(unsigned long ulBase)521 SPIDmaMaskGet(unsigned long ulBase)
522 {
523 unsigned long ulIdx;
524
525 //
526 // Loop through the table that maps SPI base addresses to interrupt
527 // numbers.
528 //
529 for(ulIdx = 0; ulIdx < (sizeof(g_ulSPIDmaMaskMap) /
530 sizeof(g_ulSPIDmaMaskMap[0])); ulIdx++)
531 {
532 //
533 // See if this base address matches.
534 //
535 if(g_ulSPIDmaMaskMap[ulIdx][0] == ulBase)
536 {
537 //
538 // Return the corresponding interrupt number.
539 //
540 return(g_ulSPIDmaMaskMap[ulIdx][1]);
541 }
542 }
543
544 //
545 // The base address could not be found, so return an error.
546 //
547 return(-1);
548 }
549
550 //*****************************************************************************
551 //
552 //! Enables transmitting and receiving.
553 //!
554 //! \param ulBase is the base address of the SPI module
555 //!
556 //! This function enables the SPI channel for transmitting and receiving.
557 //!
558 //! \return None
559 //!
560 //
561 //*****************************************************************************
562 void
SPIEnable(unsigned long ulBase)563 SPIEnable(unsigned long ulBase)
564 {
565 //
566 // Set Channel Enable Bit
567 //
568 HWREG(ulBase + MCSPI_O_CH0CTRL) |= MCSPI_CH0CTRL_EN;
569 }
570
571 //*****************************************************************************
572 //
573 //! Disables the transmitting and receiving.
574 //!
575 //! \param ulBase is the base address of the SPI module
576 //!
577 //! This function disables the SPI channel for transmitting and receiving.
578 //!
579 //! \return None
580 //!
581 //
582 //*****************************************************************************
583 void
SPIDisable(unsigned long ulBase)584 SPIDisable(unsigned long ulBase)
585 {
586 //
587 // Reset Channel Enable Bit
588 //
589 HWREG(ulBase + MCSPI_O_CH0CTRL) &= ~MCSPI_CH0CTRL_EN;
590 }
591
592
593 //*****************************************************************************
594 //
595 //! Enables the SPI DMA operation for transmitting and/or receving.
596 //!
597 //! \param ulBase is the base address of the SPI module
598 //! \param ulFlags selectes the DMA signal for transmit and/or receive.
599 //!
600 //! This function enables transmit and/or receive DMA request based on the
601 //! \e ulFlags parameter.
602 //!
603 //! The parameter \e ulFlags is the logical OR of one or more of
604 //! the following :
605 //! - \b SPI_RX_DMA
606 //! - \b SPI_TX_DMA
607 //!
608 //! \return None.
609 //
610 //*****************************************************************************
611 void
SPIDmaEnable(unsigned long ulBase,unsigned long ulFlags)612 SPIDmaEnable(unsigned long ulBase, unsigned long ulFlags)
613 {
614 //
615 // Enable DMA based on ulFlags
616 //
617 HWREG(ulBase + MCSPI_O_CH0CONF) |= ulFlags;
618 }
619
620 //*****************************************************************************
621 //
622 //! Disables the SPI DMA operation for transmitting and/or receving.
623 //!
624 //! \param ulBase is the base address of the SPI module
625 //! \param ulFlags selectes the DMA signal for transmit and/or receive.
626 //!
627 //! This function disables transmit and/or receive DMA request based on the
628 //! \e ulFlags parameter.
629 //!
630 //! The parameter \e ulFlags is the logical OR of one or more of
631 //! the following :
632 //! - \b SPI_RX_DMA
633 //! - \b SPI_TX_DMA
634 //!
635 //! \return None.
636 //
637 //*****************************************************************************
638 void
SPIDmaDisable(unsigned long ulBase,unsigned long ulFlags)639 SPIDmaDisable(unsigned long ulBase, unsigned long ulFlags)
640 {
641 //
642 // Disable DMA based on ulFlags
643 //
644 HWREG(ulBase + MCSPI_O_CH0CONF) &= ~ulFlags;
645 }
646
647 //*****************************************************************************
648 //
649 //! Performs a software reset of the specified SPI module
650 //!
651 //! \param ulBase is the base address of the SPI module
652 //!
653 //! This function performs a software reset of the specified SPI module
654 //!
655 //! \return None.
656 //
657 //*****************************************************************************
658 void
SPIReset(unsigned long ulBase)659 SPIReset(unsigned long ulBase)
660 {
661
662 //
663 // Assert soft reset (auto clear)
664 //
665 HWREG(ulBase + MCSPI_O_SYSCONFIG) |= MCSPI_SYSCONFIG_SOFTRESET;
666
667 //
668 // wait until reset is done
669 //
670 while(!(HWREG(ulBase + MCSPI_O_SYSSTATUS)& MCSPI_SYSSTATUS_RESETDONE))
671 {
672 }
673 }
674
675 //*****************************************************************************
676 //
677 //! Sets the configuration of a SPI module
678 //!
679 //! \param ulBase is the base address of the SPI module
680 //! \param ulSPIClk is the rate of clock supplied to the SPI module.
681 //! \param ulBitRate is the desired bit rate.(master mode)
682 //! \param ulMode is the mode of operation.
683 //! \param ulSubMode is one of the valid sub-modes.
684 //! \param ulConfig is logical OR of configuration paramaters.
685 //!
686 //! This function configures SPI port for operation in specified sub-mode and
687 //! required bit rated as specified by \e ulMode and \e ulBitRate parameters
688 //! respectively.
689 //!
690 //! The SPI module can operate in either master or slave mode. The parameter
691 //! \e ulMode can be one of the following
692 //! -\b SPI_MODE_MASTER
693 //! -\b SPI_MODE_SLAVE
694 //!
695 //! The SPI module supports 4 sub modes based on SPI clock polarity and phase.
696 //!
697 //! <pre>
698 //! Polarity Phase Sub-Mode
699 //! 0 0 0
700 //! 0 1 1
701 //! 1 0 2
702 //! 1 1 3
703 //! </pre>
704 //!
705 //! Required sub mode can be select by setting \e ulSubMode parameter to one
706 //! of the following
707 //! - \b SPI_SUB_MODE_0
708 //! - \b SPI_SUB_MODE_1
709 //! - \b SPI_SUB_MODE_2
710 //! - \b SPI_SUB_MODE_3
711 //!
712 //! The parameter \e ulConfig is logical OR of five values: the word length,
713 //! active level for chip select, software or hardware controled chip select,
714 //! 3 or 4 pin mode and turbo mode.
715 //! mode.
716 //!
717 //! SPI support 8, 16 and 32 bit word lengths defined by:-
718 //! - \b SPI_WL_8
719 //! - \b SPI_WL_16
720 //! - \b SPI_WL_32
721 //!
722 //! Active state of Chip[ Selece can be defined by:-
723 //! - \b SPI_CS_ACTIVELOW
724 //! - \b SPI_CS_ACTIVEHIGH
725 //!
726 //! SPI chip select can be configured to be controlled either by hardware or
727 //! software:-
728 //! - \b SPI_SW_CS
729 //! - \b SPI_HW_CS
730 //!
731 //! The module can work in 3 or 4 pin mode defined by:-
732 //! - \b SPI_3PIN_MODE
733 //! - \b SPI_4PIN_MODE
734 //!
735 //! Turbo mode can be set on or turned off using:-
736 //! - \b SPI_TURBO_MODE_ON
737 //! - \b SPI_TURBO_MODE_OFF
738 //!
739 //! \return None.
740 //
741 //*****************************************************************************
742 void
SPIConfigSetExpClk(unsigned long ulBase,unsigned long ulSPIClk,unsigned long ulBitRate,unsigned long ulMode,unsigned long ulSubMode,unsigned long ulConfig)743 SPIConfigSetExpClk(unsigned long ulBase,unsigned long ulSPIClk,
744 unsigned long ulBitRate, unsigned long ulMode,
745 unsigned long ulSubMode, unsigned long ulConfig)
746 {
747
748 unsigned long ulRegData;
749 unsigned long ulDivider;
750
751 //
752 // Read MODULCTRL register
753 //
754 ulRegData = HWREG(ulBase + MCSPI_O_MODULCTRL);
755
756 //
757 // Set Master mode with h/w chip select
758 //
759 ulRegData &= ~(MCSPI_MODULCTRL_MS |
760 MCSPI_MODULCTRL_SINGLE);
761
762 //
763 // Enable software control Chip Select, Init delay
764 // and 3-pin mode
765 //
766 ulRegData |= (((ulConfig >> 24) | ulMode) & 0xFF);
767
768 //
769 // Write the configuration
770 //
771 HWREG(ulBase + MCSPI_O_MODULCTRL) = ulRegData;
772
773 //
774 // Set IS, DPE0, DPE1 based on master or slave mode
775 //
776 if(ulMode == SPI_MODE_MASTER)
777 {
778 ulRegData = 0x1 << 16;
779 }
780 else
781 {
782 ulRegData = 0x6 << 16;
783 }
784
785 //
786 // Mask the configurations and set clock divider granularity
787 // to 1 cycle
788 //
789 ulRegData = (ulRegData & ~(MCSPI_CH0CONF_WL_M |
790 MCSPI_CH0CONF_EPOL |
791 MCSPI_CH0CONF_POL |
792 MCSPI_CH0CONF_PHA |
793 MCSPI_CH0CONF_TURBO)
794 );
795 ulRegData = (ulRegData | MCSPI_CH0CONF_CLKG);
796 //
797 // Get the divider value
798 //
799 ulDivider = ((ulSPIClk/ulBitRate) - 1);
800
801 //
802 // The least significant four bits of the divider is used fo configure
803 // CLKD in MCSPI_CHCONF next eight least significant bits are used to
804 // configure the EXTCLK in MCSPI_CHCTRL
805 //
806 ulRegData |= ((ulDivider & 0x0000000F) << 2);
807 HWREG(ulBase + MCSPI_O_CH0CTRL) = ((ulDivider & 0x00000FF0) << 4);
808
809 //
810 // Set the protocol, CS polarity, word length
811 // and turbo mode
812 //
813 ulRegData = ((ulRegData |
814 ulSubMode) | (ulConfig & 0x0008FFFF));
815
816 //
817 // Write back the CONF register
818 //
819 HWREG(ulBase + MCSPI_O_CH0CONF) = ulRegData;
820
821 }
822
823 //*****************************************************************************
824 //
825 //! Receives a word from the specified port.
826 //!
827 //! \param ulBase is the base address of the SPI module.
828 //! \param pulData is pointer to receive data variable.
829 //!
830 //! This function gets a SPI word from the receive FIFO for the specified
831 //! port.
832 //!
833 //! \return Returns the number of elements read from the receive FIFO.
834 //
835 //*****************************************************************************
836 long
SPIDataGetNonBlocking(unsigned long ulBase,unsigned long * pulData)837 SPIDataGetNonBlocking(unsigned long ulBase, unsigned long *pulData)
838 {
839 unsigned long ulRegVal;
840
841 //
842 // Read register status register
843 //
844 ulRegVal = HWREG(ulBase + MCSPI_O_CH0STAT);
845
846 //
847 // Check is data is available
848 //
849 if(ulRegVal & MCSPI_CH0STAT_RXS)
850 {
851 *pulData = HWREG(ulBase + MCSPI_O_RX0);
852 return(1);
853 }
854
855 return(0);
856 }
857
858 //*****************************************************************************
859 //
860 //! Waits for the word to be received on the specified port.
861 //!
862 //! \param ulBase is the base address of the SPI module.
863 //! \param pulData is pointer to receive data variable.
864 //!
865 //! This function gets a SPI word from the receive FIFO for the specified
866 //! port. If there is no word available, this function waits until a
867 //! word is received before returning.
868 //!
869 //! \return Returns the word read from the specified port, cast as an
870 //! \e unsigned long.
871 //
872 //*****************************************************************************
873 void
SPIDataGet(unsigned long ulBase,unsigned long * pulData)874 SPIDataGet(unsigned long ulBase, unsigned long *pulData)
875 {
876 //
877 // Wait for Rx data
878 //
879 while(!(HWREG(ulBase + MCSPI_O_CH0STAT) & MCSPI_CH0STAT_RXS))
880 {
881 }
882
883 //
884 // Read the value
885 //
886 *pulData = HWREG(ulBase + MCSPI_O_RX0);
887 }
888
889 //*****************************************************************************
890 //
891 //! Transmits a word on the specified port.
892 //!
893 //! \param ulBase is the base address of the SPI module
894 //! \param ulData is data to be transmitted.
895 //!
896 //! This function transmits a SPI word on the transmit FIFO for the specified
897 //! port.
898 //!
899 //! \return Returns the number of elements written to the transmit FIFO.
900 //!
901 //*****************************************************************************
902 long
SPIDataPutNonBlocking(unsigned long ulBase,unsigned long ulData)903 SPIDataPutNonBlocking(unsigned long ulBase, unsigned long ulData)
904 {
905 unsigned long ulRegVal;
906
907 //
908 // Read status register
909 //
910 ulRegVal = HWREG(ulBase + MCSPI_O_CH0STAT);
911
912 //
913 // Write value into Tx register/FIFO
914 // if space is available
915 //
916 if(ulRegVal & MCSPI_CH0STAT_TXS)
917 {
918 HWREG(ulBase + MCSPI_O_TX0) = ulData;
919 return(1);
920 }
921
922 return(0);
923 }
924
925 //*****************************************************************************
926 //
927 //! Waits until the word is transmitted on the specified port.
928 //!
929 //! \param ulBase is the base address of the SPI module
930 //! \param ulData is data to be transmitted.
931 //!
932 //! This function transmits a SPI word on the transmit FIFO for the specified
933 //! port. This function waits until the space is available on transmit FIFO
934 //!
935 //! \return None
936 //!
937 //*****************************************************************************
938 void
SPIDataPut(unsigned long ulBase,unsigned long ulData)939 SPIDataPut(unsigned long ulBase, unsigned long ulData)
940 {
941 //
942 // Wait for space in FIFO
943 //
944 while(!(HWREG(ulBase + MCSPI_O_CH0STAT)&MCSPI_CH0STAT_TXS))
945 {
946 }
947
948 //
949 // Write the data
950 //
951 HWREG(ulBase + MCSPI_O_TX0) = ulData;
952 }
953
954 //*****************************************************************************
955 //
956 //! Enables the transmit and/or receive FIFOs.
957 //!
958 //! \param ulBase is the base address of the SPI module
959 //! \param ulFlags selects the FIFO(s) to be enabled
960 //!
961 //! This function enables the transmit and/or receive FIFOs as specified by
962 //! \e ulFlags.
963 //! The parameter \e ulFlags shoulde be logical OR of one or more of the
964 //! following:
965 //! - \b SPI_TX_FIFO
966 //! - \b SPI_RX_FIFO
967 //!
968 //! \return None.
969 //
970 //*****************************************************************************
971 void
SPIFIFOEnable(unsigned long ulBase,unsigned long ulFlags)972 SPIFIFOEnable(unsigned long ulBase, unsigned long ulFlags)
973 {
974 //
975 // Set FIFO enable bits.
976 //
977 HWREG(ulBase + MCSPI_O_CH0CONF) |= ulFlags;
978 }
979
980 //*****************************************************************************
981 //
982 //! Disables the transmit and/or receive FIFOs.
983 //!
984 //! \param ulBase is the base address of the SPI module
985 //! \param ulFlags selects the FIFO(s) to be enabled
986 //!
987 //! This function disables transmit and/or receive FIFOs. as specified by
988 //! \e ulFlags.
989 //! The parameter \e ulFlags shoulde be logical OR of one or more of the
990 //! following:
991 //! - \b SPI_TX_FIFO
992 //! - \b SPI_RX_FIFO
993 //!
994 //! \return None.
995 //
996 //*****************************************************************************
997 void
SPIFIFODisable(unsigned long ulBase,unsigned long ulFlags)998 SPIFIFODisable(unsigned long ulBase, unsigned long ulFlags)
999 {
1000 //
1001 // Reset FIFO Enable bits.
1002 //
1003 HWREG(ulBase + MCSPI_O_CH0CONF) &= ~(ulFlags);
1004 }
1005
1006 //*****************************************************************************
1007 //
1008 //! Sets the FIFO level at which DMA requests or interrupts are generated.
1009 //!
1010 //! \param ulBase is the base address of the SPI module
1011 //! \param ulTxLevel is the Almost Empty Level for transmit FIFO.
1012 //! \param ulRxLevel is the Almost Full Level for the receive FIFO.
1013 //!
1014 //! This function Sets the FIFO level at which DMA requests or interrupts
1015 //! are generated.
1016 //!
1017 //! \return None.
1018 //
1019 //*****************************************************************************
SPIFIFOLevelSet(unsigned long ulBase,unsigned long ulTxLevel,unsigned long ulRxLevel)1020 void SPIFIFOLevelSet(unsigned long ulBase, unsigned long ulTxLevel,
1021 unsigned long ulRxLevel)
1022 {
1023 unsigned long ulRegVal;
1024
1025 //
1026 // Read the current configuration
1027 //
1028 ulRegVal = HWREG(ulBase + MCSPI_O_XFERLEVEL);
1029
1030 //
1031 // Mask and set new FIFO thresholds.
1032 //
1033 ulRegVal = ((ulRegVal & 0xFFFF0000) | (((ulRxLevel-1) << 8) | (ulTxLevel-1)));
1034
1035 //
1036 // Set the transmit and receive FIFO thresholds.
1037 //
1038 HWREG(ulBase + MCSPI_O_XFERLEVEL) = ulRegVal;
1039
1040 }
1041
1042 //*****************************************************************************
1043 //
1044 //! Gets the FIFO level at which DMA requests or interrupts are generated.
1045 //!
1046 //! \param ulBase is the base address of the SPI module
1047 //! \param pulTxLevel is a pointer to storage for the transmit FIFO level
1048 //! \param pulRxLevel is a pointer to storage for the receive FIFO level
1049 //!
1050 //! This function gets the FIFO level at which DMA requests or interrupts
1051 //! are generated.
1052 //!
1053 //! \return None.
1054 //
1055 //*****************************************************************************
1056 void
SPIFIFOLevelGet(unsigned long ulBase,unsigned long * pulTxLevel,unsigned long * pulRxLevel)1057 SPIFIFOLevelGet(unsigned long ulBase, unsigned long *pulTxLevel,
1058 unsigned long *pulRxLevel)
1059 {
1060 unsigned long ulRegVal;
1061
1062 //
1063 // Read the current configuration
1064 //
1065 ulRegVal = HWREG(ulBase + MCSPI_O_XFERLEVEL);
1066
1067 *pulTxLevel = (ulRegVal & 0xFF);
1068
1069 *pulRxLevel = ((ulRegVal >> 8) & 0xFF);
1070
1071 }
1072
1073 //*****************************************************************************
1074 //
1075 //! Sets the word count.
1076 //!
1077 //! \param ulBase is the base address of the SPI module
1078 //! \param ulWordCount is number of SPI words to be transmitted.
1079 //!
1080 //! This function sets the word count, which is the number of SPI word to
1081 //! be transferred on channel when using the FIFO buffer.
1082 //!
1083 //! \return None.
1084 //
1085 //*****************************************************************************
1086 void
SPIWordCountSet(unsigned long ulBase,unsigned long ulWordCount)1087 SPIWordCountSet(unsigned long ulBase, unsigned long ulWordCount)
1088 {
1089 unsigned long ulRegVal;
1090
1091 //
1092 // Read the current configuration
1093 //
1094 ulRegVal = HWREG(ulBase + MCSPI_O_XFERLEVEL);
1095
1096 //
1097 // Mask and set the word count
1098 //
1099 HWREG(ulBase + MCSPI_O_XFERLEVEL) = ((ulRegVal & 0x0000FFFF)|
1100 (ulWordCount & 0xFFFF) << 16);
1101 }
1102
1103 //*****************************************************************************
1104 //
1105 //! Registers an interrupt handler for a SPI interrupt.
1106 //!
1107 //! \param ulBase is the base address of the SPI module
1108 //! \param pfnHandler is a pointer to the function to be called when the
1109 //! SPI interrupt occurs.
1110 //!
1111 //! This function does the actual registering of the interrupt handler. This
1112 //! function enables the global interrupt in the interrupt controller; specific
1113 //! SPI interrupts must be enabled via SPIIntEnable(). It is the interrupt
1114 //! handler's responsibility to clear the interrupt source.
1115 //!
1116 //! \sa IntRegister() for important information about registering interrupt
1117 //! handlers.
1118 //!
1119 //! \return None.
1120 //
1121 //*****************************************************************************
1122 void
SPIIntRegister(unsigned long ulBase,void (* pfnHandler)(void))1123 SPIIntRegister(unsigned long ulBase, void(*pfnHandler)(void))
1124 {
1125 unsigned long ulInt;
1126
1127 //
1128 // Determine the interrupt number based on the SPI module
1129 //
1130 ulInt = SPIIntNumberGet(ulBase);
1131
1132 //
1133 // Register the interrupt handler.
1134 //
1135 IntRegister(ulInt, pfnHandler);
1136
1137 //
1138 // Enable the SPI interrupt.
1139 //
1140 IntEnable(ulInt);
1141 }
1142
1143 //*****************************************************************************
1144 //
1145 //! Unregisters an interrupt handler for a SPI interrupt.
1146 //!
1147 //! \param ulBase is the base address of the SPI module
1148 //!
1149 //! This function does the actual unregistering of the interrupt handler. It
1150 //! clears the handler to be called when a SPI interrupt occurs. This
1151 //! function also masks off the interrupt in the interrupt controller so that
1152 //! the interrupt handler no longer is called.
1153 //!
1154 //! \sa IntRegister() for important information about registering interrupt
1155 //! handlers.
1156 //!
1157 //! \return None.
1158 //
1159 //*****************************************************************************
1160 void
SPIIntUnregister(unsigned long ulBase)1161 SPIIntUnregister(unsigned long ulBase)
1162 {
1163 unsigned long ulInt;
1164
1165 //
1166 // Determine the interrupt number based on the SPI module
1167 //
1168 ulInt = SPIIntNumberGet(ulBase);
1169
1170 //
1171 // Disable the interrupt.
1172 //
1173 IntDisable(ulInt);
1174
1175 //
1176 // Unregister the interrupt handler.
1177 //
1178 IntUnregister(ulInt);
1179 }
1180
1181 //*****************************************************************************
1182 //
1183 //! Enables individual SPI interrupt sources.
1184 //!
1185 //! \param ulBase is the base address of the SPI module
1186 //! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
1187 //!
1188 //! This function enables the indicated SPI interrupt sources. Only the
1189 //! sources that are enabled can be reflected to the processor interrupt;
1190 //! disabled sources have no effect on the processor.
1191 //!
1192 //! The \e ulIntFlags parameter is the logical OR of any of the following:
1193 //!
1194 //! - \b SPI_INT_DMATX
1195 //! - \b SPI_INT_DMARX
1196 //! - \b SPI_INT_EOW
1197 //! - \b SPI_INT_RX_OVRFLOW
1198 //! - \b SPI_INT_RX_FULL
1199 //! - \b SPI_INT_TX_UDRFLOW
1200 //! - \b SPI_INT_TX_EMPTY
1201 //!
1202 //! \return None.
1203 //
1204 //*****************************************************************************
1205 void
SPIIntEnable(unsigned long ulBase,unsigned long ulIntFlags)1206 SPIIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
1207 {
1208 unsigned long ulDmaMsk;
1209
1210 //
1211 // Enable DMA Tx Interrupt
1212 //
1213 if(ulIntFlags & SPI_INT_DMATX)
1214 {
1215 ulDmaMsk = SPIDmaMaskGet(ulBase);
1216 HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_CLR) = ulDmaMsk;
1217 }
1218
1219 //
1220 // Enable DMA Rx Interrupt
1221 //
1222 if(ulIntFlags & SPI_INT_DMARX)
1223 {
1224 ulDmaMsk = (SPIDmaMaskGet(ulBase) >> 1);
1225 HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_CLR) = ulDmaMsk;
1226 }
1227
1228 //
1229 // Enable the specific Interrupts
1230 //
1231 HWREG(ulBase + MCSPI_O_IRQENABLE) |= (ulIntFlags & 0x0003000F);
1232 }
1233
1234
1235 //*****************************************************************************
1236 //
1237 //! Disables individual SPI interrupt sources.
1238 //!
1239 //! \param ulBase is the base address of the SPI module
1240 //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
1241 //!
1242 //! This function disables the indicated SPI interrupt sources. Only the
1243 //! sources that are enabled can be reflected to the processor interrupt;
1244 //! disabled sources have no effect on the processor.
1245 //!
1246 //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
1247 //! parameter to SPIIntEnable().
1248 //!
1249 //! \return None.
1250 //
1251 //*****************************************************************************
1252 void
SPIIntDisable(unsigned long ulBase,unsigned long ulIntFlags)1253 SPIIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
1254 {
1255 unsigned long ulDmaMsk;
1256
1257 //
1258 // Disable DMA Tx Interrupt
1259 //
1260 if(ulIntFlags & SPI_INT_DMATX)
1261 {
1262 ulDmaMsk = SPIDmaMaskGet(ulBase);
1263 HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET) = ulDmaMsk;
1264 }
1265
1266 //
1267 // Disable DMA Tx Interrupt
1268 //
1269 if(ulIntFlags & SPI_INT_DMARX)
1270 {
1271 ulDmaMsk = (SPIDmaMaskGet(ulBase) >> 1);
1272 HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET) = ulDmaMsk;
1273 }
1274
1275 //
1276 // Disable the specific Interrupts
1277 //
1278 HWREG(ulBase + MCSPI_O_IRQENABLE) &= ~(ulIntFlags & 0x0003000F);
1279 }
1280
1281 //*****************************************************************************
1282 //
1283 //! Gets the current interrupt status.
1284 //!
1285 //! \param ulBase is the base address of the SPI module
1286 //! \param bMasked is \b false if the raw interrupt status is required and
1287 //! \b true if the masked interrupt status is required.
1288 //!
1289 //! This function returns the interrupt status for the specified SPI.
1290 //! The status of interrupts that are allowed to reflect to the processor can
1291 //! be returned.
1292 //!
1293 //! \return Returns the current interrupt status, enumerated as a bit field of
1294 //! values described in SPIIntEnable().
1295 //
1296 //*****************************************************************************
1297 unsigned long
SPIIntStatus(unsigned long ulBase,tBoolean bMasked)1298 SPIIntStatus(unsigned long ulBase, tBoolean bMasked)
1299 {
1300 unsigned long ulIntStat;
1301 unsigned long ulIntFlag;
1302 unsigned long ulDmaMsk;
1303
1304 //
1305 // Get SPI interrupt status
1306 //
1307 ulIntFlag = HWREG(ulBase + MCSPI_O_IRQSTATUS) & 0x0003000F;
1308
1309 if(bMasked)
1310 {
1311 ulIntFlag &= HWREG(ulBase + MCSPI_O_IRQENABLE);
1312 }
1313
1314 //
1315 // Get the interrupt bit
1316 //
1317 ulDmaMsk = SPIDmaMaskGet(ulBase);
1318
1319 //
1320 // Get the DMA interrupt status
1321 //
1322 if(bMasked)
1323 {
1324 ulIntStat = HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_MASKED);
1325 }
1326 else
1327 {
1328 ulIntStat = HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_RAW);
1329 }
1330
1331 //
1332 // Get SPI Tx DMA done status
1333 //
1334 if(ulIntStat & ulDmaMsk)
1335 {
1336 ulIntFlag |= SPI_INT_DMATX;
1337 }
1338
1339 //
1340 // Get SPI Rx DMA done status
1341 //
1342 if(ulIntStat & (ulDmaMsk >> 1))
1343 {
1344 ulIntFlag |= SPI_INT_DMARX;
1345 }
1346
1347 //
1348 // Return status
1349 //
1350 return(ulIntFlag);
1351 }
1352
1353 //*****************************************************************************
1354 //
1355 //! Clears SPI interrupt sources.
1356 //!
1357 //! \param ulBase is the base address of the SPI module
1358 //! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.
1359 //!
1360 //! The specified SPI interrupt sources are cleared, so that they no longer
1361 //! assert. This function must be called in the interrupt handler to keep the
1362 //! interrupt from being recognized again immediately upon exit.
1363 //!
1364 //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
1365 //! parameter to SPIIntEnable().
1366 //!
1367 //! \return None.
1368 //
1369 //*****************************************************************************
1370 void
SPIIntClear(unsigned long ulBase,unsigned long ulIntFlags)1371 SPIIntClear(unsigned long ulBase, unsigned long ulIntFlags)
1372 {
1373 unsigned long ulDmaMsk;
1374
1375 //
1376 // Disable DMA Tx Interrupt
1377 //
1378 if(ulIntFlags & SPI_INT_DMATX)
1379 {
1380 ulDmaMsk = SPIDmaMaskGet(ulBase);
1381 HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_ACK) = ulDmaMsk;
1382 }
1383
1384 //
1385 // Disable DMA Tx Interrupt
1386 //
1387 if(ulIntFlags & SPI_INT_DMARX)
1388 {
1389 ulDmaMsk = (SPIDmaMaskGet(ulBase) >> 1);
1390 HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_ACK) = ulDmaMsk;
1391 }
1392
1393 //
1394 // Clear Interrupts
1395 //
1396 HWREG(ulBase + MCSPI_O_IRQSTATUS) = (ulIntFlags & 0x0003000F);
1397 }
1398
1399 //*****************************************************************************
1400 //
1401 //! Enables the chip select in software controlled mode
1402 //!
1403 //! \param ulBase is the base address of the SPI module.
1404 //!
1405 //! This function enables the Chip select in software controlled mode. The
1406 //! active state of CS will depend on the configuration done via
1407 //! \sa SPIConfigExpClkSet().
1408 //!
1409 //! \return None.
1410 //
1411 //*****************************************************************************
SPICSEnable(unsigned long ulBase)1412 void SPICSEnable(unsigned long ulBase)
1413 {
1414 //
1415 // Set Chip Select enable bit.
1416 //
1417 HWREG( ulBase+MCSPI_O_CH0CONF) |= MCSPI_CH0CONF_FORCE;
1418 }
1419
1420 //*****************************************************************************
1421 //
1422 //! Disables the chip select in software controlled mode
1423 //!
1424 //! \param ulBase is the base address of the SPI module.
1425 //!
1426 //! This function disables the Chip select in software controlled mode. The
1427 //! active state of CS will depend on the configuration done via
1428 //! sa SPIConfigSetExpClk().
1429 //!
1430 //! \return None.
1431 //
1432 //*****************************************************************************
SPICSDisable(unsigned long ulBase)1433 void SPICSDisable(unsigned long ulBase)
1434 {
1435 //
1436 // Reset Chip Select enable bit.
1437 //
1438 HWREG( ulBase+MCSPI_O_CH0CONF) &= ~MCSPI_CH0CONF_FORCE;
1439 }
1440
1441 //*****************************************************************************
1442 //
1443 //! Send/Receive data buffer over SPI channel
1444 //!
1445 //! \param ulBase is the base address of SPI module
1446 //! \param ucDout is the pointer to Tx data buffer or 0.
1447 //! \param ucDin is pointer to Rx data buffer or 0
1448 //! \param ulCount is the size of data in bytes.
1449 //! \param ulFlags controlls chip select toggling.
1450 //!
1451 //! This function transfers \e ulCount bytes of data over SPI channel. Since
1452 //! the API sends a SPI word at a time \e ulCount should be a multiple of
1453 //! word length set using SPIConfigSetExpClk().
1454 //!
1455 //! If the \e ucDout parameter is set to 0, the function will send 0xFF over
1456 //! the SPI MOSI line.
1457 //!
1458 //! If the \e ucDin parameter is set to 0, the function will ignore data on SPI
1459 //! MISO line.
1460 //!
1461 //! The parameter \e ulFlags is logical OR of one or more of the following
1462 //!
1463 //! - \b SPI_CS_ENABLE if CS needs to be enabled at start of transfer.
1464 //! - \b SPI_CS_DISABLE if CS need to be disabled at the end of transfer.
1465 //!
1466 //! This function will not return until data has been transmitted
1467 //!
1468 //! \return Returns 0 on success, -1 otherwise.
1469 //
1470 //*****************************************************************************
SPITransfer(unsigned long ulBase,unsigned char * ucDout,unsigned char * ucDin,unsigned long ulCount,unsigned long ulFlags)1471 long SPITransfer(unsigned long ulBase, unsigned char *ucDout,
1472 unsigned char *ucDin, unsigned long ulCount,
1473 unsigned long ulFlags)
1474 {
1475 unsigned long ulWordLength;
1476 long lRet;
1477
1478 //
1479 // Get the word length
1480 //
1481 ulWordLength = (HWREG(ulBase + MCSPI_O_CH0CONF) & MCSPI_CH0CONF_WL_M);
1482
1483 //
1484 // Check for word length.
1485 //
1486 if( !((ulWordLength == SPI_WL_8) || (ulWordLength == SPI_WL_16) ||
1487 (ulWordLength == SPI_WL_32)) )
1488 {
1489 return -1;
1490 }
1491
1492 if( ulWordLength == SPI_WL_8 )
1493 {
1494 //
1495 // Do byte transfer
1496 //
1497 lRet = SPITransfer8(ulBase,ucDout,ucDin,ulCount,ulFlags);
1498 }
1499 else if( ulWordLength == SPI_WL_16 )
1500 {
1501
1502 //
1503 // Do half-word transfer
1504 //
1505 lRet = SPITransfer16(ulBase,(unsigned short *)ucDout,
1506 (unsigned short *)ucDin,ulCount,ulFlags);
1507 }
1508 else
1509 {
1510 //
1511 // Do word transfer
1512 //
1513 lRet = SPITransfer32(ulBase,(unsigned long *)ucDout,
1514 (unsigned long *)ucDin,ulCount,ulFlags);
1515 }
1516
1517 //
1518 // return
1519 //
1520 return lRet;
1521
1522 }
1523 //*****************************************************************************
1524 //
1525 // Close the Doxygen group.
1526 //! @}
1527 //
1528 //*****************************************************************************
1529