Beispiel #1
0
/*******************************************************************************
* 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);
}