1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef FSL_SPI_DMA_H_
9 #define FSL_SPI_DMA_H_
10 
11 #include "fsl_dma.h"
12 #include "fsl_spi.h"
13 
14 /*!
15  * @addtogroup spi_dma_driver
16  * @{
17  */
18 
19 /*! @file */
20 
21 /*******************************************************************************
22  * Definitions
23  ******************************************************************************/
24 
25 /*! @name Driver version */
26 /*! @{ */
27 /*! @brief SPI DMA driver version 2.1.1. */
28 #define FSL_SPI_DMA_DRIVER_VERSION (MAKE_VERSION(2, 2, 1))
29 /*! @} */
30 
31 typedef struct _spi_dma_handle spi_dma_handle_t;
32 
33 /*! @brief SPI DMA callback called at the end of transfer. */
34 typedef void (*spi_dma_callback_t)(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData);
35 
36 /*! @brief SPI DMA transfer handle, users should not touch the content of the handle.*/
37 struct _spi_dma_handle
38 {
39     volatile bool txInProgress;  /*!< Send transfer finished */
40     volatile bool rxInProgress;  /*!< Receive transfer finished */
41     uint8_t bytesPerFrame;       /*!< Bytes in a frame for SPI transfer */
42     uint8_t lastwordBytes;       /*!< The Bytes of lastword for master*/
43     dma_handle_t *txHandle;      /*!< DMA handler for SPI send */
44     dma_handle_t *rxHandle;      /*!< DMA handler for SPI receive */
45     spi_dma_callback_t callback; /*!< Callback for SPI DMA transfer */
46     void *userData;              /*!< User Data for SPI DMA callback */
47     uint32_t state;              /*!< Internal state of SPI DMA transfer */
48     size_t transferSize;         /*!< Bytes need to be transfer */
49     uint32_t instance;           /*!< Index of SPI instance*/
50     const uint8_t *txNextData;   /*!< The pointer of next time tx data*/
51     const uint8_t *txEndData;    /*!< The pointer of end of data*/
52     uint8_t *rxNextData;         /*!< The pointer of next time rx data*/
53     uint8_t *rxEndData;          /*!< The pointer of end of rx data*/
54     uint32_t dataBytesEveryTime; /*!< Bytes in a time for DMA transfer, default is DMA_MAX_TRANSFER_COUNT */
55 };
56 
57 /*******************************************************************************
58  * APIs
59  ******************************************************************************/
60 
61 #if defined(__cplusplus)
62 extern "C" {
63 #endif
64 
65 /*!
66  * @name DMA Transactional
67  * @{
68  */
69 
70 /*!
71  * @brief Initialize the SPI master DMA handle.
72  *
73  * This function initializes the SPI master DMA handle which can be used for other SPI master transactional APIs.
74  * Usually, for a specified SPI instance, user need only call this API once to get the initialized handle.
75  *
76  * @param base SPI peripheral base address.
77  * @param handle SPI handle pointer.
78  * @param callback User callback function called at the end of a transfer.
79  * @param userData User data for callback.
80  * @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users.
81  * @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users.
82  */
83 status_t SPI_MasterTransferCreateHandleDMA(SPI_Type *base,
84                                            spi_dma_handle_t *handle,
85                                            spi_dma_callback_t callback,
86                                            void *userData,
87                                            dma_handle_t *txHandle,
88                                            dma_handle_t *rxHandle);
89 
90 /*!
91  * @brief Perform a non-blocking SPI transfer using DMA.
92  *
93  * @note This interface returned immediately after transfer initiates, users should call
94  * SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished.
95  *
96  * @param base SPI peripheral base address.
97  * @param handle SPI DMA handle pointer.
98  * @param xfer Pointer to dma transfer structure.
99  * @retval kStatus_Success Successfully start a transfer.
100  * @retval kStatus_InvalidArgument Input argument is invalid.
101  * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
102  */
103 status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer);
104 
105 /*!
106  * @brief Transfers a block of data using a DMA method.
107  *
108  * This function using polling way to do the first half transimission and using DMA way to
109  * do the srcond half transimission, the transfer mechanism is half-duplex.
110  * When do the second half transimission, code will return right away. When all data is transferred,
111  * the callback function is called.
112  *
113  * @param base SPI base pointer
114  * @param handle A pointer to the spi_master_dma_handle_t structure which stores the transfer state.
115  * @param xfer A pointer to the spi_half_duplex_transfer_t structure.
116  * @return status of status_t.
117  */
118 status_t SPI_MasterHalfDuplexTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_half_duplex_transfer_t *xfer);
119 
120 /*!
121  * @brief Initialize the SPI slave DMA handle.
122  *
123  * This function initializes the SPI slave DMA handle which can be used for other SPI master transactional APIs.
124  * Usually, for a specified SPI instance, user need only call this API once to get the initialized handle.
125  *
126  * @param base SPI peripheral base address.
127  * @param handle SPI handle pointer.
128  * @param callback User callback function called at the end of a transfer.
129  * @param userData User data for callback.
130  * @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users.
131  * @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users.
132  */
SPI_SlaveTransferCreateHandleDMA(SPI_Type * base,spi_dma_handle_t * handle,spi_dma_callback_t callback,void * userData,dma_handle_t * txHandle,dma_handle_t * rxHandle)133 static inline status_t SPI_SlaveTransferCreateHandleDMA(SPI_Type *base,
134                                                         spi_dma_handle_t *handle,
135                                                         spi_dma_callback_t callback,
136                                                         void *userData,
137                                                         dma_handle_t *txHandle,
138                                                         dma_handle_t *rxHandle)
139 {
140     return SPI_MasterTransferCreateHandleDMA(base, handle, callback, userData, txHandle, rxHandle);
141 }
142 
143 /*!
144  * @brief Perform a non-blocking SPI transfer using DMA.
145  *
146  * @note This interface returned immediately after transfer initiates, users should call
147  * SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished.
148  *
149  * @param base SPI peripheral base address.
150  * @param handle SPI DMA handle pointer.
151  * @param xfer Pointer to dma transfer structure.
152  * @retval kStatus_Success Successfully start a transfer.
153  * @retval kStatus_InvalidArgument Input argument is invalid.
154  * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
155  */
SPI_SlaveTransferDMA(SPI_Type * base,spi_dma_handle_t * handle,spi_transfer_t * xfer)156 static inline status_t SPI_SlaveTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer)
157 {
158     return SPI_MasterTransferDMA(base, handle, xfer);
159 }
160 
161 /*!
162  * @brief Abort a SPI transfer using DMA.
163  *
164  * @param base SPI peripheral base address.
165  * @param handle SPI DMA handle pointer.
166  */
167 void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle);
168 
169 /*!
170  * @brief Gets the master DMA transfer remaining bytes.
171  *
172  * This function gets the master DMA transfer remaining bytes.
173  *
174  * @param base SPI peripheral base address.
175  * @param handle A pointer to the spi_dma_handle_t structure which stores the transfer state.
176  * @param count A number of bytes transferred by the non-blocking transaction.
177  * @return status of status_t.
178  */
179 status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count);
180 
181 /*!
182  * @brief Abort a SPI transfer using DMA.
183  *
184  * @param base SPI peripheral base address.
185  * @param handle SPI DMA handle pointer.
186  */
SPI_SlaveTransferAbortDMA(SPI_Type * base,spi_dma_handle_t * handle)187 static inline void SPI_SlaveTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle)
188 {
189     SPI_MasterTransferAbortDMA(base, handle);
190 }
191 
192 /*!
193  * @brief Gets the slave DMA transfer remaining bytes.
194  *
195  * This function gets the slave DMA transfer remaining bytes.
196  *
197  * @param base SPI peripheral base address.
198  * @param handle A pointer to the spi_dma_handle_t structure which stores the transfer state.
199  * @param count A number of bytes transferred by the non-blocking transaction.
200  * @return status of status_t.
201  */
SPI_SlaveTransferGetCountDMA(SPI_Type * base,spi_dma_handle_t * handle,size_t * count)202 static inline status_t SPI_SlaveTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count)
203 {
204     return SPI_MasterTransferGetCountDMA(base, handle, count);
205 }
206 
207 /*! @} */
208 
209 #if defined(__cplusplus)
210 }
211 #endif
212 
213 /*! @} */
214 
215 #endif /* FSL_SPI_DMA_H_*/
216