/******************************************************************************* * Function Name: I2CM_ScbModeEnableIntr ******************************************************************************** * * Summary: * Enables an interrupt for a specific mode. * * Parameters: * None * * Return: * None * *******************************************************************************/ static void I2CM_ScbEnableIntr(void) { #if (I2CM_SCB_IRQ_INTERNAL) /* Enable interrupt in NVIC */ #if (I2CM_SCB_MODE_UNCONFIG_CONST_CFG) if (0u != I2CM_scbEnableIntr) { I2CM_EnableInt(); } #else I2CM_EnableInt(); #endif /* (I2CM_SCB_MODE_UNCONFIG_CONST_CFG) */ #endif /* (I2CM_SCB_IRQ_INTERNAL) */ }
/******************************************************************************* * Function Name: I2CM_I2CMasterClearWriteBuf ****************************************************************************//** * * Resets the write buffer pointer back to the first byte in the buffer. * * \globalvars * I2CM_mstrRdBufIndex - used to current index within master read * buffer. * I2CM_mstrStatus - used to store current status of I2C Master. * *******************************************************************************/ void I2CM_I2CMasterClearWriteBuf(void) { I2CM_DisableInt(); /* Lock from interruption */ I2CM_mstrWrBufIndex = 0u; I2CM_mstrStatus &= (uint16) ~I2CM_I2C_MSTAT_WR_CMPLT; I2CM_EnableInt(); /* Release lock */ }
/******************************************************************************* * Function Name: I2CM_I2CMasterClearStatus ****************************************************************************//** * * Clears all status flags and returns the master status. * * \return * Current status of master. See the I2CM_I2CMasterStatus() * function for constants. * * \globalvars * I2CM_mstrStatus - used to store current status of I2C Master. * *******************************************************************************/ uint32 I2CM_I2CMasterClearStatus(void) { uint32 status; I2CM_DisableInt(); /* Lock from interruption */ /* Read and clear master status */ status = (uint32) I2CM_mstrStatus; I2CM_mstrStatus = I2CM_I2C_MSTAT_CLEAR; I2CM_EnableInt(); /* Release lock */ return(status); }
/******************************************************************************* * Function Name: I2CM_I2CMasterStatus ****************************************************************************//** * * Returns the master's communication status. * * \return * Current status of I2C master. This status incorporates status constants. * Each constant is a bit field value. The value returned may have multiple * bits set to indicate the status of the read or write transfer. * - I2CM_I2C_MSTAT_RD_CMPLT - Read transfer complete. * The error condition status bits must be checked to ensure that * read transfer was completed successfully. * - I2CM_I2C_MSTAT_WR_CMPLT - Write transfer complete. * The error condition status bits must be checked to ensure that write * transfer was completed successfully. * - I2CM_I2C_MSTAT_XFER_INP - Transfer in progress. * - I2CM_I2C_MSTAT_XFER_HALT - Transfer has been halted. * The I2C bus is waiting for ReStart or Stop condition generation. * - I2CM_I2C_MSTAT_ERR_SHORT_XFER - Error condition: Write * transfer completed before all bytes were transferred. The slave NAKed * the byte which was expected to be ACKed. * - I2CM_I2C_MSTAT_ERR_ADDR_NAK - Error condition: Slave did * not acknowledge address. * - I2CM_I2C_MSTAT_ERR_ARB_LOST - Error condition: Master lost * arbitration during communications with slave. * - I2CM_I2C_MSTAT_ERR_BUS_ERROR - Error condition: bus error * occurred during master transfer due to misplaced Start or Stop * condition on the bus. * - I2CM_I2C_MSTAT_ERR_ABORT_XFER - Error condition: Slave was * addressed by another master while master performed the start condition * generation. As a result, master has automatically switched to slave * mode and is responding. The master transaction has not taken place * This error condition only applicable for Multi-Master-Slave mode. * - I2CM_I2C_MSTAT_ERR_XFER - Error condition: This is the * ORed value of all error conditions provided above. * * \globalvars * I2CM_mstrStatus - used to store current status of I2C Master. * *******************************************************************************/ uint32 I2CM_I2CMasterStatus(void) { uint32 status; I2CM_DisableInt(); /* Lock from interruption */ status = (uint32) I2CM_mstrStatus; if (I2CM_CHECK_I2C_MASTER_ACTIVE) { /* Add status of master pending transaction: MSTAT_XFER_INP */ status |= (uint32) I2CM_I2C_MSTAT_XFER_INP; } I2CM_EnableInt(); /* Release lock */ return(status); }
/******************************************************************************* * Function Name: I2CM_I2CMasterWriteBuf ****************************************************************************//** * * Automatically writes an entire buffer of data to a slave device. * Once the data transfer is initiated by this function, further data transfer * is handled by the included ISR. * Enables the I2C interrupt and clears I2CM_I2C_MSTAT_WR_CMPLT * status. * * \param slaveAddr: 7-bit slave address. * \param xferData: Pointer to buffer of data to be sent. * \param cnt: Size of buffer to send. * \param mode: Transfer mode defines: * (1) Whether a start or restart condition is generated at the beginning * of the transfer, and * (2) Whether the transfer is completed or halted before the stop * condition is generated on the bus.Transfer mode, mode constants * may be ORed together. * - I2CM_I2C_MODE_COMPLETE_XFER - Perform complete transfer * from Start to Stop. * - I2CM_I2C_MODE_REPEAT_START - Send Repeat Start instead * of Start. A Stop is generated after transfer is completed unless * NO_STOP is specified. * - I2CM_I2C_MODE_NO_STOP Execute transfer without a Stop. * The following transfer expected to perform ReStart. * * \return * Error status. * - I2CM_I2C_MSTR_NO_ERROR - Function complete without error. * The master started the transfer. * - I2CM_I2C_MSTR_BUS_BUSY - Bus is busy. Nothing was sent on * the bus. The attempt has to be retried. * - I2CM_I2C_MSTR_NOT_READY - Master is not ready for to start * transfer. A master still has not completed previous transaction or a * slave operation is in progress (in multi-master-slave configuration). * Nothing was sent on the bus. The attempt has to be retried. * * \globalvars * I2CM_mstrStatus - used to store current status of I2C Master. * I2CM_state - used to store current state of software FSM. * I2CM_mstrControl - used to control master end of transaction with * or without the Stop generation. * I2CM_mstrWrBufPtr - used to store pointer to master write buffer. * I2CM_mstrWrBufIndex - used to current index within master write * buffer. * I2CM_mstrWrBufSize - used to store master write buffer size. * *******************************************************************************/ uint32 I2CM_I2CMasterWriteBuf(uint32 slaveAddress, uint8 * wrData, uint32 cnt, uint32 mode) { uint32 errStatus; errStatus = I2CM_I2C_MSTR_NOT_READY; if(NULL != wrData) /* Check buffer pointer */ { /* Check FSM state and bus before generating Start/ReStart condition */ if(I2CM_CHECK_I2C_FSM_IDLE) { I2CM_DisableInt(); /* Lock from interruption */ /* Check bus state */ errStatus = I2CM_CHECK_I2C_STATUS(I2CM_I2C_STATUS_BUS_BUSY) ? I2CM_I2C_MSTR_BUS_BUSY : I2CM_I2C_MSTR_NO_ERROR; } else if(I2CM_CHECK_I2C_FSM_HALT) { I2CM_mstrStatus &= (uint16) ~I2CM_I2C_MSTAT_XFER_HALT; errStatus = I2CM_I2C_MSTR_NO_ERROR; } else { /* Unexpected FSM state: exit */ } } /* Check if master is ready to start */ if(I2CM_I2C_MSTR_NO_ERROR == errStatus) /* No error proceed */ { #if (!I2CM_CY_SCBIP_V0 && \ I2CM_I2C_MULTI_MASTER_SLAVE_CONST && I2CM_I2C_WAKE_ENABLE_CONST) I2CM_I2CMasterDisableEcAm(); #endif /* (!I2CM_CY_SCBIP_V0) */ /* Set up write transaction */ I2CM_state = I2CM_I2C_FSM_MSTR_WR_ADDR; I2CM_mstrWrBufIndexTmp = 0u; I2CM_mstrWrBufIndex = 0u; I2CM_mstrWrBufSize = cnt; I2CM_mstrWrBufPtr = (volatile uint8 *) wrData; I2CM_mstrControl = (uint8) mode; slaveAddress = I2CM_GET_I2C_8BIT_ADDRESS(slaveAddress); I2CM_mstrStatus &= (uint16) ~I2CM_I2C_MSTAT_WR_CMPLT; I2CM_ClearMasterInterruptSource(I2CM_INTR_MASTER_ALL); I2CM_ClearTxInterruptSource(I2CM_INTR_TX_UNDERFLOW); /* The TX and RX FIFO have to be EMPTY */ /* Enable interrupt source to catch when address is sent */ I2CM_SetTxInterruptMode(I2CM_INTR_TX_UNDERFLOW); /* Generate Start or ReStart */ if(I2CM_CHECK_I2C_MODE_RESTART(mode)) { I2CM_I2C_MASTER_GENERATE_RESTART; I2CM_TX_FIFO_WR_REG = slaveAddress; } else { I2CM_TX_FIFO_WR_REG = slaveAddress; I2CM_I2C_MASTER_GENERATE_START; } } I2CM_EnableInt(); /* Release lock */ return(errStatus); }
/******************************************************************************* * Function Name: I2CM_I2CMasterReadBuf ****************************************************************************//** * * Automatically reads an entire buffer of data from a slave device. * Once the data transfer is initiated by this function, further data transfer * is handled by the included ISR. * Enables the I2C interrupt and clears I2CM_I2C_MSTAT_RD_CMPLT * status. * * \param slaveAddr: 7-bit slave address. * \param xferData: Pointer to buffer of data to be sent. * \param cnt: Size of buffer to send. * \param mode: Transfer mode defines: * (1) Whether a start or restart condition is generated at the beginning * of the transfer, and * (2) Whether the transfer is completed or halted before the stop * condition is generated on the bus.Transfer mode, mode constants may * be ORed together. See I2CM_I2CMasterWriteBuf() * function for constants. * * \return * Error status.See I2CM_I2CMasterWriteBuf() * function for constants. * * \globalvars * I2CM_mstrStatus - used to store current status of I2C Master. * I2CM_state - used to store current state of software FSM. * I2CM_mstrControl - used to control master end of transaction with * or without the Stop generation. * I2CM_mstrRdBufPtr - used to store pointer to master read buffer. * I2CM_mstrRdBufIndex - used to current index within master read * buffer. * I2CM_mstrRdBufSize - used to store master read buffer size. * *******************************************************************************/ uint32 I2CM_I2CMasterReadBuf(uint32 slaveAddress, uint8 * rdData, uint32 cnt, uint32 mode) { uint32 errStatus; errStatus = I2CM_I2C_MSTR_NOT_READY; if(NULL != rdData) { /* Check FSM state and bus before generating Start/ReStart condition */ if(I2CM_CHECK_I2C_FSM_IDLE) { I2CM_DisableInt(); /* Lock from interruption */ /* Check bus state */ errStatus = I2CM_CHECK_I2C_STATUS(I2CM_I2C_STATUS_BUS_BUSY) ? I2CM_I2C_MSTR_BUS_BUSY : I2CM_I2C_MSTR_NO_ERROR; } else if(I2CM_CHECK_I2C_FSM_HALT) { I2CM_mstrStatus &= (uint16) ~I2CM_I2C_MSTAT_XFER_HALT; errStatus = I2CM_I2C_MSTR_NO_ERROR; } else { /* Unexpected FSM state: exit */ } } /* Check master ready to proceed */ if(I2CM_I2C_MSTR_NO_ERROR == errStatus) /* No error proceed */ { #if (!I2CM_CY_SCBIP_V0 && \ I2CM_I2C_MULTI_MASTER_SLAVE_CONST && I2CM_I2C_WAKE_ENABLE_CONST) I2CM_I2CMasterDisableEcAm(); #endif /* (!I2CM_CY_SCBIP_V0) */ /* Set up read transaction */ I2CM_state = I2CM_I2C_FSM_MSTR_RD_ADDR; I2CM_mstrRdBufIndex = 0u; I2CM_mstrRdBufSize = cnt; I2CM_mstrRdBufPtr = (volatile uint8 *) rdData; I2CM_mstrControl = (uint8) mode; slaveAddress = (I2CM_GET_I2C_8BIT_ADDRESS(slaveAddress) | I2CM_I2C_READ_FLAG); I2CM_mstrStatus &= (uint16) ~I2CM_I2C_MSTAT_RD_CMPLT; I2CM_ClearMasterInterruptSource(I2CM_INTR_MASTER_ALL); /* TX and RX FIFO have to be EMPTY */ /* Prepare reading */ if(I2CM_mstrRdBufSize < I2CM_I2C_FIFO_SIZE) { /* Reading byte-by-byte */ I2CM_SetRxInterruptMode(I2CM_INTR_RX_NOT_EMPTY); } else { /* Receive RX FIFO chunks */ I2CM_ENABLE_MASTER_AUTO_DATA_ACK; I2CM_SetRxInterruptMode(I2CM_INTR_RX_FULL); } /* Generate Start or ReStart */ if(I2CM_CHECK_I2C_MODE_RESTART(mode)) { I2CM_I2C_MASTER_GENERATE_RESTART; I2CM_TX_FIFO_WR_REG = (slaveAddress); } else { I2CM_TX_FIFO_WR_REG = (slaveAddress); I2CM_I2C_MASTER_GENERATE_START; } } I2CM_EnableInt(); /* Release lock */ return(errStatus); }