1 /******************************************************************************
3 * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
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
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.
31 ******************************************************************************/
32 /*****************************************************************************/
37 * Contains implements the interface functions of the XSpiPs driver.
38 * See xspips.h for a detailed description of the device and driver.
41 * MODIFICATION HISTORY:
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.
70 ******************************************************************************/
72 /***************************** Include Files *********************************/
76 /************************** Constant Definitions *****************************/
79 /**************************** Type Definitions *******************************/
82 /***************** Macros (Inline Functions) Definitions *********************/
84 /****************************************************************************/
87 * Send one byte to the currently selected slave. A byte of data is written to
88 * transmit FIFO/register.
90 * @param BaseAddress is the base address of the device
94 * @note C-Style signature:
95 * void XSpiPs_SendByte(u32 BaseAddress, u8 Data);
97 *****************************************************************************/
98 #define XSpiPs_SendByte(BaseAddress, Data) \
99 XSpiPs_Out32((BaseAddress) + (u32)XSPIPS_TXD_OFFSET, (u32)(Data))
101 /****************************************************************************/
104 * Receive one byte from the device's receive FIFO/register. It is assumed
105 * that the byte is already available.
107 * @param BaseAddress is the base address of the device
109 * @return The byte retrieved from the receive FIFO/register.
111 * @note C-Style signature:
112 * u8 XSpiPs_RecvByte(u32 BaseAddress);
114 *****************************************************************************/
115 #define XSpiPs_RecvByte(BaseAddress) \
116 XSpiPs_In32((u32)((BaseAddress) + (u32)XSPIPS_RXD_OFFSET))
118 /************************** Function Prototypes ******************************/
120 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
123 /************************** Variable Definitions *****************************/
126 /*****************************************************************************/
129 * Initializes a specific XSpiPs instance such that the driver is ready to use.
131 * The state of the device after initialization is:
132 * - Device is disabled
134 * - Active high clock polarity
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.
153 * - XST_SUCCESS if successful.
154 * - XST_DEVICE_IS_STARTED if the device is already started.
155 * It must be stopped to re-initialize.
159 ******************************************************************************/
160 s32 XSpiPs_CfgInitialize(XSpiPs *InstancePtr, XSpiPs_Config *ConfigPtr,
164 Xil_AssertNonvoid(InstancePtr != NULL);
165 Xil_AssertNonvoid(ConfigPtr != NULL);
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.
173 if (InstancePtr->IsBusy == TRUE) {
174 Status = (s32)XST_DEVICE_IS_STARTED;
178 * Set some default values.
180 InstancePtr->IsBusy = FALSE;
182 InstancePtr->Config.BaseAddress = EffectiveAddr;
183 InstancePtr->StatusHandler = StubStatusHandler;
185 InstancePtr->SendBufferPtr = NULL;
186 InstancePtr->RecvBufferPtr = NULL;
187 InstancePtr->RequestedBytes = 0U;
188 InstancePtr->RemainingBytes = 0U;
189 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
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.
196 XSpiPs_Reset(InstancePtr);
197 Status = (s32)XST_SUCCESS;
204 /*****************************************************************************/
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
212 * The upper layer software is responsible for re-configuring (if necessary)
213 * and restarting the SPI device after the reset.
215 * @param InstancePtr is a pointer to the XSpiPs instance.
221 ******************************************************************************/
222 void XSpiPs_Reset(XSpiPs *InstancePtr)
224 Xil_AssertVoid(InstancePtr != NULL);
225 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
228 * Abort any transfer that is in progress
230 XSpiPs_Abort(InstancePtr);
233 * Reset any values that are not reset by the hardware reset such that
234 * the software state matches the hardware device
236 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_CR_OFFSET,
237 XSPIPS_CR_RESET_STATE);
241 /*****************************************************************************/
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.
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:
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.
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.
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.
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.
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.
285 * This function is non-blocking. As a master, the SetSlaveSelect function must
286 * be called prior to this function.
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
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.
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.
308 ******************************************************************************/
309 s32 XSpiPs_Transfer(XSpiPs *InstancePtr, u8 *SendBufPtr,
310 u8 *RecvBufPtr, u32 ByteCount)
317 * The RecvBufPtr argument can be null
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);
325 * Check whether there is another transfer in progress. Not thread-safe.
327 if (InstancePtr->IsBusy == TRUE) {
328 StatusTransfer = (s32)XST_DEVICE_BUSY;
332 * Set the busy flag, which will be cleared in the ISR when the
333 * transfer is entirely done.
335 InstancePtr->IsBusy = TRUE;
338 * Set up buffer pointers.
340 InstancePtr->SendBufferPtr = SendBufPtr;
341 InstancePtr->RecvBufferPtr = RecvBufPtr;
343 InstancePtr->RequestedBytes = ByteCount;
344 InstancePtr->RemainingBytes = ByteCount;
347 * If manual chip select mode, initialize the slave select value.
349 if (XSpiPs_IsManualChipSelect(InstancePtr) != FALSE) {
350 ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
353 * Set the slave select value.
355 ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK);
356 ConfigReg |= InstancePtr->SlaveSelect;
357 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
358 XSPIPS_CR_OFFSET, ConfigReg);
364 XSpiPs_Enable(InstancePtr);
367 * Clear all the interrrupts.
369 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_SR_OFFSET,
370 XSPIPS_IXR_WR_TO_CLR_MASK);
373 * Fill the TXFIFO with as many bytes as it will take (or as many as
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--;
386 * Enable interrupts (connecting to the interrupt controller and
387 * enabling interrupts should have been done by the caller).
389 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
390 XSPIPS_IER_OFFSET, XSPIPS_IXR_DFLT_MASK);
393 * If master mode and manual start mode, issue manual start command
394 * to start the transfer.
396 if ((XSpiPs_IsManualStart(InstancePtr) == TRUE)
397 && (XSpiPs_IsMaster(InstancePtr) == TRUE)) {
398 ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
400 ConfigReg |= XSPIPS_CR_MANSTRT_MASK;
401 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
402 XSPIPS_CR_OFFSET, ConfigReg);
404 StatusTransfer = (s32)XST_SUCCESS;
406 return StatusTransfer;
409 /*****************************************************************************/
411 * Transfers specified data on the SPI bus in polled mode.
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:
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.
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.
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.
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.
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
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.
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.
462 ******************************************************************************/
463 s32 XSpiPs_PolledTransfer(XSpiPs *InstancePtr, u8 *SendBufPtr,
464 u8 *RecvBufPtr, u32 ByteCount)
474 * The RecvBufPtr argument can be NULL.
476 Xil_AssertNonvoid(InstancePtr != NULL);
477 Xil_AssertNonvoid(SendBufPtr != NULL);
478 Xil_AssertNonvoid(ByteCount > 0U);
479 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
482 * Check whether there is another transfer in progress. Not thread-safe.
484 if (InstancePtr->IsBusy == TRUE) {
485 Status_Polled = (s32)XST_DEVICE_BUSY;
489 * Set the busy flag, which will be cleared when the transfer is
492 InstancePtr->IsBusy = TRUE;
495 * Set up buffer pointers.
497 InstancePtr->SendBufferPtr = SendBufPtr;
498 InstancePtr->RecvBufferPtr = RecvBufPtr;
500 InstancePtr->RequestedBytes = ByteCount;
501 InstancePtr->RemainingBytes = ByteCount;
504 * If manual chip select mode, initialize the slave select value.
506 if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) {
507 ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
510 * Set the slave select value.
512 ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK);
513 ConfigReg |= InstancePtr->SlaveSelect;
514 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
515 XSPIPS_CR_OFFSET, ConfigReg);
521 XSpiPs_Enable(InstancePtr);
523 while((InstancePtr->RemainingBytes > (u32)0U) ||
524 (InstancePtr->RequestedBytes > (u32)0U)) {
527 * Fill the TXFIFO with as many bytes as it will take (or as
528 * many as we have to send).
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--;
540 * If master mode and manual start mode, issue manual start
541 * command to start the transfer.
543 if ((XSpiPs_IsManualStart(InstancePtr) == TRUE)
544 && (XSpiPs_IsMaster(InstancePtr) == TRUE)) {
545 ConfigReg = XSpiPs_ReadReg(
546 InstancePtr->Config.BaseAddress,
548 ConfigReg |= XSPIPS_CR_MANSTRT_MASK;
549 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
550 XSPIPS_CR_OFFSET, ConfigReg);
554 * Wait for the transfer to finish by polling Tx fifo status.
556 CheckTransfer = (u32)0U;
557 while (CheckTransfer == 0U){
558 StatusReg = XSpiPs_ReadReg(
559 InstancePtr->Config.BaseAddress,
561 if ( (StatusReg & XSPIPS_IXR_MODF_MASK) != 0U) {
563 * Clear the mode fail bit
566 InstancePtr->Config.BaseAddress,
568 XSPIPS_IXR_MODF_MASK);
569 return (s32)XST_SEND_ERROR;
571 CheckTransfer = (StatusReg &
572 XSPIPS_IXR_TXOW_MASK);
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).
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;
592 InstancePtr->RequestedBytes--;
598 * Clear the slave selects now, before terminating the transfer.
600 if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) {
601 ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
603 ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
604 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
605 XSPIPS_CR_OFFSET, ConfigReg);
609 * Clear the busy flag.
611 InstancePtr->IsBusy = FALSE;
614 * Disable the device.
616 XSpiPs_Disable(InstancePtr);
617 Status_Polled = (s32)XST_SUCCESS;
619 return Status_Polled;
622 /*****************************************************************************/
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
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
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.
644 * - XST_SUCCESS if the slave is selected or deselected
646 * - XST_DEVICE_BUSY if a transfer is in progress, slave cannot be
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.
655 ******************************************************************************/
656 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel)
660 Xil_AssertNonvoid(InstancePtr != NULL);
661 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
662 Xil_AssertNonvoid(SlaveSel <= XSPIPS_CR_SSCTRL_MAXIMUM);
665 * Do not allow the slave select to change while a transfer is in
666 * progress. Not thread-safe.
668 if (InstancePtr->IsBusy == TRUE) {
669 Status_Slave = (s32)XST_DEVICE_BUSY;
672 * If decode slave select option is set,
673 * then set slave select value directly.
674 * Update the Instance structure member.
676 if ( XSpiPs_IsDecodeSSelect( InstancePtr ) == TRUE) {
677 InstancePtr->SlaveSelect = ((u32)SlaveSel) << XSPIPS_CR_SSCTRL_SHIFT;
681 * Set the bit position to low using SlaveSel. Update the Instance
684 InstancePtr->SlaveSelect = ((~(1U << SlaveSel)) & \
685 XSPIPS_CR_SSCTRL_MAXIMUM) << XSPIPS_CR_SSCTRL_SHIFT;
689 * Read the config register, update the slave select value and write
690 * back to config register.
692 ConfigReg = XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
694 ConfigReg &= (u32)(~XSPIPS_CR_SSCTRL_MASK);
695 ConfigReg |= InstancePtr->SlaveSelect;
696 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress, XSPIPS_CR_OFFSET,
698 Status_Slave = (s32)XST_SUCCESS;
703 /*****************************************************************************/
706 * Gets the current slave select setting for the SPI device.
708 * @param InstancePtr is a pointer to the XSpiPs instance.
710 * @return The slave number selected (starting from 0).
714 ******************************************************************************/
715 u8 XSpiPs_GetSlaveSelect(XSpiPs *InstancePtr)
720 Xil_AssertNonvoid(InstancePtr != NULL);
721 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
723 ConfigReg = InstancePtr->SlaveSelect;
724 ConfigReg &= XSPIPS_CR_SSCTRL_MASK;
725 ConfigReg >>= XSPIPS_CR_SSCTRL_SHIFT;
726 ConfigReg &= XSPIPS_CR_SSCTRL_MAXIMUM;
729 * If decode slave select option is set, then read value directly.
731 if ( XSpiPs_IsDecodeSSelect( InstancePtr ) == TRUE) {
732 SlaveSel = ConfigReg;
737 * Get the slave select value
739 if(ConfigReg == 0x0FU) {
746 * Get selected slave number (0,1 or 2)
748 SlaveSel = ((~ConfigReg) & XSPIPS_CR_SSCTRL_MAXIMUM)/2;
754 /*****************************************************************************/
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.
764 * XST_SPI_MODE_FAULT A mode fault error occurred, meaning the device
765 * is selected as slave while being a master.
767 * XST_SPI_TRANSFER_DONE The requested data transfer is done
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.
776 * XST_SPI_RECEIVE_OVERRUN The SPI device lost data. Data was received
777 * but the receive data register/FIFO was full.
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).
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.
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.
797 ******************************************************************************/
798 void XSpiPs_SetStatusHandler(XSpiPs *InstancePtr, void *CallBackRef,
799 XSpiPs_StatusHandler FunctionPtr)
801 Xil_AssertVoid(InstancePtr != NULL);
802 Xil_AssertVoid(FunctionPtr != NULL);
803 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
805 InstancePtr->StatusHandler = FunctionPtr;
806 InstancePtr->StatusRef = CallBackRef;
809 /*****************************************************************************/
812 * This is a stub for the status callback. The stub is here in case the upper
813 * layers forget to set the handler.
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
824 ******************************************************************************/
825 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
832 Xil_AssertVoidAlways();
835 /*****************************************************************************/
838 * The interrupt handler for SPI interrupts. This function must be connected
839 * by the user to an interrupt controller.
841 * The interrupts that are handled are:
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.
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.
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.
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.
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.
868 * @param InstancePtr is a pointer to the XSpiPs instance.
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.
878 ******************************************************************************/
879 void XSpiPs_InterruptHandler(XSpiPs *InstancePtr)
881 XSpiPs *SpiPtr = InstancePtr;
884 u32 BytesDone; /* Number of bytes done so far. */
886 Xil_AssertVoid(InstancePtr != NULL);
887 Xil_AssertVoid(SpiPtr->IsReady == XIL_COMPONENT_IS_READY);
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.
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);
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.
908 if ((u32)XSPIPS_IXR_MODF_MASK == (u32)(IntrStatus & XSPIPS_IXR_MODF_MASK)) {
909 BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
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.
919 XSpiPs_Abort(SpiPtr);
921 SpiPtr->StatusHandler(SpiPtr->StatusRef, XST_SPI_MODE_FAULT,
924 return; /* Do not continue servicing other interrupts. */
928 if ((IntrStatus & XSPIPS_IXR_TXOW_MASK) != 0U) {
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.
941 TransCount = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
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;
949 SpiPtr->RequestedBytes--;
954 * Fill the TXFIFO until data exists, otherwise fill upto
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--;
966 if ((SpiPtr->RemainingBytes == 0U) &&
967 (SpiPtr->RequestedBytes == 0U)) {
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.
974 XSpiPs_WriteReg(SpiPtr->Config.BaseAddress,
975 XSPIPS_IDR_OFFSET, XSPIPS_IXR_DFLT_MASK);
978 * Disable slave select lines as the transfer
981 if (XSpiPs_IsManualChipSelect(InstancePtr) == TRUE) {
982 ConfigReg = XSpiPs_ReadReg(
983 SpiPtr->Config.BaseAddress,
985 ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
987 SpiPtr->Config.BaseAddress,
988 XSPIPS_CR_OFFSET, ConfigReg);
992 * Clear the busy flag.
994 SpiPtr->IsBusy = FALSE;
997 * Disable the device.
999 XSpiPs_Disable(SpiPtr);
1002 * Inform the Transfer done to upper layers.
1004 SpiPtr->StatusHandler(SpiPtr->StatusRef,
1005 XST_SPI_TRANSFER_DONE,
1006 SpiPtr->RequestedBytes);
1009 * Enable the TXOW interrupt.
1011 XSpiPs_WriteReg(SpiPtr->Config.BaseAddress,
1012 XSPIPS_IER_OFFSET, XSPIPS_IXR_TXOW_MASK);
1014 * Start the transfer by not inhibiting the transmitter
1017 if ((XSpiPs_IsManualStart(SpiPtr) == TRUE)
1018 && (XSpiPs_IsMaster(SpiPtr) == TRUE)) {
1019 ConfigReg = XSpiPs_ReadReg(
1020 SpiPtr->Config.BaseAddress,
1022 ConfigReg |= XSPIPS_CR_MANSTRT_MASK;
1024 SpiPtr->Config.BaseAddress,
1025 XSPIPS_CR_OFFSET, ConfigReg);
1031 * Check for overflow and underflow errors.
1033 if ((IntrStatus & XSPIPS_IXR_RXOVR_MASK) != 0U) {
1034 BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
1035 SpiPtr->IsBusy = FALSE;
1038 * The Slave select lines are being manually controlled.
1039 * Disable them because the transfer is complete.
1041 if (XSpiPs_IsManualChipSelect(SpiPtr) == TRUE) {
1042 ConfigReg = XSpiPs_ReadReg(
1043 SpiPtr->Config.BaseAddress,
1045 ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
1047 SpiPtr->Config.BaseAddress,
1048 XSPIPS_CR_OFFSET, ConfigReg);
1051 SpiPtr->StatusHandler(SpiPtr->StatusRef,
1052 XST_SPI_RECEIVE_OVERRUN, BytesDone);
1055 if ((IntrStatus & XSPIPS_IXR_TXUF_MASK) != 0U) {
1056 BytesDone = SpiPtr->RequestedBytes - SpiPtr->RemainingBytes;
1058 SpiPtr->IsBusy = FALSE;
1060 * The Slave select lines are being manually controlled.
1061 * Disable them because the transfer is complete.
1063 if (XSpiPs_IsManualChipSelect(SpiPtr) == TRUE) {
1064 ConfigReg = XSpiPs_ReadReg(
1065 SpiPtr->Config.BaseAddress,
1067 ConfigReg |= XSPIPS_CR_SSCTRL_MASK;
1069 SpiPtr->Config.BaseAddress,
1070 XSPIPS_CR_OFFSET, ConfigReg);
1073 SpiPtr->StatusHandler(SpiPtr->StatusRef,
1074 XST_SPI_TRANSMIT_UNDERRUN, BytesDone);
1079 /*****************************************************************************/
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
1086 * @param InstancePtr is a pointer to the XSpiPs instance.
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.
1095 ******************************************************************************/
1096 void XSpiPs_Abort(XSpiPs *InstancePtr)
1101 XSpiPs_Disable(InstancePtr);
1104 * Clear the RX FIFO and drop any data.
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);
1112 Check = (XSpiPs_ReadReg(InstancePtr->Config.BaseAddress,
1113 XSPIPS_SR_OFFSET) & XSPIPS_IXR_RXNEMPTY_MASK);
1117 * Clear mode fault condition.
1119 XSpiPs_WriteReg(InstancePtr->Config.BaseAddress,
1121 XSPIPS_IXR_MODF_MASK);
1123 InstancePtr->RemainingBytes = 0U;
1124 InstancePtr->RequestedBytes = 0U;
1125 InstancePtr->IsBusy = FALSE;