Statistics
| Branch: | Tag: | Revision:

amiro-os / periphery-lld / aos_periphAL.c @ ded1ded7

History | View | Annotate | Download (14.856 KB)

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