1 /**
2 * \file SPI_drv.c
3 *
4 * \brief SPI Driver high level APIs.
5 *
6 * This file contains the driver APIs for SPI.
7 */
9 /*
10 * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the
22 * distribution.
23 *
24 * Neither the name of Texas Instruments Incorporated nor the names of
25 * its contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 */
42 #include <ti/drv/spi/MCSPI.h>
43 #include <stdint.h>
44 #include <stdlib.h>
45 #include <ti/drv/spi/src/SPI_osal.h>
48 /* Externs */
49 extern const SPI_config_list SPI_config;
50 extern MCSPI_config_list MCSPI_config;
52 /* Used to check status and initialization */
53 static int32_t SPI_count = (-((int32_t)1));
55 static void *spiMutex = NULL;
57 /* Default SPI parameters structure */
58 const SPI_Params SPI_defaultParams = {
59 SPI_MODE_BLOCKING, /* transferMode */
60 0U, /* transferTimeout */
61 NULL, /* transferCallbackFxn */
62 SPI_MASTER, /* mode */
63 1000000, /* bitRate */
64 8, /* dataSize */
65 SPI_POL0_PHA0, /* frameFormat */
66 NULL /* custom */
67 };
69 /* Default MCSPI parameters structure */
70 const MCSPI_Params MCSPI_defaultParams = {
71 SPI_MODE_BLOCKING, /* transferMode */
72 0U, /* transferTimeout */
73 NULL, /* transferCallbackFxn */
74 SPI_MASTER, /* mode */
75 1000000, /* bitRate */
76 8, /* dataSize */
77 SPI_POL0_PHA0, /* frameFormat */
78 NULL /* custom */
79 };
81 /*
82 * ======== SPI_close ========
83 */
84 void SPI_close(SPI_Handle handle)
85 {
86 if (handle != NULL)
87 {
88 if (spiMutex != NULL)
89 {
90 /* Acquire the the SPI driver semaphore */
91 (void)SPI_osalPendLock(spiMutex, SemaphoreP_WAIT_FOREVER);
92 }
94 handle->fxnTablePtr->closeFxn(handle);
96 if (spiMutex != NULL)
97 {
98 /* Release the the SPI driver semaphorel */
99 (void)SPI_osalPostLock(spiMutex);
100 }
101 }
102 }
104 /*
105 * ======== SPI_control ========
106 */
107 int32_t SPI_control(SPI_Handle handle, uint32_t cmd, void *arg)
108 {
109 int32_t retVal = SPI_STATUS_ERROR;
111 if (handle != NULL)
112 {
113 retVal = handle->fxnTablePtr->controlFxn(handle, cmd, arg);
114 }
116 return (retVal);
117 }
119 /*
120 * ======== SPI_init ========
121 */
122 void SPI_init(void)
123 {
124 SemaphoreP_Params semParams;
126 if (SPI_count == (-((int32_t)1))) {
127 /* Call each driver's init function */
128 for (SPI_count = 0; (SPI_count < (int32_t)SPI_MAX_CONFIG_CNT) && (SPI_config[SPI_count].fxnTablePtr != NULL); SPI_count++) {
129 SPI_config[SPI_count].fxnTablePtr->spiInitFxn((SPI_Handle)&(SPI_config[SPI_count]));
130 }
131 }
133 /*
134 * Construct thread safe handles for SPI driver level
135 * Semaphore to provide exclusive access to the SPI APIs
136 */
137 if (spiMutex == NULL)
138 {
139 SPI_osalSemParamsInit(&semParams);
140 semParams.mode = SemaphoreP_Mode_BINARY;
141 spiMutex = SPI_osalCreateBlockingLock(1U, &semParams);
142 }
143 }
145 /*
146 * ======== SPI_open ========
147 */
148 SPI_Handle SPI_open(uint32_t index, SPI_Params *params)
149 {
150 SPI_Handle handle = NULL;
152 if ((SPI_Handle)&(SPI_config[index]) != NULL)
153 {
154 /* Get handle for this driver instance */
155 handle = (SPI_Handle)&(SPI_config[index]);
157 if (spiMutex != NULL)
158 {
159 /* Acquire the the SPI driver semaphore */
160 (void)SPI_osalPendLock(spiMutex, SemaphoreP_WAIT_FOREVER);
161 }
163 handle = handle->fxnTablePtr->openFxn(handle, params);
165 if (spiMutex != NULL)
166 {
167 /* Release the the SPI driver semaphorel */
168 (void)SPI_osalPostLock(spiMutex);
169 }
170 }
172 return (handle);
173 }
175 /*
176 * ======== SPI_Params_init ========
177 */
178 void SPI_Params_init(SPI_Params *params)
179 {
180 if (params != NULL)
181 {
182 *params = SPI_defaultParams;
183 }
184 }
186 /*
187 * ======== SPI_serviceISR ========
188 */
189 void SPI_serviceISR(SPI_Handle handle)
190 {
191 if (handle != NULL)
192 {
193 handle->fxnTablePtr->serviceISRFxn(handle);
194 }
195 }
197 /*
198 * ======== SPI_transfer ========
199 */
200 bool SPI_transfer(SPI_Handle handle, SPI_Transaction *transaction)
201 {
202 bool retVal = (bool)false;
204 if ((handle != NULL) && (transaction != NULL))
205 {
206 retVal = handle->fxnTablePtr->transferFxn(handle, transaction);
207 }
209 return (retVal);
210 }
212 /*
213 * ======== SPI_transferCancel ========
214 */
215 void SPI_transferCancel(SPI_Handle handle)
216 {
217 if (handle != NULL)
218 {
219 handle->fxnTablePtr->transferCancelFxn(handle);
220 }
221 }
223 /*
224 * ======== MCSPI_close ========
225 */
226 void MCSPI_close(MCSPI_Handle handle)
227 {
228 if (handle != NULL)
229 {
230 if (spiMutex != NULL)
231 {
232 /* Acquire the the SPI driver semaphore */
233 (void)SPI_osalPendLock(spiMutex, SemaphoreP_WAIT_FOREVER);
234 }
236 handle->fxnTablePtr->closeFxn(handle);
238 if (spiMutex != NULL)
239 {
240 /* Release the the SPI driver semaphorel */
241 (void)SPI_osalPostLock(spiMutex);
242 }
243 }
244 }
246 /*
247 * ======== MCSPI_control ========
248 */
249 int32_t MCSPI_control(MCSPI_Handle handle, uint32_t cmd, void *arg)
250 {
251 int32_t retVal = SPI_STATUS_ERROR;
253 if (handle != NULL)
254 {
255 retVal = handle->fxnTablePtr->controlFxn(handle, cmd, arg);
256 }
258 return (retVal);
259 }
261 /*
262 * ======== MCSPI_init ========
263 */
264 void MCSPI_init(void)
265 {
266 SPI_init();
267 }
269 /*
270 * ======== MCSPI_open ========
271 */
272 MCSPI_Handle MCSPI_open(uint32_t index, uint32_t channel, MCSPI_Params *params)
273 {
274 MCSPI_Handle handle = NULL;
276 if ((MCSPI_Handle)&(MCSPI_config[index][channel]) != NULL)
277 {
278 /* Get handle for this driver instance */
279 handle = (MCSPI_Handle)&(MCSPI_config[index][channel]);
281 if (spiMutex != NULL)
282 {
283 /* Acquire the the SPI driver semaphore */
284 (void)SPI_osalPendLock(spiMutex, SemaphoreP_WAIT_FOREVER);
285 }
287 handle = handle->fxnTablePtr->openFxn(handle, params);
289 if (spiMutex != NULL)
290 {
291 /* Release the the SPI driver semaphorel */
292 (void)SPI_osalPostLock(spiMutex);
293 }
294 }
296 return (handle);
297 }
299 /*
300 * ======== MCSPI_Params_init ========
301 */
302 void MCSPI_Params_init(MCSPI_Params *params)
303 {
304 if (params != NULL)
305 {
306 *params = MCSPI_defaultParams;
307 }
308 }
310 /*
311 * ======== _transfer ========
312 */
313 bool MCSPI_transfer(MCSPI_Handle handle, SPI_Transaction *transaction)
314 {
315 bool retVal = (bool)false;
317 if ((handle != NULL) && (transaction != NULL))
318 {
319 retVal = handle->fxnTablePtr->transferFxn(handle, transaction);
320 }
322 return (retVal);
323 }
325 /*
326 * ======== _transferCancel ========
327 */
328 void MCSPI_transferCancel(MCSPI_Handle handle)
329 {
330 if (handle != NULL)
331 {
332 handle->fxnTablePtr->transferCancelFxn(handle);
333 }
334 }