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_hw_access.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] = LPI2C_EDMA_REQ;
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 */
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,
196  lpi2c_master_command_t cmd,
197  uint8_t data)
198 {
199  DEV_ASSERT(master != NULL);
200  DEV_ASSERT(baseAddr != NULL);
201 
202  uint16_t txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
203  uint16_t txFIFOSize = LPI2C_Get_MasterTxFIFOSize(baseAddr);
204 
205  /* Check if there is room in the hardware FIFO */
206  if (txFIFOCount < txFIFOSize)
207  {
208  LPI2C_Cmd_MasterTransmit(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  uint16_t txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
234  uint16_t txFifoSize = LPI2C_Get_MasterTxFIFOSize(baseAddr);
235 
236  while ((!LPI2C_DRV_MasterCmdQueueEmpty(master)) && (txFIFOCount < txFifoSize))
237  {
238  LPI2C_Cmd_MasterTransmit(baseAddr,
239  master->cmdQueue.cmd[master->cmdQueue.readIdx],
240  master->cmdQueue.data[master->cmdQueue.readIdx]);
241  master->cmdQueue.readIdx++;
242 
243  txFIFOCount = LPI2C_Get_MasterTxFIFOCount(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  uint16_t txFIFOCount = LPI2C_Get_MasterTxFIFOCount(baseAddr);
331  uint16_t txFifoSize = LPI2C_Get_MasterTxFIFOSize(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) && (txFIFOCount < txFifoSize))
337  {
338  LPI2C_Cmd_MasterTransmit(baseAddr, LPI2C_MASTER_COMMAND_TRANSMIT, master->txBuff[0U]);
339  master->txBuff++;
340  master->txSize--;
341 
342  txFIFOCount = LPI2C_Get_MasterTxFIFOCount(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 */
363  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
364  LPI2C_MASTER_ARBITRATION_LOST_INT |
365  LPI2C_MASTER_NACK_DETECT_INT |
366  LPI2C_MASTER_TRANSMIT_DATA_INT |
367  LPI2C_MASTER_RECEIVE_DATA_INT,
368  false);
369 
370  if (resetFIFO == true)
371  {
372  /* Reset FIFOs if requested */
373  LPI2C_Reset_MasterTxFIFOCmd(baseAddr);
374  LPI2C_Reset_MasterRxFIFOCmd(baseAddr);
375  }
376 
377  /* Queue STOP command if requested */
378  if (sendStop == true)
379  {
380  LPI2C_Cmd_MasterTransmit(baseAddr, LPI2C_MASTER_COMMAND_STOP, 0U);
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_Set_MasterRxDMA(baseAddr, false);
392  }
393  else
394  {
395  (void)LPI2C_Set_MasterTxDMA(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 
421  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
422  LPI2C_SLAVE_FIFO_ERROR_INT |
423  LPI2C_SLAVE_STOP_DETECT_INT |
424  LPI2C_SLAVE_REPEATED_START_INT |
425  LPI2C_SLAVE_ADDRESS_VALID_INT |
426  LPI2C_SLAVE_RECEIVE_DATA_INT |
427  LPI2C_SLAVE_TRANSMIT_DATA_INT,
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_Set_SlaveRxDMA(baseAddr, false);
436  }
437  else
438  {
439  (void)LPI2C_Set_SlaveTxDMA(baseAddr, false);
440  }
441  }
442 
443  /* Disable LPI2C slave */
444  LPI2C_Set_SlaveEnable(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  {
472  LPI2C_Set_MasterPinConfig(baseAddr, LPI2C_CFG_2PIN_OUTPUT_ONLY);
473  LPI2C_Set_MasterNACKConfig(baseAddr, LPI2C_NACK_IGNORE);
474  }
475  else
476 #endif
477  {
478  LPI2C_Set_MasterPinConfig(baseAddr, LPI2C_CFG_2PIN_OPEN_DRAIN);
479  LPI2C_Set_MasterNACKConfig(baseAddr, LPI2C_NACK_RECEIVE);
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  {
504  LPI2C_Set_SlaveIgnoreNACK(baseAddr, LPI2C_SLAVE_NACK_CONTINUE_TRANSFER);
505  LPI2C_Set_SlaveTransmitNACK(baseAddr, LPI2C_SLAVE_TRANSMIT_NACK);
506  /* Disable all clock stretching in ultra-fast mode */
507  LPI2C_Set_SlaveACKStall(baseAddr, false);
508  LPI2C_Set_SlaveTXDStall(baseAddr, false);
509  LPI2C_Set_SlaveRXStall(baseAddr, false);
510  LPI2C_Set_SlaveAddrStall(baseAddr, false);
511  }
512  else
513 #endif
514  {
515  LPI2C_Set_SlaveIgnoreNACK(baseAddr, LPI2C_SLAVE_NACK_END_TRANSFER);
516  LPI2C_Set_SlaveTransmitNACK(baseAddr, LPI2C_SLAVE_TRANSMIT_ACK);
517  /* Enable clock stretching except ACKSTALL (we don't need to send ACK/NACK manually) */
518  LPI2C_Set_SlaveACKStall(baseAddr, false);
519  LPI2C_Set_SlaveTXDStall(baseAddr, true);
520  LPI2C_Set_SlaveRXStall(baseAddr, true);
521  LPI2C_Set_SlaveAddrStall(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 */
528  LPI2C_Set_SlaveHighSpeedModeDetect(baseAddr, true);
529  }
530  else
531 #endif
532  {
533  /* Disable detection of the High-speed Mode master code */
534  LPI2C_Set_SlaveHighSpeedModeDetect(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 {
549  /* Configure DMA channel */
550  if (dmaTransParams->transferDirection == LPI2C_TX_REQ)
551  {
552  (void)EDMA_DRV_SetChannelRequest(dmaTransParams->dmaChannel, g_lpi2cDMASrc[instance][LPI2C_TX_REQ]);
553  (void)EDMA_DRV_ConfigMultiBlockTransfer(dmaTransParams->dmaChannel, dmaTransParams->dmaTransferType, (uint32_t)dmaTransParams->bufferTransfer,
554  (uint32_t)dmaTransParams->i2cDataRegAddr, EDMA_TRANSFER_SIZE_1B, (uint32_t)1U,
555  (uint32_t)dmaTransParams->transferSize, false);
556  }
557  else
558  {
559  (void)EDMA_DRV_SetChannelRequest(dmaTransParams->dmaChannel, g_lpi2cDMASrc[instance][LPI2C_RX_REQ]);
560  (void)EDMA_DRV_ConfigMultiBlockTransfer(dmaTransParams->dmaChannel, dmaTransParams->dmaTransferType, (uint32_t)dmaTransParams->i2cDataRegAddr,
561  (uint32_t)dmaTransParams->bufferTransfer, EDMA_TRANSFER_SIZE_1B, (uint32_t)1U,
562  (uint32_t)dmaTransParams->transferSize, false);
563  }
564 }
565 
566 
567 /*FUNCTION**********************************************************************
568  *
569  * Function Name : LPI2C_DRV_MasterStartDmaTransfer
570  * Description : starts the DMA transfer for master
571  *
572  *END**************************************************************************/
573 static void LPI2C_DRV_MasterStartDmaTransfer(uint32_t instance)
574 {
575  LPI2C_Type *baseAddr = g_lpi2cBase[instance];
576  lpi2c_master_state_t *master = g_lpi2cMasterStatePtr[instance];
577  lpi2c_dma_transfer_params_t dmaTransParams;
578  bool receive = false;
579 
580  dmaTransParams.dmaChannel = master->dmaChannel;
581  if (master->txSize > 0U)
582  {
583  /* Configure watermarks for transmit DMA for master */
584  uint32_t txBytes = LPI2C_Get_MasterTxFIFOSize(baseAddr);
585  if (txBytes > master->txSize)
586  {
587  txBytes = master->txSize;
588  }
589  LPI2C_Set_MasterTxFIFOWatermark(baseAddr, (uint16_t)(txBytes - 1U));
590 
591  dmaTransParams.dmaTransferType = EDMA_TRANSFER_MEM2PERIPH;
592  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->MTDR));
593  dmaTransParams.bufferTransfer = (uint8_t *)master->txBuff;
594  dmaTransParams.transferDirection = LPI2C_TX_REQ;
595  dmaTransParams.transferSize = master->txSize;
596 
597  }
598  else
599  {
600  /* Configure watermarks for receive DMA for master */
601  LPI2C_Set_MasterRxFIFOWatermark(baseAddr, 0U);
602 
603  receive = true;
604 
605  dmaTransParams.dmaTransferType = EDMA_TRANSFER_PERIPH2MEM;
606  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->MRDR));
607  dmaTransParams.bufferTransfer = master->rxBuff;
608  dmaTransParams.transferDirection = LPI2C_RX_REQ;
609  dmaTransParams.transferSize = master->rxSize;
610  }
611 
612  (void)LPI2C_DRV_ConfigureDmaTransfer(instance, &dmaTransParams);
613 
614  /* Disable DMA requests for channel when transfer is done */
615  EDMA_DRV_DisableRequestsOnTransferComplete(dmaTransParams.dmaChannel, true);
616 
617  /* Call callback function when all the bytes were transfered. */
618  (void)EDMA_DRV_InstallCallback(dmaTransParams.dmaChannel, (LPI2C_DRV_MasterCompleteDMATransfer), (void*)(instance));
619 
620  /* Start channel */
621  (void)EDMA_DRV_StartChannel(dmaTransParams.dmaChannel);
622 
623  LPI2C_DRV_MasterSendAddress(baseAddr, master, receive);
624 
625  /* Enable transmit/receive DMA requests */
626  if (master->txSize > (uint32_t)0U)
627  {
628  (void)LPI2C_Set_MasterTxDMA(baseAddr, true);
629  }
630  else
631  {
632  LPI2C_DRV_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_RECEIVE, (uint8_t)(master->rxSize - 1U));
633  (void)LPI2C_Set_MasterRxDMA(baseAddr, true);
634  }
635 }
636 
637 
638 /*FUNCTION**********************************************************************
639  *
640  * Function Name : LPI2C_DRV_SlaveStartDmaTransfer
641  * Description : starts the DMA transfer for slave
642  *
643  *END**************************************************************************/
644 static void LPI2C_DRV_SlaveStartDmaTransfer(uint32_t instance)
645 {
646  LPI2C_Type *baseAddr = g_lpi2cBase[instance];
647  const lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
648  lpi2c_dma_transfer_params_t dmaTransParams;
649 
650  if (slave->txSize > (uint32_t)0U)
651  {
652  dmaTransParams.dmaChannel = slave->dmaChannel;
653  dmaTransParams.dmaTransferType = EDMA_TRANSFER_MEM2PERIPH;
654  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->STDR));
655  dmaTransParams.bufferTransfer = (uint8_t*)slave->txBuff;
656  dmaTransParams.transferDirection = LPI2C_TX_REQ;
657  dmaTransParams.transferSize = slave->txSize;
658  }
659  else
660  {
661  dmaTransParams.dmaChannel = slave->dmaChannel;
662  dmaTransParams.dmaTransferType = EDMA_TRANSFER_PERIPH2MEM;
663  dmaTransParams.i2cDataRegAddr = (uint32_t)(&(baseAddr->SRDR));
664  dmaTransParams.bufferTransfer = slave->rxBuff;
665  dmaTransParams.transferDirection = LPI2C_RX_REQ;
666  dmaTransParams.transferSize = slave->rxSize;
667  }
668 
669  (void)LPI2C_DRV_ConfigureDmaTransfer(instance, &dmaTransParams);
670  /* Adjustment added to source address at the beginning of TX buffer */
671  EDMA_DRV_SetSrcLastAddrAdjustment(dmaTransParams.dmaChannel, -(int32_t)(slave->txSize));
672 
673  /* Start channel */
674  (void)EDMA_DRV_StartChannel(dmaTransParams.dmaChannel);
675 
676  /* Enable transmit/receive DMA requests */
677  if (slave->txSize > (uint32_t)0U)
678  {
679  (void)LPI2C_Set_SlaveTxDMA(baseAddr, true);
680  }
681  else
682  {
683  (void)LPI2C_Set_SlaveRxDMA(baseAddr, true);
684  }
685 }
686 
687 
688 /*FUNCTION**********************************************************************
689  *
690  * Function Name : LPI2C_DRV_MasterCompleteDMATransfer
691  * Description : Finish up a transfer DMA for master. The main purpose of
692  * this function is to create a function compatible with DMA
693  * callback type
694  *
695  *END**************************************************************************/
696 static void LPI2C_DRV_MasterCompleteDMATransfer(void* parameter, edma_chn_status_t status)
697 {
698  LPI2C_Type *baseAddr;
699  lpi2c_master_state_t *master;
700 
701  (void)status;
702 
703  uint32_t instance = (uint32_t)parameter;
704 
705  baseAddr = g_lpi2cBase[instance];
706  master = g_lpi2cMasterStatePtr[instance];
707 
708  LPI2C_DRV_MasterEndTransfer(baseAddr, master, master->sendStop, false);
709 
710  /* Signal transfer end for blocking transfers */
711  if (master->blocking == true)
712  {
713  (void)OSIF_SemaPost(&(master->idleSemaphore));
714  }
715 
716  master->status = STATUS_SUCCESS;
717 }
718 
719 
720 /*FUNCTION**********************************************************************
721  *
722  * Function Name : LPI2C_DRV_MasterWaitTransferEnd
723  * Description : waits for the end of a blocking transfer
724  *
725  *END**************************************************************************/
726 static status_t LPI2C_DRV_MasterWaitTransferEnd(uint32_t instance, uint32_t timeout)
727 {
728  status_t osifError = STATUS_SUCCESS;
729  LPI2C_Type *baseAddr;
730  lpi2c_master_state_t *master;
731 
732  baseAddr = g_lpi2cBase[instance];
733  master = g_lpi2cMasterStatePtr[instance];
734 
735  /* Wait for transfer to be completed by the IRQ */
736  osifError = OSIF_SemaWait(&(master->idleSemaphore), timeout);
737 
738  if (osifError == STATUS_TIMEOUT)
739  {
740  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
741  master->status = STATUS_TIMEOUT;
742  }
743 
744  /* Blocking transfer is over */
745  master->blocking = false;
746  return master->status;
747 }
748 
749 
750 /*FUNCTION**********************************************************************
751  *
752  * Function Name : LPI2C_DRV_SlaveWaitTransferEnd
753  * Description : waits for the end of a blocking transfer
754  *
755  *END**************************************************************************/
756 static status_t LPI2C_DRV_SlaveWaitTransferEnd(uint32_t instance, uint32_t timeout)
757 {
758  status_t osifError = STATUS_SUCCESS;
759  LPI2C_Type *baseAddr;
760  lpi2c_slave_state_t *slave;
761 
762  baseAddr = g_lpi2cBase[instance];
763  slave = g_lpi2cSlaveStatePtr[instance];
764 
765  /* Wait for transfer to be completed by the IRQ */
766  osifError = OSIF_SemaWait(&(slave->idleSemaphore), timeout);
767 
768  if (osifError == STATUS_TIMEOUT)
769  {
770  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
771  slave->status = STATUS_TIMEOUT;
772  }
773 
774  /* Blocking transfer is over */
775  slave->blocking = false;
776  return slave->status;
777 }
778 
779 
780 /*FUNCTION**********************************************************************
781  *
782  * Function Name : LPI2C_DRV_MasterHandleTransmitDataRequest
783  * Description : handle a transmit request for master
784  *
785  *END**************************************************************************/
786 static void LPI2C_DRV_MasterHandleTransmitDataRequest(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
787 {
788  /* More data needed for transmission */
789  if (!LPI2C_DRV_MasterCmdQueueEmpty(master))
790  {
791  /* If there are queued commands, send them */
792  LPI2C_DRV_MasterSendQueuedCmd(baseAddr, master);
793  }
794  else if (master->txBuff != NULL)
795  {
796  /* A transmission is in progress */
797  if (master->txSize == 0U)
798  {
799  /* There is no more data in buffer, the transmission is over */
800  LPI2C_DRV_MasterEndTransfer(baseAddr, master, master->sendStop, false);
801 
802  /* Signal transfer end for blocking transfers */
803  if (master->blocking == true)
804  {
805  (void)OSIF_SemaPost(&(master->idleSemaphore));
806  }
807 
808  master->status = STATUS_SUCCESS;
809 
810  if (master->masterCallback != NULL)
811  {
812  master->masterCallback(instance, LPI2C_MASTER_EVENT_TX, master->callbackParam);
813  }
814  }
815  else
816  {
817  /* Queue data bytes to fill tx fifo */
818  LPI2C_DRV_MasterQueueData(baseAddr, master);
819  }
820  }
821  else
822  {
823  /* No more commands and no transmission in progress - disable tx event */
824  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_TRANSMIT_DATA_INT, false);
825  }
826 }
827 
828 
829 /*FUNCTION**********************************************************************
830  *
831  * Function Name : LPI2C_DRV_MasterHandleReceiveDataRequest
832  * Description : handle a receive request for master
833  *
834  *END**************************************************************************/
835 static void LPI2C_DRV_MasterHandleReceiveDataReadyEvent(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
836 {
837  /* Received data ready */
838  DEV_ASSERT(master->rxBuff != NULL);
839 
840  /* Transfer received data to user buffer */
841  while ((LPI2C_Get_MasterRxFIFOCount(baseAddr) > 0U) && (master->rxSize > 0U))
842  {
843  master->rxBuff[0U] = LPI2C_Get_MasterRxData(baseAddr);
844  master->rxBuff++;
845  master->rxSize--;
846  }
847  if (master->rxSize == 0U)
848  {
849  /* Done receiving */
850  LPI2C_DRV_MasterEndTransfer(baseAddr, master, master->sendStop, false);
851 
852  /* Signal transfer end for blocking transfers */
853  if (master->blocking == true)
854  {
855  (void)OSIF_SemaPost(&(master->idleSemaphore));
856  }
857 
858  master->status = STATUS_SUCCESS;
859 
860  if (master->masterCallback != NULL)
861  {
862  master->masterCallback(instance, LPI2C_MASTER_EVENT_RX, master->callbackParam);
863  }
864  }
865  else if (master->rxSize <= LPI2C_Get_MasterRxFIFOWatermark(baseAddr))
866  {
867  /* Reduce rx watermark to receive the last few bytes */
868  LPI2C_Set_MasterRxFIFOWatermark(baseAddr, (uint16_t)(master->rxSize - 1U));
869  }
870  else
871  {
872  /* Continue reception */
873  }
874 }
875 
876 
877 /*FUNCTION**********************************************************************
878  *
879  * Function Name : LPI2C_DRV_SlaveHandleAddressValidEvent
880  * Description : handle an address valid event for slave
881  *
882  *END**************************************************************************/
883 static void LPI2C_DRV_SlaveHandleAddressValidEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
884 {
885  uint16_t receivedAddr;
886 
887  receivedAddr = LPI2C_Get_SlaveReceivedAddr(baseAddr);
888  if ((receivedAddr & 1U) != (uint16_t)0U)
889  {
890  /* Request from master to transmit data */
891  if ((slave->slaveCallback != NULL) && slave->slaveListening)
892  {
893  slave->slaveCallback(instance, LPI2C_SLAVE_EVENT_TX_REQ, slave->callbackParam);
894  }
895 
896 #if defined(ERRATA_E10792)
897  if (slave->transferType == LPI2C_USING_INTERRUPTS) {
898  /* Enable interrupt for transmitting data */
899  LPI2C_Set_SlaveInt(g_lpi2cBase[instance], LPI2C_SLAVE_TRANSMIT_DATA_INT, true);
900  }
901 #endif
902 
903  slave->txUnderrunWarning = false;
904 
905  if ((slave->transferType == LPI2C_USING_DMA) && slave->slaveListening)
906  {
907  (void)LPI2C_DRV_SlaveStartDmaTransfer(instance);
908  }
909 
910  }
911  else
912  {
913  /* Request from master to receive data */
914  if ((slave->slaveCallback != NULL) && slave->slaveListening)
915  {
916  slave->slaveCallback(instance, LPI2C_SLAVE_EVENT_RX_REQ, slave->callbackParam);
917  }
918 
919  if ((slave->transferType == LPI2C_USING_DMA) && slave->slaveListening)
920  {
921  (void)LPI2C_DRV_SlaveStartDmaTransfer(instance);
922  }
923  }
924 
925  slave->status = STATUS_BUSY;
926 }
927 
928 
929 /*FUNCTION**********************************************************************
930  *
931  * Function Name : LPI2C_DRV_SlaveHandleTransmitDataEvent
932  * Description : handle a transmit data event for slave
933  *
934  *END**************************************************************************/
935 static void LPI2C_DRV_SlaveHandleTransmitDataEvent(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
936 {
937  if (slave->txUnderrunWarning == true)
938  {
939  /* Another Tx event after underflow warning means the dummy char was sent */
940  slave->status = STATUS_I2C_TX_UNDERRUN;
941  }
942 
943  if (slave->txSize == 0U)
944  {
945  /* Out of data, call callback to allow user to provide a new buffer */
946  if (slave->slaveCallback != NULL)
947  {
948  slave->slaveCallback(instance, LPI2C_SLAVE_EVENT_TX_EMPTY, slave->callbackParam);
949  }
950  }
951 
952  if (slave->txSize == 0U)
953  {
954  /*
955  * Still no data, record tx underflow event and send dummy char.
956  * Special case after the last tx byte: the device will ask for more data
957  * but the dummy char will not be sent if NACK and then STOP condition are
958  * received from master. So only record a "warning" for now.
959  */
960  slave->txUnderrunWarning = true;
961  LPI2C_Transmit_SlaveData(baseAddr, (uint8_t)0xFFU);
962  }
963  else
964  {
965  LPI2C_Transmit_SlaveData(baseAddr, slave->txBuff[0U]);
966  slave->txBuff++;
967  slave->txSize--;
968  }
969 }
970 
971 
972 /*FUNCTION**********************************************************************
973  *
974  * Function Name : LPI2C_DRV_SlaveHandleReceiveDataEvent
975  * Description : handle a receive data event for slave
976  *
977  *END**************************************************************************/
978 static void LPI2C_DRV_SlaveHandleReceiveDataEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
979 {
980  if (slave->rxSize == 0U)
981  {
982  /* No more room for data, call callback to allow user to provide a new buffer */
983  if (slave->slaveCallback != NULL)
984  {
985  slave->slaveCallback(instance, LPI2C_SLAVE_EVENT_RX_FULL, slave->callbackParam);
986  }
987  }
988 
989  if (slave->rxSize == 0U)
990  {
991  /* Still no room for data, record rx overrun event and dummy read data */
992  slave->status = STATUS_I2C_RX_OVERRUN;
993  (void)LPI2C_Get_SlaveData(baseAddr);
994  }
995  else
996  {
997  slave->rxBuff[0U] = LPI2C_Get_SlaveData(baseAddr);
998  slave->rxBuff++;
999  slave->rxSize--;
1000  }
1001 }
1002 
1005 /*******************************************************************************
1006  * Code
1007  ******************************************************************************/
1008 
1009 /*FUNCTION**********************************************************************
1010  *
1011  * Function Name : LPI2C_DRV_MasterInit
1012  * Description : initialize the I2C master mode driver
1013  *
1014  * Implements : LPI2C_DRV_MasterInit_Activity
1015  *END**************************************************************************/
1016 status_t LPI2C_DRV_MasterInit(uint32_t instance,
1017  const lpi2c_master_user_config_t * userConfigPtr,
1018  lpi2c_master_state_t * master)
1019 {
1020  LPI2C_Type *baseAddr;
1021  status_t retVal;
1022  uint32_t inputClock;
1023  lpi2c_baud_rate_params_t baudRate;
1024 
1025  DEV_ASSERT(master != NULL);
1026  DEV_ASSERT(userConfigPtr != NULL);
1027  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1028 
1029  /* Check to see if the LPI2C master instance is already initialized */
1030  DEV_ASSERT(g_lpi2cMasterStatePtr[instance] == NULL);
1031 
1032  /* Check the protocol clock frequency */
1033  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1034  DEV_ASSERT(retVal == STATUS_SUCCESS);
1035  DEV_ASSERT(inputClock > 0U);
1036 
1037  baseAddr = g_lpi2cBase[instance];
1038  g_lpi2cMasterStatePtr[instance] = master;
1039 
1040  /* Initialize driver status structure */
1041  master->rxBuff = NULL;
1042  master->rxSize = 0U;
1043  master->txBuff = NULL;
1044  master->txSize = 0U;
1045  master->status = STATUS_SUCCESS;
1046  master->i2cIdle = true;
1047  master->slaveAddress = userConfigPtr->slaveAddress;
1048  master->is10bitAddr = userConfigPtr->is10bitAddr;
1049  master->transferType = userConfigPtr->transferType;
1050  /* Store DMA channel number used in transfer */
1051  master->dmaChannel = userConfigPtr->dmaChannel;
1052  master->masterCallback = userConfigPtr->masterCallback;
1053  master->callbackParam = userConfigPtr->callbackParam;
1054 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1055  master->masterCode = userConfigPtr->masterCode;
1056  master->highSpeedInProgress = false;
1057 #endif
1058  master->blocking = false;
1059 
1060  /* Initialize the semaphore */
1061  retVal = OSIF_SemaCreate(&(master->idleSemaphore), 0);
1062  DEV_ASSERT(retVal == STATUS_SUCCESS);
1063 
1065 
1066  /* Enable lpi2c interrupt */
1067  INT_SYS_EnableIRQ(g_lpi2cMasterIrqId[instance]);
1068 
1069  /* Initialize module */
1070  LPI2C_Init(baseAddr);
1071 
1072  /* Set baud rate */
1073  baudRate.baudRate = userConfigPtr->baudRate;
1074 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1075  baudRate.baudRateHS = userConfigPtr->baudRateHS;
1076 #endif
1077  LPI2C_DRV_MasterSetBaudRate(instance, userConfigPtr->operatingMode, baudRate);
1078 
1079  /* Set slave address */
1080  LPI2C_DRV_MasterSetSlaveAddr(instance, userConfigPtr->slaveAddress, userConfigPtr->is10bitAddr);
1081 
1082  /* Enable LPI2C master */
1083  LPI2C_Set_MasterEnable(baseAddr, true);
1084 
1085  (void)retVal;
1086 
1087  return STATUS_SUCCESS;
1088 }
1089 
1090 
1091 /*FUNCTION**********************************************************************
1092  *
1093  * Function Name : LPI2C_DRV_MasterDeinit
1094  * Description : deinitialize the I2C master mode driver
1095  *
1096  * Implements : LPI2C_DRV_MasterDeinit_Activity
1097  *END**************************************************************************/
1099 {
1100  LPI2C_Type *baseAddr;
1101  const lpi2c_master_state_t *master;
1102 
1103  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1104 
1105  baseAddr = g_lpi2cBase[instance];
1106  master = g_lpi2cMasterStatePtr[instance];
1107  DEV_ASSERT(master != NULL);
1108 
1109  /* Destroy the semaphore */
1110  (void)OSIF_SemaDestroy(&(master->idleSemaphore));
1111 
1112  g_lpi2cMasterStatePtr[instance] = NULL;
1113 
1114  /* Disable master */
1115  LPI2C_Set_MasterEnable(baseAddr, false);
1116 
1117  /* Disable i2c interrupt */
1118  INT_SYS_DisableIRQ(g_lpi2cMasterIrqId[instance]);
1119 
1120  return STATUS_SUCCESS;
1121 }
1122 
1123 
1124 /*FUNCTION**********************************************************************
1125  *
1126  * Function Name : LPI2C_DRV_MasterGetBaudRate
1127  * Description : returns the currently configured baud rate
1128  *
1129  * Implements : LPI2C_DRV_MasterGetBaudRate_Activity
1130  *END**************************************************************************/
1131 void LPI2C_DRV_MasterGetBaudRate(uint32_t instance, lpi2c_baud_rate_params_t *baudRate)
1132 {
1133  const LPI2C_Type *baseAddr;
1134  const lpi2c_master_state_t *master;
1135  status_t retVal;
1136  uint32_t prescaler;
1137  uint32_t clkLo;
1138  uint32_t clkHi;
1139  uint32_t inputClock;
1140 
1141  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1142 
1143  baseAddr = g_lpi2cBase[instance];
1144  master = g_lpi2cMasterStatePtr[instance];
1145  DEV_ASSERT(master != NULL);
1146 
1147  /* Get the protocol clock frequency */
1148  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1149  DEV_ASSERT(retVal == STATUS_SUCCESS);
1150  DEV_ASSERT(inputClock > 0U);
1151 
1152  /* Ignoring the glitch filter, the baud rate formula is:
1153  SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))
1154  */
1155  prescaler = LPI2C_Get_MasterPrescaler(baseAddr);
1156  clkHi =LPI2C_Get_MasterClockHighPeriod(baseAddr);
1157  clkLo = LPI2C_Get_MasterClockLowPeriod(baseAddr);
1158 
1159  baudRate->baudRate = inputClock / (((uint32_t)1U << prescaler) * (clkLo + clkHi + (uint32_t)2U));
1160 
1161 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1162  if (master->operatingMode == LPI2C_HIGHSPEED_MODE)
1163  {
1164  clkHi =LPI2C_Get_MasterClockHighPeriodHS(baseAddr);
1165  clkLo = LPI2C_Get_MasterClockLowPeriodHS(baseAddr);
1166 
1167  baudRate->baudRateHS = inputClock / (((uint32_t)1U << prescaler) * (clkLo + clkHi + (uint32_t)2U));
1168  }
1169 #endif
1170 
1171  (void)retVal;
1172  (void)master;
1173 }
1174 
1175 
1176 /*FUNCTION**********************************************************************
1177  *
1178  * Function Name : LPI2C_DRV_MasterSetBaudRate
1179  * Description : set the baud rate for any subsequent I2C communication
1180  *
1181  * Implements : LPI2C_DRV_MasterSetBaudRate_Activity
1182  *END**************************************************************************/
1183 void LPI2C_DRV_MasterSetBaudRate(uint32_t instance,
1184  const lpi2c_mode_t operatingMode,
1185  const lpi2c_baud_rate_params_t baudRate)
1186 {
1187  LPI2C_Type *baseAddr;
1188  const lpi2c_master_state_t * master;
1189  status_t retVal;
1190  uint32_t inputClock;
1191  uint32_t minPrescaler;
1192  uint32_t prescaler;
1193  uint32_t clkTotal;
1194  uint32_t clkLo;
1195  uint32_t clkHi;
1196  uint32_t setHold;
1197  uint32_t dataVd;
1198 
1199  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1200 
1201  baseAddr = g_lpi2cBase[instance];
1202  master = g_lpi2cMasterStatePtr[instance];
1203  DEV_ASSERT(master != NULL);
1204 
1205  /* Check if driver is busy */
1206  DEV_ASSERT(master->i2cIdle == true);
1207 
1208  /* Get the protocol clock frequency */
1209  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1210  DEV_ASSERT(retVal == STATUS_SUCCESS);
1211  DEV_ASSERT(inputClock > 0U);
1212 
1213  /* Disable master */
1214  LPI2C_Set_MasterEnable(baseAddr, false);
1215 
1216  /* Ignoring the glitch filter, the baud rate formula is:
1217  SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))
1218  Assume CLKLO = 2*CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2
1219  */
1220  /* Compute minimum prescaler for which CLKLO and CLKHI values are in valid range. Always round up. */
1221  minPrescaler = ((inputClock - 1U) / (baudRate.baudRate * (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))) + (uint32_t)1U;
1222  for (prescaler = 0U; prescaler < 7U; prescaler++)
1223  {
1224  if (((uint32_t)1U << prescaler) >= minPrescaler)
1225  {
1226  break;
1227  }
1228  }
1229 
1230  /* Compute CLKLO and CLKHI values for this prescaler. Round to nearest integer. */
1231  clkTotal = (inputClock + ((baudRate.baudRate << prescaler) >> 1U)) / (baudRate.baudRate << prescaler);
1232  if (clkTotal > (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))
1233  {
1234  clkTotal = (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U);
1235  }
1236 
1237  /*
1238  * If we try to compute clk high and low values using clkTotal equal with 0
1239  * (this is the case when the baudrate is 0), we will get negative values for
1240  * them, so we set them to 0 for this case.
1241  */
1242  if (clkTotal == 0U)
1243  {
1244  clkHi = 0U;
1245  clkLo = 0U;
1246  }
1247  else
1248  {
1249  clkHi = (clkTotal - 2U) / 3U;
1250  clkLo = clkTotal - 2U - clkHi;
1251  }
1252 
1253  if (clkHi < CLKHI_MIN_VALUE)
1254  {
1255  clkHi = CLKHI_MIN_VALUE;
1256  }
1257  if (clkLo < CLKLO_MIN_VALUE)
1258  {
1259  clkLo = CLKLO_MIN_VALUE;
1260  }
1261 
1262  /* Compute DATAVD and SETHOLD */
1263  setHold = clkHi;
1264  dataVd = clkHi >> 1U;
1265  if (setHold < SETHOLD_MIN_VALUE)
1266  {
1267  setHold = SETHOLD_MIN_VALUE;
1268  }
1269  if (dataVd < DATAVD_MIN_VALUE)
1270  {
1271  dataVd = DATAVD_MIN_VALUE;
1272  }
1273 
1274  /* Apply settings */
1275  LPI2C_Set_MasterPrescaler(baseAddr, (lpi2c_master_prescaler_t)prescaler);
1276  LPI2C_Set_MasterDataValidDelay(baseAddr, (uint8_t)dataVd);
1277  LPI2C_Set_MasterSetupHoldDelay(baseAddr, (uint8_t)setHold);
1278  LPI2C_Set_MasterClockHighPeriod(baseAddr, (uint8_t)clkHi);
1279  LPI2C_Set_MasterClockLowPeriod(baseAddr, (uint8_t)clkLo);
1280 
1281 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1282  if (operatingMode == LPI2C_HIGHSPEED_MODE)
1283  {
1284  /* Compute settings for High-speed baud rate */
1285  /* Compute High-speed CLKLO and CLKHI values for the same prescaler. Round to nearest integer. */
1286  clkTotal = (inputClock + ((baudRate.baudRateHS << prescaler) >> 1U)) / (baudRate.baudRateHS << prescaler);
1287  if (clkTotal > (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U))
1288  {
1289  clkTotal = (CLKHI_MAX_VALUE + CLKLO_MAX_VALUE + 2U);
1290  }
1291 
1292  clkHi = (clkTotal - 2U) / 3U;
1293  clkLo = clkTotal - 2U - clkHi;
1294  if (clkHi < CLKHI_MIN_VALUE)
1295  {
1296  clkHi = CLKHI_MIN_VALUE;
1297  }
1298  if (clkLo < CLKLO_MIN_VALUE)
1299  {
1300  clkLo = CLKLO_MIN_VALUE;
1301  }
1302 
1303  /* Compute High-speed DATAVD and SETHOLD */
1304  setHold = clkHi;
1305  dataVd = clkHi >> 1U;
1306  if (setHold < SETHOLD_MIN_VALUE)
1307  {
1308  setHold = SETHOLD_MIN_VALUE;
1309  }
1310  if (dataVd < DATAVD_MIN_VALUE)
1311  {
1312  dataVd = DATAVD_MIN_VALUE;
1313  }
1314 
1315  /* Apply High-speed settings */
1316  LPI2C_Set_MasterDataValidDelayHS(baseAddr, (uint8_t)dataVd);
1317  LPI2C_Set_MasterSetupHoldDelayHS(baseAddr, (uint8_t)setHold);
1318  LPI2C_Set_MasterClockHighPeriodHS(baseAddr, (uint8_t)clkHi);
1319  LPI2C_Set_MasterClockLowPeriodHS(baseAddr, (uint8_t)clkLo);
1320  }
1321 #endif
1322 
1323  /* Perform other settings related to the chosen operating mode */
1324  LPI2C_DRV_MasterSetOperatingMode(instance, operatingMode);
1325 
1326  /* Re-enable master */
1327  LPI2C_Set_MasterEnable(baseAddr, true);
1328 
1329  (void)master;
1330  (void)retVal;
1331 }
1332 
1333 
1334 /*FUNCTION**********************************************************************
1335  *
1336  * Function Name : LPI2C_DRV_MasterSetSlaveAddr
1337  * Description : set the slave address for any subsequent I2C communication
1338  *
1339  * Implements : LPI2C_DRV_MasterSetSlaveAddr_Activity
1340  *END**************************************************************************/
1341 void LPI2C_DRV_MasterSetSlaveAddr(uint32_t instance, const uint16_t address, const bool is10bitAddr)
1342 {
1343  lpi2c_master_state_t * master;
1344 
1345  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1346 
1347  master = g_lpi2cMasterStatePtr[instance];
1348  DEV_ASSERT(master != NULL);
1349 
1350  master->slaveAddress = address;
1351  master->is10bitAddr = is10bitAddr;
1352 }
1353 
1354 
1355 /*FUNCTION**********************************************************************
1356  *
1357  * Function Name : LPI2C_DRV_MasterSendData
1358  * Description : perform a non-blocking send transaction on the I2C bus
1359  *
1360  * Implements : LPI2C_DRV_MasterSendData_Activity
1361  *END**************************************************************************/
1363  const uint8_t * txBuff,
1364  uint32_t txSize,
1365  bool sendStop)
1366 {
1367  LPI2C_Type *baseAddr;
1368  lpi2c_master_state_t *master;
1369 
1370  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1371  DEV_ASSERT(txBuff != NULL);
1372  DEV_ASSERT(txSize > 0U);
1373 
1374  baseAddr = g_lpi2cBase[instance];
1375  master = g_lpi2cMasterStatePtr[instance];
1376  DEV_ASSERT(master != NULL);
1377 
1378  /* Check if driver is busy */
1379  DEV_ASSERT(master->i2cIdle == true);
1380 
1381  /* Copy parameters to driver state structure */
1382  master->txBuff = txBuff;
1383  master->txSize = txSize;
1384  master->sendStop = sendStop;
1385  master->i2cIdle = false;
1386  master->status = STATUS_BUSY;
1387 
1388  if (master->transferType == LPI2C_USING_DMA)
1389  {
1390  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
1391  LPI2C_MASTER_ARBITRATION_LOST_INT |
1392  LPI2C_MASTER_NACK_DETECT_INT,
1393  true);
1394 
1396  }
1397  else
1398  {
1399  /* Initiate communication */
1400  LPI2C_DRV_MasterSendAddress(baseAddr, master, false);
1401 
1402  /* Queue data bytes to fill tx fifo */
1403  LPI2C_DRV_MasterQueueData(baseAddr, master);
1404 
1405  /* Set tx FIFO watermark */
1406  LPI2C_Set_MasterTxFIFOWatermark(baseAddr, 0U);
1407 
1408  /* Enable relevant events */
1409 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1410  if (master->operatingMode == LPI2C_ULTRAFAST_MODE)
1411  {
1412  /* Do not enable NACK event reporting in ultra-fast mode */
1413  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
1414  LPI2C_MASTER_ARBITRATION_LOST_INT |
1415  LPI2C_MASTER_TRANSMIT_DATA_INT,
1416  true);
1417  }
1418  else
1419 #endif
1420  {
1421  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
1422  LPI2C_MASTER_ARBITRATION_LOST_INT |
1423  LPI2C_MASTER_NACK_DETECT_INT |
1424  LPI2C_MASTER_TRANSMIT_DATA_INT,
1425  true);
1426  }
1427  }
1428 
1429  return STATUS_SUCCESS;
1430 }
1431 
1432 
1433 /*FUNCTION**********************************************************************
1434  *
1435  * Function Name : LPI2C_DRV_MasterSendDataBlocking
1436  * Description : perform a blocking send transaction on the I2C bus
1437  *
1438  * Implements : LPI2C_DRV_MasterSendDataBlocking_Activity
1439  *END**************************************************************************/
1441  const uint8_t * txBuff,
1442  uint32_t txSize,
1443  bool sendStop,
1444  uint32_t timeout)
1445 {
1446  status_t retVal = STATUS_SUCCESS;
1447 
1448  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1449  DEV_ASSERT(txBuff != NULL);
1450  DEV_ASSERT(txSize > 0U);
1451 
1452  lpi2c_master_state_t *master = g_lpi2cMasterStatePtr[instance];
1453  DEV_ASSERT(master != NULL);
1454 
1455  /* mark transfer as blocking */
1456  master->blocking = true;
1457 
1458  retVal = LPI2C_DRV_MasterSendData(instance, txBuff, txSize, sendStop);
1459  if (retVal != STATUS_SUCCESS)
1460  {
1461  master->blocking = false;
1462  return retVal;
1463  }
1464 
1465  /* Wait for transfer to end */
1466  return LPI2C_DRV_MasterWaitTransferEnd(instance, timeout);
1467 }
1468 
1469 
1470 /*FUNCTION**********************************************************************
1471  *
1472  * Function Name : LPI2C_DRV_MasterAbortTransferData
1473  * Description : abort a non-blocking I2C Master transmission or reception
1474  *
1475  * Implements : LPI2C_DRV_MasterAbortTransferData_Activity
1476  *END**************************************************************************/
1478 {
1479  LPI2C_Type *baseAddr;
1480  lpi2c_master_state_t * master;
1481 
1482  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1483 
1484  baseAddr = g_lpi2cBase[instance];
1485  master = g_lpi2cMasterStatePtr[instance];
1486  DEV_ASSERT(master != NULL);
1487 
1488  DEV_ASSERT(master->i2cIdle == false);
1489 
1490  if (master->rxBuff != NULL)
1491  {
1492  /* Aborting a reception not supported because hardware will continue the
1493  current command even if the FIFO is reset and this could last indefinitely */
1494  return STATUS_UNSUPPORTED;
1495  }
1496 
1497  /* End transfer: force stop generation, reset FIFOs */
1498  master->status = STATUS_I2C_ABORTED;
1499  LPI2C_DRV_MasterEndTransfer(baseAddr, master, true, true);
1500 
1501  return STATUS_SUCCESS;
1502 }
1503 
1504 
1505 /*FUNCTION**********************************************************************
1506  *
1507  * Function Name : LPI2C_DRV_MasterReceiveData
1508  * Description : perform a non-blocking receive transaction on the I2C bus
1509  *
1510  * Implements : LPI2C_DRV_MasterReceiveData_Activity
1511  *END**************************************************************************/
1513  uint8_t * rxBuff,
1514  uint32_t rxSize,
1515  bool sendStop)
1516 {
1517  LPI2C_Type *baseAddr;
1518  lpi2c_master_state_t * master;
1519  uint16_t rxBytes;
1520 
1521  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1522  DEV_ASSERT(rxBuff != NULL);
1523  DEV_ASSERT(rxSize > 0U);
1524 
1525  DEV_ASSERT(rxSize <= 256U);
1526 
1527  baseAddr = g_lpi2cBase[instance];
1528  master = g_lpi2cMasterStatePtr[instance];
1529  DEV_ASSERT(master != NULL);
1530 
1531  /* Check if driver is busy */
1532  DEV_ASSERT(master->i2cIdle == true);
1533 
1534 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1535  if (master->operatingMode == LPI2C_ULTRAFAST_MODE)
1536  {
1537  /* No reception possible in ultra-fast mode */
1538  return STATUS_ERROR;
1539  }
1540 #endif
1541 
1542  /* Copy parameters to driver state structure */
1543  master->rxSize = rxSize;
1544  master->i2cIdle = false;
1545  master->sendStop = sendStop;
1546  master->rxBuff = rxBuff;
1547  master->status = STATUS_BUSY;
1548 
1549  if (master->transferType == LPI2C_USING_DMA)
1550  {
1551  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
1552  LPI2C_MASTER_ARBITRATION_LOST_INT |
1553  LPI2C_MASTER_NACK_DETECT_INT,
1554  true);
1555 
1557  }
1558  else
1559  {
1560  /* Initiate communication */
1561  LPI2C_DRV_MasterSendAddress(baseAddr, master, true);
1562  /* Queue receive command for rxSize bytes */
1563  LPI2C_DRV_MasterQueueCmd(baseAddr, master, LPI2C_MASTER_COMMAND_RECEIVE, (uint8_t)(rxSize - 1U));
1564 
1565  /* Set rx FIFO watermark */
1566  rxBytes = LPI2C_Get_MasterRxFIFOSize(baseAddr);
1567  if (rxBytes > rxSize)
1568  {
1569  rxBytes = (uint8_t)rxSize;
1570  }
1571  LPI2C_Set_MasterRxFIFOWatermark(baseAddr, (uint16_t)(rxBytes - 1U));
1572 
1573  /* Enable relevant events */
1574  if (!LPI2C_DRV_MasterCmdQueueEmpty(master))
1575  {
1576  /* Enable tx event too if there are commands in the software FIFO */
1577  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
1578  LPI2C_MASTER_ARBITRATION_LOST_INT |
1579  LPI2C_MASTER_NACK_DETECT_INT |
1580  LPI2C_MASTER_TRANSMIT_DATA_INT |
1581  LPI2C_MASTER_RECEIVE_DATA_INT,
1582  true);
1583  }
1584  else
1585  {
1586  LPI2C_Set_MasterInt(baseAddr, LPI2C_MASTER_FIFO_ERROR_INT |
1587  LPI2C_MASTER_ARBITRATION_LOST_INT |
1588  LPI2C_MASTER_NACK_DETECT_INT |
1589  LPI2C_MASTER_RECEIVE_DATA_INT,
1590  true);
1591  }
1592  }
1593 
1594  return STATUS_SUCCESS;
1595 }
1596 
1597 
1598 /*FUNCTION**********************************************************************
1599  *
1600  * Function Name : LPI2C_DRV_MasterReceiveDataBlocking
1601  * Description : perform a blocking receive transaction on the I2C bus
1602  *
1603  * Implements : LPI2C_DRV_MasterReceiveDataBlocking_Activity
1604  *END**************************************************************************/
1606  uint8_t * rxBuff,
1607  uint32_t rxSize,
1608  bool sendStop,
1609  uint32_t timeout)
1610 {
1611  status_t retVal = STATUS_SUCCESS;
1612 
1613  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1614  DEV_ASSERT(rxBuff != NULL);
1615  DEV_ASSERT(rxSize > 0U);
1616 
1617  lpi2c_master_state_t *master = g_lpi2cMasterStatePtr[instance];
1618  DEV_ASSERT(master != NULL);
1619 
1620  /* mark transfer as blocking */
1621  master->blocking = true;
1622 
1623  retVal = LPI2C_DRV_MasterReceiveData(instance, rxBuff, rxSize, sendStop);
1624  if (retVal != STATUS_SUCCESS)
1625  {
1626  master->blocking = false;
1627  return retVal;
1628  }
1629 
1630  /* Wait for transfer to end */
1631  return LPI2C_DRV_MasterWaitTransferEnd(instance, timeout);
1632 }
1633 
1634 
1635 /*FUNCTION**********************************************************************
1636  *
1637  * Function Name : LPI2C_DRV_MasterGetTransferStatus
1638  * Description : return the current status of the I2C master transfer
1639  *
1640  * When performing an a-sync (non-blocking) transfer, the user can call this function
1641  * to ascertain the state of the current transfer. In addition, if the transfer is still
1642  * in progress, the user can get the number of words that should be receive.
1643  *
1644  * Implements : LPI2C_DRV_MasterGetTransferStatus_Activity
1645  *END**************************************************************************/
1647  uint32_t *bytesRemaining)
1648 {
1649  const LPI2C_Type *baseAddr;
1650  const lpi2c_master_state_t * master;
1651 
1652  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1653 
1654  baseAddr = g_lpi2cBase[instance];
1655  master = g_lpi2cMasterStatePtr[instance];
1656  DEV_ASSERT(master != NULL);
1657 
1658  if ((bytesRemaining != NULL) && (master->transferType == LPI2C_USING_INTERRUPTS))
1659  {
1660  if (master->txSize > 0U)
1661  {
1662  /* Send data */
1663  /* Remaining bytes = bytes in buffer + bytes in tx FIFO */
1664  *bytesRemaining = master->txSize + LPI2C_Get_MasterTxFIFOCount(baseAddr);
1665  }
1666  else if (master->rxSize > 0U)
1667  {
1668  /* Receive data */
1669  /* Remaining bytes = free space in buffer - bytes in rx FIFO */
1670  *bytesRemaining = master->rxSize - LPI2C_Get_MasterRxFIFOCount(baseAddr);
1671  }
1672  else
1673  {
1674  *bytesRemaining = 0U;
1675  }
1676  }
1677 
1678  return master->status;
1679 }
1680 
1681 
1682 /*FUNCTION**********************************************************************
1683  *
1684  * Function Name : LPI2C_DRV_MasterIRQHandler
1685  * Description : handle non-blocking master operation when I2C interrupt occurs
1686  *
1687  *END**************************************************************************/
1688 void LPI2C_DRV_MasterIRQHandler(uint32_t instance)
1689 {
1690  LPI2C_Type *baseAddr;
1691  lpi2c_master_state_t * master;
1692 
1693  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1694 
1695  baseAddr = g_lpi2cBase[instance];
1696  master = g_lpi2cMasterStatePtr[instance];
1697  DEV_ASSERT(master != NULL);
1698 
1699  /* Check which event caused the interrupt */
1700  if (LPI2C_Get_MasterTransmitDataRequestEvent(baseAddr))
1701  {
1702  LPI2C_DRV_MasterHandleTransmitDataRequest(instance, baseAddr, master);
1703  }
1704 
1705  if (LPI2C_Get_MasterReceiveDataReadyEvent(baseAddr))
1706  {
1707  LPI2C_DRV_MasterHandleReceiveDataReadyEvent(instance, baseAddr, master);
1708  }
1709 
1710  if (LPI2C_Get_MasterFIFOErrorEvent(baseAddr))
1711  {
1712  /* FIFO error */
1713  LPI2C_Clear_MasterFIFOErrorEvent(baseAddr);
1714 
1715 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1716  /* High-speed transfers end at STOP condition */
1717  master->highSpeedInProgress = false;
1718 #endif
1719  master->status = STATUS_ERROR;
1720 
1721  /* End transfer: no stop generation (the module will handle that by itself
1722  if needed), reset FIFOs */
1723  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
1724 
1725  /* Signal transfer end for blocking transfers */
1726  if (master->blocking == true)
1727  {
1728  (void)OSIF_SemaPost(&(master->idleSemaphore));
1729  }
1730 
1731  if (master->masterCallback != NULL)
1732  {
1733  master->masterCallback(instance, LPI2C_MASTER_EVENT_FIFO_ERROR, master->callbackParam);
1734  }
1735  }
1736 
1737  if (LPI2C_Get_MasterArbitrationLostEvent(baseAddr))
1738  {
1739  /* Arbitration lost */
1740  LPI2C_Clear_MasterArbitrationLostEvent(baseAddr);
1741 
1742  /* End transfer: no stop generation (the module will handle that by itself
1743  if needed), reset FIFOs */
1744  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
1745 
1746  /* Signal transfer end for blocking transfers */
1747  if (master->blocking == true)
1748  {
1749  (void)OSIF_SemaPost(&(master->idleSemaphore));
1750  }
1751 
1752  master->status = STATUS_I2C_ARBITRATION_LOST;
1753 
1754  if (master->masterCallback != NULL)
1755  {
1756  master->masterCallback(instance, LPI2C_MASTER_EVENT_ARBITRATION_LOST, master->callbackParam);
1757  }
1758  }
1759 
1760  if (LPI2C_Get_MasterNACKDetectEvent(baseAddr))
1761  {
1762  /* Received NACK */
1763  LPI2C_Clear_MasterNACKDetectEvent(baseAddr);
1764 
1765 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1766  /* Ignore NACK in Ultra Fast mode */
1767  if (master->operatingMode != LPI2C_ULTRAFAST_MODE)
1768  {
1769 #endif
1770  /* Signal transfer end for blocking transfers */
1771  if (master->blocking == true)
1772  {
1773  (void)OSIF_SemaPost(&(master->idleSemaphore));
1774  }
1775 
1776 #if(LPI2C_HAS_HIGH_SPEED_MODE)
1777  /* High-speed transfers end at STOP condition */
1778  master->highSpeedInProgress = false;
1779 #endif
1780  master->status = STATUS_I2C_RECEIVED_NACK;
1781 
1782  /* End transfer: no stop generation (the module will handle that by itself
1783  if needed), reset FIFOs */
1784  LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);
1785 
1786  if (master->masterCallback != NULL)
1787  {
1788  master->masterCallback(instance, LPI2C_MASTER_EVENT_NACK, master->callbackParam);
1789  }
1790 #if(LPI2C_HAS_ULTRA_FAST_MODE)
1791  }
1792 #endif
1793  }
1794 }
1795 
1796 
1797 /*FUNCTION**********************************************************************
1798  *
1799  * Function Name : LPI2C_DRV_SlaveInit
1800  * Description : initialize the I2C slave mode driver
1801  *
1802  * Implements : LPI2C_DRV_SlaveInit_Activity
1803  *END**************************************************************************/
1804 status_t LPI2C_DRV_SlaveInit(uint32_t instance,
1805  const lpi2c_slave_user_config_t * userConfigPtr,
1806  lpi2c_slave_state_t * slave)
1807 {
1808  LPI2C_Type *baseAddr;
1809  status_t retVal;
1810  uint32_t inputClock;
1811 
1812  DEV_ASSERT(slave != NULL);
1813  DEV_ASSERT(userConfigPtr != NULL);
1814  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1815 
1816  DEV_ASSERT(g_lpi2cSlaveStatePtr[instance] == NULL);
1817 
1818  /*
1819  * Check the protocol clock frequency.
1820  * LPI2C slave remains operational, even when the LPI2C functional
1821  * clock is disabled, so we don't need to check if inputClock is 0.
1822  */
1823  retVal = CLOCK_SYS_GetFreq(g_lpi2cClock[instance], &inputClock);
1824  DEV_ASSERT(retVal == STATUS_SUCCESS);
1825 
1826  baseAddr = g_lpi2cBase[instance];
1827  g_lpi2cSlaveStatePtr[instance] = slave;
1828 
1829  /* Initialize driver status structure */
1830  slave->status = STATUS_SUCCESS;
1831  slave->slaveListening = userConfigPtr->slaveListening;
1832  slave->slaveCallback = userConfigPtr->slaveCallback;
1833  slave->callbackParam = userConfigPtr->callbackParam;
1834  slave->txBuff = NULL;
1835  slave->rxBuff = NULL;
1836  slave->txSize = 0U;
1837  slave->rxSize = 0U;
1838  slave->transferType = userConfigPtr->transferType;
1839  /* Store DMA channel number used in transfer */
1840  slave->dmaChannel = userConfigPtr->dmaChannel;
1841  slave->isTransferInProgress = false;
1842  slave->blocking = false;
1843 
1844  /* Initialize the semaphore */
1845  retVal = OSIF_SemaCreate(&(slave->idleSemaphore), 0);
1846  DEV_ASSERT(retVal == STATUS_SUCCESS);
1847 
1848  /* Enable lpi2c interrupt */
1849  INT_SYS_EnableIRQ(g_lpi2cSlaveIrqId[instance]);
1850 
1851  /* Initialize module */
1852  LPI2C_Init(baseAddr);
1853 
1854  /* Configure slave address */
1855  LPI2C_Set_SlaveAddr0(baseAddr, userConfigPtr->slaveAddress);
1856  if (userConfigPtr->is10bitAddr)
1857  {
1858  LPI2C_Set_SlaveAddrConfig(baseAddr, LPI2C_SLAVE_ADDR_MATCH_0_10BIT);
1859  }
1860  else
1861  {
1862  LPI2C_Set_SlaveAddrConfig(baseAddr, LPI2C_SLAVE_ADDR_MATCH_0_7BIT);
1863  }
1864 
1865  /* Configure operating mode */
1866  LPI2C_DRV_SlaveSetOperatingMode(instance, userConfigPtr->operatingMode);
1867 
1868  if (userConfigPtr->slaveListening)
1869  {
1870  if (slave->transferType == LPI2C_USING_DMA)
1871  {
1872  /* Activate events */
1873  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
1874  LPI2C_SLAVE_FIFO_ERROR_INT |
1875  LPI2C_SLAVE_STOP_DETECT_INT |
1876  LPI2C_SLAVE_REPEATED_START_INT |
1877  LPI2C_SLAVE_ADDRESS_VALID_INT,
1878  true);
1879  }
1880  if (slave->transferType == LPI2C_USING_INTERRUPTS)
1881  {
1882  /* Activate events */
1883 #if defined(ERRATA_E10792)
1884  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
1885  LPI2C_SLAVE_FIFO_ERROR_INT |
1886  LPI2C_SLAVE_STOP_DETECT_INT |
1887  LPI2C_SLAVE_REPEATED_START_INT |
1888  LPI2C_SLAVE_ADDRESS_VALID_INT |
1889  LPI2C_SLAVE_RECEIVE_DATA_INT,
1890  true);
1891 
1892 #else
1893  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
1894  LPI2C_SLAVE_FIFO_ERROR_INT |
1895  LPI2C_SLAVE_STOP_DETECT_INT |
1896  LPI2C_SLAVE_REPEATED_START_INT |
1897  LPI2C_SLAVE_ADDRESS_VALID_INT |
1898  LPI2C_SLAVE_RECEIVE_DATA_INT |
1899  LPI2C_SLAVE_TRANSMIT_DATA_INT,
1900  true);
1901 
1902 #endif
1903 
1904  }
1905 
1906  /* Enable LPI2C slave */
1907  LPI2C_Set_SlaveEnable(baseAddr, true);
1908  }
1909 
1910  (void)retVal;
1911 
1912  return STATUS_SUCCESS;
1913 }
1914 
1915 
1916 /*FUNCTION**********************************************************************
1917  *
1918  * Function Name : LPI2C_DRV_SlaveDeinit
1919  * Description : de-initialize the I2C slave mode driver
1920  *
1921  * Implements : LPI2C_DRV_SlaveDeinit_Activity
1922  *END**************************************************************************/
1924 {
1925  LPI2C_Type *baseAddr;
1926 
1927  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1928 
1929  baseAddr = g_lpi2cBase[instance];
1930  const lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
1931  DEV_ASSERT(slave != NULL);
1932 
1933  /* Destroy the semaphore */
1934  (void)OSIF_SemaDestroy(&(slave->idleSemaphore));
1935 
1936  if ((slave->transferType == LPI2C_USING_DMA) && slave->slaveListening)
1937  {
1938  /* Disable LPI2C DMA requests. */
1939  (void)LPI2C_Set_SlaveRxDMA(baseAddr, false);
1940  (void)LPI2C_Set_SlaveTxDMA(baseAddr, false);
1941  }
1942 
1943  g_lpi2cSlaveStatePtr[instance] = NULL;
1944 
1945  /* Disable LPI2C slave */
1946  LPI2C_Set_SlaveEnable(baseAddr, false);
1947 
1948  /* Disable i2c interrupt */
1949  INT_SYS_DisableIRQ(g_lpi2cSlaveIrqId[instance]);
1950 
1951  return STATUS_SUCCESS;
1952 }
1953 
1954 
1955 /*FUNCTION**********************************************************************
1956  *
1957  * Function Name : LPI2C_DRV_SlaveSetTxBuffer
1958  * Description : Provide a buffer for transmitting data.
1959  *
1960  * Implements : LPI2C_DRV_SlaveSetTxBuffer_Activity
1961  *END**************************************************************************/
1963  const uint8_t * txBuff,
1964  uint32_t txSize)
1965 {
1966  lpi2c_slave_state_t * slave;
1967 
1968  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1969  DEV_ASSERT(txBuff != NULL);
1970  DEV_ASSERT(txSize > 0U);
1971 
1972  slave = g_lpi2cSlaveStatePtr[instance];
1973  DEV_ASSERT(slave != NULL);
1974 
1975  slave->txBuff = txBuff;
1976  slave->txSize = txSize;
1977 
1978  return STATUS_SUCCESS;
1979 }
1980 
1981 
1982 /*FUNCTION**********************************************************************
1983  *
1984  * Function Name : LPI2C_DRV_SlaveSetRxBuffer
1985  * Description : Provide a buffer for receiving data.
1986  *
1987  * Implements : LPI2C_DRV_SlaveSetRxBuffer_Activity
1988  *END**************************************************************************/
1990  uint8_t * rxBuff,
1991  uint32_t rxSize)
1992 {
1993  lpi2c_slave_state_t * slave;
1994 
1995  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
1996  DEV_ASSERT(rxBuff != NULL);
1997  DEV_ASSERT(rxSize > 0U);
1998 
1999  slave = g_lpi2cSlaveStatePtr[instance];
2000  DEV_ASSERT(slave != NULL);
2001 
2002  slave->rxBuff = rxBuff;
2003  slave->rxSize = rxSize;
2004 
2005  return STATUS_SUCCESS;
2006 }
2007 
2008 
2009 /*FUNCTION**********************************************************************
2010  *
2011  * Function Name : LPI2C_DRV_SlaveSendData
2012  * Description : perform a non-blocking send transaction on the I2C bus
2013  *
2014  * Implements : LPI2C_DRV_SlaveSendData_Activity
2015  *END**************************************************************************/
2017  const uint8_t * txBuff,
2018  uint32_t txSize)
2019 {
2020  LPI2C_Type *baseAddr;
2021  lpi2c_slave_state_t * slave;
2022 
2023  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2024  DEV_ASSERT(txBuff != NULL);
2025  DEV_ASSERT(txSize > 0U);
2026 
2027 
2028  baseAddr = g_lpi2cBase[instance];
2029  slave = g_lpi2cSlaveStatePtr[instance];
2030  DEV_ASSERT(slave != NULL);
2031 
2032  /* If the slave is in listening mode the user should not use this function or the blocking counterpart. */
2033  DEV_ASSERT(slave->slaveListening == false);
2034 
2035  /* Check if slave is busy */
2036  DEV_ASSERT(slave->isTransferInProgress == false);
2037 
2038  slave->txBuff = txBuff;
2039  slave->txSize = txSize;
2040  slave->status = STATUS_BUSY;
2041 
2042  if (slave->transferType == LPI2C_USING_DMA)
2043  {
2044  /* Activate events */
2045  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
2046  LPI2C_SLAVE_FIFO_ERROR_INT |
2047  LPI2C_SLAVE_STOP_DETECT_INT |
2048  LPI2C_SLAVE_REPEATED_START_INT |
2049  LPI2C_SLAVE_ADDRESS_VALID_INT,
2050  true);
2051 
2052  /* Enable LPI2C slave */
2053  LPI2C_Set_SlaveEnable(baseAddr, true);
2054 
2055  slave->isTransferInProgress = true;
2056 
2058  }
2059  else
2060  {
2061  /* Activate events */
2062 #if defined(ERRATA_E10792)
2063 
2064  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
2065  LPI2C_SLAVE_FIFO_ERROR_INT |
2066  LPI2C_SLAVE_STOP_DETECT_INT |
2067  LPI2C_SLAVE_REPEATED_START_INT |
2068  LPI2C_SLAVE_ADDRESS_VALID_INT,
2069  true);
2070 
2071 #else
2072  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
2073  LPI2C_SLAVE_FIFO_ERROR_INT |
2074  LPI2C_SLAVE_STOP_DETECT_INT |
2075  LPI2C_SLAVE_REPEATED_START_INT |
2076  LPI2C_SLAVE_ADDRESS_VALID_INT |
2077  LPI2C_SLAVE_TRANSMIT_DATA_INT,
2078  true);
2079 #endif
2080 
2081 
2082  /* Enable LPI2C slave */
2083  LPI2C_Set_SlaveEnable(baseAddr, true);
2084 
2085  slave->isTransferInProgress = true;
2086  }
2087 
2088  return STATUS_SUCCESS;
2089 }
2090 
2091 
2092 /*FUNCTION**********************************************************************
2093  *
2094  * Function Name : LPI2C_DRV_SlaveSendDataBlocking
2095  * Description : perform a blocking send transaction on the I2C bus
2096  *
2097  * Implements : LPI2C_DRV_SlaveSendDataBlocking_Activity
2098  *END**************************************************************************/
2100  const uint8_t * txBuff,
2101  uint32_t txSize,
2102  uint32_t timeout)
2103 {
2104  status_t retVal = STATUS_SUCCESS;
2105 
2106  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2107  DEV_ASSERT(txBuff != NULL);
2108  DEV_ASSERT(txSize > 0U);
2109 
2110  lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
2111  DEV_ASSERT(slave != NULL);
2112 
2113  /* mark transfer as blocking */
2114  slave->blocking = true;
2115 
2116  retVal = LPI2C_DRV_SlaveSendData(instance, txBuff, txSize);
2117  if (retVal != STATUS_SUCCESS)
2118  {
2119  return retVal;
2120  }
2121 
2122  /* Wait for transfer to end */
2123  return LPI2C_DRV_SlaveWaitTransferEnd(instance, timeout);
2124 }
2125 
2126 
2127 /*FUNCTION**********************************************************************
2128  *
2129  * Function Name : LPI2C_DRV_SlaveReceiveData
2130  * Description : perform a non-blocking receive transaction on the I2C bus
2131  *
2132  * Implements : LPI2C_DRV_SlaveReceiveData_Activity
2133  *END**************************************************************************/
2135  uint8_t * rxBuff,
2136  uint32_t rxSize)
2137 {
2138  LPI2C_Type *baseAddr;
2139  lpi2c_slave_state_t * slave;
2140 
2141  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2142  DEV_ASSERT(rxBuff != NULL);
2143  DEV_ASSERT(rxSize > 0U);
2144 
2145  baseAddr = g_lpi2cBase[instance];
2146  slave = g_lpi2cSlaveStatePtr[instance];
2147  DEV_ASSERT(slave != NULL);
2148 
2149  /* If the slave is in listening mode the user should not use this function or the blocking counterpart. */
2150  DEV_ASSERT(slave->slaveListening == false);
2151 
2152  /* Check if slave is busy */
2153  DEV_ASSERT(slave->isTransferInProgress == false);
2154 
2155  slave->rxBuff = rxBuff;
2156  slave->rxSize = rxSize;
2157  slave->status = STATUS_BUSY;
2158 
2159  if (slave->transferType == LPI2C_USING_DMA)
2160  {
2161  /* Activate events */
2162  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
2163  LPI2C_SLAVE_FIFO_ERROR_INT |
2164  LPI2C_SLAVE_STOP_DETECT_INT |
2165  LPI2C_SLAVE_REPEATED_START_INT |
2166  LPI2C_SLAVE_ADDRESS_VALID_INT,
2167  true);
2168 
2169  /* Enable LPI2C slave */
2170  LPI2C_Set_SlaveEnable(baseAddr, true);
2171 
2172  slave->isTransferInProgress = true;
2173 
2175  }
2176  else
2177  {
2178  slave->isTransferInProgress = true;
2179 
2180  /* Activate events */
2181  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_BIT_ERROR_INT |
2182  LPI2C_SLAVE_FIFO_ERROR_INT |
2183  LPI2C_SLAVE_STOP_DETECT_INT |
2184  LPI2C_SLAVE_REPEATED_START_INT |
2185  LPI2C_SLAVE_ADDRESS_VALID_INT |
2186  LPI2C_SLAVE_RECEIVE_DATA_INT,
2187  true);
2188 
2189  /* Enable LPI2C slave */
2190  LPI2C_Set_SlaveEnable(baseAddr, true);
2191  }
2192 
2193  return STATUS_SUCCESS;
2194 }
2195 
2196 
2197 /*FUNCTION**********************************************************************
2198  *
2199  * Function Name : LPI2C_DRV_SlaveReceiveDataBlocking
2200  * Description : perform a blocking receive transaction on the I2C bus
2201  *
2202  * Implements : LPI2C_DRV_SlaveReceiveDataBlocking_Activity
2203  *END**************************************************************************/
2205  uint8_t *rxBuff,
2206  uint32_t rxSize,
2207  uint32_t timeout)
2208 {
2209  status_t retVal = STATUS_SUCCESS;
2210 
2211  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2212  DEV_ASSERT(rxBuff != NULL);
2213  DEV_ASSERT(rxSize > 0U);
2214 
2215  lpi2c_slave_state_t *slave = g_lpi2cSlaveStatePtr[instance];
2216  DEV_ASSERT(slave != NULL);
2217 
2218  /* mark transfer as blocking */
2219  slave->blocking = true;
2220 
2221  retVal = LPI2C_DRV_SlaveReceiveData(instance, rxBuff, rxSize);
2222  if (retVal != STATUS_SUCCESS)
2223  {
2224  return retVal;
2225  }
2226 
2227  /* Wait for transfer to end */
2228  return LPI2C_DRV_SlaveWaitTransferEnd(instance, timeout);
2229 }
2230 
2231 
2232 /*FUNCTION**********************************************************************
2233  *
2234  * Function Name : LPI2C_DRV_SlaveGetTransferStatus
2235  * Description : return the current status of the I2C slave transfer
2236  *
2237  * When performing an a-sync (non-blocking) transfer, the user can call this function
2238  * to ascertain the state of the current transfer. In addition, if the transfer is still
2239  * in progress, the user can get the number of words that should be receive.
2240  *
2241  * Implements : LPI2C_DRV_SlaveGetTransferStatus_Activity
2242  *END**************************************************************************/
2244  uint32_t *bytesRemaining)
2245 {
2246  const lpi2c_slave_state_t *slave;
2247 
2248  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2249 
2250  slave = g_lpi2cSlaveStatePtr[instance];
2251  DEV_ASSERT(slave != NULL);
2252 
2253  if ((bytesRemaining != NULL) && (slave->transferType == LPI2C_USING_INTERRUPTS))
2254  {
2255  if (slave->txSize > 0U)
2256  {
2257  /* Send data */
2258  *bytesRemaining = slave->txSize;
2259  }
2260  else if (slave->rxSize > 0U)
2261  {
2262  /* Receive data */
2263  *bytesRemaining = slave->rxSize;
2264  }
2265  else
2266  {
2267  *bytesRemaining = 0U;
2268  }
2269  }
2270 
2271  return slave->status;
2272 }
2273 
2274 
2275 /*FUNCTION**********************************************************************
2276  *
2277  * Function Name : LPI2C_DRV_SlaveAbortTransferData
2278  * Description : abort a non-blocking I2C Master transmission or reception
2279  *
2280  * Implements : LPI2C_DRV_SlaveAbortTransferData_Activity
2281  *END**************************************************************************/
2283 {
2284  lpi2c_slave_state_t * slave;
2285  LPI2C_Type *baseAddr;
2286 
2287  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2288 
2289  baseAddr = g_lpi2cBase[instance];
2290  slave = g_lpi2cSlaveStatePtr[instance];
2291  DEV_ASSERT(slave != NULL);
2292 
2293  if (!slave->slaveListening)
2294  {
2295  DEV_ASSERT(slave->isTransferInProgress == true);
2296 
2297  slave->status = STATUS_I2C_ABORTED;
2298  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2299  }
2300 
2301  return STATUS_SUCCESS;
2302 }
2303 
2304 
2305 /*FUNCTION**********************************************************************
2306  *
2307  * Function Name : LPI2C_DRV_SlaveIRQHandler
2308  * Description : handle non-blocking slave operation when I2C interrupt occurs
2309  *
2310  *END**************************************************************************/
2311 void LPI2C_DRV_SlaveIRQHandler(uint32_t instance)
2312 {
2313  LPI2C_Type *baseAddr;
2314  lpi2c_slave_state_t * slave;
2315  bool stopDetect = false, repeatStartDetect = false;
2316 
2317  DEV_ASSERT(instance < LPI2C_INSTANCE_COUNT);
2318 
2319  baseAddr = g_lpi2cBase[instance];
2320  slave = g_lpi2cSlaveStatePtr[instance];
2321  DEV_ASSERT(slave != NULL);
2322 
2323  /* Check which event caused the interrupt */
2324  if (LPI2C_Get_SlaveAddressValidEvent(baseAddr))
2325  {
2326  LPI2C_DRV_SlaveHandleAddressValidEvent(instance, baseAddr, slave);
2327  }
2328 
2329  if (LPI2C_Get_SlaveTransmitDataEvent(baseAddr))
2330  {
2331  if (LPI2C_Get_SlaveInt(baseAddr, LPI2C_SLAVE_TRANSMIT_DATA_INT))
2332  {
2333  LPI2C_DRV_SlaveHandleTransmitDataEvent(instance, baseAddr, slave);
2334  }
2335  }
2336 
2337  if (LPI2C_Get_SlaveReceiveDataEvent(baseAddr))
2338  {
2339  if (LPI2C_Get_SlaveInt(baseAddr, LPI2C_SLAVE_RECEIVE_DATA_INT))
2340  {
2341  LPI2C_DRV_SlaveHandleReceiveDataEvent(instance, baseAddr, slave);
2342  }
2343  }
2344 
2345  stopDetect = LPI2C_Get_SlaveSTOPDetectEvent(baseAddr);
2346  repeatStartDetect = LPI2C_Get_SlaveRepeatedStartEvent(baseAddr);
2347  if ((stopDetect == true) || (repeatStartDetect == true))
2348  {
2349  /* Either STOP or repeated START have the same meaning here: the current transfer is over */
2350  LPI2C_Clear_SlaveSTOPDetectEvent(baseAddr);
2351  LPI2C_Clear_SlaveRepeatedStartEvent(baseAddr);
2352 
2353 #if defined(ERRATA_E10792)
2354  /* Deactivate interrupts for transmitting data */
2355  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_TRANSMIT_DATA_INT, false);
2356 #endif
2357 
2358  if(slave->transferType == LPI2C_USING_DMA)
2359  {
2360  (void)EDMA_DRV_StopChannel(slave->dmaChannel);
2361  }
2362 
2363  if (slave->status == STATUS_BUSY)
2364  {
2365  /* Report success if no error was recorded */
2366  slave->status = STATUS_SUCCESS;
2367  }
2368 
2369  if (!slave->slaveListening)
2370  {
2371  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2372 
2373  /* Signal transfer end for blocking transfers */
2374  if (slave->blocking == true)
2375  {
2376  (void)OSIF_SemaPost(&(slave->idleSemaphore));
2377  }
2378  }
2379 
2380  if(slave->slaveCallback != NULL)
2381  {
2382  slave->slaveCallback(instance, LPI2C_SLAVE_EVENT_STOP, slave->callbackParam);
2383  }
2384  }
2385 
2386  if (LPI2C_Get_SlaveBitErrorEvent(baseAddr))
2387  {
2388  slave->status = STATUS_ERROR;
2389  LPI2C_Clear_SlaveBitErrorEvent(baseAddr);
2390 
2391 #if defined(ERRATA_E10792)
2392  /* Deactivate interrupts for transmitting data */
2393  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_TRANSMIT_DATA_INT, false);
2394 #endif
2395 
2396  if (slave->transferType == LPI2C_USING_DMA) {
2397  (void)EDMA_DRV_StopChannel(slave->dmaChannel);
2398  }
2399 
2400  if (!slave->slaveListening){
2401 
2402  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2403 
2404  /* Signal transfer end for blocking transfers */
2405  if (slave->blocking == true)
2406  {
2407  (void)OSIF_SemaPost(&(slave->idleSemaphore));
2408  }
2409  }
2410 
2411  if(slave->slaveCallback != NULL)
2412  {
2413  slave->slaveCallback(instance, LPI2C_SLAVE_EVENT_STOP, slave->callbackParam);
2414  }
2415  }
2416 
2417  if (LPI2C_Get_SlaveFIFOErrorEvent(baseAddr))
2418  {
2419  /* In Ultra-Fast mode clock stretching is disabled, so it is possible to get
2420  this event if the slave can't keep up */
2421  slave->status = STATUS_I2C_RX_OVERRUN;
2422  LPI2C_Clear_SlaveFIFOErrorEvent(baseAddr);
2423 
2424 #if defined(ERRATA_E10792)
2425  /* Deactivate interrupts for transmitting data */
2426  LPI2C_Set_SlaveInt(baseAddr, LPI2C_SLAVE_TRANSMIT_DATA_INT, false);
2427 #endif
2428 
2429  if (slave->transferType == LPI2C_USING_DMA) {
2430  (void)EDMA_DRV_StopChannel(slave->dmaChannel);
2431  }
2432 
2433  if (!slave->slaveListening)
2434  {
2435  LPI2C_DRV_SlaveEndTransfer(baseAddr, slave);
2436 
2437  /* Signal transfer end for blocking transfers */
2438  if (slave->blocking == true)
2439  {
2440  (void)OSIF_SemaPost(&(slave->idleSemaphore));
2441  }
2442  }
2443 
2444  if(slave->slaveCallback != NULL)
2445  {
2446  slave->slaveCallback(instance, LPI2C_SLAVE_EVENT_STOP, slave->callbackParam);
2447  }
2448  }
2449 }
2450 
2451 /*******************************************************************************
2452  * EOF
2453  ******************************************************************************/
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_DRV_MasterEndTransfer(LPI2C_Type *baseAddr, lpi2c_master_state_t *master, bool sendStop, bool resetFIFO)
Definition: lpi2c_driver.c:354
lpi2c_slave_callback_t slaveCallback
Definition: lpi2c_driver.h:188
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:786
status_t LPI2C_DRV_MasterAbortTransferData(uint32_t instance)
Abort a non-blocking I2C Master transmission or reception.
edma_transfer_type_t
A type for the DMA transfer. Implements : edma_transfer_type_t_Class.
Definition: edma_driver.h:237
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 status_t LPI2C_DRV_SlaveWaitTransferEnd(uint32_t instance, uint32_t timeout)
Definition: lpi2c_driver.c:756
lpi2c_transfer_type_t transferType
Definition: lpi2c_driver.h:165
static void LPI2C_DRV_MasterQueueData(LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:324
static void LPI2C_DRV_SlaveStartDmaTransfer(uint32_t instance)
Definition: lpi2c_driver.c:644
status_t EDMA_DRV_StopChannel(uint8_t channel)
Stops the eDMA channel.
Definition: edma_driver.c:838
lpi2c_master_callback_t masterCallback
Definition: lpi2c_driver.h:167
static void LPI2C_DRV_SlaveHandleTransmitDataEvent(uint32_t instance, LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:935
status_t LPI2C_DRV_SlaveReceiveData(uint32_t instance, uint8_t *rxBuff, uint32_t rxSize)
Perform a non-blocking receive transaction on the I2C bus.
static void LPI2C_DRV_SlaveHandleAddressValidEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:883
static void LPI2C_DRV_MasterSendQueuedCmd(LPI2C_Type *baseAddr, lpi2c_master_state_t *master)
Definition: lpi2c_driver.c:228
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.
#define LPI2C_BASE_PTRS
Definition: S32K142.h:5319
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:696
status_t EDMA_DRV_SetChannelRequest(uint8_t channel, uint8_t req)
Configures the DMA request for the eDMA channel.
Definition: edma_driver.c:863
lpi2c_transfer_type_t transferType
Definition: lpi2c_driver.h:186
lpi2c_mode_t
I2C operating modes Implements : lpi2c_mode_t_Class.
Definition: lpi2c_driver.h:73
void EDMA_DRV_DisableRequestsOnTransferComplete(uint8_t channel, bool disable)
Disables/Enables the DMA request after the major loop completes for the TCD.
Definition: edma_driver.c:1191
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: S32K142.h:5327
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
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
void EDMA_DRV_SetSrcLastAddrAdjustment(uint8_t channel, int32_t adjust)
Configures the source address last adjustment.
Definition: edma_driver.c:980
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:77
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:835
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
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:193
clock_names_t
Clock names.
Slave configuration structure.
Definition: lpi2c_driver.h:180
Slave internal context structure.
Definition: lpi2c_driver.h:279
Baud rate structure.
Definition: lpi2c_driver.h:202
static void LPI2C_DRV_MasterStartDmaTransfer(uint32_t instance)
Definition: lpi2c_driver.c:573
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_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.
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:44
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.
status_t LPI2C_DRV_MasterDeinit(uint32_t instance)
De-initialize the LPI2C master mode driver.
void LPI2C_DRV_SlaveIRQHandler(uint32_t instance)
Handle slave operation when I2C interrupt occurs.
Master configuration structure.
Definition: lpi2c_driver.h:155
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:813
__I uint32_t MRDR
Definition: S32K142.h:5287
static void LPI2C_DRV_SlaveHandleReceiveDataEvent(uint32_t instance, const LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:978
status_t LPI2C_DRV_SlaveDeinit(uint32_t instance)
De-initialize the I2C slave mode driver.
__IO uint32_t MTDR
Definition: S32K142.h:5285
static status_t LPI2C_DRV_MasterWaitTransferEnd(uint32_t instance, uint32_t timeout)
Definition: lpi2c_driver.c:726
status_t OSIF_SemaPost(semaphore_t *const pSem)
Increment a semaphore.
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
#define LPI2C_SLAVE_IRQS
Definition: S32K142.h:5328
#define LPI2C_PCC_CLOCKS
#define LPI2C_EDMA_REQ
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.
lpi2c_dma_transfer_params_t
Definition: lpi2c_driver.c:151
Master internal context structure.
Definition: lpi2c_driver.h:244
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.
__IO uint32_t STDR
Definition: S32K142.h:5302
__I uint32_t SRDR
Definition: S32K142.h:5304
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.
status_t EDMA_DRV_ConfigMultiBlockTransfer(uint8_t channel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t blockSize, uint32_t blockCount, bool disableReqOnCompletion)
Configures a multiple block data transfer with DMA.
Definition: edma_driver.c:589
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:293
#define LPI2C_INSTANCE_COUNT
Definition: S32K142.h:5308
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K142.h:192
static void LPI2C_DRV_SlaveEndTransfer(LPI2C_Type *baseAddr, lpi2c_slave_state_t *slave)
Definition: lpi2c_driver.c:413