Statistics
| Branch: | Tag: | Revision:

amiro-os / periphery-lld / aos_periphAL.c @ 9d8f1b9e

History | View | Annotate | Download (14.676 KB)

1 e545e620 Thomas Schöpping
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3 84f0ce9e Thomas Schöpping
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 e545e620 Thomas Schöpping

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19 dd56d656 Thomas Schöpping
#include <periphAL.h>
20 e545e620 Thomas Schöpping
21
/*============================================================================*/
22 1f94ac64 Thomas Schöpping
/* DEBUG                                                                      */
23
/*============================================================================*/
24
25 dd56d656 Thomas Schöpping
#if (AMIROOS_CFG_DBG == true)
26 1f94ac64 Thomas Schöpping
27 dd56d656 Thomas Schöpping
#include <amiroos.h>
28
#include <chprintf.h>
29 1f94ac64 Thomas Schöpping
30 dd56d656 Thomas Schöpping
void apalDbgAssertMsg(const bool c, const char* fmt, ...)
31
{
32
  if (!c) {
33
    va_list ap;
34 232ccea6 Thomas Schöpping
35 dd56d656 Thomas Schöpping
    va_start(ap, fmt);
36
    chvprintf((BaseSequentialStream*)&aos.iostream, fmt, ap);
37
    va_end(ap);
38
    chThdExit(MSG_RESET);
39
  }
40 1f94ac64 Thomas Schöpping
41 dd56d656 Thomas Schöpping
  return;
42
}
43 1f94ac64 Thomas Schöpping
44 dd56d656 Thomas Schöpping
int apalDbgPrintf(const char* fmt, ...)
45
{
46
  va_list ap;
47 b7ac1f29 Thomas Schöpping
48 dd56d656 Thomas Schöpping
  va_start(ap, fmt);
49
  const int chars = chvprintf((BaseSequentialStream*)&aos.iostream, fmt, ap);
50
  va_end(ap);
51 b7ac1f29 Thomas Schöpping
52 dd56d656 Thomas Schöpping
  return chars;
53
}
54 1f94ac64 Thomas Schöpping
55 7de0cc90 Thomas Schöpping
#endif /* (AMIROOS_CFG_DBG == true) */
56 1f94ac64 Thomas Schöpping
57
/*============================================================================*/
58 dd56d656 Thomas Schöpping
/* TIMING                                                                     */
59 e545e620 Thomas Schöpping
/*============================================================================*/
60
61 dd56d656 Thomas Schöpping
#if (AMIROOS_CFG_DBG == true)
62
63
void apalSleep(apalTime_t us)
64 e545e620 Thomas Schöpping
{
65
  // check if the specified time can be represented by the system
66 1f94ac64 Thomas Schöpping
  apalDbgAssert(us <= chTimeI2US(TIME_INFINITE));
67 e545e620 Thomas Schöpping
68 3940ba8a Thomas Schöpping
  const sysinterval_t interval = chTimeUS2I(us);
69 e545e620 Thomas Schöpping
  // TIME_IMMEDIATE makes no sense and would even cause system halt
70 3940ba8a Thomas Schöpping
  if (interval != TIME_IMMEDIATE) {
71
    chThdSleep(interval);
72 e545e620 Thomas Schöpping
  }
73 dd56d656 Thomas Schöpping
74 e545e620 Thomas Schöpping
  return;
75
}
76
77 dd56d656 Thomas Schöpping
#endif /* (AMIROOS_CFG_DBG == true) */
78
79 e545e620 Thomas Schöpping
/*============================================================================*/
80
/* GPIO                                                                       */
81
/*============================================================================*/
82
83 dd56d656 Thomas Schöpping
#if (HAL_USE_PAL == TRUE)
84
85
apalExitStatus_t apalGpioRead(apalGpio_t* gpio, apalGpioState_t* const val)
86 e545e620 Thomas Schöpping
{
87 1f94ac64 Thomas Schöpping
  apalDbgAssert(gpio != NULL);
88
  apalDbgAssert(val != NULL);
89 e545e620 Thomas Schöpping
90 3106e8cc Thomas Schöpping
  *val = (palReadLine(gpio->line) == PAL_HIGH) ? APAL_GPIO_HIGH : APAL_GPIO_LOW;
91 dd56d656 Thomas Schöpping
92 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
93
}
94
95 dd56d656 Thomas Schöpping
apalExitStatus_t apalGpioWrite(apalGpio_t* gpio, const apalGpioState_t val)
96 e545e620 Thomas Schöpping
{
97 1f94ac64 Thomas Schöpping
  apalDbgAssert(gpio != NULL);
98 e545e620 Thomas Schöpping
99 3106e8cc Thomas Schöpping
  // palWriteLine() is not guaranteed to be atomic, thus the scheduler is locked.
100 e545e620 Thomas Schöpping
  syssts_t sysstatus = chSysGetStatusAndLockX();
101 3106e8cc Thomas Schöpping
  palWriteLine(gpio->line, (val == APAL_GPIO_HIGH) ? PAL_HIGH : PAL_LOW);
102 e545e620 Thomas Schöpping
  chSysRestoreStatusX(sysstatus);
103 dd56d656 Thomas Schöpping
104 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
105
}
106
107 dd56d656 Thomas Schöpping
apalExitStatus_t apalGpioToggle(apalGpio_t* gpio)
108 e545e620 Thomas Schöpping
{
109 1f94ac64 Thomas Schöpping
  apalDbgAssert(gpio != NULL);
110 e545e620 Thomas Schöpping
111 3106e8cc Thomas Schöpping
  // palWriteLine() is not guaranteed to be atomic, thus the scheduler is locked.
112 e545e620 Thomas Schöpping
  syssts_t sysstatus = chSysGetStatusAndLockX();
113 3106e8cc Thomas Schöpping
  palWriteLine(gpio->line, (palReadLine(gpio->line) == PAL_HIGH) ? PAL_LOW : PAL_HIGH);
114 e545e620 Thomas Schöpping
  chSysRestoreStatusX(sysstatus);
115 dd56d656 Thomas Schöpping
116 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
117
}
118
119 dd56d656 Thomas Schöpping
apalExitStatus_t apalGpioIsInterruptEnabled(apalGpio_t* gpio, bool* const enabled)
120 232ccea6 Thomas Schöpping
{
121
  apalDbgAssert(gpio != NULL);
122
  apalDbgAssert(enabled != NULL);
123
124
  *enabled = palIsLineEventEnabledX(gpio->line);
125 dd56d656 Thomas Schöpping
126 232ccea6 Thomas Schöpping
  return APAL_STATUS_OK;
127
}
128
129 dd56d656 Thomas Schöpping
apalExitStatus_t apalControlGpioGet(const apalControlGpio_t* const cgpio, apalControlGpioState_t* const val)
130 e545e620 Thomas Schöpping
{
131 1f94ac64 Thomas Schöpping
  apalDbgAssert(cgpio != NULL);
132
  apalDbgAssert(cgpio->gpio != NULL);
133
  apalDbgAssert(val != NULL);
134 e545e620 Thomas Schöpping
135 3106e8cc Thomas Schöpping
  *val = ((palReadLine(cgpio->gpio->line) == PAL_HIGH) ^ (cgpio->meta.active == APAL_GPIO_ACTIVE_HIGH)) ? APAL_GPIO_OFF : APAL_GPIO_ON;
136 dd56d656 Thomas Schöpping
137 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
138
}
139
140 dd56d656 Thomas Schöpping
apalExitStatus_t apalControlGpioSet(const apalControlGpio_t* const cgpio, const apalControlGpioState_t val)
141 e545e620 Thomas Schöpping
{
142 1f94ac64 Thomas Schöpping
  apalDbgAssert(cgpio != NULL);
143
  apalDbgAssert(cgpio->gpio != NULL);
144
  apalDbgAssert(cgpio->meta.direction == APAL_GPIO_DIRECTION_OUTPUT || cgpio->meta.direction == APAL_GPIO_DIRECTION_BIDIRECTIONAL);
145 e545e620 Thomas Schöpping
146 3106e8cc Thomas Schöpping
  // palWriteLine() is not guaranteed to be atomic, thus the scheduler is locked.
147 e545e620 Thomas Schöpping
  syssts_t sysstatus = chSysGetStatusAndLockX();
148 3106e8cc Thomas Schöpping
  palWriteLine(cgpio->gpio->line, ((cgpio->meta.active == APAL_GPIO_ACTIVE_HIGH) ^ (val == APAL_GPIO_ON)) ? PAL_LOW : PAL_HIGH);
149 e545e620 Thomas Schöpping
  chSysRestoreStatusX(sysstatus);
150 dd56d656 Thomas Schöpping
151 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
152
}
153
154 dd56d656 Thomas Schöpping
apalExitStatus_t apalControlGpioSetInterrupt(const apalControlGpio_t* const cgpio, const bool enable)
155 232ccea6 Thomas Schöpping
{
156
  apalDbgAssert(cgpio != NULL);
157
  apalDbgAssert(cgpio->gpio != NULL);
158
159
  if (enable) {
160
    apalDbgAssert(pal_lld_get_line_event(cgpio->gpio->line) != NULL);
161
    palEnableLineEvent(cgpio->gpio->line, APAL2CH_EDGE(cgpio->meta.edge));
162
  } else {
163
    palDisableLineEvent(cgpio->gpio->line);
164
  }
165
166
  return APAL_STATUS_OK;
167
}
168
169 7de0cc90 Thomas Schöpping
#endif /* (HAL_USE_PAL == TRUE) */
170 e545e620 Thomas Schöpping
171
/*============================================================================*/
172
/* PWM                                                                        */
173
/*============================================================================*/
174
175 dd56d656 Thomas Schöpping
#if (HAL_USE_PWM == TRUE)
176
177
apalExitStatus_t apalPWMSet(apalPWMDriver_t* pwm, const apalPWMchannel_t channel, const apalPWMwidth_t width)
178 e545e620 Thomas Schöpping
{
179 1f94ac64 Thomas Schöpping
  apalDbgAssert(pwm != NULL);
180 e545e620 Thomas Schöpping
181
  pwmEnableChannel(pwm, (pwmchannel_t)channel, pwm->period * ((float)width / (float)APAL_PWM_WIDTH_MAX) + 0.5f);
182 dd56d656 Thomas Schöpping
183 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
184
}
185
186 dd56d656 Thomas Schöpping
apalExitStatus_t apalPWMGetFrequency(apalPWMDriver_t* pwm, apalPWMfrequency_t* const frequency)
187 e545e620 Thomas Schöpping
{
188 1f94ac64 Thomas Schöpping
  apalDbgAssert(pwm != NULL);
189
  apalDbgAssert(frequency != NULL);
190 e545e620 Thomas Schöpping
191
  *frequency = pwm->config->frequency;
192 dd56d656 Thomas Schöpping
193 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
194
}
195
196 dd56d656 Thomas Schöpping
apalExitStatus_t apalPWMGetPeriod(apalPWMDriver_t* pwm, apalPWMperiod_t* const period)
197 e545e620 Thomas Schöpping
{
198 1f94ac64 Thomas Schöpping
  apalDbgAssert(pwm != NULL);
199
  apalDbgAssert(period != NULL);
200 e545e620 Thomas Schöpping
201
  *period = pwm->period;
202 dd56d656 Thomas Schöpping
203 e545e620 Thomas Schöpping
  return APAL_STATUS_OK;
204
}
205
206 7de0cc90 Thomas Schöpping
#endif /* (HAL_USE_PWM == TRUE) */
207 e545e620 Thomas Schöpping
208
/*============================================================================*/
209
/* QEI                                                                        */
210
/*============================================================================*/
211
212 dd56d656 Thomas Schöpping
#if (HAL_USE_QEI == TRUE)
213
214
apalExitStatus_t apalQEIGetDirection(apalQEIDriver_t* qei, apalQEIDirection_t* const direction)
215 e545e620 Thomas Schöpping
{
216 1f94ac64 Thomas Schöpping
  apalDbgAssert(qei != NULL);
217
  apalDbgAssert(direction != NULL);
218 e545e620 Thomas Schöpping
219
  *direction = (qei_lld_get_direction(qei)) ? APAL_QEI_DIRECTION_DOWN : APAL_QEI_DIRECTION_UP;
220
221
  return APAL_STATUS_OK;
222
}
223
224 dd56d656 Thomas Schöpping
apalExitStatus_t apalQEIGetPosition(apalQEIDriver_t* qei, apalQEICount_t* const position)
225 e545e620 Thomas Schöpping
{
226 1f94ac64 Thomas Schöpping
  apalDbgAssert(qei != NULL);
227
  apalDbgAssert(position != NULL);
228 e545e620 Thomas Schöpping
229
  *position = qei_lld_get_position(qei);
230
231
  return APAL_STATUS_OK;
232
}
233
234 dd56d656 Thomas Schöpping
apalExitStatus_t apalQEIGetRange(apalQEIDriver_t* qei, apalQEICount_t* const range)
235 e545e620 Thomas Schöpping
{
236 1f94ac64 Thomas Schöpping
  apalDbgAssert(qei != NULL);
237
  apalDbgAssert(range != NULL);
238 e545e620 Thomas Schöpping
239
  *range = qei_lld_get_range(qei);
240
241
  return APAL_STATUS_OK;
242
}
243
244 7de0cc90 Thomas Schöpping
#endif /* (HAL_USE_QEI == TRUE) */
245 e545e620 Thomas Schöpping
246
/*============================================================================*/
247
/* I2C                                                                        */
248
/*============================================================================*/
249
250 7de0cc90 Thomas Schöpping
#if (HAL_USE_I2C == TRUE) || defined(__DOXYGEN__)
251 e545e620 Thomas Schöpping
252 dd56d656 Thomas Schöpping
apalExitStatus_t apalI2CMasterTransmit(apalI2CDriver_t* i2cd, const apalI2Caddr_t addr, const uint8_t* const txbuf, const size_t txbytes, uint8_t* const rxbuf, const size_t rxbytes, const apalTime_t timeout)
253 e545e620 Thomas Schöpping
{
254 1f94ac64 Thomas Schöpping
  apalDbgAssert(i2cd != NULL);
255 e545e620 Thomas Schöpping
256
#if (I2C_USE_MUTUAL_EXCLUSION == TRUE)
257 5ab6a6a4 Thomas Schöpping
  // check whether the I2C driver was locked externally
258
  const bool i2cd_locked_external = i2cd->mutex.owner == currp;
259
  if (!i2cd_locked_external) {
260
    i2cAcquireBus(i2cd);
261
  }
262 7de0cc90 Thomas Schöpping
#endif /* (I2C_USE_MUTUAL_EXCLUSION == TRUE) */
263 e545e620 Thomas Schöpping
264 1e5f7648 Thomas Schöpping
#pragma GCC diagnostic push
265
#pragma GCC diagnostic ignored "-Wtype-limits"
266 e545e620 Thomas Schöpping
#if defined(STM32F1XX_I2C)
267
  // Due to a hardware limitation, for STM32F1 platform the minimum number of bytes that can be received is two.
268
  msg_t status = MSG_OK;
269
  if (rxbytes == 1) {
270
    uint8_t buffer[2];
271 0128be0f Marc Rothmann
    status = i2cMasterTransmitTimeout(i2cd, addr, txbuf, txbytes, buffer, 2, ((timeout >= TIME_INFINITE) ? TIME_INFINITE : TIME_US2I(timeout)) );
272 e545e620 Thomas Schöpping
    rxbuf[0] = buffer[0];
273
  } else {
274 0128be0f Marc Rothmann
    status = i2cMasterTransmitTimeout(i2cd, addr, txbuf, txbytes, rxbuf, rxbytes, ((timeout >= TIME_INFINITE) ? TIME_INFINITE : TIME_US2I(timeout)) );
275 e545e620 Thomas Schöpping
  }
276 7de0cc90 Thomas Schöpping
#else /* defined(STM32F1XX_I2C) */
277 0128be0f Marc Rothmann
  const msg_t status = i2cMasterTransmitTimeout(i2cd, addr, txbuf, txbytes, rxbuf, rxbytes, ((timeout >= TIME_INFINITE) ? TIME_INFINITE : TIME_US2I(timeout)) );
278 7de0cc90 Thomas Schöpping
#endif /* defined(STM32F1XX_I2C) */
279 1e5f7648 Thomas Schöpping
#pragma GCC diagnostic pop
280 e545e620 Thomas Schöpping
281
#if (I2C_USE_MUTUAL_EXCLUSION == TRUE)
282 5ab6a6a4 Thomas Schöpping
  if (!i2cd_locked_external) {
283
    i2cReleaseBus(i2cd);
284
  }
285 7de0cc90 Thomas Schöpping
#endif /* (I2C_USE_MUTUAL_EXCLUSION == TRUE) */
286 e545e620 Thomas Schöpping
287
  switch (status)
288
  {
289
    case MSG_OK:
290
#if defined(STM32F1XX_I2C)
291
      return (rxbytes != 1) ? APAL_STATUS_OK : APAL_STATUS_WARNING;
292 7de0cc90 Thomas Schöpping
#else /* defined(STM32F1XX_I2C) */
293 e545e620 Thomas Schöpping
      return APAL_STATUS_OK;
294 7de0cc90 Thomas Schöpping
#endif /* defined(STM32F1XX_I2C) */
295 e545e620 Thomas Schöpping
    case MSG_TIMEOUT:
296
      return APAL_STATUS_TIMEOUT;
297
    case MSG_RESET:
298
    default:
299
      return APAL_STATUS_ERROR;
300
  }
301
}
302
303 dd56d656 Thomas Schöpping
apalExitStatus_t apalI2CMasterReceive(apalI2CDriver_t* i2cd, const apalI2Caddr_t addr, uint8_t* const rxbuf, const size_t rxbytes, const apalTime_t timeout)
304 e545e620 Thomas Schöpping
{
305 1f94ac64 Thomas Schöpping
  apalDbgAssert(i2cd != NULL);
306 e545e620 Thomas Schöpping
307
#if (I2C_USE_MUTUAL_EXCLUSION == TRUE)
308 5ab6a6a4 Thomas Schöpping
  // check whether the I2C driver was locked externally
309
  const bool i2cd_locked_external = i2cd->mutex.owner == currp;
310
  if (!i2cd_locked_external) {
311
    i2cAcquireBus(i2cd);
312
  }
313 7de0cc90 Thomas Schöpping
#endif /* (I2C_USE_MUTUAL_EXCLUSION == TRUE) */
314 e545e620 Thomas Schöpping
315 1e5f7648 Thomas Schöpping
#pragma GCC diagnostic push
316
#pragma GCC diagnostic ignored "-Wtype-limits"
317 e545e620 Thomas Schöpping
#if defined(STM32F1XX_I2C)
318
  // Due to a hardware limitation, for STM32F1 platform the minimum number of bytes that can be received is two.
319
  msg_t status = MSG_OK;
320
  if (rxbytes == 1) {
321
    uint8_t buffer[2];
322 0128be0f Marc Rothmann
    status = i2cMasterReceiveTimeout(i2cd, addr, buffer, 2, ((timeout >= TIME_INFINITE) ? TIME_INFINITE : TIME_US2I(timeout)) );
323 e545e620 Thomas Schöpping
    rxbuf[0] = buffer[0];
324
  } else {
325 0128be0f Marc Rothmann
    status = i2cMasterReceiveTimeout(i2cd, addr, rxbuf, rxbytes, ((timeout >= TIME_INFINITE) ? TIME_INFINITE : TIME_US2I(timeout)) );
326 e545e620 Thomas Schöpping
  }
327 7de0cc90 Thomas Schöpping
#else /* defined(STM32F1XX_I2C) */
328 0128be0f Marc Rothmann
  const msg_t status = i2cMasterReceiveTimeout(i2cd, addr, rxbuf, rxbytes, ((timeout >= TIME_INFINITE) ? TIME_INFINITE : TIME_US2I(timeout)) );
329 7de0cc90 Thomas Schöpping
#endif /* defined(STM32F1XX_I2C) */
330 1e5f7648 Thomas Schöpping
#pragma GCC diagnostic pop
331 e545e620 Thomas Schöpping
332
#if (I2C_USE_MUTUAL_EXCLUSION == TRUE)
333 5ab6a6a4 Thomas Schöpping
  if (!i2cd_locked_external) {
334
    i2cReleaseBus(i2cd);
335
  }
336 7de0cc90 Thomas Schöpping
#endif /* (I2C_USE_MUTUAL_EXCLUSION == TRUE) */
337 e545e620 Thomas Schöpping
338
  switch (status)
339
  {
340
    case MSG_OK:
341
#if defined(STM32F1XX_I2C)
342
      return (rxbytes != 1) ? APAL_STATUS_OK : APAL_STATUS_WARNING;
343 7de0cc90 Thomas Schöpping
#else /* defined(STM32F1XX_I2C) */
344 e545e620 Thomas Schöpping
      return APAL_STATUS_OK;
345 7de0cc90 Thomas Schöpping
#endif /* defined(STM32F1XX_I2C) */
346 e545e620 Thomas Schöpping
    case MSG_TIMEOUT:
347
      return APAL_STATUS_TIMEOUT;
348
    case MSG_RESET:
349
    default:
350
      return APAL_STATUS_ERROR;
351
  }
352
}
353
354 7de0cc90 Thomas Schöpping
#endif /* (HAL_USE_I2C == TRUE) */
355 e545e620 Thomas Schöpping
356
/*============================================================================*/
357
/* SPI                                                                        */
358
/*============================================================================*/
359
360 7de0cc90 Thomas Schöpping
#if (HAL_USE_SPI == TRUE) || defined(__DOXYGEN__)
361 e545e620 Thomas Schöpping
362 dd56d656 Thomas Schöpping
apalExitStatus_t apalSPITransmit(apalSPIDriver_t* spid, const uint8_t* const data, const size_t length)
363 70dd091e Thomas Schöpping
{
364
  apalDbgAssert(spid != NULL);
365
366
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
367
  // check whether the SPI driver was locked externally
368
  const bool spid_locked_external = spid->mutex.owner == currp;
369
  if (!spid_locked_external) {
370
    spiAcquireBus(spid);
371
  }
372
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
373
374 dd56d656 Thomas Schöpping
  spiSelect(spid);
375
  spiSend(spid, length, data);
376
  spiUnselect(spid);
377 70dd091e Thomas Schöpping
378
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
379
  if (!spid_locked_external) {
380
    spiReleaseBus(spid);
381
  }
382
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
383
384
  return APAL_STATUS_OK;
385
}
386
387 dd56d656 Thomas Schöpping
apalExitStatus_t apalSPIReceive(apalSPIDriver_t* spid, uint8_t* const data, const size_t length)
388 e545e620 Thomas Schöpping
{
389 1f94ac64 Thomas Schöpping
  apalDbgAssert(spid != NULL);
390 e545e620 Thomas Schöpping
391 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
392 5ab6a6a4 Thomas Schöpping
  // check whether the SPI driver was locked externally
393
  const bool spid_locked_external = spid->mutex.owner == currp;
394
  if (!spid_locked_external) {
395
    spiAcquireBus(spid);
396
  }
397 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
398 5ab6a6a4 Thomas Schöpping
399 e545e620 Thomas Schöpping
  spiSelect(spid);
400 dd56d656 Thomas Schöpping
  spiReceive(spid, length, data);
401 e545e620 Thomas Schöpping
  spiUnselect(spid);
402 5ab6a6a4 Thomas Schöpping
403 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
404 5ab6a6a4 Thomas Schöpping
  if (!spid_locked_external) {
405
    spiReleaseBus(spid);
406
  }
407 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
408 e545e620 Thomas Schöpping
409
  return APAL_STATUS_OK;
410
}
411
412 dd56d656 Thomas Schöpping
apalExitStatus_t apalSPITransmitAndReceive(apalSPIDriver_t* spid, const uint8_t* const txData , uint8_t* const rxData, const size_t txLength, const size_t rxLength)
413 e545e620 Thomas Schöpping
{
414 1f94ac64 Thomas Schöpping
  apalDbgAssert(spid != NULL);
415 e545e620 Thomas Schöpping
416 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
417 5ab6a6a4 Thomas Schöpping
  // check whether the SPI driver was locked externally
418
  const bool spid_locked_external = spid->mutex.owner == currp;
419
  if (!spid_locked_external) {
420
    spiAcquireBus(spid);
421
  }
422 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
423 5ab6a6a4 Thomas Schöpping
424 e545e620 Thomas Schöpping
  spiSelect(spid);
425 dd56d656 Thomas Schöpping
  spiSend(spid, txLength, txData);
426
  spiReceive(spid, rxLength, rxData);
427 e545e620 Thomas Schöpping
  spiUnselect(spid);
428 5ab6a6a4 Thomas Schöpping
429 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
430 5ab6a6a4 Thomas Schöpping
  if (!spid_locked_external) {
431
    spiReleaseBus(spid);
432
  }
433 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
434 e545e620 Thomas Schöpping
435
  return APAL_STATUS_OK;
436
}
437
438 dd56d656 Thomas Schöpping
apalExitStatus_t apalSPIExchange(apalSPIDriver_t* spid, const uint8_t* const txData , uint8_t* const rxData, const size_t length)
439 e545e620 Thomas Schöpping
{
440 1f94ac64 Thomas Schöpping
  apalDbgAssert(spid != NULL);
441 e545e620 Thomas Schöpping
442 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
443 5ab6a6a4 Thomas Schöpping
  // check whether the SPI driver was locked externally
444
  const bool spid_locked_external = spid->mutex.owner == currp;
445
  if (!spid_locked_external) {
446
    spiAcquireBus(spid);
447
  }
448 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
449 5ab6a6a4 Thomas Schöpping
450 e545e620 Thomas Schöpping
  spiSelect(spid);
451 dd56d656 Thomas Schöpping
  spiExchange(spid, length, txData, rxData);
452 e545e620 Thomas Schöpping
  spiUnselect(spid);
453 5ab6a6a4 Thomas Schöpping
454 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
455 5ab6a6a4 Thomas Schöpping
  if (!spid_locked_external) {
456
    spiReleaseBus(spid);
457
  }
458 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
459 e545e620 Thomas Schöpping
460
  return APAL_STATUS_OK;
461
}
462
463 dd56d656 Thomas Schöpping
apalExitStatus_t apalSPIReconfigure(apalSPIDriver_t* spid, const apalSPIConfig_t* config)
464 e251c4e6 Robin Ewers
{
465 1f94ac64 Thomas Schöpping
  apalDbgAssert(spid != NULL);
466 dd56d656 Thomas Schöpping
  apalDbgAssert(config != NULL);
467 e251c4e6 Robin Ewers
468 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
469 5ab6a6a4 Thomas Schöpping
  // check whether the SPI driver was locked externally
470
  const bool spid_locked_external = spid->mutex.owner == currp;
471
  if (!spid_locked_external) {
472
    spiAcquireBus(spid);
473
  }
474 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
475 5ab6a6a4 Thomas Schöpping
476 dd56d656 Thomas Schöpping
  spiStop(spid);
477
  spiStart(spid, config);
478 5ab6a6a4 Thomas Schöpping
479 7de0cc90 Thomas Schöpping
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
480 5ab6a6a4 Thomas Schöpping
  if (!spid_locked_external) {
481
    spiReleaseBus(spid);
482
  }
483 7de0cc90 Thomas Schöpping
#endif /* (SPI_USE_MUTUAL_EXCLUSION == TRUE) */
484 e545e620 Thomas Schöpping
485
  return APAL_STATUS_OK;
486
}
487
488 7de0cc90 Thomas Schöpping
#endif /* (HAL_USE_SPI == TRUE) */