S32 SDK
flexio_i2c_driver.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
19 #include "flexio_i2c_driver.h"
20 #include "flexio_hal.h"
21 #include "flexio_common.h"
22 #include "clock_manager.h"
23 
98 /*******************************************************************************
99  * Variables
100  ******************************************************************************/
101 
104  /* Constraints used for baud rate computation */
105 #define DIVIDER_MIN_VALUE 1U
106 #define DIVIDER_MAX_VALUE 0xFFU
107 
108  /* Shifters/Timers used for I2C simulation The parameter x represents the
109  resourceIndex value for the current driver instance */
110 #define TX_SHIFTER(x) (x)
111 #define RX_SHIFTER(x) (uint8_t)((x) + 1U)
112 #define SCL_TIMER(x) (x)
113 #define CONTROL_TIMER(x) (uint8_t)((x) + 1U)
114 
115 /*******************************************************************************
116  * Private Functions
117  ******************************************************************************/
118 
119 
120 /*FUNCTION**********************************************************************
121  *
122  * Function Name : FLEXIO_I2C_DRV_MasterComputeBaudRateDivider
123  * Description : Computes the baud rate divider for a target baud rate
124  *
125  *END**************************************************************************/
126 static void FLEXIO_I2C_DRV_MasterComputeBaudRateDivider(uint32_t baudRate,
127  uint16_t *divider,
128  uint32_t inputClock)
129 {
130  uint32_t tmpDiv;
131 
132  /* Compute divider: ((input_clock / baud_rate) / 2) - 1 - 1. The extra -1 is from the
133  timer reset setting used for clock stretching. Round to nearest integer */
134  tmpDiv = ((inputClock + baudRate) / (2U * baudRate)) - 2U;
135  /* Enforce upper/lower limits */
136  if (tmpDiv < DIVIDER_MIN_VALUE)
137  {
138  tmpDiv = DIVIDER_MIN_VALUE;
139  }
140  if (tmpDiv > DIVIDER_MAX_VALUE)
141  {
142  tmpDiv = DIVIDER_MAX_VALUE;
143  }
144 
145  *divider = (uint16_t)tmpDiv;
146 }
147 
148 
149 /*FUNCTION**********************************************************************
150  *
151  * Function Name : FLEXIO_I2C_DRV_MasterConfigure
152  * Description : configures the FLEXIO module as I2C master
153  *
154  *END**************************************************************************/
155 static void FLEXIO_I2C_DRV_MasterConfigure(const flexio_i2c_master_state_t *master, uint32_t inputClock, uint32_t baudRate)
156 {
157  FLEXIO_Type *baseAddr;
158  uint16_t divider;
159  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
160 
161  baseAddr = g_flexioBase[master->flexioCommon.instance];
162  resourceIndex = master->flexioCommon.resourceIndex;
163 
164  /* Compute divider.*/
165  FLEXIO_I2C_DRV_MasterComputeBaudRateDivider(baudRate, &divider, inputClock);
166 
167  /* Configure tx shifter */
169  TX_SHIFTER(resourceIndex),
173  /* Shifter disabled and pin enabled causes the pin to be held low.
174  So disable pin too, will be enabled at transfer time. */
176  TX_SHIFTER(resourceIndex),
178  master->sdaPin, /* output on SDA pin */
181  CONTROL_TIMER(resourceIndex), /* use control timer to drive the shifter */
183 
184  /* Configure rx shifter */
186  RX_SHIFTER(resourceIndex),
191  RX_SHIFTER(resourceIndex),
193  master->sdaPin, /* input from SDA pin */
196  CONTROL_TIMER(resourceIndex), /* use control timer to drive the shifter */
198 
199  /* Configure SCL timer */
200  FLEXIO_HAL_SetTimerCompare(baseAddr, SCL_TIMER(resourceIndex), divider);
201  FLEXIO_HAL_SetTimerConfig(baseAddr,
202  SCL_TIMER(resourceIndex),
205  FLEXIO_TIMER_ENABLE_TRG_HIGH, /* enable when Tx data is available */
207  FLEXIO_TIMER_RESET_PIN_OUT, /* reset if output equals pin (for clock stretching) */
208  FLEXIO_TIMER_DECREMENT_CLK_SHIFT_TMR, /* decrement on FlexIO clock */
211  SCL_TIMER(resourceIndex),
212  (uint8_t)((TX_SHIFTER(resourceIndex) << 2U) + 1U), /* trigger on tx shifter status flag */
215  master->sclPin, /* output on SCL pin */
217  FLEXIO_PIN_CONFIG_OPEN_DRAIN, /* enable output */
219 
220  /* Configure control timer for shifters */
221  FLEXIO_HAL_SetTimerCompare(baseAddr, CONTROL_TIMER(resourceIndex), 0x000FU);
222  FLEXIO_HAL_SetTimerConfig(baseAddr,
223  CONTROL_TIMER(resourceIndex),
226  FLEXIO_TIMER_ENABLE_TIM_ENABLE, /* enable on SCL timer enable */
227  FLEXIO_TIMER_DISABLE_TIM_DISABLE, /* disable on SCL timer disable */
229  FLEXIO_TIMER_DECREMENT_PIN_SHIFT_PIN, /* decrement on SCL pin input */
232  CONTROL_TIMER(resourceIndex),
233  (uint8_t)((TX_SHIFTER(resourceIndex) << 2U) + 1U), /* trigger on tx shifter status flag */
236  master->sclPin, /* use SCL pin as input */
240 }
241 
242 
243 /*FUNCTION**********************************************************************
244  *
245  * Function Name : FLEXIO_I2C_DRV_MasterSetBytesNo
246  * Description : configures the number of SCL clocks needed for the entire transmission
247  *
248  *END**************************************************************************/
249 static void FLEXIO_I2C_DRV_MasterSetBytesNo(FLEXIO_Type *baseAddr, const flexio_i2c_master_state_t *master)
250 {
251  uint16_t timerCmp;
252  uint32_t bytesNo;
253  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
254 
255  resourceIndex = master->flexioCommon.resourceIndex;
256  /* Compute number of SCL ticks, including address */
257  bytesNo = master->txRemainingBytes;
258  bytesNo = (bytesNo * 18U) + 1U;
259  /* Set number of ticks in low part of timer compare register */
260  timerCmp = FLEXIO_HAL_GetTimerCompare(baseAddr, SCL_TIMER(resourceIndex));
261  timerCmp = (uint16_t)((timerCmp & 0x00FFU) | (uint16_t)((bytesNo & 0xFFU) << 8U));
262  FLEXIO_HAL_SetTimerCompare(baseAddr, SCL_TIMER(resourceIndex), timerCmp);
263 }
264 
265 
266 /*FUNCTION**********************************************************************
267  *
268  * Function Name : FLEXIO_I2C_DRV_MasterSendAddress
269  * Description : send address byte
270  *
271  *END**************************************************************************/
272 static void FLEXIO_I2C_DRV_MasterSendAddress(FLEXIO_Type *baseAddr, const flexio_i2c_master_state_t *master)
273 {
274  uint8_t addrByte;
275  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
276 
277  resourceIndex = master->flexioCommon.resourceIndex;
278  /* Address byte: slave 7-bit address + D = 0(transmit) or 1 (receive) */
279  addrByte = (uint8_t)((uint8_t)(master->slaveAddress << 1U) + (uint8_t)(master->receive ? 1U : 0U));
280  FLEXIO_HAL_WriteShifterBuffer(baseAddr, TX_SHIFTER(resourceIndex), (uint32_t)addrByte << 24U, FLEXIO_SHIFTER_RW_MODE_BIT_SWAP);
281 }
282 
283 
284 /*FUNCTION**********************************************************************
285  *
286  * Function Name : FLEXIO_I2C_DRV_ReadData
287  * Description : Handles data reception
288  *
289  *END**************************************************************************/
290 static void FLEXIO_I2C_DRV_ReadData(flexio_i2c_master_state_t *master)
291 {
292  FLEXIO_Type *baseAddr;
293  uint8_t data;
294  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
295 
296  baseAddr = g_flexioBase[master->flexioCommon.instance];
297  resourceIndex = master->flexioCommon.resourceIndex;
298 
299  /* Read data from rx shifter */
300  data = (uint8_t)FLEXIO_HAL_ReadShifterBuffer(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_RW_MODE_BIT_SWAP);
301 
302  if (master->rxRemainingBytes == 0U)
303  {
304  return;
305  }
306 
307  if (master->addrReceived == false)
308  {
309  /* This was the address byte */
310  master->addrReceived = true;
311  if (master->receive == true)
312  {
313  /* Send ACK from now on */
314  FLEXIO_HAL_SetShifterStopBit(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_STOP_BIT_0);
315  }
316  }
317  else
318  {
319  master->rxRemainingBytes--;
320  if (master->receive == true)
321  {
322  /* Put data in user buffer */
323  *(master->data) = data;
324  master->data++;
325  }
326  }
327  if ((master->receive == true) && (master->rxRemainingBytes == 1U))
328  {
329  /* Send NACK for last byte */
330  FLEXIO_HAL_SetShifterStopBit(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_STOP_BIT_1);
331  /* Also instruct rx shifter to expect NACK */
332  FLEXIO_HAL_SetShifterStopBit(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_STOP_BIT_1);
333  }
334 }
335 
336 
337 /*FUNCTION**********************************************************************
338  *
339  * Function Name : FLEXIO_I2C_DRV_WriteData
340  * Description : Handles data transmission
341  *
342  *END**************************************************************************/
343 static void FLEXIO_I2C_DRV_WriteData(flexio_i2c_master_state_t *master)
344 {
345  FLEXIO_Type *baseAddr;
346  uint32_t data;
347  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
348 
349  baseAddr = g_flexioBase[master->flexioCommon.instance];
350  resourceIndex = master->flexioCommon.resourceIndex;
351 
352  /* If txRemainingBytes == 0 the transmission is over */
353  if (master->txRemainingBytes == 0U)
354  {
355  return;
356  }
357 
358  master->txRemainingBytes--;
359 
360  if (master->txRemainingBytes == 0U)
361  {
362  /* Done transmitting */
363  if (master->sendStop == true)
364  {
365  /* Transmit stop condition */
366  data = 0x0;
367  }
368  else
369  {
370  /* Do not transmit stop condition */
371  data = 0xFFU;
372  }
373  }
374  else if (master->receive == true)
375  {
376  /* Transmit 0xFF to leave the line free while receiving */
377  data = 0xFFU;
378  }
379  else
380  {
381  /* Read data from user buffer */
382  data = *(master->data);
383  master->data++;
384  }
385 
386  /* Shift data before bit-swapping it to get the relevant bits in the lower part of the shifter */
387  data <<= 24U;
388  FLEXIO_HAL_WriteShifterBuffer(baseAddr, TX_SHIFTER(resourceIndex), data, FLEXIO_SHIFTER_RW_MODE_BIT_SWAP);
389 }
390 
391 
392 /*FUNCTION**********************************************************************
393  *
394  * Function Name : FLEXIO_I2C_DRV_MasterEndTransfer
395  * Description : End the current transfer
396  *
397  *END**************************************************************************/
398 static void FLEXIO_I2C_DRV_MasterEndTransfer(flexio_i2c_master_state_t *master)
399 {
400  FLEXIO_Type *baseAddr;
401  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
402 
403  baseAddr = g_flexioBase[master->flexioCommon.instance];
404  resourceIndex = master->flexioCommon.resourceIndex;
405 
406  /* Restore Rx stop bit, in case it was changed by a receive */
407  FLEXIO_HAL_SetShifterStopBit(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_STOP_BIT_0);
408  /* Restore Tx stop bit, in case it was changed by a receive */
409  FLEXIO_HAL_SetShifterStopBit(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_STOP_BIT_1);
410  /* Clear Rx status in case there is a character left in the buffer */
411  FLEXIO_HAL_ClearShifterStatus(baseAddr, RX_SHIFTER(resourceIndex));
412 
413  /* Disable transfer engine */
414  switch (master->driverType)
415  {
417  /* Disable interrupts for Rx and Tx shifters */
419  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
420  false);
422  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
423  false);
424  /* Disable interrupt for SCL timer */
425  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << SCL_TIMER(resourceIndex)), false);
426  break;
428  /* Nothing to do here */
429  break;
431  /* Disable error interrupt for Rx shifter */
432  FLEXIO_HAL_SetShifterErrorInterrupt(baseAddr, (uint8_t)(1U << RX_SHIFTER(resourceIndex)), false);
433  /* Disable interrupt for SCL timer */
434  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << SCL_TIMER(resourceIndex)), false);
435  /* Stop DMA channels */
436  (void)EDMA_DRV_StopChannel(master->txDMAChannel);
437  (void)EDMA_DRV_StopChannel(master->rxDMAChannel);
438  /* Disable FlexIO DMA requests for both shifters */
439  FLEXIO_HAL_SetShifterDMARequest(baseAddr, (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))), false);
440  break;
441  default:
442  /* Impossible type - do nothing */
443  break;
444  }
445 
446  master->driverIdle = true;
447 
448  /* Signal transfer end for blocking transfers */
449  if (master->blocking == true)
450  {
451  (void)OSIF_SemaPost(&(master->idleSemaphore));
452  }
453 }
454 
455 
456 /*FUNCTION**********************************************************************
457  *
458  * Function Name : FLEXIO_I2C_DRV_MasterEnableTransfer
459  * Description : Enables timers and shifters to start a transfer
460  *
461  *END**************************************************************************/
462 static void FLEXIO_I2C_DRV_MasterEnableTransfer(flexio_i2c_master_state_t *master)
463 {
464  FLEXIO_Type *baseAddr;
465  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
466 
467  resourceIndex = master->flexioCommon.resourceIndex;
468  baseAddr = g_flexioBase[master->flexioCommon.instance];
469 
470  /* enable timers and shifters */
471  FLEXIO_HAL_SetShifterMode(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_TRANSMIT);
472  FLEXIO_HAL_SetShifterMode(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_RECEIVE);
473  FLEXIO_HAL_SetTimerMode(baseAddr, SCL_TIMER(resourceIndex), FLEXIO_TIMER_MODE_8BIT_BAUD);
474  FLEXIO_HAL_SetTimerMode(baseAddr, CONTROL_TIMER(resourceIndex), FLEXIO_TIMER_MODE_16BIT);
475  /* enable Tx pin */
476  FLEXIO_HAL_SetShifterPinConfig(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_PIN_CONFIG_OPEN_DRAIN);
477 }
478 
479 
480 /*FUNCTION**********************************************************************
481  *
482  * Function Name : FLEXIO_I2C_DRV_MasterStopTransfer
483  * Description : Forcefully stops the current transfer
484  *
485  *END**************************************************************************/
486 static void FLEXIO_I2C_DRV_MasterStopTransfer(flexio_i2c_master_state_t *master)
487 {
488  FLEXIO_Type *baseAddr;
489  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
490 
491  resourceIndex = master->flexioCommon.resourceIndex;
492  baseAddr = g_flexioBase[master->flexioCommon.instance];
493 
494  /* disable Tx pin */
495  FLEXIO_HAL_SetShifterPinConfig(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_PIN_CONFIG_DISABLED);
496  /* disable and re-enable timers and shifters to reset them */
497  FLEXIO_HAL_SetShifterMode(baseAddr, TX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_DISABLED);
498  FLEXIO_HAL_SetShifterMode(baseAddr, RX_SHIFTER(resourceIndex), FLEXIO_SHIFTER_MODE_DISABLED);
499  FLEXIO_HAL_SetTimerMode(baseAddr, SCL_TIMER(resourceIndex), FLEXIO_TIMER_MODE_DISABLED);
500  FLEXIO_HAL_SetTimerMode(baseAddr, CONTROL_TIMER(resourceIndex), FLEXIO_TIMER_MODE_DISABLED);
501 
502  /* clear any leftover error flags */
503  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, TX_SHIFTER(resourceIndex));
504  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex));
505  /* discard any leftover rx. data */
506  FLEXIO_HAL_ClearShifterStatus(baseAddr, RX_SHIFTER(resourceIndex));
507 
508  /* end the transfer */
509  FLEXIO_I2C_DRV_MasterEndTransfer(master);
510 }
511 
512 
513 /*FUNCTION**********************************************************************
514  *
515  * Function Name : FLEXIO_I2C_DRV_MasterWaitTransferEnd
516  * Description : waits for the end of a blocking transfer
517  *
518  *END**************************************************************************/
519 static status_t FLEXIO_I2C_DRV_MasterWaitTransferEnd(flexio_i2c_master_state_t *master, uint32_t timeout)
520 {
521  status_t osifError = STATUS_SUCCESS;
522 
523  switch (master->driverType)
524  {
526  /* Wait for transfer to be completed by the IRQ */
527  osifError = OSIF_SemaWait(&(master->idleSemaphore), timeout);
528  break;
530  /* Call FLEXIO_I2C_DRV_MasterGetStatus() to do the transfer */
531  while (FLEXIO_I2C_DRV_MasterGetStatus(master, NULL) == STATUS_BUSY)
532  {
533  }
534  break;
536  /* Wait for transfer to be completed by the DMA IRQ */
537  osifError = OSIF_SemaWait(&(master->idleSemaphore), timeout);
538  break;
539  default:
540  /* Impossible type - do nothing */
541  break;
542  }
543 
544  /* blocking transfer is over */
545  master->blocking = false;
546  if (osifError == STATUS_TIMEOUT)
547  {
548  /* abort current transfer */
549  master->status = STATUS_TIMEOUT;
550  FLEXIO_I2C_DRV_MasterStopTransfer(master);
551  }
552 
553  return master->status;
554 }
555 
556 
557 /*FUNCTION**********************************************************************
558  *
559  * Function Name : FLEXIO_I2C_DRV_MasterCheckNack
560  * Description : Checks if the current Rx shifter error is NACK or RX_OVERFLOW
561  *
562  * If there is a Tx event active it is an indication that module was not
563  * serviced for a long time - chances are this is an overflow.
564  * It is not certain, and it is even possible to have both NACK and overflow,
565  * but there is no way to tell, so we chose the safe option (if it is an
566  * overflow and we abort the transfer we may block the I2C bus).
567  *
568  *
569  *END**************************************************************************/
570 static inline bool FLEXIO_I2C_DRV_MasterCheckNack(const FLEXIO_Type *baseAddr, const flexio_i2c_master_state_t *master)
571 {
572  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
573 
574  resourceIndex = master->flexioCommon.resourceIndex;
575  return !(FLEXIO_HAL_GetShifterStatus(baseAddr, TX_SHIFTER(resourceIndex)));
576 }
577 
578 
579 /*FUNCTION**********************************************************************
580  *
581  * Function Name : FLEXIO_I2C_DRV_MasterBusBusy
582  * Description : Check status of the I2C bus.
583  * If either SDA or SCL is low, the bus is busy.
584  *
585  *END**************************************************************************/
586 static inline bool FLEXIO_I2C_DRV_MasterBusBusy(const FLEXIO_Type *baseAddr, const flexio_i2c_master_state_t *master)
587 {
588  uint8_t pinMask = (uint8_t)((1U << master->sdaPin) | (1U << master->sclPin));
589  if ((FLEXIO_HAL_GetPinData(baseAddr) & pinMask) == pinMask)
590  {
591  /* both pins are high, bus is not busy */
592  return false;
593  }
594  else
595  {
596  /* bus is busy */
597  return true;
598  }
599 }
600 
601 
602 /*FUNCTION**********************************************************************
603  *
604  * Function Name : FLEXIO_I2C_DRV_MasterCheckStatus
605  * Description : Check status of the I2C transfer. This function can be
606  * called either in an interrupt routine or directly in polling
607  * mode to advance the I2C transfer.
608  *
609  *END**************************************************************************/
610 static void FLEXIO_I2C_DRV_MasterCheckStatus(void *stateStruct)
611 {
612  FLEXIO_Type *baseAddr;
613  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
615 
616  DEV_ASSERT(stateStruct != NULL);
617 
618  master = (flexio_i2c_master_state_t *)stateStruct;
619  baseAddr = g_flexioBase[master->flexioCommon.instance];
620  resourceIndex = master->flexioCommon.resourceIndex;
621 
622  /* Check for errors */
623  if (FLEXIO_HAL_GetShifterErrorStatus(baseAddr, TX_SHIFTER(resourceIndex)))
624  {
625  master->status = STATUS_I2C_TX_UNDERRUN;
626  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, TX_SHIFTER(resourceIndex));
627  /* don't stop the transfer, continue processing events */
628  }
629  if (FLEXIO_HAL_GetShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex)))
630  {
631  /* Device limitation: not possible to tell the difference between NACK and receive overflow */
632  if (FLEXIO_I2C_DRV_MasterCheckNack(baseAddr, master))
633  {
634  master->status = STATUS_I2C_RECEIVED_NACK;
635  /* Force the transfer to stop */
636  FLEXIO_I2C_DRV_MasterStopTransfer(master);
637  /* Call callback to announce the event to the user */
638  if (master->callback != NULL)
639  {
640  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
641  }
642  return;
643  }
644  else
645  {
646  master->status = STATUS_I2C_RX_OVERRUN;
647  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex));
648  /* don't stop the transfer, continue processing events */
649  }
650  }
651  /* Check if data was received */
652  if (FLEXIO_HAL_GetShifterStatus(baseAddr, RX_SHIFTER(resourceIndex)))
653  {
654  FLEXIO_I2C_DRV_ReadData(master);
655  }
656  /* Check if the transfer is over */
657  if (FLEXIO_HAL_GetTimerStatus(baseAddr, SCL_TIMER(resourceIndex)))
658  {
659  /* Clear timer status */
660  FLEXIO_HAL_ClearTimerStatus(baseAddr, SCL_TIMER(resourceIndex));
661  /* Record success if there was no error */
662  if (master->status == STATUS_BUSY)
663  {
664  master->status = STATUS_SUCCESS;
665  }
666  /* End transfer. In case of race condition between Tx_shifter and timer_end events,
667  it is possible for the clock to be restarted. So we use forced stop to avoid this. */
668  FLEXIO_I2C_DRV_MasterStopTransfer(master);
669  /* Call callback to announce the event to the user */
670  if (master->callback != NULL)
671  {
672  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
673  }
674  /* Skip checking Tx event if transfer is over */
675  return;
676  }
677  /* Check if transmitter needs more data */
678  if (FLEXIO_HAL_GetShifterStatus(baseAddr, TX_SHIFTER(resourceIndex)))
679  {
680  FLEXIO_I2C_DRV_WriteData(master);
681  if (master->txRemainingBytes == 0U)
682  {
683  /* Done transmitting, disable Tx interrupt */
684  FLEXIO_HAL_SetShifterInterrupt(baseAddr, (uint8_t)(1U << TX_SHIFTER(resourceIndex)), false);
685  }
686  }
687 }
688 
689 
690 /*FUNCTION**********************************************************************
691  *
692  * Function Name : FLEXIO_I2C_DRV_MasterComputeTxRegAddr
693  * Description : Computes the address of the register used for DMA tx transfer
694  *
695  *END**************************************************************************/
696 static inline uint32_t FLEXIO_I2C_DRV_MasterComputeTxRegAddr(const flexio_i2c_master_state_t *master)
697 {
698  uint32_t addr;
699  const FLEXIO_Type *baseAddr;
700  uint8_t shifter;
701 
702  baseAddr = g_flexioBase[master->flexioCommon.instance];
703  shifter = TX_SHIFTER(master->flexioCommon.resourceIndex);
704  addr = (uint32_t)(&(baseAddr->SHIFTBUFBIS[shifter])) + (sizeof(uint32_t) - 1U);
705  return addr;
706 }
707 
708 
709 /*FUNCTION**********************************************************************
710  *
711  * Function Name : FLEXIO_I2C_DRV_MasterComputeRxRegAddr
712  * Description : Computes the address of the register used for DMA rx transfer
713  *
714  *END**************************************************************************/
715 static inline uint32_t FLEXIO_I2C_DRV_MasterComputeRxRegAddr(const flexio_i2c_master_state_t *master)
716 {
717  uint32_t addr;
718  const FLEXIO_Type *baseAddr;
719  uint8_t shifter;
720 
721  baseAddr = g_flexioBase[master->flexioCommon.instance];
722  shifter = RX_SHIFTER(master->flexioCommon.resourceIndex);
723  addr = (uint32_t)(&(baseAddr->SHIFTBUFBIS[shifter]));
724  return addr;
725 }
726 
727 
728 /*FUNCTION**********************************************************************
729  *
730  * Function Name : FLEXIO_I2C_DRV_MasterDmaBlockImmediate
731  * Description : Configures a DMA transfer to trigger immediately
732  *
733  *END**************************************************************************/
734 static inline void FLEXIO_I2C_DRV_MasterDmaBlockImmediate(edma_software_tcd_t *stcdBase, uint8_t blockNo)
735 {
736  /* Set the START bit for this TCD to 1 */
737  stcdBase[blockNo].CSR |= (uint16_t)DMA_TCD_CSR_START(1U);
738 }
739 
740 
741 /*FUNCTION**********************************************************************
742  *
743  * Function Name : FLEXIO_I2C_DRV_MasterDmaBlockTerminate
744  * Description : Configures a DMA transfer to disable the DMArequuest upon transfer completion
745  *
746  *END**************************************************************************/
747 static inline void FLEXIO_I2C_DRV_MasterDmaBlockTerminate(edma_software_tcd_t *stcdBase, uint8_t blockNo)
748 {
749  /* Set the DREQ bit for this TCD to 1 */
750  stcdBase[blockNo].CSR |= (uint16_t)DMA_TCD_CSR_DREQ(1U);
751 }
752 
753 
754 /*FUNCTION**********************************************************************
755  *
756  * Function Name : FLEXIO_I2C_DRV_MasterDmaConfigTx
757  * Description : Configures DMA transfer for Tx
758  *
759  *END**************************************************************************/
760 static inline void FLEXIO_I2C_DRV_MasterDmaConfigTx(flexio_i2c_master_state_t *master,
761  edma_software_tcd_t *stcdBase)
762 {
763  edma_scatter_gather_list_t srcList[2U];
764  edma_scatter_gather_list_t destList[2U];
765  uint32_t addr;
766  DMA_Type *edmaBase = g_edmaBase[0U];
767 
768  /* Configure Tx chain */
769  /* First block: transmit data */
770  if (master->receive == false)
771  {
772  addr = (uint32_t)(master->data);
773  }
774  else
775  {
776  /* if receiving, send 0xFF to keep the line clear */
777  master->dummyDmaIdle = 0xFFU;
778  addr = (uint32_t)(&(master->dummyDmaIdle));
779  }
780  srcList[0U].address = addr;
781  srcList[0U].length = master->rxRemainingBytes;
782  srcList[0U].type = EDMA_TRANSFER_MEM2PERIPH;
783  destList[0U].address = FLEXIO_I2C_DRV_MasterComputeTxRegAddr(master);
784  destList[0U].length = master->rxRemainingBytes;
785  destList[0U].type = EDMA_TRANSFER_MEM2PERIPH;
786 
787  /* Second block: transmit stop/repeated start */
788  if (master->sendStop)
789  {
790  master->dummyDmaStop = 0U;
791  }
792  else
793  {
794  master->dummyDmaStop = 0xFFU;
795  }
796  srcList[1U].address = (uint32_t)(&(master->dummyDmaStop));
797  srcList[1U].length = 1U;
798  srcList[1U].type = EDMA_TRANSFER_MEM2PERIPH;
799  destList[1U].address = FLEXIO_I2C_DRV_MasterComputeTxRegAddr(master);
800  destList[1U].length = 1U;
801  destList[1U].type = EDMA_TRANSFER_MEM2PERIPH;
802 
803  /* use 2 STCDs for tx, transfer size: 1 byte, 1 byte per DMA request */
804  (void)EDMA_DRV_ConfigScatterGatherTransfer(master->txDMAChannel, stcdBase, EDMA_TRANSFER_SIZE_1B,
805  1U, srcList, destList, 2U);
806 
807  if (master->receive == true)
808  {
809  /* if there is no data to transmit, don't increment source offset */
810  EDMA_HAL_TCDSetSrcOffset(edmaBase, master->txDMAChannel, 0);
811  }
812  /* set DREQ bit for last block */
813  FLEXIO_I2C_DRV_MasterDmaBlockTerminate(stcdBase, 0U);
814 }
815 
816 
817 /*FUNCTION**********************************************************************
818  *
819  * Function Name : FLEXIO_I2C_DRV_MasterDmaConfigRx
820  * Description : Configures DMA transfer for Rx
821  *
822  *END**************************************************************************/
823 static inline void FLEXIO_I2C_DRV_MasterDmaConfigRx(flexio_i2c_master_state_t *master,
824  edma_software_tcd_t *stcdBase)
825 {
826  edma_scatter_gather_list_t srcList[6U];
827  edma_scatter_gather_list_t destList[6U];
828  DMA_Type *edmaBase = g_edmaBase[0U];
829  uint32_t tmp;
830  uint8_t blockCnt = 0U;
831  const FLEXIO_Type *baseAddr;
832  uint8_t shifter;
833  uint8_t dmaChn;
834 
835  baseAddr = g_flexioBase[master->flexioCommon.instance];
836  dmaChn = master->rxDMAChannel;
837 
838  /* Configure Rx chain */
839  if (master->receive == false)
840  {
841  /* when transmitting we don't need scatter-gather for receive, just move read data to dummy location */
844  FLEXIO_I2C_DRV_MasterComputeRxRegAddr(master),
845  (uint32_t)(&(master->dummyDmaReceive)),
847  1U);
848  /* no data to receive, don't increment destination offset */
849  EDMA_HAL_TCDSetDestOffset(edmaBase, dmaChn, 0);
850  /* set major loop count to rxRemainingBytes + 1, to include address byte */
851  EDMA_HAL_TCDSetMajorCount(edmaBase, dmaChn, master->rxRemainingBytes + 1U);
852  EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(edmaBase, dmaChn, true);
853  }
854  else
855  {
856  /* First block: receive address byte (dummy read) */
857  srcList[blockCnt].address = FLEXIO_I2C_DRV_MasterComputeRxRegAddr(master);
858  srcList[blockCnt].length = 1U;
859  srcList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
860  destList[blockCnt].address = (uint32_t)(&(master->dummyDmaReceive));
861  destList[blockCnt].length = 1U;
862  destList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
863  blockCnt++;
864  /* When receiving just 1 byte skip the "middle" part */
865  if (master->rxRemainingBytes > 1U)
866  {
867  /* Second block: set tx shifter stop bit to 0 (transmit ACK) */
868  shifter = TX_SHIFTER(master->flexioCommon.resourceIndex);
869  tmp = baseAddr->SHIFTCFG[shifter];
870  tmp &= ~(FLEXIO_SHIFTCFG_SSTOP_MASK);
872  master->dmaReceiveTxStop0 = (uint8_t)(tmp & 0xFFU);
873  srcList[blockCnt].address = (uint32_t)(&(master->dmaReceiveTxStop0));
874  srcList[blockCnt].length = 1U;
875  srcList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
876  destList[blockCnt].address = (uint32_t)(&(baseAddr->SHIFTCFG[shifter]));
877  destList[blockCnt].length = 1U;
878  destList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
879  blockCnt++;
880  /* Third block: receive all but the last data byte */
881  srcList[blockCnt].address = FLEXIO_I2C_DRV_MasterComputeRxRegAddr(master);
882  srcList[blockCnt].length = master->rxRemainingBytes - 1U;
883  srcList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
884  destList[blockCnt].address = (uint32_t)(master->data);
885  destList[blockCnt].length = master->rxRemainingBytes - 1U;
886  destList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
887  blockCnt++;
888  /* Fourth block: set tx shifter stop bit to 1 (transmit NACK for last byte) */
889  tmp = baseAddr->SHIFTCFG[shifter];
890  tmp &= ~(FLEXIO_SHIFTCFG_SSTOP_MASK);
892  master->dmaReceiveTxStop1 = (uint8_t)(tmp & 0xFFU);
893  srcList[blockCnt].address = (uint32_t)(&(master->dmaReceiveTxStop1));
894  srcList[blockCnt].length = 1U;
895  srcList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
896  destList[blockCnt].address = (uint32_t)(&(baseAddr->SHIFTCFG[shifter]));
897  destList[blockCnt].length = 1U;
898  destList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
899  blockCnt++;
900  }
901  /* Fifth block: set rx shifter stop bit to 1 (expect NACK) */
902  shifter = RX_SHIFTER(master->flexioCommon.resourceIndex);
903  tmp = baseAddr->SHIFTCFG[shifter];
904  tmp &= ~(FLEXIO_SHIFTCFG_SSTOP_MASK);
906  master->dmaReceiveRxStop1 = (uint8_t)(tmp & 0xFFU);
907  srcList[blockCnt].address = (uint32_t)(&(master->dmaReceiveRxStop1));
908  srcList[blockCnt].length = 1U;
909  srcList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
910  destList[blockCnt].address = (uint32_t)(&(baseAddr->SHIFTCFG[shifter]));
911  destList[blockCnt].length = 1U;
912  destList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
913  blockCnt++;
914  /* Sixth block: receive last byte */
915  srcList[blockCnt].address = FLEXIO_I2C_DRV_MasterComputeRxRegAddr(master);
916  srcList[blockCnt].length = 1U;
917  srcList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
918  destList[blockCnt].address = (uint32_t)(&(master->data[master->rxRemainingBytes - 1U]));
919  destList[blockCnt].length = 1U;
920  destList[blockCnt].type = EDMA_TRANSFER_PERIPH2MEM;
921  blockCnt++;
922 
923  /* use blockCnt (3 or 6) STCDs for rx, transfer size: 1 byte, 1 byte per DMA request */
925  stcdBase,
926  EDMA_TRANSFER_SIZE_1B, 1U, srcList, destList, blockCnt);
927 
928  /* set all config transfers to SHIFTCFG registers to trigger immediately */
929  FLEXIO_I2C_DRV_MasterDmaBlockImmediate(stcdBase, 0U);
930  if (master->rxRemainingBytes > 1U)
931  {
932  FLEXIO_I2C_DRV_MasterDmaBlockImmediate(stcdBase, 2U);
933  FLEXIO_I2C_DRV_MasterDmaBlockImmediate(stcdBase, 3U);
934  }
935  /* set DREQ bit for last block */
936  FLEXIO_I2C_DRV_MasterDmaBlockTerminate(stcdBase, (uint8_t)(blockCnt - 2U));
937  }
938 }
939 
940 
941 /*FUNCTION**********************************************************************
942  *
943  * Function Name : FLEXIO_I2C_DRV_MasterStartDmaTransfer
944  * Description : Starts a DMA transfer
945  *
946  *END**************************************************************************/
947 static void FLEXIO_I2C_DRV_MasterStartDmaTransfer(flexio_i2c_master_state_t *master)
948 {
949  uint32_t alignedStcd;
950  edma_software_tcd_t *stcdBase;
951 
952  /* get aligned address to use for software TCDs */
953  alignedStcd = STCD_ADDR(master->stcd);
954  stcdBase = (edma_software_tcd_t *)(alignedStcd);
955 
956  /* Configure Tx and Rx chains */
957  FLEXIO_I2C_DRV_MasterDmaConfigTx(master, stcdBase);
958  FLEXIO_I2C_DRV_MasterDmaConfigRx(master, &stcdBase[FLEXIO_I2C_DMA_TX_CHAIN_LENGTH]);
959 
960  /* Start both DMA channels */
961  (void)EDMA_DRV_StartChannel(master->txDMAChannel);
962  (void)EDMA_DRV_StartChannel(master->rxDMAChannel);
963 }
964 
965 
966 
967 /*FUNCTION**********************************************************************
968  *
969  * Function Name : FLEXIO_I2C_DRV_MasterEndDmaTransfer
970  * Description : Starts a DMA transfer
971  *
972  *END**************************************************************************/
973 static void FLEXIO_I2C_DRV_MasterEndDmaTransfer(void *stateStruct)
974 {
976  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
977  FLEXIO_Type *baseAddr;
978 
979  DEV_ASSERT(stateStruct != NULL);
980 
981  master = (flexio_i2c_master_state_t *)stateStruct;
982  baseAddr = g_flexioBase[master->flexioCommon.instance];
983  resourceIndex = master->flexioCommon.resourceIndex;
984 
985  /* Check for NACK */
986  if (FLEXIO_HAL_GetShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex)))
987  {
988  FLEXIO_HAL_ClearShifterErrorStatus(baseAddr, RX_SHIFTER(resourceIndex));
989  master->status = STATUS_I2C_RECEIVED_NACK;
990  /* Force the transfer to stop */
991  FLEXIO_I2C_DRV_MasterStopTransfer(master);
992  /* Call callback to announce the event to the user */
993  if (master->callback != NULL)
994  {
995  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
996  }
997  return;
998  }
999  /* Check if the transfer is over */
1000  if (FLEXIO_HAL_GetTimerStatus(baseAddr, SCL_TIMER(resourceIndex)))
1001  {
1002  /* Clear timer status */
1003  FLEXIO_HAL_ClearTimerStatus(baseAddr, SCL_TIMER(resourceIndex));
1004  /* Record success if there was no error */
1005  if (master->status == STATUS_BUSY)
1006  {
1007  master->status = STATUS_SUCCESS;
1008  }
1009  /* End transfer */
1010  FLEXIO_I2C_DRV_MasterStopTransfer(master);
1011  /* Call callback to announce the event to the user */
1012  if (master->callback != NULL)
1013  {
1014  master->callback(master, FLEXIO_EVENT_END_TRANSFER, master->callbackParam);
1015  }
1016  }
1017 }
1018 
1019 
1020 /*FUNCTION**********************************************************************
1021  *
1022  * Function Name : FLEXIO_I2C_DRV_MasterStartTransfer
1023  * Description : Perform a send or receive transaction on the I2C bus
1024  *
1025  *END**************************************************************************/
1026 static status_t FLEXIO_I2C_DRV_MasterStartTransfer(flexio_i2c_master_state_t *master,
1027  uint8_t * buff,
1028  uint32_t size,
1029  bool sendStop,
1030  bool receive)
1031 {
1032  FLEXIO_Type *baseAddr;
1033  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1034 
1035  DEV_ASSERT(master != NULL);
1036 
1037  baseAddr = g_flexioBase[master->flexioCommon.instance];
1038  resourceIndex = master->flexioCommon.resourceIndex;
1039 
1040  /* Check if driver is busy */
1041  DEV_ASSERT(master->driverIdle);
1042  /* Check if transfer size is in admissible range */
1044 
1045  /* Check if bus is busy */
1046  if (FLEXIO_I2C_DRV_MasterBusBusy(baseAddr, master))
1047  {
1048  return STATUS_I2C_BUS_BUSY;
1049  }
1050 
1051  /* Initialize transfer data */
1052  master->data = (uint8_t *)buff;
1053  /* Tx - one extra byte for stop condition */
1054  master->txRemainingBytes = size + 1U;
1055  master->rxRemainingBytes = size;
1056  master->status = STATUS_BUSY;
1057  master->driverIdle = false;
1058  master->sendStop = sendStop;
1059  master->receive = receive;
1060  master->addrReceived = false;
1061 
1062  /* Configure device for requested number of bytes, keeping the existing baud rate */
1063  FLEXIO_I2C_DRV_MasterSetBytesNo(baseAddr, master);
1064  /* Enable timers and shifters */
1065  FLEXIO_I2C_DRV_MasterEnableTransfer(master);
1066  /* Enable transfer engine */
1067  switch (master->driverType)
1068  {
1070  /* Send address to start transfer */
1071  FLEXIO_I2C_DRV_MasterSendAddress(baseAddr, master);
1072  /* Enable interrupt for Tx and Rx shifters */
1074  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
1075  true);
1077  (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))),
1078  true);
1079  /* Enable interrupt for SCL timer */
1080  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << SCL_TIMER(resourceIndex)), true);
1081  break;
1083  /* Send address to start transfer */
1084  FLEXIO_I2C_DRV_MasterSendAddress(baseAddr, master);
1085  /* Nothing to do here, FLEXIO_I2C_DRV_MasterGetStatus() will handle the transfer */
1086  break;
1088  FLEXIO_I2C_DRV_MasterStartDmaTransfer(master);
1089  /* Enable error interrupt for Rx shifter - for NACK detection */
1090  FLEXIO_HAL_SetShifterErrorInterrupt(baseAddr, (uint8_t)(1U << RX_SHIFTER(resourceIndex)), true);
1091  /* Enable interrupt for SCL timer - for end of transfer detection */
1092  FLEXIO_HAL_SetTimerInterrupt(baseAddr, (uint8_t)(1U << SCL_TIMER(resourceIndex)), true);
1093  /* Send address to start transfer */
1094  FLEXIO_I2C_DRV_MasterSendAddress(baseAddr, master);
1095  /* Enable FlexIO DMA requests for both shifters */
1096  FLEXIO_HAL_SetShifterDMARequest(baseAddr, (uint8_t)((1U << TX_SHIFTER(resourceIndex)) | (1U << RX_SHIFTER(resourceIndex))), true);
1097  break;
1098  default:
1099  /* Impossible type - do nothing */
1100  break;
1101  }
1102 
1103  return STATUS_SUCCESS;
1104 }
1105 
1108 /*******************************************************************************
1109  * Code
1110  ******************************************************************************/
1111 
1112 /*FUNCTION**********************************************************************
1113  *
1114  * Function Name : FLEXIO_I2C_DRV_MasterInit
1115  * Description : Initialize the FLEXIO_I2C master mode driver
1116  * Implements : FLEXIO_I2C_DRV_MasterInit_Activity
1117  *
1118  *END**************************************************************************/
1120  const flexio_i2c_master_user_config_t * userConfigPtr,
1121  flexio_i2c_master_state_t * master)
1122 {
1123  uint32_t inputClock;
1124  status_t clkErr;
1125  status_t retCode;
1126  status_t osifError = STATUS_SUCCESS;
1127  uint8_t dmaReqTx;
1128  uint8_t dmaReqRx;
1129 
1130  DEV_ASSERT(master != NULL);
1131  DEV_ASSERT(instance < FLEXIO_INSTANCE_COUNT);
1132 
1133  /* Check that device was initialized */
1134  DEV_ASSERT(g_flexioDeviceStatePtr[instance] != NULL);
1135 
1136  /* Get the protocol clock frequency */
1137  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[instance], &inputClock);
1138  DEV_ASSERT(clkErr == STATUS_SUCCESS);
1139  DEV_ASSERT(inputClock > 0U);
1140 
1141  /* Instruct the resource allocator that we need two shifters/timers */
1142  master->flexioCommon.resourceCount = 2U;
1143  /* Common FlexIO driver initialization */
1144  retCode = FLEXIO_DRV_InitDriver(instance, &(master->flexioCommon));
1145  if (retCode != STATUS_SUCCESS)
1146  { /* Initialization failed, not enough resources */
1147  return retCode;
1148  }
1149 
1150  /* Initialize the semaphore */
1151  if (userConfigPtr->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1152  {
1153  osifError = OSIF_SemaCreate(&(master->idleSemaphore), 0U);
1154  DEV_ASSERT(osifError == STATUS_SUCCESS);
1155  }
1156 
1157  /* Initialize driver-specific context structure */
1158  master->driverType = userConfigPtr->driverType;
1159  master->slaveAddress = userConfigPtr->slaveAddress;
1160  master->sdaPin = userConfigPtr->sdaPin;
1161  master->sclPin = userConfigPtr->sclPin;
1162  master->callback = userConfigPtr->callback;
1163  master->callbackParam = userConfigPtr->callbackParam;
1164  master->blocking = false;
1165  master->driverIdle = true;
1166  master->status = STATUS_SUCCESS;
1167 
1168  /* Configure device for I2C mode */
1169  FLEXIO_I2C_DRV_MasterConfigure(master, inputClock, userConfigPtr->baudRate);
1170 
1171  /* Set up transfer engine */
1172  switch (master->driverType)
1173  {
1175  master->flexioCommon.isr = FLEXIO_I2C_DRV_MasterCheckStatus;
1176  break;
1178  /* Nothing to do here, FLEXIO_I2C_DRV_MasterGetStatus() will handle the transfer */
1179  break;
1181  /* Store DMA channel numbers */
1182  master->txDMAChannel = userConfigPtr->txDMAChannel;
1183  master->rxDMAChannel = userConfigPtr->rxDMAChannel;
1184  /* Configure DMA request sources */
1185  dmaReqTx = g_flexioDMASrc[instance][TX_SHIFTER(master->flexioCommon.resourceIndex)];
1186  dmaReqRx = g_flexioDMASrc[instance][RX_SHIFTER(master->flexioCommon.resourceIndex)];
1187  DMAMUX_HAL_SetChannelSource(g_dmamuxBase[0U], userConfigPtr->txDMAChannel, dmaReqTx);
1188  DMAMUX_HAL_SetChannelSource(g_dmamuxBase[0U], userConfigPtr->rxDMAChannel, dmaReqRx);
1189  /* For DMA transfers we use timer interrupts to signal transfer end */
1190  master->flexioCommon.isr = FLEXIO_I2C_DRV_MasterEndDmaTransfer;
1191  break;
1192  default:
1193  /* Impossible type - do nothing */
1194  break;
1195  }
1196 
1197  (void)clkErr;
1198  (void)osifError;
1199  return STATUS_SUCCESS;
1200 }
1201 
1202 
1203 /*FUNCTION**********************************************************************
1204  *
1205  * Function Name : FLEXIO_I2C_DRV_MasterDeinit
1206  * Description : De-initialize the FLEXIO_I2C master mode driver
1207  * Implements : FLEXIO_I2C_DRV_MasterDeinit_Activity
1208  *
1209  *END**************************************************************************/
1211 {
1212  DEV_ASSERT(master != NULL);
1213 
1214  /* Check if driver is busy */
1215  DEV_ASSERT(master->driverIdle);
1216 
1217  /* Destroy the semaphore */
1218  if (master->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1219  {
1220  (void)OSIF_SemaDestroy(&(master->idleSemaphore));
1221  }
1222  return FLEXIO_DRV_DeinitDriver(&(master->flexioCommon));
1223 }
1224 
1225 
1226 /*FUNCTION**********************************************************************
1227  *
1228  * Function Name : FLEXIO_I2C_DRV_MasterSetBaudRate
1229  * Description : Set the baud rate for any subsequent I2C communication
1230  * Implements : FLEXIO_I2C_DRV_MasterSetBaudRate_Activity
1231  *
1232  *END**************************************************************************/
1234 {
1235  FLEXIO_Type *baseAddr;
1236  uint16_t divider;
1237  uint16_t timerCmp;
1238  uint32_t inputClock;
1239  status_t clkErr;
1240  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1241 
1242  DEV_ASSERT(master != NULL);
1243 
1244  baseAddr = g_flexioBase[master->flexioCommon.instance];
1245  resourceIndex = master->flexioCommon.resourceIndex;
1246 
1247  /* Check if driver is busy */
1248  DEV_ASSERT(master->driverIdle);
1249  /* Get the protocol clock frequency */
1250  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[master->flexioCommon.instance], &inputClock);
1251  DEV_ASSERT(clkErr == STATUS_SUCCESS);
1252  DEV_ASSERT(inputClock > 0U);
1253 
1254  /* Compute divider */
1255  FLEXIO_I2C_DRV_MasterComputeBaudRateDivider(baudRate, &divider, inputClock);
1256 
1257  /* Configure timer divider in the lower 8 bits of TIMCMP[CMP] */
1258  timerCmp = FLEXIO_HAL_GetTimerCompare(baseAddr, SCL_TIMER(resourceIndex));
1259  timerCmp = (uint16_t)((timerCmp & 0xFF00U) | divider);
1260  FLEXIO_HAL_SetTimerCompare(baseAddr, SCL_TIMER(resourceIndex), timerCmp);
1261 
1262  (void)clkErr;
1263  return STATUS_SUCCESS;
1264 }
1265 
1266 
1267 /*FUNCTION**********************************************************************
1268  *
1269  * Function Name : FLEXIO_I2C_DRV_MasterGetBaudRate
1270  * Description : Get the currently configured baud rate
1271  * Implements : FLEXIO_I2C_DRV_MasterGetBaudRate_Activity
1272  *
1273  *END**************************************************************************/
1275 {
1276  const FLEXIO_Type *baseAddr;
1277  uint32_t inputClock;
1278  uint16_t divider;
1279  uint16_t timerCmp;
1280  status_t clkErr;
1281  uint8_t resourceIndex; /* Index of first used internal resource instance (shifter and timer) */
1282 
1283  DEV_ASSERT(master != NULL);
1284 
1285  baseAddr = g_flexioBase[master->flexioCommon.instance];
1286  resourceIndex = master->flexioCommon.resourceIndex;
1287 
1288  /* Get the protocol clock frequency */
1289  clkErr = CLOCK_SYS_GetFreq(g_flexioClock[master->flexioCommon.instance], &inputClock);
1290  DEV_ASSERT(clkErr == STATUS_SUCCESS);
1291  DEV_ASSERT(inputClock > 0U);
1292 
1293  /* Get the currently configured divider */
1294  timerCmp = FLEXIO_HAL_GetTimerCompare(baseAddr, SCL_TIMER(resourceIndex));
1295  divider = (uint16_t)(timerCmp & 0x00FFU);
1296 
1297  /* Compute baud rate: input_clock / (2 * (divider + 2)). Round to nearest integer */
1298  *baudRate = (inputClock + divider + 2U) / (2U * ((uint32_t)divider + 2U));
1299 
1300  (void)clkErr;
1301  return STATUS_SUCCESS;
1302 }
1303 
1304 
1305 /*FUNCTION**********************************************************************
1306  *
1307  * Function Name : FLEXIO_I2C_DRV_MasterSetSlaveAddr
1308  * Description : Set the slave address for any subsequent I2C communication
1309  * Implements : FLEXIO_I2C_DRV_MasterSetSlaveAddr_Activity
1310  *
1311  *END**************************************************************************/
1313 {
1314  DEV_ASSERT(master != NULL);
1315 
1316  /* Check if driver is busy */
1317  DEV_ASSERT(master->driverIdle);
1318 
1319  master->slaveAddress = address;
1320  return STATUS_SUCCESS;
1321 }
1322 
1323 
1324 /*FUNCTION**********************************************************************
1325  *
1326  * Function Name : FLEXIO_I2C_DRV_MasterSendData
1327  * Description : Perform a non-blocking send transaction on the I2C bus
1328  * Implements : FLEXIO_I2C_DRV_MasterSendData_Activity
1329  *
1330  *END**************************************************************************/
1332  const uint8_t * txBuff,
1333  uint32_t txSize,
1334  bool sendStop)
1335 {
1336  DEV_ASSERT(master != NULL);
1337  DEV_ASSERT(txBuff != NULL);
1338  DEV_ASSERT(txSize > 0U);
1339 
1340  return FLEXIO_I2C_DRV_MasterStartTransfer(master, (uint8_t *)txBuff, txSize, sendStop, false);
1341 }
1342 
1343 
1344 /*FUNCTION**********************************************************************
1345  *
1346  * Function Name : FLEXIO_I2C_DRV_MasterSendDataBlocking
1347  * Description : Perform a blocking send transaction on the I2C bus
1348  * Implements : FLEXIO_I2C_DRV_MasterSendDataBlocking_Activity
1349  *
1350  *END**************************************************************************/
1352  const uint8_t * txBuff,
1353  uint32_t txSize,
1354  bool sendStop,
1355  uint32_t timeout)
1356 {
1357  status_t status;
1358 
1359  DEV_ASSERT(master != NULL);
1360  DEV_ASSERT(txBuff != NULL);
1361  DEV_ASSERT(txSize > 0U);
1362 
1363  /* Mark transfer as blocking */
1364  if (master->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1365  {
1366  master->blocking = true;
1367  }
1368  /* Start the transfer */
1369  status = FLEXIO_I2C_DRV_MasterStartTransfer(master, (uint8_t *)txBuff, txSize, sendStop, false);
1370  if (status != STATUS_SUCCESS)
1371  {
1372  /* Transfer could not be started */
1373  master->blocking = false;
1374  return status;
1375  }
1376 
1377  /* Wait for transfer to end */
1378  return FLEXIO_I2C_DRV_MasterWaitTransferEnd(master, timeout);
1379 }
1380 
1381 
1382 /*FUNCTION**********************************************************************
1383  *
1384  * Function Name : FLEXIO_I2C_DRV_MasterReceiveData
1385  * Description : Perform a non-blocking receive transaction on the I2C bus
1386  * Implements : FLEXIO_I2C_DRV_MasterReceiveData_Activity
1387  *
1388  *END**************************************************************************/
1390  uint8_t * rxBuff,
1391  uint32_t rxSize,
1392  bool sendStop)
1393 {
1394  DEV_ASSERT(master != NULL);
1395  DEV_ASSERT(rxBuff != NULL);
1396  DEV_ASSERT(rxSize > 0U);
1397 
1398  return FLEXIO_I2C_DRV_MasterStartTransfer(master, rxBuff, rxSize, sendStop, true);
1399 }
1400 
1401 
1402 /*FUNCTION**********************************************************************
1403  *
1404  * Function Name : FLEXIO_I2C_DRV_MasterReceiveDataBlocking
1405  * Description : Perform a blocking receive transaction on the I2C bus
1406  * Implements : FLEXIO_I2C_DRV_MasterReceiveDataBlocking_Activity
1407  *
1408  *END**************************************************************************/
1410  uint8_t * rxBuff,
1411  uint32_t rxSize,
1412  bool sendStop,
1413  uint32_t timeout)
1414 {
1415  status_t status;
1416 
1417  DEV_ASSERT(master != NULL);
1418  DEV_ASSERT(rxBuff != NULL);
1419  DEV_ASSERT(rxSize > 0U);
1420 
1421  /* Mark transfer as blocking */
1422  if (master->driverType != FLEXIO_DRIVER_TYPE_POLLING)
1423  {
1424  master->blocking = true;
1425  }
1426  /* Start the transfer */
1427  status = FLEXIO_I2C_DRV_MasterStartTransfer(master, rxBuff, rxSize, sendStop, true);
1428  if (status != STATUS_SUCCESS)
1429  {
1430  /* Transfer could not be started */
1431  master->blocking = false;
1432  return status;
1433  }
1434 
1435  /* Wait for transfer to end */
1436  return FLEXIO_I2C_DRV_MasterWaitTransferEnd(master, timeout);
1437 }
1438 
1439 
1440 /*FUNCTION**********************************************************************
1441  *
1442  * Function Name : FLEXIO_I2C_DRV_MasterTransferAbort
1443  * Description : Aborts a non-blocking I2C master transaction
1444  * Implements : FLEXIO_I2C_DRV_MasterTransferAbort_Activity
1445  *
1446  *END**************************************************************************/
1448 {
1449  DEV_ASSERT(master != NULL);
1450 
1451  /* Warning: an ongoing transfer can't be aborted safely due to device limitation;
1452  there is no way to know the exact stage of the transfer, and if we disable the module
1453  during the ACK bit (transmit) or during a 0 data bit (receive) the slave will hold
1454  the SDA line low forever and block the I2C bus. NACK reception is the only exception,
1455  as there is no slave to hold the line low. Therefore this function should only be used
1456  in extreme circumstances, and the application must have a way to reset the I2C slave
1457  */
1458 
1459  master->status = STATUS_I2C_ABORTED;
1460  FLEXIO_I2C_DRV_MasterStopTransfer(master);
1461 
1462  return STATUS_SUCCESS;
1463 }
1464 
1465 
1466 /*FUNCTION**********************************************************************
1467  *
1468  * Function Name : FLEXIO_I2C_DRV_MasterGetStatus
1469  * Description : Get the status of the current non-blocking I2C master transaction
1470  * Implements : FLEXIO_I2C_DRV_MasterGetStatus_Activity
1471  *
1472  *END**************************************************************************/
1474 {
1475  DEV_ASSERT(master != NULL);
1476 
1477  if ((!master->driverIdle) && (master->driverType == FLEXIO_DRIVER_TYPE_POLLING))
1478  {
1479  /* In polling mode advance the I2C transfer here */
1480  FLEXIO_I2C_DRV_MasterCheckStatus(master);
1481  }
1482 
1483  if (bytesRemaining != NULL)
1484  {
1485  /* Use rxRemainingBytes even for transmit; byte is not transmitted
1486  until rx shifter confirms the ACK */
1487  *bytesRemaining = master->rxRemainingBytes;
1488  }
1489 
1490  if (!master->driverIdle)
1491  {
1492  return STATUS_BUSY;
1493  }
1494  else
1495  {
1496  return master->status;
1497  }
1498 }
1499 
1500 
1501 /*******************************************************************************
1502  * EOF
1503  ******************************************************************************/
eDMA TCD Implements : edma_software_tcd_t_Class
Definition: edma_driver.h:260
static void FLEXIO_HAL_SetShifterInterrupt(FLEXIO_Type *baseAddr, uint8_t interruptMask, bool enable)
Enables or disables the shifter interrupts.
Definition: flexio_hal.h:823
static void FLEXIO_HAL_SetShifterMode(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_mode_t mode)
Sets the mode of the specified shifter.
Definition: flexio_hal.h:1198
static uint16_t FLEXIO_HAL_GetTimerCompare(const FLEXIO_Type *baseAddr, uint8_t timer)
Returns the compare value of the specified timer.
Definition: flexio_hal.h:2091
DMAMUX_Type *const g_dmamuxBase[DMAMUX_INSTANCE_COUNT]
Array for DMAMUX module register base address.
Definition: edma_common.c:50
static void FLEXIO_HAL_SetTimerControl(FLEXIO_Type *baseAddr, uint8_t timer, uint8_t trigger, flexio_trigger_polarity_t triggerPolarity, flexio_trigger_source_t triggerSource, uint8_t pin, flexio_pin_polarity_t pinPolarity, flexio_pin_config_t pinConfig, flexio_timer_mode_t mode)
Sets all control settings for specified timer.
Definition: flexio_hal.h:1689
static uint8_t FLEXIO_HAL_GetPinData(const FLEXIO_Type *baseAddr)
Returns the current input data read from the FlexIO pins.
Definition: flexio_hal.h:570
status_t OSIF_SemaDestroy(const semaphore_t *const pSem)
Destroys a previously created semaphore.
static bool FLEXIO_HAL_GetTimerStatus(const FLEXIO_Type *baseAddr, uint8_t timer)
Returns the current status of the specified timer.
Definition: flexio_hal.h:724
#define FLEXIO_I2C_MAX_SIZE
Maximum size of a transfer. The restriction is that the total number of SCL edges must not exceed 8 b...
static void FLEXIO_HAL_SetTimerMode(FLEXIO_Type *baseAddr, uint8_t timer, flexio_timer_mode_t mode)
Sets the mode of the specified timer.
Definition: flexio_hal.h:1658
FLEXIO_Type *const g_flexioBase[FLEXIO_INSTANCE_COUNT]
Definition: flexio_common.c:56
status_t EDMA_DRV_StopChannel(uint8_t channel)
Stops the eDMA channel.
Definition: edma_driver.c:790
#define FLEXIO_INSTANCE_COUNT
Definition: S32K144.h:3507
void EDMA_HAL_TCDSetMajorCount(DMA_Type *base, uint32_t channel, uint32_t count)
Sets the major iteration count according to minor loop channel link setting.
Definition: edma_hal.c:388
status_t FLEXIO_I2C_DRV_MasterInit(uint32_t instance, const flexio_i2c_master_user_config_t *userConfigPtr, flexio_i2c_master_state_t *master)
Initialize the FLEXIO_I2C master mode driver.
static void FLEXIO_HAL_WriteShifterBuffer(FLEXIO_Type *baseAddr, uint8_t shifter, uint32_t value, flexio_shifter_buffer_mode_t mode)
Writes a value in the specified shifter buffer.
Definition: flexio_hal.h:1465
static void FLEXIO_HAL_SetShifterPinConfig(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_pin_config_t config)
Configures the pin assigned to the specified shifter.
Definition: flexio_hal.h:1155
static void FLEXIO_HAL_ClearTimerStatus(FLEXIO_Type *baseAddr, uint8_t timer)
Clears the status of the specified timer.
Definition: flexio_hal.h:767
status_t OSIF_SemaCreate(semaphore_t *const pSem, const uint8_t initValue)
Creates a semaphore with a given value.
static void FLEXIO_HAL_SetTimerInterrupt(FLEXIO_Type *baseAddr, uint8_t interruptMask, bool enable)
Enables or disables the timer interrupts.
Definition: flexio_hal.h:959
static void FLEXIO_HAL_SetShifterConfig(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_start_t start, flexio_shifter_stop_t stop, flexio_shifter_source_t source)
Sets all configuration settings for specified shifter.
Definition: flexio_hal.h:1396
status_t FLEXIO_DRV_DeinitDriver(const flexio_common_state_t *driver)
status_t FLEXIO_I2C_DRV_MasterGetBaudRate(flexio_i2c_master_state_t *master, uint32_t *baudRate)
Get the currently configured baud rate.
static uint32_t FLEXIO_HAL_ReadShifterBuffer(const FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_buffer_mode_t mode)
Reads the value from the specified shifter buffer.
Definition: flexio_hal.h:1421
#define DEV_ASSERT(x)
Definition: devassert.h:78
#define STCD_ADDR(address)
Definition: edma_driver.h:90
static void EDMA_HAL_TCDSetSrcOffset(DMA_Type *base, uint32_t channel, int16_t offset)
Configures the source address signed offset for the hardware TCD.
Definition: edma_hal.h:813
__IO uint32_t SHIFTBUFBIS[FLEXIO_SHIFTBUFBIS_COUNT]
Definition: S32K144.h:3493
static void FLEXIO_HAL_SetShifterControl(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_mode_t mode, uint8_t pin, flexio_pin_polarity_t pinPolarity, flexio_pin_config_t pinConfig, uint8_t timer, flexio_timer_polarity_t timerPolarity)
Sets all control settings for the specified shifter.
Definition: flexio_hal.h:1228
status_t CLOCK_SYS_GetFreq(clock_names_t clockName, uint32_t *frequency)
Gets the clock frequency for a specific clock name.
status_t FLEXIO_I2C_DRV_MasterSetSlaveAddr(flexio_i2c_master_state_t *master, uint16_t address)
Set the slave address for any subsequent I2C communication.
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
status_t EDMA_DRV_ConfigScatterGatherTransfer(uint8_t channel, edma_software_tcd_t *stcd, edma_transfer_size_t transferSize, uint32_t bytesOnEachRequest, const edma_scatter_gather_list_t *srcList, const edma_scatter_gather_list_t *destList, uint8_t tcdCount)
Configures the DMA transfer in a scatter-gather mode.
Definition: edma_driver.c:614
const uint8_t g_flexioDMASrc[FLEXIO_INSTANCE_COUNT][FEATURE_FLEXIO_MAX_SHIFTER_COUNT]
Definition: flexio_common.c:68
Data structure for configuring a discrete memory transfer. Implements : edma_scatter_gather_list_t_Cl...
Definition: edma_driver.h:179
status_t FLEXIO_I2C_DRV_MasterDeinit(flexio_i2c_master_state_t *master)
De-initialize the FLEXIO_I2C master mode driver.
static void FLEXIO_HAL_SetTimerCompare(FLEXIO_Type *baseAddr, uint8_t timer, uint16_t value)
Configures the compare value for the specified timer.
Definition: flexio_hal.h:2118
#define FLEXIO_SHIFTCFG_SSTOP(x)
Definition: S32K144.h:3659
status_t FLEXIO_DRV_InitDriver(uint32_t instance, flexio_common_state_t *driver)
static void FLEXIO_HAL_SetTimerConfig(FLEXIO_Type *baseAddr, uint8_t timer, flexio_timer_start_t start, flexio_timer_stop_t stop, flexio_timer_enable_t enable, flexio_timer_disable_t disable, flexio_timer_reset_t reset, flexio_timer_decrement_t decrement, flexio_timer_output_t output)
Sets all configuration settings for specified timer.
Definition: flexio_hal.h:2060
edma_transfer_type_t type
Definition: edma_driver.h:182
static void EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(DMA_Type *base, uint32_t channel, bool disable)
Disables/Enables the DMA request after the major loop completes for the TCD.
Definition: edma_hal.h:1117
status_t OSIF_SemaWait(semaphore_t *const pSem, const uint32_t timeout)
Decrement a semaphore with timeout.
status_t EDMA_DRV_StartChannel(uint8_t channel)
Starts an eDMA channel.
Definition: edma_driver.c:765
#define DMA_TCD_CSR_START(x)
Definition: S32K144.h:3026
status_t FLEXIO_I2C_DRV_MasterSetBaudRate(flexio_i2c_master_state_t *master, uint32_t baudRate)
Set the baud rate for any subsequent I2C communication.
__IO uint32_t SHIFTCFG[FLEXIO_SHIFTCFG_COUNT]
Definition: S32K144.h:3489
static void EDMA_HAL_TCDSetDestOffset(DMA_Type *base, uint32_t channel, int16_t offset)
Configures the destination address signed offset for the TCD.
Definition: edma_hal.h:987
status_t OSIF_SemaPost(semaphore_t *const pSem)
Increment a semaphore.
flexio_device_state_t * g_flexioDeviceStatePtr[FLEXIO_INSTANCE_COUNT]
Definition: flexio_common.c:59
DMA_Type *const g_edmaBase[DMA_INSTANCE_COUNT]
Array for the eDMA module register base address.
Definition: edma_common.c:47
static bool FLEXIO_HAL_GetShifterStatus(const FLEXIO_Type *baseAddr, uint8_t shifter)
Returns the current status of the specified shifter.
Definition: flexio_hal.h:593
static void FLEXIO_HAL_ClearShifterErrorStatus(FLEXIO_Type *baseAddr, uint8_t shifter)
Clears the error status of the specified shifter.
Definition: flexio_hal.h:699
Master internal context structure.
#define FLEXIO_SHIFTCFG_SSTOP_MASK
Definition: S32K144.h:3656
static void DMAMUX_HAL_SetChannelSource(DMAMUX_Type *base, uint32_t channel, uint8_t source)
Configures the DMA request for the DMAMUX channel.
Definition: dmamux_hal.h:108
static void FLEXIO_HAL_SetShifterErrorInterrupt(FLEXIO_Type *baseAddr, uint8_t interruptMask, bool enable)
Enables or disables the shifter error interrupts.
Definition: flexio_hal.h:891
Master configuration structure.
status_t FLEXIO_I2C_DRV_MasterSendDataBlocking(flexio_i2c_master_state_t *master, const uint8_t *txBuff, uint32_t txSize, bool sendStop, uint32_t timeout)
Perform a blocking send transaction on the I2C bus.
static bool FLEXIO_HAL_GetShifterErrorStatus(const FLEXIO_Type *baseAddr, uint8_t shifter)
Returns the current error status of the specified shifter.
Definition: flexio_hal.h:658
const clock_names_t g_flexioClock[FLEXIO_INSTANCE_COUNT]
Definition: flexio_common.c:65
status_t EDMA_DRV_ConfigSingleBlockTransfer(uint8_t channel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t dataBufferSize)
Configures a simple single block data transfer with DMA.
Definition: edma_driver.c:487
status_t FLEXIO_I2C_DRV_MasterReceiveDataBlocking(flexio_i2c_master_state_t *master, uint8_t *rxBuff, uint32_t rxSize, bool sendStop, uint32_t timeout)
Perform a blocking receive transaction on the I2C bus.
status_t FLEXIO_I2C_DRV_MasterTransferAbort(flexio_i2c_master_state_t *master)
Aborts a non-blocking I2C master transaction.
status_t FLEXIO_I2C_DRV_MasterReceiveData(flexio_i2c_master_state_t *master, uint8_t *rxBuff, uint32_t rxSize, bool sendStop)
Perform a non-blocking receive transaction on the I2C bus.
static void FLEXIO_HAL_SetShifterStopBit(FLEXIO_Type *baseAddr, uint8_t shifter, flexio_shifter_stop_t stop)
Configures the stop bit of the specified shifter.
Definition: flexio_hal.h:1324
status_t FLEXIO_I2C_DRV_MasterGetStatus(flexio_i2c_master_state_t *master, uint32_t *bytesRemaining)
Get the status of the current non-blocking I2C master transaction.
status_t FLEXIO_I2C_DRV_MasterSendData(flexio_i2c_master_state_t *master, const uint8_t *txBuff, uint32_t txSize, bool sendStop)
Perform a non-blocking send transaction on the I2C bus.
static void FLEXIO_HAL_ClearShifterStatus(FLEXIO_Type *baseAddr, uint8_t shifter)
Clears the status of the specified shifter.
Definition: flexio_hal.h:635
#define DMA_TCD_CSR_DREQ(x)
Definition: S32K144.h:3038
static void FLEXIO_HAL_SetShifterDMARequest(FLEXIO_Type *baseAddr, uint8_t requestMask, bool enable)
Enables or disables the shifter DMA requests.
Definition: flexio_hal.h:1010