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