]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53_bsp/psu_cortexa53_0/libsrc/spips_v3_0/src/xspips.c
Add in the CORTEX_A53_64-bit_UltraScale_MPSoC demo application (a demo has been inclu...
[freertos] / FreeRTOS / Demo / CORTEX_A53_64-bit_UltraScale_MPSoC / RTOSDemo_A53_bsp / psu_cortexa53_0 / libsrc / spips_v3_0 / src / xspips.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2010 - 2015 Xilinx, Inc.  All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 *
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
30 *
31 ******************************************************************************/
32 /*****************************************************************************/
33 /**
34 *
35 * @file xspips.c
36 *
37 * Contains implements the interface functions of the XSpiPs driver.
38 * See xspips.h for a detailed description of the device and driver.
39 *
40 * <pre>
41 * MODIFICATION HISTORY:
42 *
43 * Ver   Who    Date     Changes
44 * ----- ------ -------- -----------------------------------------------
45 * 1.00  drg/jz 01/25/10 First release
46 * 1.01  sg     03/07/12 Updated the code to always clear the relevant bits
47 *                       before writing to config register.
48 *                       Always clear the slave select bits before write and
49 *                       clear the bits to no slave at the end of transfer
50 *                       Modified the Polled transfer transmit/receive logic.
51 *                       Tx should wait on TXOW Interrupt and Rx on RXNEMTY.
52 * 1.03  sg     09/21/12 Added memory barrier dmb in polled transfer and
53 *                       interrupt handler to overcome the clock domain
54 *                       crossing issue in the controller. For CR #679252.
55 * 1.04a sg     01/30/13 Changed SPI transfer logic for polled and interrupt
56 *                       modes to be based on filled tx fifo count and receive
57 *                       based on it. RXNEMPTY interrupt is not used.
58 *                       SetSlaveSelect API logic is modified to drive the bit
59 *                       position low based on the slave select value
60 *                       requested. GetSlaveSelect API will return the value
61 *                       based on bit position that is low.
62 * 1.06a hk     08/22/13 Changed GetSlaveSelect function. CR# 727866.
63 *                       Added masking ConfigReg before writing in SetSlaveSel
64 *                       Added extended slave select support - CR#722569.
65 *                       Added check for MODF in polled transfer function.
66 * 3.00  kvn    02/13/15 Modified code for MISRA-C:2012 compliance.
67 *
68 * </pre>
69 *
70 ******************************************************************************/
71
72 /***************************** Include Files *********************************/
73
74 #include "xspips.h"
75
76 /************************** Constant Definitions *****************************/
77
78
79 /**************************** Type Definitions *******************************/
80
81
82 /***************** Macros (Inline Functions) Definitions *********************/
83
84 /****************************************************************************/
85 /*
86 *
87 * Send one byte to the currently selected slave. A byte of data is written to
88 * transmit FIFO/register.
89 *
90 * @param        BaseAddress is the  base address of the device
91 *
92 * @return       None.
93 *
94 * @note         C-Style signature:
95 *               void XSpiPs_SendByte(u32 BaseAddress, u8 Data);
96 *
97 *****************************************************************************/
98 #define XSpiPs_SendByte(BaseAddress, Data) \
99         XSpiPs_Out32((BaseAddress) + (u32)XSPIPS_TXD_OFFSET, (u32)(Data))
100
101 /****************************************************************************/
102 /*
103 *
104 * Receive one byte from the device's receive FIFO/register. It is assumed
105 * that the byte is already available.
106 *
107 * @param        BaseAddress is the  base address of the device
108 *
109 * @return       The byte retrieved from the receive FIFO/register.
110 *
111 * @note         C-Style signature:
112 *               u8 XSpiPs_RecvByte(u32 BaseAddress);
113 *
114 *****************************************************************************/
115 #define XSpiPs_RecvByte(BaseAddress) \
116                 XSpiPs_In32((u32)((BaseAddress) + (u32)XSPIPS_RXD_OFFSET))
117
118 /************************** Function Prototypes ******************************/
119
120 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
121                                 u32 ByteCount);
122
123 /************************** Variable Definitions *****************************/
124
125
126 /*****************************************************************************/
127 /**
128 *
129 * Initializes a specific XSpiPs instance such that the driver is ready to use.
130 *
131 * The state of the device after initialization is:
132 *   - Device is disabled
133 *   - Slave mode
134 *   - Active high clock polarity
135 *   - Clock phase 0
136 *
137 * @param        InstancePtr is a pointer to the XSpiPs instance.
138 * @param        ConfigPtr is a reference to a structure containing information
139 *               about a specific SPI device. This function initializes an
140 *               InstancePtr object for a specific device specified by the
141 *               contents of Config. This function can initialize multiple
142 *               instance objects with the use of multiple calls giving different
143 *               Config information on each call.
144 * @param        EffectiveAddr is the device base address in the virtual memory
145 *               address space. The caller is responsible for keeping the address
146 *               mapping from EffectiveAddr to the device physical base address
147 *               unchanged once this function is invoked. Unexpected errors may
148 *               occur if the address mapping changes after this function is
149 *               called. If address translation is not used, use
150 *               ConfigPtr->Config.BaseAddress for this device.
151 *
152 * @return
153 *               - XST_SUCCESS if successful.
154 *               - XST_DEVICE_IS_STARTED if the device is already started.
155 *               It must be stopped to re-initialize.
156 *
157 * @note         None.
158 *
159 ******************************************************************************/
160 s32 XSpiPs_CfgInitialize(XSpiPs *InstancePtr, XSpiPs_Config *ConfigPtr,
161                                 u32 EffectiveAddr)
162 {
163         s32 Status;
164         Xil_AssertNonvoid(InstancePtr != NULL);
165         Xil_AssertNonvoid(ConfigPtr != NULL);
166
167         /*
168          * If the device is busy, disallow the initialize and return a status
169          * indicating it is already started. This allows the user to stop the
170          * device and re-initialize, but prevents a user from inadvertently
171          * initializing. This assumes the busy flag is cleared at startup.
172          */
173         if (InstancePtr->IsBusy == TRUE) {
174                 Status = (s32)XST_DEVICE_IS_STARTED;
175         } else {
176
177                 /*
178                  * Set some default values.
179                  */
180                 InstancePtr->IsBusy = FALSE;
181
182                 InstancePtr->Config.BaseAddress = EffectiveAddr;
183                 InstancePtr->StatusHandler = StubStatusHandler;
184
185                 InstancePtr->SendBufferPtr = NULL;
186                 InstancePtr->RecvBufferPtr = NULL;
187                 InstancePtr->RequestedBytes = 0U;
188                 InstancePtr->RemainingBytes = 0U;
189                 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
190
191                 /*
192                  * Reset the SPI device to get it into its initial state. It is
193                  * expected that device configuration will take place after this
194                  * initialization is done, but before the device is started.
195                  */
196                 XSpiPs_Reset(InstancePtr);
197                 Status = (s32)XST_SUCCESS;
198         }
199
200         return Status;
201 }
202
203
204 /*****************************************************************************/
205 /**
206 *
207 * Resets the SPI device. Reset must only be called after the driver has been
208 * initialized. The configuration of the device after reset is the same as its
209 * configuration after initialization.  Any data transfer that is in progress
210 * is aborted.
211 *
212 * The upper layer software is responsible for re-configuring (if necessary)
213 * and restarting the SPI device after the reset.
214 *
215 * @param        InstancePtr is a pointer to the XSpiPs instance.
216 *
217 * @return       None.
218 *
219 * @note         None.
220 *
221 ******************************************************************************/
222 void XSpiPs_Reset(XSpiPs *InstancePtr)
223 {
224         Xil_AssertVoid(InstancePtr != NULL);
225         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
226
227         /*
228          * Abort any transfer that is in progress
229          */
230         XSpiPs_Abort(InstancePtr);
231
232         /*
233          * Reset any values that are not reset by the hardware reset such that
234          * the software state matches the hardware device
235          */
236         XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_CR_OFFSET,
237                         XSPIPS_CR_RESET_STATE);
238
239 }
240
241 /*****************************************************************************/
242 /**
243 *
244 * Transfers specified data on the SPI bus. If the SPI device is configured as
245 * a master, this function initiates bus communication and sends/receives the
246 * data to/from the selected SPI slave. If the SPI device is configured as a
247 * slave, this function prepares the buffers to be sent/received when selected
248 * by a master. For every byte sent, a byte is received. This function should
249 * be used to perform interrupt based transfers.
250 *
251 * The caller has the option of providing two different buffers for send and
252 * receive, or one buffer for both send and receive, or no buffer for receive.
253 * The receive buffer must be at least as big as the send buffer to prevent
254 * unwanted memory writes. This implies that the byte count passed in as an
255 * argument must be the smaller of the two buffers if they differ in size.
256 * Here are some sample usages:
257 * <pre>
258 *   XSpiPs_Transfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
259 *       The caller wishes to send and receive, and provides two different
260 *       buffers for send and receive.
261 *
262 *   XSpiPs_Transfer(InstancePtr, SendBuf, NULL, ByteCount)
263 *       The caller wishes only to send and does not care about the received
264 *       data. The driver ignores the received data in this case.
265 *
266 *   XSpiPs_Transfer(InstancePtr, SendBuf, SendBuf, ByteCount)
267 *       The caller wishes to send and receive, but provides the same buffer
268 *       for doing both. The driver sends the data and overwrites the send
269 *       buffer with received data as it transfers the data.
270 *
271 *   XSpiPs_Transfer(InstancePtr, RecvBuf, RecvBuf, ByteCount)
272 *       The caller wishes to only receive and does not care about sending
273 *       data.  In this case, the caller must still provide a send buffer, but
274 *       it can be the same as the receive buffer if the caller does not care
275 *       what it sends.  The device must send N bytes of data if it wishes to
276 *       receive N bytes of data.
277 * </pre>
278 * Although this function takes entire buffers as arguments, the driver can only
279 * transfer a limited number of bytes at a time, limited by the size of the
280 * FIFO. A call to this function only starts the transfer, then subsequent
281 * transfers of the data is performed by the interrupt service routine until
282 * the entire buffer has been transferred. The status callback function is
283 * called when the entire buffer has been sent/received.
284 *
285 * This function is non-blocking. As a master, the SetSlaveSelect function must
286 * be called prior to this function.
287 *
288 * @param        InstancePtr is a pointer to the XSpiPs instance.
289 * @param        SendBufPtr is a pointer to a buffer of data for sending.
290 *               This buffer must not be NULL.
291 * @param        RecvBufPtr is a pointer to a buffer for received data.
292 *               This argument can be NULL if do not care about receiving.
293 * @param        ByteCount contains the number of bytes to send/receive.
294 *               The number of bytes received always equals the number of bytes
295 *               sent.
296 *
297 * @return
298 *               - XST_SUCCESS if the buffers are successfully handed off to the
299 *               device for transfer.
300 *               - XST_DEVICE_BUSY indicates that a data transfer is already in
301 *               progress. This is determined by the driver.
302 *
303 * @note
304 *
305 * This function is not thread-safe.  The higher layer software must ensure that
306 * no two threads are transferring data on the SPI bus at the same time.
307 *
308 ******************************************************************************/
309 s32 XSpiPs_Transfer(XSpiPs *InstancePtr, u8 *SendBufPtr,
310                         u8 *RecvBufPtr, u32 ByteCount)
311 {
312         u32 ConfigReg;
313         u8 TransCount = 0U;
314         s32 StatusTransfer;
315
316         /*
317          * The RecvBufPtr argument can be null
318          */
319         Xil_AssertNonvoid(InstancePtr != NULL);
320         Xil_AssertNonvoid(SendBufPtr != NULL);
321         Xil_AssertNonvoid(ByteCount > 0U);
322         Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
323
324         /*
325          * Check whether there is another transfer in progress. Not thread-safe.
326          */
327         if (InstancePtr->IsBusy == TRUE) {
328                 StatusTransfer = (s32)XST_DEVICE_BUSY;
329         } else {
330
331                 /*
332                  * Set the busy flag, which will be cleared in the ISR when the
333                  * transfer is entirely done.
334                  */
335                 InstancePtr->IsBusy = TRUE;
336
337                 /*
338                  * Set up buffer pointers.
339                  */
340                 InstancePtr->SendBufferPtr = SendBufPtr;
341                 InstancePtr->RecvBufferPtr = RecvBufPtr;
342
343                 InstancePtr->RequestedBytes = ByteCount;
344                 InstancePtr->RemainingBytes = ByteCount;
345
346         /*
347          * If manual chip select mode, initialize the slave select value.
348          */
349         if (XSpiPs_IsManualChipSelect(InstancePtr) != FALSE) {
350                 ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
351                                          XSPIPS_CR_OFFSET);
352                 /*
353                  * Set the slave select value.
354                  */
355                 ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK);
356                 ConfigReg |= InstancePtr->SlaveSelect;
357                 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
358                                  XSPIPS_CR_OFFSET, ConfigReg);
359         }
360
361                 /*
362                  * Enable the device.
363                  */
364                 XSpiPs_Enable(InstancePtr);
365
366                 /*
367                  * Clear all the interrrupts.
368                  */
369                 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_SR_OFFSET,
370                                 XSPIPS_IXR_WR_TO_CLR_MASK);
371
372                 /*
373                  * Fill the TXFIFO with as many bytes as it will take (or as many as
374                  * we have to send).
375                  */
376                 while ((InstancePtr->RemainingBytes > 0U) &&
377                         (TransCount < XSPIPS_FIFO_DEPTH)) {
378                         XSpiPs_SendByte(InstancePtr->Config.BaseAddress,
379                                   *InstancePtr->SendBufferPtr);
380                   InstancePtr->SendBufferPtr += 1;
381                         InstancePtr->RemainingBytes--;
382                         TransCount++;
383                 }
384
385                 /*
386                  * Enable interrupts (connecting to the interrupt controller and
387                  * enabling interrupts should have been done by the caller).
388                  */
389                 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
390                                 XSPIPS_IER_OFFSET, XSPIPS_IXR_DFLT_MASK);
391
392                 /*
393                  * If master mode and manual start mode, issue manual start command
394                  * to start the transfer.
395                  */
396              if ((XSpiPs_IsManualStart(InstancePtr) == TRUE)
397                 && (XSpiPs_IsMaster(InstancePtr) == TRUE)) {
398                         ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
399                                                    XSPIPS_CR_OFFSET);
400                                 ConfigReg |= XSPIPS_CR_MANSTRT_MASK;
401                         XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
402                                          XSPIPS_CR_OFFSET, ConfigReg);
403                  }
404                 StatusTransfer = (s32)XST_SUCCESS;
405         }
406         return StatusTransfer;
407 }
408
409 /*****************************************************************************/
410 /**
411 * Transfers specified data on the SPI bus in polled mode.
412 *
413 * The caller has the option of providing two different buffers for send and
414 * receive, or one buffer for both send and receive, or no buffer for receive.
415 * The receive buffer must be at least as big as the send buffer to prevent
416 * unwanted memory writes. This implies that the byte count passed in as an
417 * argument must be the smaller of the two buffers if they differ in size.
418 * Here are some sample usages:
419 * <pre>
420 *   XSpiPs_PolledTransfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
421 *       The caller wishes to send and receive, and provides two different
422 *       buffers for send and receive.
423 *
424 *   XSpiPs_PolledTransfer(InstancePtr, SendBuf, NULL, ByteCount)
425 *       The caller wishes only to send and does not care about the received
426 *       data. The driver ignores the received data in this case.
427 *
428 *   XSpiPs_PolledTransfer(InstancePtr, SendBuf, SendBuf, ByteCount)
429 *       The caller wishes to send and receive, but provides the same buffer
430 *       for doing both. The driver sends the data and overwrites the send
431 *       buffer with received data as it transfers the data.
432 *
433 *   XSpiPs_PolledTransfer(InstancePtr, RecvBuf, RecvBuf, ByteCount)
434 *       The caller wishes to only receive and does not care about sending
435 *       data.  In this case, the caller must still provide a send buffer, but
436 *       it can be the same as the receive buffer if the caller does not care
437 *       what it sends.  The device must send N bytes of data if it wishes to
438 *       receive N bytes of data.
439 *
440 * </pre>
441 *
442 * @param        InstancePtr is a pointer to the XSpiPs instance.
443 * @param        SendBufPtr is a pointer to a buffer of data for sending.
444 *               This buffer must not be NULL.
445 * @param        RecvBufPtr is a pointer to a buffer for received data.
446 *               This argument can be NULL if do not care about receiving.
447 * @param        ByteCount contains the number of bytes to send/receive.
448 *               The number of bytes received always equals the number of bytes
449 *               sent.
450
451 * @return
452 *               - XST_SUCCESS if the buffers are successfully handed off to the
453 *               device for transfer.
454 *               - XST_DEVICE_BUSY indicates that a data transfer is already in
455 *               progress. This is determined by the driver.
456 *
457 * @note
458 *
459 * This function is not thread-safe.  The higher layer software must ensure that
460 * no two threads are transferring data on the SPI bus at the same time.
461 *
462 ******************************************************************************/
463 s32 XSpiPs_PolledTransfer(XSpiPs *InstancePtr, u8 *SendBufPtr,
464                                 u8 *RecvBufPtr, u32 ByteCount)
465 {
466         u32 StatusReg;
467         u32 ConfigReg;
468         u32 TransCount;
469         u32 CheckTransfer;
470         s32 Status_Polled;
471         u8 TempData;
472
473         /*
474          * The RecvBufPtr argument can be NULL.
475          */
476         Xil_AssertNonvoid(InstancePtr != NULL);
477         Xil_AssertNonvoid(SendBufPtr != NULL);
478         Xil_AssertNonvoid(ByteCount > 0U);
479         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
480
481         /*
482          * Check whether there is another transfer in progress. Not thread-safe.
483          */
484         if (InstancePtr->IsBusy == TRUE) {
485                 Status_Polled = (s32)XST_DEVICE_BUSY;
486         } else {
487
488                 /*
489                  * Set the busy flag, which will be cleared when the transfer is
490                  * entirely done.
491                  */
492                 InstancePtr->IsBusy = TRUE;
493
494                 /*
495                  * Set up buffer pointers.
496                  */
497                 InstancePtr->SendBufferPtr = SendBufPtr;
498                 InstancePtr->RecvBufferPtr = RecvBufPtr;
499
500                 InstancePtr->RequestedBytes = ByteCount;
501                 InstancePtr->RemainingBytes = ByteCount;
502
503                 /*
504                  * If manual chip select mode, initialize the slave select value.
505                  */
506              if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) {
507                         ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
508                                                  XSPIPS_CR_OFFSET);
509                         /*
510                          * Set the slave select value.
511                          */
512                         ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK);
513                         ConfigReg |= InstancePtr->SlaveSelect;
514                         XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
515                                          XSPIPS_CR_OFFSET, ConfigReg);
516                 }
517
518                 /*
519                  * Enable the device.
520                  */
521                 XSpiPs_Enable(InstancePtr);
522
523                 while((InstancePtr->RemainingBytes > (u32)0U) ||
524                         (InstancePtr->RequestedBytes > (u32)0U)) {
525                         TransCount = 0U;
526                         /*
527                          * Fill the TXFIFO with as many bytes as it will take (or as
528                          * many as we have to send).
529                          */
530                         while ((InstancePtr->RemainingBytes > (u32)0U) &&
531                                 ((u32)TransCount < (u32)XSPIPS_FIFO_DEPTH)) {
532                                 XSpiPs_SendByte(InstancePtr->Config.BaseAddress,
533                                                 *InstancePtr->SendBufferPtr);
534                                 InstancePtr->SendBufferPtr += 1;
535                                 InstancePtr->RemainingBytes--;
536                                 ++TransCount;
537                         }
538
539                         /*
540                          * If master mode and manual start mode, issue manual start
541                          * command to start the transfer.
542                          */
543                         if ((XSpiPs_IsManualStart(InstancePtr) == TRUE)
544                                 && (XSpiPs_IsMaster(InstancePtr) == TRUE)) {
545                                 ConfigReg = XSpiPs_ReadReg(
546                                                 InstancePtr->Config.BaseAddress,
547                                                  XSPIPS_CR_OFFSET);
548                                 ConfigReg |= XSPIPS_CR_MANSTRT_MASK;
549                                 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
550                                                  XSPIPS_CR_OFFSET, ConfigReg);
551                         }
552
553                         /*
554                          * Wait for the transfer to finish by polling Tx fifo status.
555                          */
556                 CheckTransfer = (u32)0U;
557                 while (CheckTransfer == 0U){
558                         StatusReg = XSpiPs_ReadReg(
559                                                 InstancePtr->Config.BaseAddress,
560                                                         XSPIPS_SR_OFFSET);
561                                 if ( (StatusReg & XSPIPS_IXR_MODF_MASK) != 0U) {
562                                         /*
563                                          * Clear the mode fail bit
564                                          */
565                                         XSpiPs_WriteReg(
566                                                 InstancePtr->Config.BaseAddress,
567                                                 XSPIPS_SR_OFFSET,
568                                                 XSPIPS_IXR_MODF_MASK);
569                                         return (s32)XST_SEND_ERROR;
570                                 }
571                         CheckTransfer = (StatusReg &
572                                                         XSPIPS_IXR_TXOW_MASK);
573                     }
574
575                         /*
576                          * A transmit has just completed. Process received data and
577                          * check for more data to transmit.
578                          * First get the data received as a result of the transmit
579                          * that just completed. Receive data based on the
580                          * count obtained while filling tx fifo. Always get the
581                          * received data, but only fill the receive buffer if it
582                          * points to something (the upper layer software may not
583                          * care to receive data).
584                          */
585                         while (TransCount != (u32)0U) {
586                                 TempData = (u8)XSpiPs_RecvByte(
587                                         InstancePtr->Config.BaseAddress);
588                                 if (InstancePtr->RecvBufferPtr != NULL) {
589                                         *(InstancePtr->RecvBufferPtr) = TempData;
590                                         InstancePtr->RecvBufferPtr += 1;
591                                 }
592                                 InstancePtr->RequestedBytes--;
593                                 --TransCount;
594                         }
595                 }
596
597                 /*
598                  * Clear the slave selects now, before terminating the transfer.
599                  */
600                 if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) {
601                         ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
602                                                 XSPIPS_CR_OFFSET);
603                         ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
604                         XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
605                                          XSPIPS_CR_OFFSET, ConfigReg);
606                 }
607
608                 /*
609                  * Clear the busy flag.
610                  */
611                 InstancePtr->IsBusy = FALSE;
612
613                 /*
614                  * Disable the device.
615                  */
616                 XSpiPs_Disable(InstancePtr);
617                 Status_Polled = (s32)XST_SUCCESS;
618         }
619         return Status_Polled;
620 }
621
622 /*****************************************************************************/
623 /**
624 *
625 * Selects or deselect the slave with which the master communicates. This setting
626 * affects the SPI_ss_outN signals. The behavior depends on the setting of the
627 * CR_SSDECEN bit. If CR_SSDECEN is 0, the SPI_ss_outN bits will be output with a
628 * single signal low. If CR_SSDECEN is 1, the SPI_ss_outN bits will reflect the
629 * value set.
630 *
631 * The user is not allowed to deselect the slave while a transfer is in progress.
632 * If no transfer is in progress, the user can select a new slave, which
633 * implicitly deselects the current slave. In order to explicitly deselect the
634 * current slave, a value of all 1's, 0x0F can be passed in as the argument to
635 * the function.
636 *
637 * @param        InstancePtr is a pointer to the XSpiPs instance.
638 * @param        SlaveSel is the slave number to be selected.
639 *               Normally, 3 slaves can be selected with values 0-2.
640 *               In case, 3-8 decode option is set, then upto 8 slaves
641 *               can be selected. Only one slave can be selected at a time.
642 *
643 * @return
644 *               - XST_SUCCESS if the slave is selected or deselected
645 *               successfully.
646 *               - XST_DEVICE_BUSY if a transfer is in progress, slave cannot be
647 *               changed.
648 *
649 * @note
650 *
651 * This function only sets the slave which will be selected when a transfer
652 * occurs. The slave is not selected when the SPI is idle. The slave select
653 * has no affect when the device is configured as a slave.
654 *
655 ******************************************************************************/
656 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel)
657 {
658         u32 ConfigReg;
659         s32 Status_Slave;
660         Xil_AssertNonvoid(InstancePtr != NULL);
661         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
662         Xil_AssertNonvoid(SlaveSel <= XSPIPS_CR_SSCTRL_MAXIMUM);
663
664         /*
665          * Do not allow the slave select to change while a transfer is in
666          * progress. Not thread-safe.
667          */
668         if (InstancePtr->IsBusy == TRUE) {
669                 Status_Slave = (s32)XST_DEVICE_BUSY;
670         } else {
671                 /*
672                  * If decode slave select option is set,
673                  * then set slave select value directly.
674                  * Update the Instance structure member.
675                  */
676                 if ( XSpiPs_IsDecodeSSelect( InstancePtr ) == TRUE) {
677                         InstancePtr->SlaveSelect = ((u32)SlaveSel) << XSPIPS_CR_SSCTRL_SHIFT;
678                 }
679                 else {
680                 /*
681                  * Set the bit position to low using SlaveSel. Update the Instance
682                  * structure member.
683                  */
684                         InstancePtr->SlaveSelect = ((~(1U << SlaveSel)) & \
685                                 XSPIPS_CR_SSCTRL_MAXIMUM) << XSPIPS_CR_SSCTRL_SHIFT;
686                 }
687
688                 /*
689                  * Read the config register, update the slave select value and write
690                  * back to config register.
691                  */
692                 ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
693                                  XSPIPS_CR_OFFSET);
694                 ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK);
695                 ConfigReg |= InstancePtr->SlaveSelect;
696                 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_CR_OFFSET,
697                                  ConfigReg);
698             Status_Slave = (s32)XST_SUCCESS;
699         }
700         return Status_Slave;
701 }
702
703 /*****************************************************************************/
704 /**
705 *
706 * Gets the current slave select setting for the SPI device.
707 *
708 * @param        InstancePtr is a pointer to the XSpiPs instance.
709 *
710 * @return       The slave number selected (starting from 0).
711 *
712 * @note         None.
713 *
714 ******************************************************************************/
715 u8 XSpiPs_GetSlaveSelect(XSpiPs *InstancePtr)
716 {
717         u32 ConfigReg;
718         u32 SlaveSel;
719
720         Xil_AssertNonvoid(InstancePtr != NULL);
721         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
722
723         ConfigReg = InstancePtr->SlaveSelect;
724         ConfigReg &= XSPIPS_CR_SSCTRL_MASK;
725         ConfigReg >>= XSPIPS_CR_SSCTRL_SHIFT;
726         ConfigReg &= XSPIPS_CR_SSCTRL_MAXIMUM;
727
728         /*
729          * If decode slave select option is set, then read value directly.
730          */
731         if ( XSpiPs_IsDecodeSSelect( InstancePtr ) == TRUE) {
732                 SlaveSel = ConfigReg;
733         }
734         else {
735
736                 /*
737                  * Get the slave select value
738                  */
739                 if(ConfigReg == 0x0FU) {
740                         /*
741                          * No slave selected
742                          */
743                         SlaveSel = 0xFU;
744                 }else {
745                         /*
746                          * Get selected slave number (0,1 or 2)
747                          */
748                         SlaveSel = ((~ConfigReg) & XSPIPS_CR_SSCTRL_MAXIMUM)/2;
749                 }
750         }
751         return (u8)SlaveSel;
752 }
753
754 /*****************************************************************************/
755 /**
756 *
757 * Sets the status callback function, the status handler, which the driver
758 * calls when it encounters conditions that should be reported to upper
759 * layer software. The handler executes in an interrupt context, so it must
760 * minimize the amount of processing performed. One of the following status
761 * events is passed to the status handler.
762 *
763 * <pre>
764 * XST_SPI_MODE_FAULT            A mode fault error occurred, meaning the device
765 *                               is selected as slave while being a master.
766 *
767 * XST_SPI_TRANSFER_DONE         The requested data transfer is done
768 *
769 * XST_SPI_TRANSMIT_UNDERRUN     As a slave device, the master clocked data
770 *                               but there were none available in the transmit
771 *                               register/FIFO. This typically means the slave
772 *                               application did not issue a transfer request
773 *                               fast enough, or the processor/driver could not
774 *                               fill the transmit register/FIFO fast enough.
775 *
776 * XST_SPI_RECEIVE_OVERRUN       The SPI device lost data. Data was received
777 *                               but the receive data register/FIFO was full.
778 *
779 * XST_SPI_SLAVE_MODE_FAULT      A slave SPI device was selected as a slave
780 *                               while it was disabled. This indicates the
781 *                               master is already transferring data (which is
782 *                               being dropped until the slave application
783 *                               issues a transfer).
784 * </pre>
785 * @param        InstancePtr is a pointer to the XSpiPs instance.
786 * @param        CallBackRef is the upper layer callback reference passed back
787 *               when the callback function is invoked.
788 * @param        FunctionPtr is the pointer to the callback function.
789 *
790 * @return       None.
791 *
792 * @note
793 *
794 * The handler is called within interrupt context, so it should do its work
795 * quickly and queue potentially time-consuming work to a task-level thread.
796 *
797 ******************************************************************************/
798 void XSpiPs_SetStatusHandler(XSpiPs *InstancePtr, void *CallBackRef,
799                                 XSpiPs_StatusHandler FunctionPtr)
800 {
801         Xil_AssertVoid(InstancePtr != NULL);
802         Xil_AssertVoid(FunctionPtr != NULL);
803         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
804
805         InstancePtr->StatusHandler = FunctionPtr;
806         InstancePtr->StatusRef = CallBackRef;
807 }
808
809 /*****************************************************************************/
810 /**
811 *
812 * This is a stub for the status callback. The stub is here in case the upper
813 * layers forget to set the handler.
814 *
815 * @param        CallBackRef is a pointer to the upper layer callback reference
816 * @param        StatusEvent is the event that just occurred.
817 * @param        ByteCount is the number of bytes transferred up until the event
818 *               occurred.
819 *
820 * @return       None.
821 *
822 * @note         None.
823 *
824 ******************************************************************************/
825 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
826                                 u32 ByteCount)
827 {
828         (void) CallBackRef;
829         (void) StatusEvent;
830         (void) ByteCount;
831
832         Xil_AssertVoidAlways();
833 }
834
835 /*****************************************************************************/
836 /**
837 *
838 * The interrupt handler for SPI interrupts. This function must be connected
839 * by the user to an interrupt controller.
840 *
841 * The interrupts that are handled are:
842 *
843 * - Mode Fault Error. This interrupt is generated if this device is selected
844 *   as a slave when it is configured as a master. The driver aborts any data
845 *   transfer that is in progress by resetting FIFOs (if present) and resetting
846 *   its buffer pointers. The upper layer software is informed of the error.
847 *
848 * - Data Transmit Register (FIFO) Empty. This interrupt is generated when the
849 *   transmit register or FIFO is empty. The driver uses this interrupt during a
850 *   transmission to continually send/receive data until the transfer is done.
851 *
852 * - Data Transmit Register (FIFO) Underflow. This interrupt is generated when
853 *   the SPI device, when configured as a slave, attempts to read an empty
854 *   DTR/FIFO.  An empty DTR/FIFO usually means that software is not giving the
855 *   device data in a timely manner. No action is taken by the driver other than
856 *   to inform the upper layer software of the error.
857 *
858 * - Data Receive Register (FIFO) Overflow. This interrupt is generated when the
859 *   SPI device attempts to write a received byte to an already full DRR/FIFO.
860 *   A full DRR/FIFO usually means software is not emptying the data in a timely
861 *   manner.  No action is taken by the driver other than to inform the upper
862 *   layer software of the error.
863 *
864 * - Slave Mode Fault Error. This interrupt is generated if a slave device is
865 *   selected as a slave while it is disabled. No action is taken by the driver
866 *   other than to inform the upper layer software of the error.
867 *
868 * @param        InstancePtr is a pointer to the XSpiPs instance.
869 *
870 * @return       None.
871 *
872 * @note
873 *
874 * The slave select register is being set to deselect the slave when a transfer
875 * is complete.  This is being done regardless of whether it is a slave or a
876 * master since the hardware does not drive the slave select as a slave.
877 *
878 ******************************************************************************/
879 void XSpiPs_InterruptHandler(XSpiPs *InstancePtr)
880 {
881         XSpiPs *SpiPtr = InstancePtr;
882         u32 IntrStatus;
883         u32 ConfigReg;
884         u32 BytesDone; /* Number of bytes done so far. */
885
886         Xil_AssertVoid(InstancePtr != NULL);
887         Xil_AssertVoid(SpiPtr->IsReady == XIL_COMPONENT_IS_READY);
888
889         /*
890          * Immediately clear the interrupts in case the ISR causes another
891          * interrupt to be generated. If we clear at the end of the ISR,
892          * we may miss newly generated interrupts.
893          * Disable the TXOW interrupt because we transmit from within the ISR,
894          * which could potentially cause another TX_OW interrupt.
895          */
896         IntrStatus =
897                 XSpiPs_ReadReg(SpiPtr->Config.BaseAddress, XSPIPS_SR_OFFSET);
898         XSpiPs_WriteReg(SpiPtr->Config.BaseAddress, XSPIPS_SR_OFFSET,
899                         (IntrStatus & XSPIPS_IXR_WR_TO_CLR_MASK));
900         XSpiPs_WriteReg(SpiPtr->Config.BaseAddress, XSPIPS_IDR_OFFSET,
901                         XSPIPS_IXR_TXOW_MASK);
902
903         /*
904          * Check for mode fault error. We want to check for this error first,
905          * before checking for progress of a transfer, since this error needs
906          * to abort any operation in progress.
907          */
908         if ((u32)XSPIPS_IXR_MODF_MASK == (u32)(IntrStatus & XSPIPS_IXR_MODF_MASK)) {
909                 BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
910
911                 /*
912                  * Abort any operation currently in progress. This includes
913                  * clearing the mode fault condition by reading the status
914                  * register. Note that the status register should be read after
915                  * the abort, since reading the status register clears the mode
916                  * fault condition and would cause the device to restart any
917                  * transfer that may be in progress.
918                  */
919                 XSpiPs_Abort(SpiPtr);
920
921                 SpiPtr->StatusHandler(SpiPtr->StatusRef, XST_SPI_MODE_FAULT,
922                                         BytesDone);
923
924                 return; /* Do not continue servicing other interrupts. */
925         }
926
927
928         if ((IntrStatus & XSPIPS_IXR_TXOW_MASK) != 0U) {
929                 u8 TempData;
930                 u32 TransCount;
931                 /*
932                  * A transmit has just completed. Process received data and
933                  * check for more data to transmit.
934                  * First get the data received as a result of the transmit that
935                  * just completed.  Always get the received data, but only fill
936                  * the receive buffer if it is not null (it can be null when
937                  * the device does not care to receive data).
938                  * Initialize the TransCount based on the requested bytes.
939                  * Loop on receive FIFO based on TransCount.
940                  */
941                 TransCount = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
942
943                 while (TransCount != 0U) {
944                         TempData = (u8)XSpiPs_RecvByte(SpiPtr->Config.BaseAddress);
945                         if (SpiPtr->RecvBufferPtr != NULL) {
946                                 *SpiPtr->RecvBufferPtr = TempData;
947                                 SpiPtr->RecvBufferPtr += 1;
948                         }
949                         SpiPtr->RequestedBytes--;
950                         --TransCount;
951                 }
952
953                 /*
954                  * Fill the TXFIFO until data exists, otherwise fill upto
955                  * FIFO depth.
956                  */
957                 while ((SpiPtr->RemainingBytes > 0U) &&
958                         (TransCount < XSPIPS_FIFO_DEPTH)) {
959                         XSpiPs_SendByte(SpiPtr->Config.BaseAddress,
960                                          *SpiPtr->SendBufferPtr);
961                         SpiPtr->SendBufferPtr += 1;
962                         SpiPtr->RemainingBytes--;
963                         ++TransCount;
964                 }
965
966                 if ((SpiPtr->RemainingBytes == 0U) &&
967                         (SpiPtr->RequestedBytes == 0U)) {
968                         /*
969                          * No more data to send. Disable the interrupt and
970                          * inform the upper layer software that the transfer
971                          * is done. The interrupt will be re-enabled when
972                          * another transfer is initiated.
973                          */
974                         XSpiPs_WriteReg(SpiPtr->Config.BaseAddress,
975                                  XSPIPS_IDR_OFFSET, XSPIPS_IXR_DFLT_MASK);
976
977                         /*
978                          * Disable slave select lines as the transfer
979                          * is complete.
980                          */
981                         if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) {
982                                 ConfigReg = XSpiPs_ReadReg(
983                                         SpiPtr->Config.BaseAddress,
984                                          XSPIPS_CR_OFFSET);
985                                 ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
986                                 XSpiPs_WriteReg(
987                                         SpiPtr->Config.BaseAddress,
988                                          XSPIPS_CR_OFFSET, ConfigReg);
989                         }
990
991                         /*
992                          * Clear the busy flag.
993                          */
994                         SpiPtr->IsBusy = FALSE;
995
996                         /*
997                          * Disable the device.
998                          */
999                         XSpiPs_Disable(SpiPtr);
1000
1001                         /*
1002                          * Inform the Transfer done to upper layers.
1003                          */
1004                         SpiPtr->StatusHandler(SpiPtr->StatusRef,
1005                                                 XST_SPI_TRANSFER_DONE,
1006                                                 SpiPtr->RequestedBytes);
1007                 } else {
1008                         /*
1009                          * Enable the TXOW interrupt.
1010                          */
1011                         XSpiPs_WriteReg(SpiPtr->Config.BaseAddress,
1012                                  XSPIPS_IER_OFFSET, XSPIPS_IXR_TXOW_MASK);
1013                         /*
1014                          * Start the transfer by not inhibiting the transmitter
1015                          * any longer.
1016                          */
1017                         if ((XSpiPs_IsManualStart(SpiPtr) == TRUE)
1018                                 && (XSpiPs_IsMaster(SpiPtr) == TRUE)) {
1019                                 ConfigReg = XSpiPs_ReadReg(
1020                                         SpiPtr->Config.BaseAddress,
1021                                          XSPIPS_CR_OFFSET);
1022                                 ConfigReg |= XSPIPS_CR_MANSTRT_MASK;
1023                                 XSpiPs_WriteReg(
1024                                         SpiPtr->Config.BaseAddress,
1025                                          XSPIPS_CR_OFFSET, ConfigReg);
1026                         }
1027                 }
1028         }
1029
1030         /*
1031          * Check for overflow and underflow errors.
1032          */
1033         if ((IntrStatus & XSPIPS_IXR_RXOVR_MASK) != 0U) {
1034                 BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
1035                 SpiPtr->IsBusy = FALSE;
1036
1037                 /*
1038                  * The Slave select lines are being manually controlled.
1039                  * Disable them because the transfer is complete.
1040                  */
1041                 if (XSpiPs_IsManualChipSelect(SpiPtr) == TRUE) {
1042                         ConfigReg = XSpiPs_ReadReg(
1043                                 SpiPtr->Config.BaseAddress,
1044                                  XSPIPS_CR_OFFSET);
1045                         ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
1046                         XSpiPs_WriteReg(
1047                                 SpiPtr->Config.BaseAddress,
1048                                  XSPIPS_CR_OFFSET, ConfigReg);
1049                 }
1050
1051                 SpiPtr->StatusHandler(SpiPtr->StatusRef,
1052                         XST_SPI_RECEIVE_OVERRUN, BytesDone);
1053         }
1054
1055         if ((IntrStatus & XSPIPS_IXR_TXUF_MASK) != 0U) {
1056                 BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
1057
1058                 SpiPtr->IsBusy = FALSE;
1059                 /*
1060                  * The Slave select lines are being manually controlled.
1061                  * Disable them because the transfer is complete.
1062                  */
1063                 if (XSpiPs_IsManualChipSelect(SpiPtr) == TRUE) {
1064                         ConfigReg = XSpiPs_ReadReg(
1065                                 SpiPtr->Config.BaseAddress,
1066                                  XSPIPS_CR_OFFSET);
1067                         ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
1068                         XSpiPs_WriteReg(
1069                                 SpiPtr->Config.BaseAddress,
1070                                  XSPIPS_CR_OFFSET, ConfigReg);
1071                 }
1072
1073                 SpiPtr->StatusHandler(SpiPtr->StatusRef,
1074                         XST_SPI_TRANSMIT_UNDERRUN, BytesDone);
1075         }
1076
1077 }
1078
1079 /*****************************************************************************/
1080 /**
1081 *
1082 * Aborts a transfer in progress by disabling the device and resetting the FIFOs
1083 * if present. The byte counts are cleared, the busy flag is cleared, and mode
1084 * fault is cleared.
1085 *
1086 * @param        InstancePtr is a pointer to the XSpiPs instance.
1087 *
1088 * @return       None.
1089 *
1090 * @note
1091 *
1092 * This function does a read/modify/write of the Config register. The user of
1093 * this function needs to take care of critical sections.
1094 *
1095 ******************************************************************************/
1096 void XSpiPs_Abort(XSpiPs *InstancePtr)
1097 {
1098
1099         u8 Temp;
1100         u32 Check;
1101         XSpiPs_Disable(InstancePtr);
1102
1103         /*
1104          * Clear the RX FIFO and drop any data.
1105          */
1106         Check = (XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
1107                 XSPIPS_SR_OFFSET) & XSPIPS_IXR_RXNEMPTY_MASK);
1108         while (Check != (u32)0U) {
1109                 Temp = (u8)XSpiPs_RecvByte(InstancePtr->Config.BaseAddress);
1110                 if(Temp != (u8)0U){
1111                 }
1112                 Check = (XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
1113                 XSPIPS_SR_OFFSET) & XSPIPS_IXR_RXNEMPTY_MASK);
1114         }
1115
1116         /*
1117          * Clear mode fault condition.
1118          */
1119         XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
1120                         XSPIPS_SR_OFFSET,
1121                         XSPIPS_IXR_MODF_MASK);
1122
1123         InstancePtr->RemainingBytes = 0U;
1124         InstancePtr->RequestedBytes = 0U;
1125         InstancePtr->IsBusy = FALSE;
1126 }