/******************************************************************************* * Function Name: I2CM_Stop ******************************************************************************** * * Summary: * Disables the SCB component and its interrupt. * It also disables all TX interrupt sources so as not to cause an unexpected * interrupt trigger because after the component is enabled, the TX FIFO * is empty. * * Parameters: * None * * Return: * None * *******************************************************************************/ void I2CM_Stop(void) { #if (I2CM_SCB_IRQ_INTERNAL) I2CM_DisableInt(); #endif /* (I2CM_SCB_IRQ_INTERNAL) */ /* Call Stop function specific to current operation mode */ I2CM_ScbModeStop(); /* Disable SCB IP */ I2CM_CTRL_REG &= (uint32) ~I2CM_CTRL_ENABLED; /* Disable all TX interrupt sources so as not to cause an unexpected * interrupt trigger because after the component is enabled, the TX FIFO * is empty. * For SCB IP v0, it is critical as it does not mask-out interrupt * sources when they are disabled. This can cause a code lock-up in the * interrupt handler because TX FIFO cannot be loaded after the block * is disabled. */ I2CM_SetTxInterruptMode(I2CM_NO_INTR_SOURCES); #if (I2CM_SCB_IRQ_INTERNAL) I2CM_ClearPendingInt(); #endif /* (I2CM_SCB_IRQ_INTERNAL) */ }
/******************************************************************************* * 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); }