S32 SDK
lpi2c_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  */
89 #include "lpi2c_driver.h"
90 #include "interrupt_manager.h"
91 #include "lpi2c_hal.h"
92 #include "clock_manager.h"
93 
94 /*******************************************************************************
95  * Variables
96  ******************************************************************************/
97 
100 /* Constraints used for baud rate computation */
101 #define CLKHI_MIN_VALUE 1U
102 #define CLKLO_MIN_VALUE 3U
103 #define CLKHI_MAX_VALUE (((1U << LPI2C_MCCR0_CLKHI_WIDTH) - 1U) >> 1U)
104 #define CLKLO_MAX_VALUE (CLKHI_MAX_VALUE << 1U)
105 #define DATAVD_MIN_VALUE 1U
106 #define SETHOLD_MIN_VALUE 2U
107 
108 /* Table of base addresses for LPI2C instances. */
109 LPI2C_Type * const g_lpi2cBase[LPI2C_INSTANCE_COUNT] = LPI2C_BASE_PTRS;
110 
111  /* LPI2C DMA request sources */
112  const uint8_t g_lpi2cDMASrc[LPI2C_INSTANCE_COUNT][2] = {{(uint8_t)EDMA_REQ_LPI2C0_TX, (uint8_t)EDMA_REQ_LPI2C0_RX}};
113 
114 /* Pointer to runtime state structure.*/
115 lpi2c_master_state_t* g_lpi2cMasterStatePtr[LPI2C_INSTANCE_COUNT] = {NULL};
116 lpi2c_slave_state_t* g_lpi2cSlaveStatePtr[LPI2C_INSTANCE_COUNT] = {NULL};
117 
118 /* Table for lpi2c IRQ numbers */
119 const IRQn_Type g_lpi2cMasterIrqId[LPI2C_INSTANCE_COUNT] = LPI2C_MASTER_IRQS;
120 const IRQn_Type g_lpi2cSlaveIrqId[LPI2C_INSTANCE_COUNT] = LPI2C_SLAVE_IRQS;
121 
122 /* PCC clock sources, for getting the input clock frequency */
123 const clock_names_t g_lpi2cClock[LPI2C_INSTANCE_COUNT] = {PCC_LPI2C0_CLOCK};
124 
125 /* Callback for master DMA transfer done.*/
126 static void LPI2C_DRV_MasterCompleteDMATransfer(void* parameter, edma_chn_status_t status);
127 
129 typedef enum
130 {
131  LPI2C_TX_REQ = 0,
132  LPI2C_RX_REQ = 1,
133 } lpi2c_transfer_direction_t;
134 
141 typedef struct
142 {
144  uint8_t dmaChannel; /* Channel number for the DMA channel */
145  edma_transfer_type_t dmaTransferType; /* Type for the DMA transfer */
146  uint32_t i2cDataRegAddr; /* An i2c data register address */
147  uint8_t *bufferTransfer; /* Buffer used for transfer */
148  uint32_t transferSize; /* Size of the data to be transfered */
149  lpi2c_transfer_direction_t transferDirection; /* Tells if the driver will make a receive or transmit DMA transfer */
152 
153 
154 /*******************************************************************************
155  * Private Functions
156  ******************************************************************************/
157 
158 
159 /*FUNCTION**********************************************************************
160  *
161  * Function Name : LPI2C_DRV_MasterCmdQueueEmpty
162  * Description : checks if there are any commands in the master software queue
163  *
164  *END**************************************************************************/
165 static inline bool LPI2C_DRV_MasterCmdQueueEmpty(const lpi2c_master_state_t * master)
166 {
167  DEV_ASSERT(master != NULL);
168 
169  return (master->cmdQueue.writeIdx == master->cmdQueue.readIdx);
170 }
171 
172 
173 /*FUNCTION**********************************************************************
174  *
175  * Function Name : LPI2C_DRV_MasterResetQueue
176  * Description : resets the master software queue
177  *
178  *END**************************************************************************/
180 {
181  DEV_ASSERT(master != NULL);
182 
183  master->cmdQueue.readIdx = 0U;
184  master->cmdQueue.writeIdx = 0U;
185 }
186 
187 
188 /*FUNCTION**********************************************************************
189  *
190  * Function Name : LPI2C_DRV_MasterQueueCmd
191  * Description : queues a command in the hardware FIFO or in the master software queue
192  *
193  *END**************************************************************************/
194 static inline void LPI2C_DRV_MasterQueueCmd(LPI2C_Type *baseAddr,
195  lpi2c_master_state_t * master,
197  uint8_t data)
198 {
199  DEV_ASSERT(master != NULL);
200  DEV_ASSERT(baseAddr != NULL);
201 
202  uint8_t txFIFOCount = LPI2C_HAL_MasterGetTxFIFOCount(baseAddr);
203  uint16_t txFIFOSize = LPI2C_HAL_MasterGetTxFIFOSize(baseAddr);
204 
205  /* Check if there is room in the hardware FIFO */
206  if ((uint16_t)txFIFOCount < txFIFOSize)
207  {
208  LPI2C_HAL_MasterTransmitCmd(baseAddr, cmd, data);
209  }
210  else
211  {
212  /* Hardware FIFO full, use software FIFO */
213  DEV_ASSERT(master->cmdQueue.writeIdx < LPI2C_MASTER_CMD_QUEUE_SIZE);
214 
215  master->cmdQueue.cmd[master->cmdQueue.writeIdx] = cmd;
216  master->cmdQueue.data[master->cmdQueue.writeIdx] = data;
217  master->cmdQueue.writeIdx++;
218  }
219 }
220 
221 
222 /*FUNCTION**********************************************************************
223  *
224  * Function Name : LPI2C_DRV_MasterSendQueuedCmd
225  * Description : transfers commands from the master software queue to the hardware FIFO
226  *
227  *END**************************************************************************/
228 static inline void LPI2C_DRV_MasterSendQueuedCmd(LPI2C_Type *baseAddr, lpi2c_master_state_t * master)
229 {
230  DEV_ASSERT(master != NULL);
231  DEV_ASSERT(baseAddr != NULL);
232 
233  uint8_t txFIFOCount = LPI2C_HAL_MasterGetTxFIFOCount(baseAddr);
234  uint16_t txFifoSize = LPI2C_HAL_MasterGetTxFIFOSize(baseAddr);
235 
236  while ((!LPI2C_DRV_MasterCmdQueueEmpty(master)) && ((uint16_t)txFIFOCount < txFifoSize))
237  {
239  master->cmdQueue.cmd[master->cmdQueue.readIdx],
240  master->cmdQueue.data[master->cmdQueue.readIdx]);
241  master->cmdQueue.readIdx++;
242 
243  txFIFOCount = LPI2C_HAL_MasterGetTxFIFOCount(baseAddr);
244  }
245 
246  if (LPI2C_DRV_MasterCmdQueueEmpty(master))
247  {
248  /* Reset queue */
250  }
251 }
252 
253 
254 /*FUNCTION**********************************************************************
255  *
256  * Function Name : LPI2C_DRV_MasterSendAddress
257  * Description : send start event and slave address
258  * parameter receive specifies the direction of the transfer
259  *
260  *END**************************************************************************/
262  lpi2c_master_state_t * master,
263  bool receive)
264 {
265  uint8_t addrByte;
266  lpi2c_master_command_t startCommand;
267 
268  DEV_ASSERT(master != NULL);
269  DEV_ASSERT(baseAddr != NULL);
270 
271 #if(LPI2C_HAS_HIGH_SPEED_MODE)
272  if ((master->operatingMode == LPI2C_HIGHSPEED_MODE) && (master->highSpeedInProgress == false))
273  {
274  /* Initiating High-speed mode - send master code first */
275  LPI2C_DRV_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_START_NACK, master->masterCode);
276  master->highSpeedInProgress = true;
277  }
278 
279  if (master->highSpeedInProgress == true)
280  {
281  /* Use high-speed settings after start event in High Speed mode */
282  startCommand = LPI2C_MASTER_COMMAND_START_HS;
283  }
284  else
285 #endif
286  {
287  /* Normal START command */
288  startCommand = LPI2C_MASTER_COMMAND_START;
289  }
290 
291  if (master->is10bitAddr)
292  {
293  /* 10-bit addressing */
294  /* First address byte: 1111 0XXD, where XX are bits 10 and 9 of address, and D = 0(transmit) */
295  addrByte = (uint8_t)(0xF0U + ((master->slaveAddress >> 7U) & 0x6U) + (uint8_t)0U);
296  LPI2C_DRV_MasterQueueCmd(baseAddr, master, startCommand, addrByte);
297  /* Second address byte: Remaining 8 bits of address */
298  addrByte = (uint8_t)(master->slaveAddress & 0xFFU);
299  LPI2C_DRV_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_TRANSMIT, addrByte);
300  if (receive == true)
301  {
302  /* Receiving from 10-bit slave - must send repeated start and resend first address byte */
303  /* First address byte: 1111 0XXD, where XX are bits 10 and 9 of address, and D = 1 (receive) */
304  addrByte = (uint8_t)(0xF0U + ((master->slaveAddress >> 7U) & 0x6U) + (uint8_t)1U);
305  LPI2C_DRV_MasterQueueCmd(baseAddr, master, startCommand, addrByte);
306  }
307  }
308  else
309  {
310  /* 7-bit addressing */
311  /* Address byte: slave 7-bit address + D = 0(transmit) or 1 (receive) */
312  addrByte = (uint8_t)((master->slaveAddress << 1U) + (uint8_t)receive);
313  LPI2C_DRV_MasterQueueCmd(baseAddr, master, startCommand, addrByte);
314  }
315 }
316 
317 
318 /*FUNCTION**********************************************************************
319  *
320  * Function Name : LPI2C_DRV_MasterQueueData
321  * Description : queues transmit data in the LPI2C tx fifo until it is full
322  *
323  *END**************************************************************************/
324 static void LPI2C_DRV_MasterQueueData(LPI2C_Type *baseAddr,
325  lpi2c_master_state_t * master)
326 {
327  DEV_ASSERT(master != NULL);
328  DEV_ASSERT(baseAddr != NULL);
329 
330  uint8_t txFIFOCount = LPI2C_HAL_MasterGetTxFIFOCount(baseAddr);
331  uint16_t txFifoSize = LPI2C_HAL_MasterGetTxFIFOSize(baseAddr);
332 
333  /* Don't queue any data if there are commands in the software queue */
334  if (LPI2C_DRV_MasterCmdQueueEmpty(master))
335  {
336  while ((master->txSize > 0U) && ((uint16_t)txFIFOCount < txFifoSize))
337  {
338  LPI2C_HAL_MasterTransmitCmd(baseAddr, LPI2C_MASTER_COMMAND_TRANSMIT, master->txBuff[0U]);
339  master->txBuff++;
340  master->txSize--;
341 
342  txFIFOCount = LPI2C_HAL_MasterGetTxFIFOCount(baseAddr);
343  }
344  }
345 }
346 
347 
348 /*FUNCTION**********************************************************************
349  *
350  * Function Name : LPI2C_DRV_MasterEndTransfer
351  * Description : ends current transmission or reception
352  *
353  *END**************************************************************************/
355  lpi2c_master_state_t * master,
356  bool sendStop,
357  bool resetFIFO)
358 {
359  DEV_ASSERT(master != NULL);
360  DEV_ASSERT(baseAddr != NULL);
361 
362  /* Disable all events */
368  false);
369 
370  if (resetFIFO == true)
371  {
372  /* Reset FIFOs if requested */
375  }
376 
377  /* Queue STOP command if requested */
378  if (sendStop == true)
379  {
381 #if(LPI2C_HAS_HIGH_SPEED_MODE)
382  master->highSpeedInProgress = false; /* High-speed transfers end at STOP condition */
383 #endif
384  }
385 
386  if (master->transferType == LPI2C_USING_DMA)
387  {
388  /* Disable LPI2C DMA request. */
389  if (master->rxSize != (uint16_t)0)
390  {
391  (void)LPI2C_HAL_MasterSetRxDMA(baseAddr, false);
392  }
393  else
394  {
395  (void)LPI2C_HAL_MasterSetTxDMA(baseAddr, false);
396  }
397  }
398 
399  master->txBuff = NULL;
400  master->txSize = 0;
401  master->rxBuff = NULL;
402  master->rxSize = 0;
403  master->i2cIdle = true;
404 }
405 
406 
407 /*FUNCTION**********************************************************************
408  *
409  * Function Name : LPI2C_DRV_SlaveEndTransfer
410  * Description : ends current transmission or reception
411  *
412  *END**************************************************************************/
414  lpi2c_slave_state_t *slave)
415 {
416  DEV_ASSERT(slave != NULL);
417  DEV_ASSERT(baseAddr != NULL);
418 
419  /* Deactivate events */
420 
428  false);
429 
430  /* For DMA we must disable the DMA request. */
431  if (slave->transferType == LPI2C_USING_DMA)
432  {
433  if (slave->rxSize != (uint16_t)0)
434  {
435  (void)LPI2C_HAL_SlaveSetRxDMA(baseAddr, false);
436  }
437  else
438  {
439  (void)LPI2C_HAL_SlaveSetTxDMA(baseAddr, false);
440  }
441  }
442 
443  /* Disable LPI2C slave */
444  LPI2C_HAL_SlaveSetEnable(baseAddr, false);
445 
446  slave->isTransferInProgress = false;
447  slave->rxBuff = NULL;
448  slave->rxSize = 0U;
449  slave->txBuff = NULL;
450  slave->rxSize = 0U;
451 }
452 
453 
454 /*FUNCTION**********************************************************************
455  *
456  * Function Name : LPI2C_DRV_MasterSetOperatingMode
457  * Description : sets the operating mode of the I2C master
458  *
459  *END**************************************************************************/
460 static void LPI2C_DRV_MasterSetOperatingMode(uint32_t instance, lpi2c_mode_t operatingMode)
461 {
462  LPI2C_Type *baseAddr;
463  lpi2c_master_state_t * master;
464 
465  baseAddr = g_lpi2cBase[instance];
466  master = g_lpi2cMasterStatePtr[instance];
467  DEV_ASSERT(master != NULL);
468 
469 #if(LPI2C_HAS_ULTRA_FAST_MODE)
470  if (operatingMode == LPI2C_ULTRAFAST_MODE)
471  {
474  }
475  else
476 #endif
477  {
480  }
481 
482  master->operatingMode = operatingMode;
483 }
484 
485 
486 /*FUNCTION**********************************************************************
487  *
488  * Function Name : LPI2C_DRV_SlaveSetOperatingMode
489  * Description : sets the operating mode of the I2C slave
490  *
491  *END**************************************************************************/
492 static void LPI2C_DRV_SlaveSetOperatingMode(uint32_t instance, lpi2c_mode_t operatingMode)
493 {
494  LPI2C_Type *baseAddr;
495  lpi2c_slave_state_t * slave;
496 
497  baseAddr = g_lpi2cBase[instance];
498  slave = g_lpi2cSlaveStatePtr[instance];
499  DEV_ASSERT(slave != NULL);
500 
501 #if(LPI2C_HAS_ULTRA_FAST_MODE)
502  if (operatingMode == LPI2C_ULTRAFAST_MODE)
503  {
506  /* Disable all clock stretching in ultra-fast mode */
507  LPI2C_HAL_SlaveSetACKStall(baseAddr, false);
508  LPI2C_HAL_SlaveSetTXDStall(baseAddr, false);
509  LPI2C_HAL_SlaveSetRXStall(baseAddr, false);
510  LPI2C_HAL_SlaveSetAddrStall(baseAddr, false);
511  }
512  else
513 #endif
514  {
517  /* Enable clock stretching except ACKSTALL (we don't need to send ACK/NACK manually) */
518  LPI2C_HAL_SlaveSetACKStall(baseAddr, false);
519  LPI2C_HAL_SlaveSetTXDStall(baseAddr, true);
520  LPI2C_HAL_SlaveSetRXStall(baseAddr, true);
521  LPI2C_HAL_SlaveSetAddrStall(baseAddr, true);
522  }
523 
524 #if(LPI2C_HAS_HIGH_SPEED_MODE)
525  if (operatingMode == LPI2C_HIGHSPEED_MODE)
526  {
527  /* Enable detection of the High-speed Mode master code */
529  }
530  else
531 #endif
532  {
533  /* Disable detection of the High-speed Mode master code */
534  LPI2C_HAL_SlaveSetHighSpeedModeDetect(baseAddr, false);
535  }
536 
537  slave->operatingMode = operatingMode;
538 }
539 
540 
541 /*FUNCTION**********************************************************************
542  *
543  * Function Name : LPI2C_DRV_ConfigureDmaTransfer
544  * Description : configures the DMA transfer
545  *
546  *END**************************************************************************/
547 static void LPI2C_DRV_ConfigureDmaTransfer(uint32_t instance, const lpi2c_dma_transfer_params_t *dmaTransParams)
548 {
551 
552  /* Configure DMA channel */
553  if (dmaTransParams->transferDirection == LPI2C_TX_REQ)
554  {
555  DMAMUX_HAL_SetChannelSource(baseDmaMux, dmaTransParams->dmaChannel, g_lpi2cDMASrc[instance][LPI2C_TX_REQ]);
556  (void)EDMA_DRV_ConfigSingleBlockTransfer(dmaTransParams->dmaChannel, dmaTransParams->dmaTransferType, (uint32_t)dmaTransParams->bufferTransfer,
557  (uint32_t)dmaTransParams->i2cDataRegAddr, EDMA_TRANSFER_SIZE_1B, (uint32_t)1U);
558  }
559  else
560  {
561  DMAMUX_HAL_SetChannelSource(baseDmaMux, dmaTransParams->dmaChannel, g_lpi2cDMASrc[instance][LPI2C_RX_REQ]);
562  (void)EDMA_DRV_ConfigSingleBlockTransfer(dmaTransParams->dmaChannel, dmaTransParams->dmaTransferType, (uint32_t)dmaTransParams->i2cDataRegAddr,
563  (uint32_t)dmaTransParams->bufferTransfer, EDMA_TRANSFER_SIZE_1B, (uint32_t)1U);
564  }
565  (void)EDMA_HAL_TCDSetMajorCount(baseDma, dmaTransParams->dmaChannel, (uint32_t)dmaTransParams->transferSize);
566 }
567 
568 
569 /*FUNCTION**********************************************************************
570  *
571  * Function Name : LPI2C_DRV_MasterStartDmaTransfer
572  * Description : starts the DMA transfer for master
573  *
574  *END**************************************************************************/
575 static void LPI2C_DRV_MasterStartDmaTransfer(uint32_t instance)
576 {
577  LPI2C_Type *baseAddr = g_lpi2cBase[instance];
578  lpi2c_master_state_t *master = g_lpi2cMasterStatePtr[instance];
579  lpi2c_dma_transfer_params_t dmaTransParams;
580  bool receive = false;
581 
582  dmaTransParams.dmaChannel = master->dmaChannel;
583  if (master->txSize > 0U)
584  {
585  /* Configure watermarks for transmit DMA for master */
586  uint32_t txBytes = LPI2C_HAL_MasterGetTxFIFOSize(baseAddr);
587  if (txBytes > master->txSize)
588  {
589  txBytes = master->txSize;
590  }
591  LPI2C_HAL_MasterSetTxFIFOWatermark(baseAddr, (uint8_t)(txBytes - 1U));
592 
593  dmaTransParams.dmaTransferType = EDMA_TRANSFER_MEM2PERIPH;
594  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->MTDR));
595  dmaTransParams.bufferTransfer = (uint8_t *)master->txBuff;
596  dmaTransParams.transferDirection = LPI2C_TX_REQ;
597  dmaTransParams.transferSize = master->txSize;
598 
599  }
600  else
601  {
602  /* Configure watermarks for receive DMA for master */
604 
605  receive = true;
606 
607  dmaTransParams.dmaTransferType = EDMA_TRANSFER_PERIPH2MEM;
608  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->MRDR));
609  dmaTransParams.bufferTransfer = master->rxBuff;
610  dmaTransParams.transferDirection = LPI2C_RX_REQ;
611  dmaTransParams.transferSize = master->rxSize;
612  }
613 
614  (void)LPI2C_DRV_ConfigureDmaTransfer(instance, &dmaTransParams);
615 
616  /* Disable DMA requests for channel when transfer is done */
617  (void)EDMA_HAL_TCDSetDisableDmaRequestAfterTCDDoneCmd(g_edmaBase[LPI2C_DMA_INSTANCE], dmaTransParams.dmaChannel, true);
618 
619  /* Call callback function when all the bytes were transfered. */
620  (void)EDMA_DRV_InstallCallback(dmaTransParams.dmaChannel, (LPI2C_DRV_MasterCompleteDMATransfer), (void*)(instance));
621 
622  /* Start channel */
623  (void)EDMA_DRV_StartChannel(dmaTransParams.dmaChannel);
624 
625  LPI2C_DRV_MasterSendAddress(baseAddr, master, receive);
626 
627  /* Enable transmit/receive DMA requests */
628  if (master->txSize > (uint32_t)0U)
629  {
630  (void)LPI2C_HAL_MasterSetTxDMA(baseAddr, true);
631  }
632  else
633  {
634  LPI2C_DRV_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_RECEIVE, (uint8_t)(master->rxSize - 1U));
635  (void)LPI2C_HAL_MasterSetRxDMA(baseAddr, true);
636  }
637 }
638 
639 
640 /*FUNCTION**********************************************************************
641  *
642  * Function Name : LPI2C_DRV_SlaveStartDmaTransfer
643  * Description : starts the DMA transfer for slave
644  *
645  *END**************************************************************************/
646 static void LPI2C_DRV_SlaveStartDmaTransfer(uint32_t instance)
647 {
648  LPI2C_Type *baseAddr = g_lpi2cBase[instance];
649  const lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
650  lpi2c_dma_transfer_params_t dmaTransParams;
651 
652  if (slave->txSize > (uint32_t)0U)
653  {
654  dmaTransParams.dmaChannel = slave->dmaChannel;
655  dmaTransParams.dmaTransferType = EDMA_TRANSFER_MEM2PERIPH;
656  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->STDR));
657  dmaTransParams.bufferTransfer = (uint8_t*)slave->txBuff;
658  dmaTransParams.transferDirection = LPI2C_TX_REQ;
659  dmaTransParams.transferSize = slave->txSize;
660  }
661  else
662  {
663  dmaTransParams.dmaChannel = slave->dmaChannel;
664  dmaTransParams.dmaTransferType = EDMA_TRANSFER_PERIPH2MEM;
665  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->SRDR));
666  dmaTransParams.bufferTransfer = slave->rxBuff;
667  dmaTransParams.transferDirection = LPI2C_RX_REQ;
668  dmaTransParams.transferSize = slave->rxSize;
669  }
670 
671  (void)LPI2C_DRV_ConfigureDmaTransfer(instance, &dmaTransParams);
672  /* Adjustment added to source address at the beginning of TX buffer */
673  EDMA_HAL_TCDSetSrcLastAdjust(g_edmaBase[LPI2C_DMA_INSTANCE],dmaTransParams.dmaChannel, -(int32_t)(slave->txSize));
674 
675  /* Start channel */
676  (void)EDMA_DRV_StartChannel(dmaTransParams.dmaChannel);
677 
678  /* Enable transmit/receive DMA requests */
679  if (slave->txSize > (uint32_t)0U)
680  {
681  (void)LPI2C_HAL_SlaveSetTxDMA(baseAddr, true);
682  }
683  else
684  {
685  (void)LPI2C_HAL_SlaveSetRxDMA(baseAddr, true);
686  }
687 }
688 
689 
690 /*FUNCTION**********************************************************************
691  *
692  * Function Name : LPI2C_DRV_MasterCompleteDMATransfer
693  * Description : Finish up a transfer DMA for master. The main purpose of
694  * this function is to create a function compatible with DMA
695  * callback type
696  *
697  *END**************************************************************************/
698 static void LPI2C_DRV_MasterCompleteDMATransfer(void* parameter, edma_chn_status_t status)
699 {
700  LPI2C_Type *baseAddr;
701  lpi2c_master_state_t *master;
702 
703  (void)status;
704 
705  uint32_t instance = (uint32_t)parameter;
706 
707  baseAddr = g_lpi2cBase[instance];
708  master = g_lpi2cMasterStatePtr[instance];
709 
710  LPI2C_DRV_MasterEndTransfer(baseAddr, master, master->sendStop, false);
711 
712  /* Signal transfer end for blocking transfers */
713  if (master->blocking == true)
714  {
715  (void)OSIF_SemaPost(&(master->idleSemaphore));
716  }
717 
718  master->status = STATUS_SUCCESS;
719 }
720 
721 
722 /*FUNCTION**********************************************************************
723  *
724  * Function Name : LPI2C_DRV_MasterWaitTransferEnd
725  * Description : waits for the end of a blocking transfer
726  *
727  *END**************************************************************************/
728 static status_t LPI2C_DRV_MasterWaitTransferEnd(uint32_t instance, uint32_t timeout)
729 {
730  status_t osifError = STATUS_SUCCESS;
731  LPI2C_Type *baseAddr;
732  lpi2c_master_state_t *master;
733 
734  baseAddr = g_lpi2cBase[instance];
735  master = g_lpi2cMasterStatePtr[instance];
736 
737  /* Wait for transfer to be completed by the IRQ */
738  osifError = OSIF_SemaWait(&(master->idleSemaphore), timeout);
739 
740  if (osifError == STATUS_TIMEOUT)
741  {
742  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
743  master->status = STATUS_TIMEOUT;
744  }
745 
746  /* Blocking transfer is over */
747  master->blocking = false;
748  return master->status;
749 }
750 
751 
752 /*FUNCTION**********************************************************************
753  *
754  * Function Name : LPI2C_DRV_SlaveWaitTransferEnd
755  * Description : waits for the end of a blocking transfer
756  *
757  *END**************************************************************************/
758 static status_t LPI2C_DRV_SlaveWaitTransferEnd(uint32_t instance, uint32_t timeout)
759 {
760  status_t osifError = STATUS_SUCCESS;
761  LPI2C_Type *baseAddr;
762  lpi2c_slave_state_t *slave;
763 
764  baseAddr = g_lpi2cBase[instance];
765  slave = g_lpi2cSlaveStatePtr[instance];
766 
767  /* Wait for transfer to be completed by the IRQ */
768  osifError = OSIF_SemaWait(&(slave->idleSemaphore), timeout);
769 
770  if (osifError == STATUS_TIMEOUT)
771  {
772  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
773  slave->status = STATUS_TIMEOUT;
774  }
775 
776  /* Blocking transfer is over */
777  slave->blocking = false;
778  return slave->status;
779 }
780 
781 
782 /*FUNCTION**********************************************************************
783  *
784  * Function Name : LPI2C_DRV_MasterHandleTransmitDataRequest
785  * Description : handle a transmit request for master
786  *
787  *END**************************************************************************/
788 static void LPI2C_DRV_MasterHandleTransmitDataRequest(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
789 {
790  /* More data needed for transmission */
791  if (!LPI2C_DRV_MasterCmdQueueEmpty(master))
792  {
793  /* If there are queued commands, send them */
794  LPI2C_DRV_MasterSendQueuedCmd(baseAddr, master);
795  }
796  else if (master->txBuff != NULL)
797  {
798  /* A transmission is in progress */
799  if (master->txSize == 0U)
800  {
801  /* There is no more data in buffer, the transmission is over */
802  LPI2C_DRV_MasterEndTransfer(baseAddr, master, master->sendStop, false);
803 
804  /* Signal transfer end for blocking transfers */
805  if (master->blocking == true)
806  {
807  (void)OSIF_SemaPost(&(master->idleSemaphore));
808  }
809 
810  master->status = STATUS_SUCCESS;
811 
812  if (master->masterCallback != NULL)
813  {
814  master->masterCallback((uint8_t)instance, LPI2C_MASTER_EVENT_TX, master->callbackParam);
815  }
816  }
817  else
818  {
819  /* Queue data bytes to fill tx fifo */
820  LPI2C_DRV_MasterQueueData(baseAddr, master);
821  }
822  }
823  else
824  {
825  /* No more commands and no transmission in progress - disable tx event */
827  }
828 }
829 
830 
831 /*FUNCTION**********************************************************************
832  *
833  * Function Name : LPI2C_DRV_MasterHandleReceiveDataRequest
834  * Description : handle a receive request for master
835  *
836  *END**************************************************************************/
837 static void LPI2C_DRV_MasterHandleReceiveDataReadyEvent(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
838 {
839  /* Received data ready */
840  DEV_ASSERT(master->rxBuff != NULL);
841 
842  /* Transfer received data to user buffer */
843  while ((LPI2C_HAL_MasterGetRxFIFOCount(baseAddr) > 0U) && (master->rxSize > 0U))
844  {
845  master->rxBuff[0U] = LPI2C_HAL_MasterGetRxData(baseAddr);
846  master->rxBuff++;
847  master->rxSize--;
848  }
849  if (master->rxSize == 0U)
850  {
851  /* Done receiving */
852  LPI2C_DRV_MasterEndTransfer(baseAddr, master, master->sendStop, false);
853 
854  /* Signal transfer end for blocking transfers */
855  if (master->blocking == true)
856  {
857  (void)OSIF_SemaPost(&(master->idleSemaphore));
858  }
859 
860  master->status = STATUS_SUCCESS;
861 
862  if (master->masterCallback != NULL)
863  {
864  master->masterCallback((uint8_t)instance, LPI2C_MASTER_EVENT_RX, master->callbackParam);
865  }
866  }
867  else if (master->rxSize <= LPI2C_HAL_MasterGetRxFIFOWatermark(baseAddr))
868  {
869  /* Reduce rx watermark to receive the last few bytes */
870  LPI2C_HAL_MasterSetRxFIFOWatermark(baseAddr, (uint8_t)(master->rxSize - 1U));
871  }
872  else
873  {
874  /* Continue reception */
875  }
876 }
877 
878 
879 /*FUNCTION**********************************************************************
880  *
881  * Function Name : LPI2C_DRV_SlaveHandleAddressValidEvent
882  * Description : handle an address valid event for slave
883  *
884  *END**************************************************************************/
885 static void LPI2C_DRV_SlaveHandleAddressValidEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
886 {
887  uint16_t receivedAddr;
888 
889  receivedAddr = LPI2C_HAL_SlaveGetReceivedAddr(baseAddr);
890  if ((receivedAddr & 1U) != (uint16_t)0U)
891  {
892  /* Request from master to transmit data */
893  if ((slave->slaveCallback != NULL) && slave->slaveListening)
894  {
895  slave->slaveCallback((uint8_t)instance, LPI2C_SLAVE_EVENT_TX_REQ, slave->callbackParam);
896  }
897 
898 #if defined(ERRATA_E10792)
899  if (slave->transferType == LPI2C_USING_INTERRUPTS) {
900  /* Enable interrupt for transmitting data */
901  LPI2C_HAL_SlaveSetInt(g_lpi2cBase[instance], LPI2C_HAL_SLAVE_TRANSMIT_DATA_INT, true);
902  }
903 #endif
904 
905  slave->txUnderrunWarning = false;
906 
907  if ((slave->transferType == LPI2C_USING_DMA) && slave->slaveListening)
908  {
909  (void)LPI2C_DRV_SlaveStartDmaTransfer(instance);
910  }
911 
912  }
913  else
914  {
915  /* Request from master to receive data */
916  if ((slave->slaveCallback != NULL) && slave->slaveListening)
917  {
918  slave->slaveCallback((uint8_t)instance, LPI2C_SLAVE_EVENT_RX_REQ, slave->callbackParam);
919  }
920 
921  if ((slave->transferType == LPI2C_USING_DMA) && slave->slaveListening)
922  {
923  (void)LPI2C_DRV_SlaveStartDmaTransfer(instance);
924  }
925  }
926 
927  slave->status = STATUS_BUSY;
928 }
929 
930 
931 /*FUNCTION**********************************************************************
932  *
933  * Function Name : LPI2C_DRV_SlaveHandleTransmitDataEvent
934  * Description : handle a transmit data event for slave
935  *
936  *END**************************************************************************/
937 static void LPI2C_DRV_SlaveHandleTransmitDataEvent(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
938 {
939  if (slave->txUnderrunWarning == true)
940  {
941  /* Another Tx event after underflow warning means the dummy char was sent */
942  slave->status = STATUS_I2C_TX_UNDERRUN;
943  }
944 
945  if (slave->txSize == 0U)
946  {
947  /* Out of data, call callback to allow user to provide a new buffer */
948  if (slave->slaveCallback != NULL)
949  {
950  slave->slaveCallback((uint8_t)instance, LPI2C_SLAVE_EVENT_TX_EMPTY, slave->callbackParam);
951  }
952  }
953 
954  if (slave->txSize == 0U)
955  {
956  /*
957  * Still no data, record tx underflow event and send dummy char.
958  * Special case after the last tx byte: the device will ask for more data
959  * but the dummy char will not be sent if NACK and then STOP condition are
960  * received from master. So only record a "warning" for now.
961  */
962  slave->txUnderrunWarning = true;
963  LPI2C_HAL_SlaveTransmitData(baseAddr, (uint8_t)0xFFU);
964  }
965  else
966  {
967  LPI2C_HAL_SlaveTransmitData(baseAddr, slave->txBuff[0U]);
968  slave->txBuff++;
969  slave->txSize--;
970  }
971 }
972 
973 
974 /*FUNCTION**********************************************************************
975  *
976  * Function Name : LPI2C_DRV_SlaveHandleReceiveDataEvent
977  * Description : handle a receive data event for slave
978  *
979  *END**************************************************************************/
980 static void LPI2C_DRV_SlaveHandleReceiveDataEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
981 {
982  if (slave->rxSize == 0U)
983  {
984  /* No more room for data, call callback to allow user to provide a new buffer */
985  if (slave->slaveCallback != NULL)
986  {
987  slave->slaveCallback((uint8_t)instance, LPI2C_SLAVE_EVENT_RX_FULL, slave->callbackParam);
988  }
989  }
990 
991  if (slave->rxSize == 0U)
992  {
993  /* Still no room for data, record rx overrun event and dummy read data */
994  slave->status = STATUS_I2C_RX_OVERRUN;
995  (void)LPI2C_HAL_SlaveGetData(baseAddr);
996  }
997  else
998  {
999  slave->rxBuff[0U] = LPI2C_HAL_SlaveGetData(baseAddr);
1000  slave->rxBuff++;
1001  slave->rxSize--;
1002  }
1003 }
1004 
1007 /*******************************************************************************
1008  * Code
1009  ******************************************************************************/
1010 
1011 /*FUNCTION**********************************************************************
1012  *
1013  * Function Name : LPI2C_DRV_MasterInit
1014  * Description : initialize the I2C master mode driver
1015  *
1016  * Implements : LPI2C_DRV_MasterInit_Activity
1017  *END**************************************************************************/
1018 status_t LPI2C_DRV_MasterInit(uint32_t instance,
1019  const lpi2c_master_user_config_t * userConfigPtr,
1020  lpi2c_master_state_t * master)
1021 {
1022  LPI2C_Type *baseAddr;
1023  status_t retVal;
1024  uint32_t inputClock;
1025  lpi2c_baud_rate_params_t baudRate;
1026 
1027  DEV_ASSERT(master != NULL);
1028  DEV_ASSERT(userConfigPtr != NULL);
1029  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1030 
1031  /* Check to see if the LPI2C master instance is already initialized */
1032  DEV_ASSERT(g_lpi2cMasterStatePtr[instance] == NULL);
1033 
1034  /* Check the protocol clock frequency */
1035  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1036  DEV_ASSERT(retVal == STATUS_SUCCESS);
1037  DEV_ASSERT(inputClock > 0U);
1038 
1039  baseAddr = g_lpi2cBase[instance];
1040  g_lpi2cMasterStatePtr[instance] = master;
1041 
1042  /* Initialize driver status structure */
1043  master->rxBuff = NULL;
1044  master->rxSize = 0U;
1045  master->txBuff = NULL;
1046  master->txSize = 0U;
1047  master->status = STATUS_SUCCESS;
1048  master->i2cIdle = true;
1049  master->slaveAddress = userConfigPtr->slaveAddress;
1050  master->is10bitAddr = userConfigPtr->is10bitAddr;
1051  master->transferType = userConfigPtr->transferType;
1052  /* Store DMA channel number used in transfer */
1053  master->dmaChannel = userConfigPtr->dmaChannel;
1054  master->masterCallback = userConfigPtr->masterCallback;
1055  master->callbackParam = userConfigPtr->callbackParam;
1056 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1057  master->masterCode = userConfigPtr->masterCode;
1058  master->highSpeedInProgress = false;
1059 #endif
1060  master->blocking = false;
1061 
1062  /* Initialize the semaphore */
1063  retVal = OSIF_SemaCreate(&(master->idleSemaphore), 0);
1064  DEV_ASSERT(retVal == STATUS_SUCCESS);
1065 
1067 
1068  /* Enable lpi2c interrupt */
1069  INT_SYS_EnableIRQ(g_lpi2cMasterIrqId[instance]);
1070 
1071  /* Initialize module */
1072  LPI2C_HAL_Init(baseAddr);
1073 
1074  /* Set baud rate */
1075  baudRate.baudRate = userConfigPtr->baudRate;
1076 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1077  baudRate.baudRateHS = userConfigPtr->baudRateHS;
1078 #endif
1079  LPI2C_DRV_MasterSetBaudRate(instance, userConfigPtr->operatingMode, baudRate);
1080 
1081  /* Set slave address */
1082  LPI2C_DRV_MasterSetSlaveAddr(instance, userConfigPtr->slaveAddress, userConfigPtr->is10bitAddr);
1083 
1084  /* Enable LPI2C master */
1085  LPI2C_HAL_MasterSetEnable(baseAddr, true);
1086 
1087  (void)retVal;
1088 
1089  return STATUS_SUCCESS;
1090 }
1091 
1092 
1093 /*FUNCTION**********************************************************************
1094  *
1095  * Function Name : LPI2C_DRV_MasterDeinit
1096  * Description : deinitialize the I2C master mode driver
1097  *
1098  * Implements : LPI2C_DRV_MasterDeinit_Activity
1099  *END**************************************************************************/
1101 {
1102  LPI2C_Type *baseAddr;
1103  const lpi2c_master_state_t *master;
1104 
1105  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1106 
1107  baseAddr = g_lpi2cBase[instance];
1108  master = g_lpi2cMasterStatePtr[instance];
1109  DEV_ASSERT(master != NULL);
1110 
1111  /* Destroy the semaphore */
1112  (void)OSIF_SemaDestroy(&(master->idleSemaphore));
1113 
1114  g_lpi2cMasterStatePtr[instance] = NULL;
1115 
1116  /* Disable master */
1117  LPI2C_HAL_MasterSetEnable(baseAddr, false);
1118 
1119  /* Disable i2c interrupt */
1120  INT_SYS_DisableIRQ(g_lpi2cMasterIrqId[instance]);
1121 
1122  return STATUS_SUCCESS;
1123 }
1124 
1125 
1126 /*FUNCTION**********************************************************************
1127  *
1128  * Function Name : LPI2C_DRV_MasterGetBaudRate
1129  * Description : returns the currently configured baud rate
1130  *
1131  * Implements : LPI2C_DRV_MasterGetBaudRate_Activity
1132  *END**************************************************************************/
1133 void LPI2C_DRV_MasterGetBaudRate(uint32_t instance, lpi2c_baud_rate_params_t *baudRate)
1134 {
1135  const LPI2C_Type *baseAddr;
1136  const lpi2c_master_state_t *master;
1137  status_t retVal;
1138  uint32_t prescaler;
1139  uint32_t clkLo;
1140  uint32_t clkHi;
1141  uint32_t inputClock;
1142 
1143  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1144 
1145  baseAddr = g_lpi2cBase[instance];
1146  master = g_lpi2cMasterStatePtr[instance];
1147  DEV_ASSERT(master != NULL);
1148 
1149  /* Get the protocol clock frequency */
1150  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1151  DEV_ASSERT(retVal == STATUS_SUCCESS);
1152  DEV_ASSERT(inputClock > 0U);
1153 
1154  /* Ignoring the glitch filter, the baud rate formula is:
1155  SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))
1156  */
1157  prescaler = LPI2C_HAL_MasterGetPrescaler(baseAddr);
1158  clkHi = LPI2C_HAL_MasterGetClockHighPeriod(baseAddr);
1159  clkLo = LPI2C_HAL_MasterGetClockLowPeriod(baseAddr);
1160 
1161  baudRate->baudRate = inputClock / (((uint32_t)1U << prescaler) * (clkLo + clkHi + (uint32_t)2U));
1162 
1163 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1164  if (master->operatingMode == LPI2C_HIGHSPEED_MODE)
1165  {
1166  clkHi = LPI2C_HAL_MasterGetClockHighPeriodHS(baseAddr);
1167  clkLo = LPI2C_HAL_MasterGetClockLowPeriodHS(baseAddr);
1168 
1169  baudRate->baudRateHS = inputClock / (((uint32_t)1U << prescaler) * (clkLo + clkHi + (uint32_t)2U));
1170  }
1171 #endif
1172 
1173  (void)retVal;
1174  (void)master;
1175 }
1176 
1177 
1178 /*FUNCTION**********************************************************************
1179  *
1180  * Function Name : LPI2C_DRV_MasterSetBaudRate
1181  * Description : set the baud rate for any subsequent I2C communication
1182  *
1183  * Implements : LPI2C_DRV_MasterSetBaudRate_Activity
1184  *END**************************************************************************/
1185 void LPI2C_DRV_MasterSetBaudRate(uint32_t instance,
1186  const lpi2c_mode_t operatingMode,
1187  const lpi2c_baud_rate_params_t baudRate)
1188 {
1189  LPI2C_Type *baseAddr;
1190  const lpi2c_master_state_t * master;
1191  status_t retVal;
1192  uint32_t inputClock;
1193  uint32_t minPrescaler;
1194  uint32_t prescaler;
1195  uint32_t clkTotal;
1196  uint32_t clkLo;
1197  uint32_t clkHi;
1198  uint32_t setHold;
1199  uint32_t dataVd;
1200 
1201  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1202 
1203  baseAddr = g_lpi2cBase[instance];
1204  master = g_lpi2cMasterStatePtr[instance];
1205  DEV_ASSERT(master != NULL);
1206 
1207  /* Check if driver is busy */
1208  DEV_ASSERT(master->i2cIdle == true);
1209 
1210  /* Get the protocol clock frequency */
1211  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1212  DEV_ASSERT(retVal == STATUS_SUCCESS);
1213  DEV_ASSERT(inputClock > 0U);
1214 
1215  /* Disable master */
1216  LPI2C_HAL_MasterSetEnable(baseAddr, false);
1217 
1218  /* Ignoring the glitch filter, the baud rate formula is:
1219  SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))
1220  Assume CLKLO = 2*CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2
1221  */
1222  /* Compute minimum prescaler for which CLKLO and CLKHI values are in valid range. Always round up. */
1223  minPrescaler = ((inputClock - 1U) / (baudRate.baudRate * (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))) + (uint32_t)1U;
1224  for (prescaler = 0U; prescaler < 7U; prescaler++)
1225  {
1226  if (((uint32_t)1U << prescaler) >= minPrescaler)
1227  {
1228  break;
1229  }
1230  }
1231 
1232  /* Compute CLKLO and CLKHI values for this prescaler. Round to nearest integer. */
1233  clkTotal = (inputClock + ((baudRate.baudRate << prescaler) >> 1U)) / (baudRate.baudRate << prescaler);
1234  if (clkTotal > (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))
1235  {
1236  clkTotal = (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U);
1237  }
1238 
1239  /*
1240  * If we try to compute clk high and low values using clkTotal equal with 0
1241  * (this is the case when the baudrate is 0), we will get negative values for
1242  * them, so we set them to 0 for this case.
1243  */
1244  if (clkTotal == 0U)
1245  {
1246  clkHi = 0U;
1247  clkLo = 0U;
1248  }
1249  else
1250  {
1251  clkHi = (clkTotal - 2U) / 3U;
1252  clkLo = clkTotal - 2U - clkHi;
1253  }
1254 
1255  if (clkHi < CLKHI_MIN_VALUE)
1256  {
1257  clkHi = CLKHI_MIN_VALUE;
1258  }
1259  if (clkLo < CLKLO_MIN_VALUE)
1260  {
1261  clkLo = CLKLO_MIN_VALUE;
1262  }
1263 
1264  /* Compute DATAVD and SETHOLD */
1265  setHold = clkHi;
1266  dataVd = clkHi >> 1U;
1267  if (setHold < SETHOLD_MIN_VALUE)
1268  {
1269  setHold = SETHOLD_MIN_VALUE;
1270  }
1271  if (dataVd < DATAVD_MIN_VALUE)
1272  {
1273  dataVd = DATAVD_MIN_VALUE;
1274  }
1275 
1276  /* Apply settings */
1278  LPI2C_HAL_MasterSetDataValidDelay(baseAddr, (uint8_t)dataVd);
1279  LPI2C_HAL_MasterSetSetupHoldDelay(baseAddr, (uint8_t)setHold);
1280  LPI2C_HAL_MasterSetClockHighPeriod(baseAddr, (uint8_t)clkHi);
1281  LPI2C_HAL_MasterSetClockLowPeriod(baseAddr, (uint8_t)clkLo);
1282 
1283 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1284  if (operatingMode == LPI2C_HIGHSPEED_MODE)
1285  {
1286  /* Compute settings for High-speed baud rate */
1287  /* Compute High-speed CLKLO and CLKHI values for the same prescaler. Round to nearest integer. */
1288  clkTotal = (inputClock + ((baudRate.baudRateHS << prescaler) >> 1U)) / (baudRate.baudRateHS << prescaler);
1289  if (clkTotal > (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))
1290  {
1291  clkTotal = (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U);
1292  }
1293 
1294  clkHi = (clkTotal - 2U) / 3U;
1295  clkLo = clkTotal - 2U - clkHi;
1296  if (clkHi < CLKHI_MIN_VALUE)
1297  {
1298  clkHi = CLKHI_MIN_VALUE;
1299  }
1300  if (clkLo < CLKLO_MIN_VALUE)
1301  {
1302  clkLo = CLKLO_MIN_VALUE;
1303  }
1304 
1305  /* Compute High-speed DATAVD and SETHOLD */
1306  setHold = clkHi;
1307  dataVd = clkHi >> 1U;
1308  if (setHold < SETHOLD_MIN_VALUE)
1309  {
1310  setHold = SETHOLD_MIN_VALUE;
1311  }
1312  if (dataVd < DATAVD_MIN_VALUE)
1313  {
1314  dataVd = DATAVD_MIN_VALUE;
1315  }
1316 
1317  /* Apply High-speed settings */
1318  LPI2C_HAL_MasterSetDataValidDelayHS(baseAddr, (uint8_t)dataVd);
1319  LPI2C_HAL_MasterSetSetupHoldDelayHS(baseAddr, (uint8_t)setHold);
1320  LPI2C_HAL_MasterSetClockHighPeriodHS(baseAddr, (uint8_t)clkHi);
1321  LPI2C_HAL_MasterSetClockLowPeriodHS(baseAddr, (uint8_t)clkLo);
1322  }
1323 #endif
1324 
1325  /* Perform other settings related to the chosen operating mode */
1326  LPI2C_DRV_MasterSetOperatingMode(instance, operatingMode);
1327 
1328  /* Re-enable master */
1329  LPI2C_HAL_MasterSetEnable(baseAddr, true);
1330 
1331  (void)master;
1332  (void)retVal;
1333 }
1334 
1335 
1336 /*FUNCTION**********************************************************************
1337  *
1338  * Function Name : LPI2C_DRV_MasterSetSlaveAddr
1339  * Description : set the slave address for any subsequent I2C communication
1340  *
1341  * Implements : LPI2C_DRV_MasterSetSlaveAddr_Activity
1342  *END**************************************************************************/
1343 void LPI2C_DRV_MasterSetSlaveAddr(uint32_t instance, const uint16_t address, const bool is10bitAddr)
1344 {
1345  lpi2c_master_state_t * master;
1346 
1347  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1348 
1349  master = g_lpi2cMasterStatePtr[instance];
1350  DEV_ASSERT(master != NULL);
1351 
1352  master->slaveAddress = address;
1353  master->is10bitAddr = is10bitAddr;
1354 }
1355 
1356 
1357 /*FUNCTION**********************************************************************
1358  *
1359  * Function Name : LPI2C_DRV_MasterSendData
1360  * Description : perform a non-blocking send transaction on the I2C bus
1361  *
1362  * Implements : LPI2C_DRV_MasterSendData_Activity
1363  *END**************************************************************************/
1365  const uint8_t * txBuff,
1366  uint32_t txSize,
1367  bool sendStop)
1368 {
1369  LPI2C_Type *baseAddr;
1370  lpi2c_master_state_t *master;
1371 
1372  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1373  DEV_ASSERT(txBuff != NULL);
1374  DEV_ASSERT(txSize > 0U);
1375 
1376  baseAddr = g_lpi2cBase[instance];
1377  master = g_lpi2cMasterStatePtr[instance];
1378  DEV_ASSERT(master != NULL);
1379 
1380  /* Check if driver is busy */
1381  DEV_ASSERT(master->i2cIdle == true);
1382 
1383  /* Copy parameters to driver state structure */
1384  master->txBuff = txBuff;
1385  master->txSize = txSize;
1386  master->sendStop = sendStop;
1387  master->i2cIdle = false;
1388  master->status = STATUS_BUSY;
1389 
1390  if (master->transferType == LPI2C_USING_DMA)
1391  {
1395  true);
1396 
1398  }
1399  else
1400  {
1401  /* Initiate communication */
1402  LPI2C_DRV_MasterSendAddress(baseAddr, master, false);
1403 
1404  /* Queue data bytes to fill tx fifo */
1405  LPI2C_DRV_MasterQueueData(baseAddr, master);
1406 
1407  /* Set tx FIFO watermark */
1408  LPI2C_HAL_MasterSetTxFIFOWatermark(baseAddr, 0U);
1409 
1410  /* Enable relevant events */
1411 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1412  if (master->operatingMode == LPI2C_ULTRAFAST_MODE)
1413  {
1414  /* Do not enable NACK event reporting in ultra-fast mode */
1418  true);
1419  }
1420  else
1421 #endif
1422  {
1427  true);
1428  }
1429  }
1430 
1431  return STATUS_SUCCESS;
1432 }
1433 
1434 
1435 /*FUNCTION**********************************************************************
1436  *
1437  * Function Name : LPI2C_DRV_MasterSendDataBlocking
1438  * Description : perform a blocking send transaction on the I2C bus
1439  *
1440  * Implements : LPI2C_DRV_MasterSendDataBlocking_Activity
1441  *END**************************************************************************/
1443  const uint8_t * txBuff,
1444  uint32_t txSize,
1445  bool sendStop,
1446  uint32_t timeout)
1447 {
1448  status_t retVal = STATUS_SUCCESS;
1449 
1450  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1451  DEV_ASSERT(txBuff != NULL);
1452  DEV_ASSERT(txSize > 0U);
1453 
1454  lpi2c_master_state_t *master = g_lpi2cMasterStatePtr[instance];
1455  DEV_ASSERT(master != NULL);
1456 
1457  /* mark transfer as blocking */
1458  master->blocking = true;
1459 
1460  retVal = LPI2C_DRV_MasterSendData(instance, txBuff, txSize, sendStop);
1461  if (retVal != STATUS_SUCCESS)
1462  {
1463  master->blocking = false;
1464  return retVal;
1465  }
1466 
1467  /* Wait for transfer to end */
1468  return LPI2C_DRV_MasterWaitTransferEnd(instance, timeout);
1469 }
1470 
1471 
1472 /*FUNCTION**********************************************************************
1473  *
1474  * Function Name : LPI2C_DRV_MasterAbortTransferData
1475  * Description : abort a non-blocking I2C Master transmission or reception
1476  *
1477  * Implements : LPI2C_DRV_MasterAbortTransferData_Activity
1478  *END**************************************************************************/
1480 {
1481  LPI2C_Type *baseAddr;
1482  lpi2c_master_state_t * master;
1483 
1484  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1485 
1486  baseAddr = g_lpi2cBase[instance];
1487  master = g_lpi2cMasterStatePtr[instance];
1488  DEV_ASSERT(master != NULL);
1489 
1490  DEV_ASSERT(master->i2cIdle == false);
1491 
1492  if (master->rxBuff != NULL)
1493  {
1494  /* Aborting a reception not supported because hardware will continue the
1495  current command even if the FIFO is reset and this could last indefinitely */
1496  return STATUS_UNSUPPORTED;
1497  }
1498 
1499  /* End transfer: force stop generation, reset FIFOs */
1500  master->status = STATUS_I2C_ABORTED;
1501  LPI2C_DRV_MasterEndTransfer(baseAddr, master, true, true);
1502 
1503  return STATUS_SUCCESS;
1504 }
1505 
1506 
1507 /*FUNCTION**********************************************************************
1508  *
1509  * Function Name : LPI2C_DRV_MasterReceiveData
1510  * Description : perform a non-blocking receive transaction on the I2C bus
1511  *
1512  * Implements : LPI2C_DRV_MasterReceiveData_Activity
1513  *END**************************************************************************/
1515  uint8_t * rxBuff,
1516  uint32_t rxSize,
1517  bool sendStop)
1518 {
1519  LPI2C_Type *baseAddr;
1520  lpi2c_master_state_t * master;
1521  uint16_t rxBytes;
1522 
1523  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1524  DEV_ASSERT(rxBuff != NULL);
1525  DEV_ASSERT(rxSize > 0U);
1526 
1527  DEV_ASSERT(rxSize <= 256U);
1528 
1529  baseAddr = g_lpi2cBase[instance];
1530  master = g_lpi2cMasterStatePtr[instance];
1531  DEV_ASSERT(master != NULL);
1532 
1533  /* Check if driver is busy */
1534  DEV_ASSERT(master->i2cIdle == true);
1535 
1536 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1537  if (master->operatingMode == LPI2C_ULTRAFAST_MODE)
1538  {
1539  /* No reception possible in ultra-fast mode */
1540  return STATUS_ERROR;
1541  }
1542 #endif
1543 
1544  /* Copy parameters to driver state structure */
1545  master->rxSize = rxSize;
1546  master->i2cIdle = false;
1547  master->sendStop = sendStop;
1548  master->rxBuff = rxBuff;
1549  master->status = STATUS_BUSY;
1550 
1551  if (master->transferType == LPI2C_USING_DMA)
1552  {
1556  true);
1557 
1559  }
1560  else
1561  {
1562  /* Initiate communication */
1563  LPI2C_DRV_MasterSendAddress(baseAddr, master, true);
1564  /* Queue receive command for rxSize bytes */
1565  LPI2C_DRV_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_RECEIVE, (uint8_t)(rxSize - 1U));
1566 
1567  /* Set rx FIFO watermark */
1568  rxBytes = LPI2C_HAL_MasterGetRxFIFOSize(baseAddr);
1569  if (rxBytes > rxSize)
1570  {
1571  rxBytes = (uint8_t)rxSize;
1572  }
1573  LPI2C_HAL_MasterSetRxFIFOWatermark(baseAddr, (uint8_t)(rxBytes - 1U));
1574 
1575  /* Enable relevant events */
1576  if (!LPI2C_DRV_MasterCmdQueueEmpty(master))
1577  {
1578  /* Enable tx event too if there are commands in the software FIFO */
1584  true);
1585  }
1586  else
1587  {
1592  true);
1593  }
1594  }
1595 
1596  return STATUS_SUCCESS;
1597 }
1598 
1599 
1600 /*FUNCTION**********************************************************************
1601  *
1602  * Function Name : LPI2C_DRV_MasterReceiveDataBlocking
1603  * Description : perform a blocking receive transaction on the I2C bus
1604  *
1605  * Implements : LPI2C_DRV_MasterReceiveDataBlocking_Activity
1606  *END**************************************************************************/
1608  uint8_t * rxBuff,
1609  uint32_t rxSize,
1610  bool sendStop,
1611  uint32_t timeout)
1612 {
1613  status_t retVal = STATUS_SUCCESS;
1614 
1615  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1616  DEV_ASSERT(rxBuff != NULL);
1617  DEV_ASSERT(rxSize > 0U);
1618 
1619  lpi2c_master_state_t *master = g_lpi2cMasterStatePtr[instance];
1620  DEV_ASSERT(master != NULL);
1621 
1622  /* mark transfer as blocking */
1623  master->blocking = true;
1624 
1625  retVal = LPI2C_DRV_MasterReceiveData(instance, rxBuff, rxSize, sendStop);
1626  if (retVal != STATUS_SUCCESS)
1627  {
1628  master->blocking = false;
1629  return retVal;
1630  }
1631 
1632  /* Wait for transfer to end */
1633  return LPI2C_DRV_MasterWaitTransferEnd(instance, timeout);
1634 }
1635 
1636 
1637 /*FUNCTION**********************************************************************
1638  *
1639  * Function Name : LPI2C_DRV_MasterGetTransferStatus
1640  * Description : return the current status of the I2C master transfer
1641  *
1642  * When performing an a-sync (non-blocking) transfer, the user can call this function
1643  * to ascertain the state of the current transfer. In addition, if the transfer is still
1644  * in progress, the user can get the number of words that should be receive.
1645  *
1646  * Implements : LPI2C_DRV_MasterGetTransferStatus_Activity
1647  *END**************************************************************************/
1649  uint32_t *bytesRemaining)
1650 {
1651  const LPI2C_Type *baseAddr;
1652  const lpi2c_master_state_t * master;
1653 
1654  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1655 
1656  baseAddr = g_lpi2cBase[instance];
1657  master = g_lpi2cMasterStatePtr[instance];
1658  DEV_ASSERT(master != NULL);
1659 
1660  if ((bytesRemaining != NULL) && (master->transferType == LPI2C_USING_INTERRUPTS))
1661  {
1662  if (master->txSize > 0U)
1663  {
1664  /* Send data */
1665  /* Remaining bytes = bytes in buffer + bytes in tx FIFO */
1666  *bytesRemaining = master->txSize + LPI2C_HAL_MasterGetTxFIFOCount(baseAddr);
1667  }
1668  else if (master->rxSize > 0U)
1669  {
1670  /* Receive data */
1671  /* Remaining bytes = free space in buffer - bytes in rx FIFO */
1672  *bytesRemaining = master->rxSize - LPI2C_HAL_MasterGetRxFIFOCount(baseAddr);
1673  }
1674  else
1675  {
1676  *bytesRemaining = 0U;
1677  }
1678  }
1679 
1680  return master->status;
1681 }
1682 
1683 
1684 /*FUNCTION**********************************************************************
1685  *
1686  * Function Name : LPI2C_DRV_MasterIRQHandler
1687  * Description : handle non-blocking master operation when I2C interrupt occurs
1688  *
1689  *END**************************************************************************/
1690 void LPI2C_DRV_MasterIRQHandler(uint32_t instance)
1691 {
1692  LPI2C_Type *baseAddr;
1693  lpi2c_master_state_t * master;
1694 
1695  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1696 
1697  baseAddr = g_lpi2cBase[instance];
1698  master = g_lpi2cMasterStatePtr[instance];
1699  DEV_ASSERT(master != NULL);
1700 
1701  /* Check which event caused the interrupt */
1703  {
1704  LPI2C_DRV_MasterHandleTransmitDataRequest(instance, baseAddr, master);
1705  }
1706 
1708  {
1709  LPI2C_DRV_MasterHandleReceiveDataReadyEvent(instance, baseAddr, master);
1710  }
1711 
1712  if (LPI2C_HAL_MasterGetFIFOErrorEvent(baseAddr))
1713  {
1714  /* FIFO error */
1716 
1717 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1718  /* High-speed transfers end at STOP condition */
1719  master->highSpeedInProgress = false;
1720 #endif
1721  master->status = STATUS_ERROR;
1722 
1723  /* End transfer: no stop generation (the module will handle that by itself
1724  if needed), reset FIFOs */
1725  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
1726 
1727  /* Signal transfer end for blocking transfers */
1728  if (master->blocking == true)
1729  {
1730  (void)OSIF_SemaPost(&(master->idleSemaphore));
1731  }
1732 
1733  if (master->masterCallback != NULL)
1734  {
1735  master->masterCallback((uint8_t)instance, LPI2C_MASTER_EVENT_FIFO_ERROR, master->callbackParam);
1736  }
1737  }
1738 
1740  {
1741  /* Arbitration lost */
1743 
1744  /* End transfer: no stop generation (the module will handle that by itself
1745  if needed), reset FIFOs */
1746  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
1747 
1748  /* Signal transfer end for blocking transfers */
1749  if (master->blocking == true)
1750  {
1751  (void)OSIF_SemaPost(&(master->idleSemaphore));
1752  }
1753 
1754  master->status = STATUS_I2C_ARBITRATION_LOST;
1755 
1756  if (master->masterCallback != NULL)
1757  {
1758  master->masterCallback((uint8_t)instance, LPI2C_MASTER_EVENT_ARBITRATION_LOST, master->callbackParam);
1759  }
1760  }
1761 
1762  if (LPI2C_HAL_MasterGetNACKDetectEvent(baseAddr))
1763  {
1764  /* Received NACK */
1766 
1767 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1768  /* Ignore NACK in Ultra Fast mode */
1769  if (master->operatingMode != LPI2C_ULTRAFAST_MODE)
1770  {
1771 #endif
1772  /* Signal transfer end for blocking transfers */
1773  if (master->blocking == true)
1774  {
1775  (void)OSIF_SemaPost(&(master->idleSemaphore));
1776  }
1777 
1778 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1779  /* High-speed transfers end at STOP condition */
1780  master->highSpeedInProgress = false;
1781 #endif
1782  master->status = STATUS_I2C_RECEIVED_NACK;
1783 
1784  /* End transfer: no stop generation (the module will handle that by itself
1785  if needed), reset FIFOs */
1786  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
1787 
1788  if (master->masterCallback != NULL)
1789  {
1790  master->masterCallback((uint8_t)instance, LPI2C_MASTER_EVENT_NACK, master->callbackParam);
1791  }
1792 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1793  }
1794 #endif
1795  }
1796 }
1797 
1798 
1799 /*FUNCTION**********************************************************************
1800  *
1801  * Function Name : LPI2C_DRV_SlaveInit
1802  * Description : initialize the I2C slave mode driver
1803  *
1804  * Implements : LPI2C_DRV_SlaveInit_Activity
1805  *END**************************************************************************/
1806 status_t LPI2C_DRV_SlaveInit(uint32_t instance,
1807  const lpi2c_slave_user_config_t * userConfigPtr,
1808  lpi2c_slave_state_t * slave)
1809 {
1810  LPI2C_Type *baseAddr;
1811  status_t retVal;
1812  uint32_t inputClock;
1813 
1814  DEV_ASSERT(slave != NULL);
1815  DEV_ASSERT(userConfigPtr != NULL);
1816  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1817 
1818  DEV_ASSERT(g_lpi2cSlaveStatePtr[instance] == NULL);
1819 
1820  /*
1821  * Check the protocol clock frequency.
1822  * LPI2C slave remains operational, even when the LPI2C functional
1823  * clock is disabled, so we don't need to check if inputClock is 0.
1824  */
1825  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1826  DEV_ASSERT(retVal == STATUS_SUCCESS);
1827 
1828  baseAddr = g_lpi2cBase[instance];
1829  g_lpi2cSlaveStatePtr[instance] = slave;
1830 
1831  /* Initialize driver status structure */
1832  slave->status = STATUS_SUCCESS;
1833  slave->slaveListening = userConfigPtr->slaveListening;
1834  slave->slaveCallback = userConfigPtr->slaveCallback;
1835  slave->callbackParam = userConfigPtr->callbackParam;
1836  slave->txBuff = NULL;
1837  slave->rxBuff = NULL;
1838  slave->txSize = 0U;
1839  slave->rxSize = 0U;
1840  slave->transferType = userConfigPtr->transferType;
1841  /* Store DMA channel number used in transfer */
1842  slave->dmaChannel = userConfigPtr->dmaChannel;
1843  slave->isTransferInProgress = false;
1844  slave->blocking = false;
1845 
1846  /* Initialize the semaphore */
1847  retVal = OSIF_SemaCreate(&(slave->idleSemaphore), 0);
1848  DEV_ASSERT(retVal == STATUS_SUCCESS);
1849 
1850  /* Enable lpi2c interrupt */
1851  INT_SYS_EnableIRQ(g_lpi2cSlaveIrqId[instance]);
1852 
1853  /* Initialize module */
1854  LPI2C_HAL_Init(baseAddr);
1855 
1856  /* Configure slave address */
1857  LPI2C_HAL_SlaveSetAddr0(baseAddr, userConfigPtr->slaveAddress);
1858  if (userConfigPtr->is10bitAddr)
1859  {
1861  }
1862  else
1863  {
1865  }
1866 
1867  /* Configure operating mode */
1868  LPI2C_DRV_SlaveSetOperatingMode(instance, userConfigPtr->operatingMode);
1869 
1870  if (userConfigPtr->slaveListening)
1871  {
1872  if (slave->transferType == LPI2C_USING_DMA)
1873  {
1874  /* Activate events */
1880  true);
1881  }
1882  if (slave->transferType == LPI2C_USING_INTERRUPTS)
1883  {
1884  /* Activate events */
1885 #if defined(ERRATA_E10792)
1892  true);
1893 
1894 #else
1902  true);
1903 
1904 #endif
1905 
1906  }
1907 
1908  /* Enable LPI2C slave */
1909  LPI2C_HAL_SlaveSetEnable(baseAddr, true);
1910  }
1911 
1912  (void)retVal;
1913 
1914  return STATUS_SUCCESS;
1915 }
1916 
1917 
1918 /*FUNCTION**********************************************************************
1919  *
1920  * Function Name : LPI2C_DRV_SlaveDeinit
1921  * Description : de-initialize the I2C slave mode driver
1922  *
1923  * Implements : LPI2C_DRV_SlaveDeinit_Activity
1924  *END**************************************************************************/
1926 {
1927  LPI2C_Type *baseAddr;
1928 
1929  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1930 
1931  baseAddr = g_lpi2cBase[instance];
1932  const lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
1933  DEV_ASSERT(slave != NULL);
1934 
1935  /* Destroy the semaphore */
1936  (void)OSIF_SemaDestroy(&(slave->idleSemaphore));
1937 
1938  if ((slave->transferType == LPI2C_USING_DMA) && slave->slaveListening)
1939  {
1940  /* Disable LPI2C DMA requests. */
1941  (void)LPI2C_HAL_SlaveSetRxDMA(baseAddr, false);
1942  (void)LPI2C_HAL_SlaveSetTxDMA(baseAddr, false);
1943  }
1944 
1945  g_lpi2cSlaveStatePtr[instance] = NULL;
1946 
1947  /* Disable LPI2C slave */
1948  LPI2C_HAL_SlaveSetEnable(baseAddr, false);
1949 
1950  /* Disable i2c interrupt */
1951  INT_SYS_DisableIRQ(g_lpi2cSlaveIrqId[instance]);
1952 
1953  return STATUS_SUCCESS;
1954 }
1955 
1956 
1957 /*FUNCTION**********************************************************************
1958  *
1959  * Function Name : LPI2C_DRV_SlaveSetTxBuffer
1960  * Description : Provide a buffer for transmitting data.
1961  *
1962  * Implements : LPI2C_DRV_SlaveSetTxBuffer_Activity
1963  *END**************************************************************************/
1965  const uint8_t * txBuff,
1966  uint32_t txSize)
1967 {
1968  lpi2c_slave_state_t * slave;
1969 
1970  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1971  DEV_ASSERT(txBuff != NULL);
1972  DEV_ASSERT(txSize > 0U);
1973 
1974  slave = g_lpi2cSlaveStatePtr[instance];
1975  DEV_ASSERT(slave != NULL);
1976 
1977  slave->txBuff = txBuff;
1978  slave->txSize = txSize;
1979 
1980  return STATUS_SUCCESS;
1981 }
1982 
1983 
1984 /*FUNCTION**********************************************************************
1985  *
1986  * Function Name : LPI2C_DRV_SlaveSetRxBuffer
1987  * Description : Provide a buffer for receiving data.
1988  *
1989  * Implements : LPI2C_DRV_SlaveSetRxBuffer_Activity
1990  *END**************************************************************************/
1992  uint8_t * rxBuff,
1993  uint32_t rxSize)
1994 {
1995  lpi2c_slave_state_t * slave;
1996 
1997  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1998  DEV_ASSERT(rxBuff != NULL);
1999  DEV_ASSERT(rxSize > 0U);
2000 
2001  slave = g_lpi2cSlaveStatePtr[instance];
2002  DEV_ASSERT(slave != NULL);
2003 
2004  slave->rxBuff = rxBuff;
2005  slave->rxSize = rxSize;
2006 
2007  return STATUS_SUCCESS;
2008 }
2009 
2010 
2011 /*FUNCTION**********************************************************************
2012  *
2013  * Function Name : LPI2C_DRV_SlaveSendData
2014  * Description : perform a non-blocking send transaction on the I2C bus
2015  *
2016  * Implements : LPI2C_DRV_SlaveSendData_Activity
2017  *END**************************************************************************/
2019  const uint8_t * txBuff,
2020  uint32_t txSize)
2021 {
2022  LPI2C_Type *baseAddr;
2023  lpi2c_slave_state_t * slave;
2024 
2025  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2026  DEV_ASSERT(txBuff != NULL);
2027  DEV_ASSERT(txSize > 0U);
2028 
2029 
2030  baseAddr = g_lpi2cBase[instance];
2031  slave = g_lpi2cSlaveStatePtr[instance];
2032  DEV_ASSERT(slave != NULL);
2033 
2034  /* If the slave is in listening mode the user should not use this function or the blocking counterpart. */
2035  DEV_ASSERT(slave->slaveListening == false);
2036 
2037  /* Check if slave is busy */
2038  DEV_ASSERT(slave->isTransferInProgress == false);
2039 
2040  slave->txBuff = txBuff;
2041  slave->txSize = txSize;
2042  slave->status = STATUS_BUSY;
2043 
2044  if (slave->transferType == LPI2C_USING_DMA)
2045  {
2046  /* Activate events */
2052  true);
2053 
2054  /* Enable LPI2C slave */
2055  LPI2C_HAL_SlaveSetEnable(baseAddr, true);
2056 
2057  slave->isTransferInProgress = true;
2058 
2060  }
2061  else
2062  {
2063  /* Activate events */
2064 #if defined(ERRATA_E10792)
2065 
2071  true);
2072 
2073 #else
2080  true);
2081 #endif
2082 
2083 
2084  /* Enable LPI2C slave */
2085  LPI2C_HAL_SlaveSetEnable(baseAddr, true);
2086 
2087  slave->isTransferInProgress = true;
2088  }
2089 
2090  return STATUS_SUCCESS;
2091 }
2092 
2093 
2094 /*FUNCTION**********************************************************************
2095  *
2096  * Function Name : LPI2C_DRV_SlaveSendDataBlocking
2097  * Description : perform a blocking send transaction on the I2C bus
2098  *
2099  * Implements : LPI2C_DRV_SlaveSendDataBlocking_Activity
2100  *END**************************************************************************/
2102  const uint8_t * txBuff,
2103  uint32_t txSize,
2104  uint32_t timeout)
2105 {
2106  status_t retVal = STATUS_SUCCESS;
2107 
2108  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2109  DEV_ASSERT(txBuff != NULL);
2110  DEV_ASSERT(txSize > 0U);
2111 
2112  lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
2113  DEV_ASSERT(slave != NULL);
2114 
2115  /* mark transfer as blocking */
2116  slave->blocking = true;
2117 
2118  retVal = LPI2C_DRV_SlaveSendData(instance, txBuff, txSize);
2119  if (retVal != STATUS_SUCCESS)
2120  {
2121  return retVal;
2122  }
2123 
2124  /* Wait for transfer to end */
2125  return LPI2C_DRV_SlaveWaitTransferEnd(instance, timeout);
2126 }
2127 
2128 
2129 /*FUNCTION**********************************************************************
2130  *
2131  * Function Name : LPI2C_DRV_SlaveReceiveData
2132  * Description : perform a non-blocking receive transaction on the I2C bus
2133  *
2134  * Implements : LPI2C_DRV_SlaveReceiveData_Activity
2135  *END**************************************************************************/
2137  uint8_t * rxBuff,
2138  uint32_t rxSize)
2139 {
2140  LPI2C_Type *baseAddr;
2141  lpi2c_slave_state_t * slave;
2142 
2143  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2144  DEV_ASSERT(rxBuff != NULL);
2145  DEV_ASSERT(rxSize > 0U);
2146 
2147  baseAddr = g_lpi2cBase[instance];
2148  slave = g_lpi2cSlaveStatePtr[instance];
2149  DEV_ASSERT(slave != NULL);
2150 
2151  /* If the slave is in listening mode the user should not use this function or the blocking counterpart. */
2152  DEV_ASSERT(slave->slaveListening == false);
2153 
2154  /* Check if slave is busy */
2155  DEV_ASSERT(slave->isTransferInProgress == false);
2156 
2157  slave->rxBuff = rxBuff;
2158  slave->rxSize = rxSize;
2159  slave->status = STATUS_BUSY;
2160 
2161  if (slave->transferType == LPI2C_USING_DMA)
2162  {
2163  /* Activate events */
2169  true);
2170 
2171  /* Enable LPI2C slave */
2172  LPI2C_HAL_SlaveSetEnable(baseAddr, true);
2173 
2174  slave->isTransferInProgress = true;
2175 
2177  }
2178  else
2179  {
2180  slave->isTransferInProgress = true;
2181 
2182  /* Activate events */
2189  true);
2190 
2191  /* Enable LPI2C slave */
2192  LPI2C_HAL_SlaveSetEnable(baseAddr, true);
2193  }
2194 
2195  return STATUS_SUCCESS;
2196 }
2197 
2198 
2199 /*FUNCTION**********************************************************************
2200  *
2201  * Function Name : LPI2C_DRV_SlaveReceiveDataBlocking
2202  * Description : perform a blocking receive transaction on the I2C bus
2203  *
2204  * Implements : LPI2C_DRV_SlaveReceiveDataBlocking_Activity
2205  *END**************************************************************************/
2207  uint8_t *rxBuff,
2208  uint32_t rxSize,
2209  uint32_t timeout)
2210 {
2211  status_t retVal = STATUS_SUCCESS;
2212 
2213  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2214  DEV_ASSERT(rxBuff != NULL);
2215  DEV_ASSERT(rxSize > 0U);
2216 
2217  lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
2218  DEV_ASSERT(slave != NULL);
2219 
2220  /* mark transfer as blocking */
2221  slave->blocking = true;
2222 
2223  retVal = LPI2C_DRV_SlaveReceiveData(instance, rxBuff, rxSize);
2224  if (retVal != STATUS_SUCCESS)
2225  {
2226  return retVal;
2227  }
2228 
2229  /* Wait for transfer to end */
2230  return LPI2C_DRV_SlaveWaitTransferEnd(instance, timeout);
2231 }
2232 
2233 
2234 /*FUNCTION**********************************************************************
2235  *
2236  * Function Name : LPI2C_DRV_SlaveGetTransferStatus
2237  * Description : return the current status of the I2C slave transfer
2238  *
2239  * When performing an a-sync (non-blocking) transfer, the user can call this function
2240  * to ascertain the state of the current transfer. In addition, if the transfer is still
2241  * in progress, the user can get the number of words that should be receive.
2242  *
2243  * Implements : LPI2C_DRV_SlaveGetTransferStatus_Activity
2244  *END**************************************************************************/
2246  uint32_t *bytesRemaining)
2247 {
2248  const lpi2c_slave_state_t *slave;
2249 
2250  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2251 
2252  slave = g_lpi2cSlaveStatePtr[instance];
2253  DEV_ASSERT(slave != NULL);
2254 
2255  if ((bytesRemaining != NULL) && (slave->transferType == LPI2C_USING_INTERRUPTS))
2256  {
2257  if (slave->txSize > 0U)
2258  {
2259  /* Send data */
2260  *bytesRemaining = slave->txSize;
2261  }
2262  else if (slave->rxSize > 0U)
2263  {
2264  /* Receive data */
2265  *bytesRemaining = slave->rxSize;
2266  }
2267  else
2268  {
2269  *bytesRemaining = 0U;
2270  }
2271  }
2272 
2273  return slave->status;
2274 }
2275 
2276 
2277 /*FUNCTION**********************************************************************
2278  *
2279  * Function Name : LPI2C_DRV_SlaveAbortTransferData
2280  * Description : abort a non-blocking I2C Master transmission or reception
2281  *
2282  * Implements : LPI2C_DRV_SlaveAbortTransferData_Activity
2283  *END**************************************************************************/
2285 {
2286  lpi2c_slave_state_t * slave;
2287  LPI2C_Type *baseAddr;
2288 
2289  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2290 
2291  baseAddr = g_lpi2cBase[instance];
2292  slave = g_lpi2cSlaveStatePtr[instance];
2293  DEV_ASSERT(slave != NULL);
2294 
2295  if (!slave->slaveListening)
2296  {
2297  DEV_ASSERT(slave->isTransferInProgress == true);
2298 
2299  slave->status = STATUS_I2C_ABORTED;
2300  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2301  }
2302 
2303  return STATUS_SUCCESS;
2304 }
2305 
2306 
2307 /*FUNCTION**********************************************************************
2308  *
2309  * Function Name : LPI2C_DRV_SlaveIRQHandler
2310  * Description : handle non-blocking slave operation when I2C interrupt occurs
2311  *
2312  *END**************************************************************************/
2313 void LPI2C_DRV_SlaveIRQHandler(uint32_t instance)
2314 {
2315  LPI2C_Type *baseAddr;
2316  lpi2c_slave_state_t * slave;
2317  bool stopDetect = false, repeatStartDetect = false;
2318 
2319  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2320 
2321  baseAddr = g_lpi2cBase[instance];
2322  slave = g_lpi2cSlaveStatePtr[instance];
2323  DEV_ASSERT(slave != NULL);
2324 
2325  /* Check which event caused the interrupt */
2327  {
2328  LPI2C_DRV_SlaveHandleAddressValidEvent(instance, baseAddr, slave);
2329  }
2330 
2332  {
2334  {
2335  LPI2C_DRV_SlaveHandleTransmitDataEvent(instance, baseAddr, slave);
2336  }
2337  }
2338 
2339  if (LPI2C_HAL_SlaveGetReceiveDataEvent(baseAddr))
2340  {
2342  {
2343  LPI2C_DRV_SlaveHandleReceiveDataEvent(instance, baseAddr, slave);
2344  }
2345  }
2346 
2347  stopDetect = LPI2C_HAL_SlaveGetSTOPDetectEvent(baseAddr);
2348  repeatStartDetect = LPI2C_HAL_SlaveGetRepeatedStartEvent(baseAddr);
2349  if ((stopDetect == true) || (repeatStartDetect == true))
2350  {
2351  /* Either STOP or repeated START have the same meaning here: the current transfer is over */
2354 
2355 #if defined(ERRATA_E10792)
2356  /* Deactivate interrupts for transmitting data */
2358 #endif
2359 
2360  if(slave->transferType == LPI2C_USING_DMA)
2361  {
2362  (void)EDMA_DRV_StopChannel(slave->dmaChannel);
2363  }
2364 
2365  if (slave->status == STATUS_BUSY)
2366  {
2367  /* Report success if no error was recorded */
2368  slave->status = STATUS_SUCCESS;
2369  }
2370 
2371  if (!slave->slaveListening)
2372  {
2373  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2374 
2375  /* Signal transfer end for blocking transfers */
2376  if (slave->blocking == true)
2377  {
2378  (void)OSIF_SemaPost(&(slave->idleSemaphore));
2379  }
2380  }
2381 
2382  if(slave->slaveCallback != NULL)
2383  {
2384  slave->slaveCallback((uint8_t)instance, LPI2C_SLAVE_EVENT_STOP, slave->callbackParam);
2385  }
2386  }
2387 
2388  if (LPI2C_HAL_SlaveGetBitErrorEvent(baseAddr))
2389  {
2390  slave->status = STATUS_ERROR;
2392 
2393 #if defined(ERRATA_E10792)
2394  /* Deactivate interrupts for transmitting data */
2396 #endif
2397 
2398  if (slave->transferType == LPI2C_USING_DMA) {
2399  (void)EDMA_DRV_StopChannel(slave->dmaChannel);
2400  }
2401 
2402  if (!slave->slaveListening){
2403 
2404  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2405 
2406  /* Signal transfer end for blocking transfers */
2407  if (slave->blocking == true)
2408  {
2409  (void)OSIF_SemaPost(&(slave->idleSemaphore));
2410  }
2411  }
2412 
2413  if(slave->slaveCallback != NULL)
2414  {
2415  slave->slaveCallback((uint8_t)instance, LPI2C_SLAVE_EVENT_STOP, slave->callbackParam);
2416  }
2417  }
2418 
2419  if (LPI2C_HAL_SlaveGetFIFOErrorEvent(baseAddr))
2420  {
2421  /* In Ultra-Fast mode clock stretching is disabled, so it is possible to get
2422  this event if the slave can't keep up */
2423  slave->status = STATUS_I2C_RX_OVERRUN;
2425 
2426 #if defined(ERRATA_E10792)
2427  /* Deactivate interrupts for transmitting data */
2429 #endif
2430 
2431  if (slave->transferType == LPI2C_USING_DMA) {
2432  (void)EDMA_DRV_StopChannel(slave->dmaChannel);
2433  }
2434 
2435  if (!slave->slaveListening)
2436  {
2437  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2438 
2439  /* Signal transfer end for blocking transfers */
2440  if (slave->blocking == true)
2441  {
2442  (void)OSIF_SemaPost(&(slave->idleSemaphore));
2443  }
2444  }
2445 
2446  if(slave->slaveCallback != NULL)
2447  {
2448  slave->slaveCallback((uint8_t)instance, LPI2C_SLAVE_EVENT_STOP, slave->callbackParam);
2449  }
2450  }
2451 }
2452 
2453 /*******************************************************************************
2454  * EOF
2455  ******************************************************************************/
static void LPI2C_DRV_SlaveSetOperatingMode(uint32_t instance, lpi2c_mode_t operatingMode)
Definition: lpi2c_driver.c:492
status_t LPI2C_DRV_SlaveGetTransferStatus(uint32_t instance, uint32_t *bytesRemaining)
Return the current status of the I2C slave transfer.
static void LPI2C_HAL_SlaveSetHighSpeedModeDetect(LPI2C_Type *baseAddr, bool enable)
Control detection of the High-speed Mode master code.
Definition: lpi2c_hal.h:2783
static void LPI2C_DRV_MasterEndTransfer(LPI2C_Type *baseAddr, lpi2c_master_state_t *master, bool sendStop, bool resetFIFO)
Definition: lpi2c_driver.c:354
static uint8_t LPI2C_HAL_MasterGetClockLowPeriodHS(const LPI2C_Type *baseAddr)
Return the configured minimum clock low period in high-speed mode.
Definition: lpi2c_hal.h:1915
static bool LPI2C_HAL_MasterGetReceiveDataReadyEvent(const LPI2C_Type *baseAddr)
Indicate the availability of receive data.
Definition: lpi2c_hal.h:572
static void LPI2C_HAL_SlaveClearFIFOErrorEvent(LPI2C_Type *baseAddr)
Clear the FIFO overflow or underflow flag.
Definition: lpi2c_hal.h:2499
#define LPI2C_HAL_SLAVE_STOP_DETECT_INT
Definition: lpi2c_hal.h:99
static void LPI2C_HAL_MasterSetEnable(LPI2C_Type *baseAddr, bool enable)
Enable or disable the LPI2C master.
Definition: lpi2c_hal.h:449
static bool LPI2C_HAL_SlaveGetReceiveDataEvent(const LPI2C_Type *baseAddr)
Check the availability of receive data.
Definition: lpi2c_hal.h:2462
DMAMUX_Type *const g_dmamuxBase[DMAMUX_INSTANCE_COUNT]
Array for DMAMUX module register base address.
Definition: edma_common.c:50
static void LPI2C_HAL_MasterSetClockHighPeriodHS(LPI2C_Type *baseAddr, uint8_t value)
Set the minimum clock high period in high-speed mode.
Definition: lpi2c_hal.h:1857
static bool LPI2C_HAL_SlaveGetBitErrorEvent(const LPI2C_Type *baseAddr)
Check the detection of a bit error.
Definition: lpi2c_hal.h:2364
static void LPI2C_HAL_MasterSetClockHighPeriod(LPI2C_Type *baseAddr, uint8_t value)
Set the minimum clock high period.
Definition: lpi2c_hal.h:1700
static void LPI2C_HAL_MasterSetSetupHoldDelayHS(LPI2C_Type *baseAddr, uint8_t value)
Set the setup and hold time for a START / STOP condition in high-speed mode.
Definition: lpi2c_hal.h:1816
static void LPI2C_HAL_SlaveSetIgnoreNACK(LPI2C_Type *baseAddr, lpi2c_slave_nack_config_t nack_config)
Control slave behaviour when NACK is detected.
Definition: lpi2c_hal.h:2820
lpi2c_slave_callback_t slaveCallback
Definition: lpi2c_driver.h:165
status_t LPI2C_DRV_MasterGetTransferStatus(uint32_t instance, uint32_t *bytesRemaining)
Return the current status of the I2C master transfer.
status_t OSIF_SemaDestroy(const semaphore_t *const pSem)
Destroys a previously created semaphore.
static void LPI2C_DRV_MasterHandleTransmitDataRequest(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:788
status_t LPI2C_DRV_MasterAbortTransferData(uint32_t instance)
Abort a non-blocking I2C Master transmission or reception.
static lpi2c_master_prescaler_t LPI2C_HAL_MasterGetPrescaler(const LPI2C_Type *baseAddr)
Return the LPI2C master prescaler.
Definition: lpi2c_hal.h:1381
edma_transfer_type_t
A type for the DMA transfer. Implements : edma_transfer_type_t_Class.
Definition: edma_driver.h:170
static void LPI2C_DRV_MasterQueueCmd(LPI2C_Type *baseAddr, lpi2c_master_state_t *master, lpi2c_master_command_t cmd, uint8_t data)
Definition: lpi2c_driver.c:194
static bool LPI2C_DRV_MasterCmdQueueEmpty(const lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:165
static bool LPI2C_HAL_SlaveGetFIFOErrorEvent(const LPI2C_Type *baseAddr)
Check the detection of a FIFO overflow or underflow.
Definition: lpi2c_hal.h:2345
static status_t LPI2C_DRV_SlaveWaitTransferEnd(uint32_t instance, uint32_t timeout)
Definition: lpi2c_driver.c:758
lpi2c_transfer_type_t transferType
Definition: lpi2c_driver.h:142
static void LPI2C_DRV_MasterQueueData(LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:324
static void LPI2C_HAL_SlaveSetRxDMA(LPI2C_Type *baseAddr, bool enable)
Enable/disable slave receive data DMA requests.
Definition: lpi2c_hal.h:2656
static void LPI2C_DRV_SlaveStartDmaTransfer(uint32_t instance)
Definition: lpi2c_driver.c:646
static void LPI2C_HAL_MasterClearFIFOErrorEvent(LPI2C_Type *baseAddr)
Clear the FIFO error event flag.
Definition: lpi2c_hal.h:774
static void LPI2C_HAL_SlaveClearBitErrorEvent(LPI2C_Type *baseAddr)
Clear bit error flag.
Definition: lpi2c_hal.h:2513
static void EDMA_HAL_TCDSetSrcLastAdjust(DMA_Type *base, uint32_t channel, int32_t size)
Configures the last source address adjustment for the TCD.
Definition: edma_hal.h:952
static uint8_t LPI2C_HAL_MasterGetRxData(const LPI2C_Type *baseAddr)
Return the received data.
Definition: lpi2c_hal.h:2058
status_t EDMA_DRV_StopChannel(uint8_t channel)
Stops the eDMA channel.
Definition: edma_driver.c:790
lpi2c_master_callback_t masterCallback
Definition: lpi2c_driver.h:144
static void LPI2C_DRV_SlaveHandleTransmitDataEvent(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:937
status_t LPI2C_DRV_SlaveReceiveData(uint32_t instance, uint8_t *rxBuff, uint32_t rxSize)
Perform a non-blocking receive transaction on the I2C bus.
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K144.h:269
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
static void LPI2C_DRV_SlaveHandleAddressValidEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:885
static void LPI2C_DRV_MasterSendQueuedCmd(LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:228
#define LPI2C_HAL_MASTER_TRANSMIT_DATA_INT
Definition: lpi2c_hal.h:88
static void LPI2C_HAL_SlaveSetInt(LPI2C_Type *baseAddr, uint32_t interrupts, bool enable)
Enable or disable specified LPI2C slave interrupts.
Definition: lpi2c_hal.h:2571
status_t LPI2C_DRV_SlaveSendDataBlocking(uint32_t instance, const uint8_t *txBuff, uint32_t txSize, uint32_t timeout)
Perform a blocking send transaction on the I2C bus.
static void LPI2C_HAL_MasterSetTxFIFOWatermark(LPI2C_Type *baseAddr, uint8_t value)
Set the transmit FIFO watermark.
Definition: lpi2c_hal.h:1971
#define LPI2C_BASE_PTRS
Definition: S32K144.h:5383
static uint8_t LPI2C_HAL_MasterGetClockHighPeriodHS(const LPI2C_Type *baseAddr)
Return the configured minimum clock high period in high-speed mode.
Definition: lpi2c_hal.h:1876
status_t OSIF_SemaCreate(semaphore_t *const pSem, const uint8_t initValue)
Creates a semaphore with a given value.
static void LPI2C_DRV_MasterCompleteDMATransfer(void *parameter, edma_chn_status_t status)
Definition: lpi2c_driver.c:698
static void LPI2C_HAL_MasterSetInt(LPI2C_Type *baseAddr, uint32_t interrupts, bool enable)
Enable or disable specified LPI2C master interrupts.
Definition: lpi2c_hal.h:931
static void LPI2C_HAL_SlaveSetTXDStall(LPI2C_Type *baseAddr, bool enable)
Enable or disable clock stretching for data transmission.
Definition: lpi2c_hal.h:3047
lpi2c_transfer_type_t transferType
Definition: lpi2c_driver.h:163
lpi2c_mode_t
I2C operating modes Implements : lpi2c_mode_t_Class.
Definition: lpi2c_driver.h:50
static void LPI2C_HAL_MasterClearArbitrationLostEvent(LPI2C_Type *baseAddr)
Clear the arbitration lost event flag.
Definition: lpi2c_hal.h:789
static void LPI2C_HAL_MasterSetNACKConfig(LPI2C_Type *baseAddr, lpi2c_nack_config_t configuration)
Configure the reaction of the module on NACK reception.
Definition: lpi2c_hal.h:1289
#define LPI2C_HAL_SLAVE_ADDRESS_VALID_INT
Definition: lpi2c_hal.h:102
void LPI2C_DRV_MasterSetSlaveAddr(uint32_t instance, const uint16_t address, const bool is10bitAddr)
Set the slave address for any subsequent I2C communication.
#define LPI2C_MASTER_IRQS
Definition: S32K144.h:5391
status_t LPI2C_DRV_SlaveSetRxBuffer(uint32_t instance, uint8_t *rxBuff, uint32_t rxSize)
Provide a buffer for receiving data.
static void LPI2C_DRV_ConfigureDmaTransfer(uint32_t instance, const lpi2c_dma_transfer_params_t *dmaTransParams)
Definition: lpi2c_driver.c:547
static bool LPI2C_HAL_SlaveGetInt(const LPI2C_Type *baseAddr, uint32_t interrupts)
Return the state of the specified LPI2C slave interrupt.
Definition: lpi2c_hal.h:2611
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
static bool LPI2C_HAL_SlaveGetTransmitDataEvent(const LPI2C_Type *baseAddr)
Check if transmit data is requested.
Definition: lpi2c_hal.h:2483
static bool LPI2C_HAL_SlaveGetSTOPDetectEvent(const LPI2C_Type *baseAddr)
Check the detection of a STOP condition.
Definition: lpi2c_hal.h:2382
void LPI2C_DRV_MasterGetBaudRate(uint32_t instance, lpi2c_baud_rate_params_t *baudRate)
Get the currently configured baud rate.
#define DEV_ASSERT(x)
Definition: devassert.h:78
status_t LPI2C_DRV_MasterReceiveDataBlocking(uint32_t instance, uint8_t *rxBuff, uint32_t rxSize, bool sendStop, uint32_t timeout)
Perform a blocking receive transaction on the I2C bus.
static void LPI2C_DRV_MasterHandleReceiveDataReadyEvent(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:837
status_t LPI2C_DRV_MasterSendData(uint32_t instance, const uint8_t *txBuff, uint32_t txSize, bool sendStop)
Perform a non-blocking send transaction on the I2C bus.
static void LPI2C_DRV_MasterResetQueue(lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:179
static void LPI2C_HAL_SlaveSetRXStall(LPI2C_Type *baseAddr, bool enable)
Enable or disable clock stretching for data reception.
Definition: lpi2c_hal.h:3085
status_t LPI2C_DRV_SlaveSetTxBuffer(uint32_t instance, const uint8_t *txBuff, uint32_t txSize)
Provide a buffer for transmitting data.
edma_chn_status_t
Channel status for eDMA channel.
Definition: edma_driver.h:125
static void LPI2C_HAL_SlaveSetTxDMA(LPI2C_Type *baseAddr, bool enable)
Enable/disable slave transmit data DMA requests.
Definition: lpi2c_hal.h:2675
Slave configuration structure.
Definition: lpi2c_driver.h:157
Slave internal context structure.
Definition: lpi2c_driver.h:241
Baud rate structure.
Definition: lpi2c_driver.h:179
static void LPI2C_HAL_SlaveSetTransmitNACK(LPI2C_Type *baseAddr, lpi2c_slave_nack_transmit_t nack)
Configure the ACK/NACK transmission after a received byte.
Definition: lpi2c_hal.h:3438
static void LPI2C_DRV_MasterStartDmaTransfer(uint32_t instance)
Definition: lpi2c_driver.c:575
status_t LPI2C_DRV_SlaveSendData(uint32_t instance, const uint8_t *txBuff, uint32_t txSize)
Perform a non-blocking send transaction on the I2C bus.
status_t LPI2C_DRV_SlaveAbortTransferData(uint32_t instance)
Abort a non-blocking I2C Master transmission or reception.
status_t CLOCK_SYS_GetFreq(clock_names_t clockName, uint32_t *frequency)
Gets the clock frequency for a specific clock name.
static void LPI2C_HAL_SlaveSetAddrStall(LPI2C_Type *baseAddr, bool enable)
Enable or disable clock stretching for valid address reception.
Definition: lpi2c_hal.h:3123
static void LPI2C_HAL_MasterSetClockLowPeriod(LPI2C_Type *baseAddr, uint8_t value)
Set the minimum clock low period.
Definition: lpi2c_hal.h:1737
static void LPI2C_HAL_MasterClearNACKDetectEvent(LPI2C_Type *baseAddr)
Clear the unexpected NACK event flag.
Definition: lpi2c_hal.h:804
static void LPI2C_DRV_MasterSendAddress(LPI2C_Type *baseAddr, lpi2c_master_state_t *master, bool receive)
Definition: lpi2c_driver.c:261
void LPI2C_DRV_MasterIRQHandler(uint32_t instance)
Handle master operation when I2C interrupt occurs.
static void LPI2C_HAL_SlaveSetACKStall(LPI2C_Type *baseAddr, bool enable)
Enable or disable clock stretching for the sending of the ACK bit.
Definition: lpi2c_hal.h:3009
static void LPI2C_HAL_MasterRxFIFOResetCmd(LPI2C_Type *baseAddr)
Reset the master receive FIFO.
Definition: lpi2c_hal.h:356
static void LPI2C_HAL_MasterSetPinConfig(LPI2C_Type *baseAddr, lpi2c_pin_config_t configuration)
Set the pin mode of the module.
Definition: lpi2c_hal.h:1179
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 LPI2C_DRV_MasterInit(uint32_t instance, const lpi2c_master_user_config_t *userConfigPtr, lpi2c_master_state_t *master)
Initialize the LPI2C master mode driver.
static bool LPI2C_HAL_MasterGetFIFOErrorEvent(const LPI2C_Type *baseAddr)
Check the occurrence of a FIFO error event.
Definition: lpi2c_hal.h:650
#define LPI2C_HAL_MASTER_RECEIVE_DATA_INT
Definition: lpi2c_hal.h:87
status_t LPI2C_DRV_MasterDeinit(uint32_t instance)
De-initialize the LPI2C master mode driver.
#define LPI2C_DMA_INSTANCE
void LPI2C_DRV_SlaveIRQHandler(uint32_t instance)
Handle slave operation when I2C interrupt occurs.
Master configuration structure.
Definition: lpi2c_driver.h:132
static void LPI2C_HAL_MasterSetDataValidDelayHS(LPI2C_Type *baseAddr, uint8_t value)
Set the data hold time for SDA in high-speed mode.
Definition: lpi2c_hal.h:1775
static uint16_t LPI2C_HAL_SlaveGetReceivedAddr(const LPI2C_Type *baseAddr)
Return the received slave address.
Definition: lpi2c_hal.h:3418
static uint8_t LPI2C_HAL_MasterGetClockLowPeriod(const LPI2C_Type *baseAddr)
Return the configured minimum clock low period.
Definition: lpi2c_hal.h:1755
lpi2c_master_prescaler_t
LPI2C master prescaler options Implements : lpi2c_master_prescaler_t_Class.
Definition: lpi2c_hal.h:193
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
#define LPI2C_HAL_SLAVE_RECEIVE_DATA_INT
Definition: lpi2c_hal.h:103
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
__I uint32_t MRDR
Definition: S32K144.h:5351
clock_names_t
Clock names.
static uint8_t LPI2C_HAL_MasterGetRxFIFOWatermark(const LPI2C_Type *baseAddr)
Return the configured receive FIFO watermark.
Definition: lpi2c_hal.h:1952
static uint16_t LPI2C_HAL_MasterGetTxFIFOSize(const LPI2C_Type *baseAddr)
Get the size of the Master Transmit FIFO.
Definition: lpi2c_hal.h:339
static void LPI2C_DRV_SlaveHandleReceiveDataEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:980
static void LPI2C_HAL_MasterSetRxFIFOWatermark(LPI2C_Type *baseAddr, uint8_t value)
Set the receive FIFO watermark.
Definition: lpi2c_hal.h:1934
status_t LPI2C_DRV_SlaveDeinit(uint32_t instance)
De-initialize the I2C slave mode driver.
static void LPI2C_HAL_SlaveSetAddr0(LPI2C_Type *baseAddr, uint16_t addr)
Configure the ADDR0 address for slave address match.
Definition: lpi2c_hal.h:3361
__IO uint32_t MTDR
Definition: S32K144.h:5349
static void LPI2C_HAL_MasterSetPrescaler(LPI2C_Type *baseAddr, lpi2c_master_prescaler_t prescaler)
Configure the LPI2C master prescaler.
Definition: lpi2c_hal.h:1363
#define LPI2C_HAL_SLAVE_FIFO_ERROR_INT
Definition: lpi2c_hal.h:97
static status_t LPI2C_DRV_MasterWaitTransferEnd(uint32_t instance, uint32_t timeout)
Definition: lpi2c_driver.c:728
status_t OSIF_SemaPost(semaphore_t *const pSem)
Increment a semaphore.
lpi2c_master_command_t
LPI2C master commands Implements : lpi2c_master_command_t_Class.
Definition: lpi2c_hal.h:208
static void LPI2C_HAL_MasterSetSetupHoldDelay(LPI2C_Type *baseAddr, uint8_t value)
Set the setup and hold delay for a START / STOP condition.
Definition: lpi2c_hal.h:1660
static uint8_t LPI2C_HAL_SlaveGetData(const LPI2C_Type *baseAddr)
Return the data received by the LPI2C slave receiver.
Definition: lpi2c_hal.h:3525
DMA_Type *const g_edmaBase[DMA_INSTANCE_COUNT]
Array for the eDMA module register base address.
Definition: edma_common.c:47
void LPI2C_HAL_Init(LPI2C_Type *baseAddr)
Initializes the LPI2C module to a known state.
Definition: lpi2c_hal.c:59
static void LPI2C_HAL_MasterSetDataValidDelay(LPI2C_Type *baseAddr, uint8_t value)
Set the data hold time for SDA.
Definition: lpi2c_hal.h:1621
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
static bool LPI2C_HAL_SlaveGetAddressValidEvent(const LPI2C_Type *baseAddr)
Check the validity of the Address Status Register.
Definition: lpi2c_hal.h:2441
static void LPI2C_HAL_MasterSetTxDMA(LPI2C_Type *baseAddr, bool enable)
Enable/disable transmit data DMA requests.
Definition: lpi2c_hal.h:867
#define LPI2C_HAL_SLAVE_BIT_ERROR_INT
Definition: lpi2c_hal.h:98
#define LPI2C_SLAVE_IRQS
Definition: S32K144.h:5392
static void LPI2C_HAL_SlaveSetAddrConfig(LPI2C_Type *baseAddr, lpi2c_slave_addr_config_t configuration)
Control address match configuration.
Definition: lpi2c_hal.h:2745
static void LPI2C_HAL_MasterTransmitCmd(LPI2C_Type *baseAddr, lpi2c_master_command_t cmd, uint8_t data)
Provide commands and data for the LPI2C master.
Definition: lpi2c_hal.h:2042
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
void LPI2C_DRV_MasterSetBaudRate(uint32_t instance, const lpi2c_mode_t operatingMode, const lpi2c_baud_rate_params_t baudRate)
Set the baud rate for any subsequent I2C communication.
static uint16_t LPI2C_HAL_MasterGetRxFIFOSize(const LPI2C_Type *baseAddr)
Get the size of the Master Receive FIFO.
Definition: lpi2c_hal.h:321
lpi2c_dma_transfer_params_t
Definition: lpi2c_driver.c:151
Master internal context structure.
Definition: lpi2c_driver.h:206
status_t LPI2C_DRV_MasterReceiveData(uint32_t instance, uint8_t *rxBuff, uint32_t rxSize, bool sendStop)
Perform a non-blocking receive transaction on the I2C bus.
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
static uint8_t LPI2C_HAL_MasterGetClockHighPeriod(const LPI2C_Type *baseAddr)
Return the configured minimum clock high period.
Definition: lpi2c_hal.h:1718
static bool LPI2C_HAL_MasterGetTransmitDataRequestEvent(const LPI2C_Type *baseAddr)
Indicate if the LPI2C master requests more data.
Definition: lpi2c_hal.h:591
static void LPI2C_HAL_SlaveClearSTOPDetectEvent(LPI2C_Type *baseAddr)
Clear the STOP detect flag.
Definition: lpi2c_hal.h:2527
static uint8_t LPI2C_HAL_MasterGetTxFIFOCount(const LPI2C_Type *baseAddr)
Return the number of words in the transmit FIFO.
Definition: lpi2c_hal.h:2023
static void LPI2C_HAL_MasterTxFIFOResetCmd(LPI2C_Type *baseAddr)
Reset the master transmit FIFO.
Definition: lpi2c_hal.h:373
static bool LPI2C_HAL_MasterGetArbitrationLostEvent(const LPI2C_Type *baseAddr)
Check the occurrence of an arbitration lost event.
Definition: lpi2c_hal.h:670
__IO uint32_t STDR
Definition: S32K144.h:5366
static void LPI2C_HAL_SlaveClearRepeatedStartEvent(LPI2C_Type *baseAddr)
Clear the repeated START detect flag.
Definition: lpi2c_hal.h:2541
__I uint32_t SRDR
Definition: S32K144.h:5368
static void LPI2C_HAL_SlaveSetEnable(LPI2C_Type *baseAddr, bool enable)
Enable or disable the LPI2C slave.
Definition: lpi2c_hal.h:2200
static bool LPI2C_HAL_MasterGetNACKDetectEvent(const LPI2C_Type *baseAddr)
Check the occurrence of an unexpected NACK event.
Definition: lpi2c_hal.h:691
status_t LPI2C_DRV_SlaveReceiveDataBlocking(uint32_t instance, uint8_t *rxBuff, uint32_t rxSize, uint32_t timeout)
Perform a blocking receive transaction on the I2C bus.
status_t LPI2C_DRV_SlaveInit(uint32_t instance, const lpi2c_slave_user_config_t *userConfigPtr, lpi2c_slave_state_t *slave)
Initialize the I2C slave mode driver.
static void LPI2C_DRV_MasterSetOperatingMode(uint32_t instance, lpi2c_mode_t operatingMode)
Definition: lpi2c_driver.c:460
status_t LPI2C_DRV_MasterSendDataBlocking(uint32_t instance, const uint8_t *txBuff, uint32_t txSize, bool sendStop, uint32_t timeout)
Perform a blocking send transaction on the I2C bus.
static void LPI2C_HAL_MasterSetRxDMA(LPI2C_Type *baseAddr, bool enable)
Enable/disable receive data DMA requests.
Definition: lpi2c_hal.h:848
status_t EDMA_DRV_InstallCallback(uint8_t channel, edma_callback_t callback, void *parameter)
Registers the callback function and the parameter for eDMA channel.
Definition: edma_driver.c:285
#define LPI2C_INSTANCE_COUNT
Definition: S32K144.h:5372
#define LPI2C_HAL_SLAVE_TRANSMIT_DATA_INT
Definition: lpi2c_hal.h:104
static uint8_t LPI2C_HAL_MasterGetRxFIFOCount(const LPI2C_Type *baseAddr)
Return the number of words in the receive FIFO.
Definition: lpi2c_hal.h:2006
#define LPI2C_HAL_MASTER_ARBITRATION_LOST_INT
Definition: lpi2c_hal.h:83
static void LPI2C_DRV_SlaveEndTransfer(LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:413
#define LPI2C_HAL_MASTER_FIFO_ERROR_INT
Definition: lpi2c_hal.h:82
#define LPI2C_HAL_MASTER_NACK_DETECT_INT
Definition: lpi2c_hal.h:84
static bool LPI2C_HAL_SlaveGetRepeatedStartEvent(const LPI2C_Type *baseAddr)
Check the detection of a repeated START condition.
Definition: lpi2c_hal.h:2401
static void LPI2C_HAL_SlaveTransmitData(LPI2C_Type *baseAddr, uint8_t data)
Provide data for the LPI2C slave transmitter.
Definition: lpi2c_hal.h:3474
#define LPI2C_HAL_SLAVE_REPEATED_START_INT
Definition: lpi2c_hal.h:100
static void LPI2C_HAL_MasterSetClockLowPeriodHS(LPI2C_Type *baseAddr, uint8_t value)
Set the minimum clock low period in high-speed mode.
Definition: lpi2c_hal.h:1896