/******************************************************************************* * Function Name: I2C_1_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 I2C_1_Stop(void) { #if (I2C_1_SCB_IRQ_INTERNAL) I2C_1_DisableInt(); #endif /* (I2C_1_SCB_IRQ_INTERNAL) */ /* Call Stop function specific to current operation mode */ I2C_1_ScbModeStop(); /* Disable SCB IP */ I2C_1_CTRL_REG &= (uint32) ~I2C_1_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. */ I2C_1_SetTxInterruptMode(I2C_1_NO_INTR_SOURCES); #if (I2C_1_SCB_IRQ_INTERNAL) I2C_1_ClearPendingInt(); #endif /* (I2C_1_SCB_IRQ_INTERNAL) */ }
/******************************************************************************* * Function Name: I2C_1_I2CStop ******************************************************************************** * * Summary: * Resets the I2C FSM into the default state and disables TX interrupt sources. * * Parameters: * None * * Return: * None * * Global variables: * * *******************************************************************************/ void I2C_1_I2CStop(void) { /* Disable TX interrupt sources in order not to cause a false trigger. * The incoming transaction will enable an appropriate TX interrupt. */ I2C_1_SetTxInterruptMode(I2C_1_NO_INTR_SOURCES); #if(I2C_1_CY_SCBIP_V0) /* Clear pending interrupt as TX FIFO becomes empty and block does not gate interrupt trigger when disabled */ I2C_1_ClearPendingInt(); #endif /* (I2C_1_CY_SCBIP_V0) */ I2C_1_state = I2C_1_I2C_FSM_IDLE; }
/******************************************************************************* * Function Name: I2C_1_I2CMasterWriteBuf ******************************************************************************** * * Summary: * 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 SCB_ I2C_MSTAT_WR_CMPLT status. * * Parameters: * slaveAddr: 7-bit slave address. * xferData: Pointer to buffer of data to be sent. * cnt: Size of buffer to send. * mode: Transfer mode defines: start or restart condition generation at * begin of the transfer and complete the transfer or halt before * generating a stop. * * Return: * Error status. * * Global variables: * I2C_1_mstrStatus - used to store current status of I2C Master. * I2C_1_state - used to store current state of software FSM. * I2C_1_mstrControl - used to control master end of transaction with * or without the Stop generation. * I2C_1_mstrWrBufPtr - used to store pointer to master write buffer. * I2C_1_mstrWrBufIndex - used to current index within master write * buffer. * I2C_1_mstrWrBufSize - used to store master write buffer size. * *******************************************************************************/ uint32 I2C_1_I2CMasterWriteBuf(uint32 slaveAddress, uint8 * wrData, uint32 cnt, uint32 mode) { uint32 errStatus; errStatus = I2C_1_I2C_MSTR_NOT_READY; if(NULL != wrData) /* Check buffer pointer */ { /* Check FSM state and bus before generating Start/ReStart condition */ if(I2C_1_CHECK_I2C_FSM_IDLE) { I2C_1_DisableInt(); /* Lock from interruption */ /* Check bus state */ errStatus = I2C_1_CHECK_I2C_STATUS(I2C_1_I2C_STATUS_BUS_BUSY) ? I2C_1_I2C_MSTR_BUS_BUSY : I2C_1_I2C_MSTR_NO_ERROR; } else if(I2C_1_CHECK_I2C_FSM_HALT) { I2C_1_mstrStatus &= (uint16) ~I2C_1_I2C_MSTAT_XFER_HALT; errStatus = I2C_1_I2C_MSTR_NO_ERROR; } else { /* Unexpected FSM state: exit */ } } /* Check if master is ready to start */ if(I2C_1_I2C_MSTR_NO_ERROR == errStatus) /* No error proceed */ { #if (!I2C_1_CY_SCBIP_V0 && \ I2C_1_I2C_MULTI_MASTER_SLAVE_CONST && I2C_1_I2C_WAKE_ENABLE_CONST) I2C_1_I2CMasterDisableEcAm(); #endif /* (!I2C_1_CY_SCBIP_V0) */ /* Set up write transaction */ I2C_1_state = I2C_1_I2C_FSM_MSTR_WR_ADDR; I2C_1_mstrWrBufIndexTmp = 0u; I2C_1_mstrWrBufIndex = 0u; I2C_1_mstrWrBufSize = cnt; I2C_1_mstrWrBufPtr = (volatile uint8 *) wrData; I2C_1_mstrControl = (uint8) mode; slaveAddress = I2C_1_GET_I2C_8BIT_ADDRESS(slaveAddress); I2C_1_mstrStatus &= (uint16) ~I2C_1_I2C_MSTAT_WR_CMPLT; I2C_1_ClearMasterInterruptSource(I2C_1_INTR_MASTER_ALL); I2C_1_ClearTxInterruptSource(I2C_1_INTR_TX_UNDERFLOW); /* The TX and RX FIFO have to be EMPTY */ /* Generate Start or ReStart */ if(I2C_1_CHECK_I2C_MODE_RESTART(mode)) { I2C_1_I2C_MASTER_GENERATE_RESTART; I2C_1_TX_FIFO_WR_REG = slaveAddress; } else { I2C_1_TX_FIFO_WR_REG = slaveAddress; I2C_1_I2C_MASTER_GENERATE_START; } /* Catch when address is sent */ I2C_1_SetTxInterruptMode(I2C_1_INTR_TX_UNDERFLOW); } I2C_1_EnableInt(); /* Release lock */ return(errStatus); }