Exemplo n.º 1
0
/*******************************************************************************
* Function Name: I2C_1_I2CSlaveSetAddress
********************************************************************************
*
* Summary:
*  Sets the I2C slave address.
*
* Parameters:
*  address: I2C slave address for the primary device. This value may be any
*  address between 0 and 127.
*
* Return:
*  None
*
*******************************************************************************/
void I2C_1_I2CSlaveSetAddress(uint32 address)
{
    uint32 matchReg;

    matchReg = I2C_1_RX_MATCH_REG;

    matchReg &= ((uint32) ~I2C_1_RX_MATCH_ADDR_MASK); /* Clear address bits */
    matchReg |= ((uint32)  I2C_1_GET_I2C_8BIT_ADDRESS(address));

    I2C_1_RX_MATCH_REG = matchReg;
}
Exemplo n.º 2
0
/*******************************************************************************
* 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);
}
Exemplo n.º 3
0
/*******************************************************************************
* Function Name: I2C_1_I2CMasterSendRestart
********************************************************************************
*
* Summary:
*  Generates Restart condition and sends slave address with read/write bit.
*  This function is blocking and does not return until start condition and
*  address are sent and ACK/NACK response is received or errors occurred.
*
* Parameters:
*  slaveAddress: Right justified 7-bit Slave address (valid range 8 to 120).
*  bitRnW:       Direction of the following transfer. It is defined by
*                read/write bit within address byte.
*
* Return:
*  Error status
*
*
* Global variables:
*  I2C_1_state - used to store current state of software FSM.
*
*******************************************************************************/
uint32 I2C_1_I2CMasterSendRestart(uint32 slaveAddress, uint32 bitRnW)
{
    uint32 resetIp;
    uint32 errStatus;

    resetIp   = 0u;
    errStatus = I2C_1_I2C_MSTR_NOT_READY;

    /* Check FSM state before generating ReStart condition */
    if(I2C_1_CHECK_I2C_MASTER_ACTIVE)
    {
        slaveAddress = I2C_1_GET_I2C_8BIT_ADDRESS(slaveAddress);

        if(0u == bitRnW) /* Write direction */
        {
            I2C_1_state = I2C_1_I2C_FSM_MSTR_WR_DATA;
        }
        else  /* Read direction */
        {
            I2C_1_state  = I2C_1_I2C_FSM_MSTR_RD_DATA;
                      slaveAddress |= I2C_1_I2C_READ_FLAG;
        }

        /* TX and RX FIFO have to be EMPTY */

        /* Clean-up interrupt status */
        I2C_1_ClearMasterInterruptSource(I2C_1_INTR_MASTER_ALL);

        /* A proper ReStart sequence is: generate ReStart, then put an address byte in the TX FIFO.
        * Otherwise the master treats the address in the TX FIFO as a data byte if a previous transfer is write.
        * The write transfer continues instead of ReStart.
        */
        I2C_1_I2C_MASTER_GENERATE_RESTART;

        while(I2C_1_CHECK_I2C_MASTER_CMD(I2C_1_I2C_MASTER_CMD_M_START))
        {
            /* Wait until ReStart has been generated */
        }

        /* Put address into TX FIFO */
        I2C_1_TX_FIFO_WR_REG = slaveAddress;

        /* Wait for address to be transferred */
        while(!I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_ACK      |
                                                  I2C_1_INTR_MASTER_I2C_NACK     |
                                                  I2C_1_INTR_MASTER_I2C_ARB_LOST |
                                                  I2C_1_INTR_MASTER_I2C_BUS_ERROR))
        {
            /* Wait until address has been transferred */
        }

        /* Check results of address phase */
        if(I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_ACK))
        {
            errStatus = I2C_1_I2C_MSTR_NO_ERROR;
        }
        else if(I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_NACK))
        {
             errStatus = I2C_1_I2C_MSTR_ERR_LB_NAK;
        }
        else if(I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_ARB_LOST))
        {
            I2C_1_state = I2C_1_I2C_FSM_IDLE;
                         errStatus = I2C_1_I2C_MSTR_ERR_ARB_LOST;
                         resetIp   = I2C_1_I2C_RESET_ERROR;
        }
        else /* I2C_1_INTR_MASTER_I2C_BUS_ERROR set is else condition */
        {
            I2C_1_state = I2C_1_I2C_FSM_IDLE;
                         errStatus = I2C_1_I2C_MSTR_ERR_BUS_ERR;
                         resetIp   = I2C_1_I2C_RESET_ERROR;
        }

        I2C_1_ClearMasterInterruptSource(I2C_1_INTR_MASTER_I2C_ACK      |
                                                    I2C_1_INTR_MASTER_I2C_NACK     |
                                                    I2C_1_INTR_MASTER_I2C_ARB_LOST |
                                                    I2C_1_INTR_MASTER_I2C_BUS_ERROR);

        /* Reset block in case of: LOST_ARB or BUS_ERR */
        if(0u != resetIp)
        {
            I2C_1_SCB_SW_RESET;
        }
    }

    return(errStatus);
}
Exemplo n.º 4
0
/*******************************************************************************
* Function Name: I2C_1_I2CMasterSendStart
********************************************************************************
*
* Summary:
*  Generates Start condition and sends slave address with read/write bit.
*  Disables the I2C interrupt.
*  This function is blocking and does not return until start condition and
*  address byte are sent and ACK/NACK response is received or errors occurred.
*
* Parameters:
*  slaveAddress: Right justified 7-bit Slave address (valid range 8 to 120).
*  bitRnW:       Direction of the following transfer. It is defined by
*                read/write bit within address byte.
*
* Return:
*  Erorr status.
*
* Global variables:
*  I2C_1_state - used to store current state of software FSM.
*
*******************************************************************************/
uint32 I2C_1_I2CMasterSendStart(uint32 slaveAddress, uint32 bitRnW)
{
    uint32  resetIp;
    uint32 errStatus;

    resetIp   = 0u;
    errStatus = I2C_1_I2C_MSTR_NOT_READY;

    /* Check FSM state before generating Start condition */
    if(I2C_1_CHECK_I2C_FSM_IDLE)
    {
        /* If bus is free, generate Start condition */
        if(I2C_1_CHECK_I2C_STATUS(I2C_1_I2C_STATUS_BUS_BUSY))
        {
            errStatus = I2C_1_I2C_MSTR_BUS_BUSY;
        }
        else
        {
            I2C_1_DisableInt();  /* Lock from interruption */

        #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) */

            slaveAddress = I2C_1_GET_I2C_8BIT_ADDRESS(slaveAddress);

            if(0u == bitRnW) /* Write direction */
            {
                I2C_1_state = I2C_1_I2C_FSM_MSTR_WR_DATA;
            }
            else /* Read direction */
            {
                I2C_1_state = I2C_1_I2C_FSM_MSTR_RD_DATA;
                         slaveAddress |= I2C_1_I2C_READ_FLAG;
            }

            /* TX and RX FIFO have to be EMPTY */

            I2C_1_TX_FIFO_WR_REG = slaveAddress; /* Put address in TX FIFO */
            I2C_1_ClearMasterInterruptSource(I2C_1_INTR_MASTER_ALL);

            I2C_1_I2C_MASTER_GENERATE_START;


            while(!I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_ACK      |
                                                      I2C_1_INTR_MASTER_I2C_NACK     |
                                                      I2C_1_INTR_MASTER_I2C_ARB_LOST |
                                                      I2C_1_INTR_MASTER_I2C_BUS_ERROR))
            {
                /*
                * Write: wait until address has been transferred
                * Read : wait until address has been transferred, data byte is going to RX FIFO as well.
                */
            }

            /* Check the results of the address phase */
            if(I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_ACK))
            {
                errStatus = I2C_1_I2C_MSTR_NO_ERROR;
            }
            else if(I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_NACK))
            {
                errStatus = I2C_1_I2C_MSTR_ERR_LB_NAK;
            }
            else if(I2C_1_CHECK_INTR_MASTER(I2C_1_INTR_MASTER_I2C_ARB_LOST))
            {
                I2C_1_state = I2C_1_I2C_FSM_IDLE;
                             errStatus = I2C_1_I2C_MSTR_ERR_ARB_LOST;
                             resetIp   = I2C_1_I2C_RESET_ERROR;
            }
            else /* I2C_1_INTR_MASTER_I2C_BUS_ERROR set is else condition */
            {
                I2C_1_state = I2C_1_I2C_FSM_IDLE;
                             errStatus = I2C_1_I2C_MSTR_ERR_BUS_ERR;
                             resetIp   = I2C_1_I2C_RESET_ERROR;
            }

            I2C_1_ClearMasterInterruptSource(I2C_1_INTR_MASTER_I2C_ACK      |
                                                        I2C_1_INTR_MASTER_I2C_NACK     |
                                                        I2C_1_INTR_MASTER_I2C_ARB_LOST |
                                                        I2C_1_INTR_MASTER_I2C_BUS_ERROR);

            /* Reset block in case of: LOST_ARB or BUS_ERR */
            if(0u != resetIp)
            {
                I2C_1_SCB_SW_RESET;
            }
        }
    }

    return(errStatus);
}
Exemplo n.º 5
0
/*******************************************************************************
* Function Name: I2C_1_I2CMasterReadBuf
********************************************************************************
*
* Summary:
*  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 SCB_ I2C_MSTAT_RD_CMPLT status.
*
* Parameters:
*  slaveAddr: 7-bit slave address.
*  xferData:  Pointer to buffer where to put data from slave.
*  cnt:       Size of buffer to read.
*  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_mstrRdBufPtr - used to store pointer to master write buffer.
*  I2C_1_mstrRdBufIndex - used to current index within master write
*  buffer.
*  I2C_1_mstrRdBufSize - used to store master write buffer size.
*
*******************************************************************************/
uint32 I2C_1_I2CMasterReadBuf(uint32 slaveAddress, uint8 * rdData, uint32 cnt, uint32 mode)
{
    uint32 errStatus;

    errStatus = I2C_1_I2C_MSTR_NOT_READY;

    if(NULL != rdData)
    {
        /* 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 master ready to proceed */
    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 read transaction */
        I2C_1_state = I2C_1_I2C_FSM_MSTR_RD_ADDR;
        I2C_1_mstrRdBufIndex = 0u;
        I2C_1_mstrRdBufSize  = cnt;
        I2C_1_mstrRdBufPtr   = (volatile uint8 *) rdData;
        I2C_1_mstrControl    = (uint8) mode;

        slaveAddress = (I2C_1_GET_I2C_8BIT_ADDRESS(slaveAddress) | I2C_1_I2C_READ_FLAG);

        I2C_1_mstrStatus &= (uint16) ~I2C_1_I2C_MSTAT_RD_CMPLT;

        I2C_1_ClearMasterInterruptSource(I2C_1_INTR_MASTER_ALL);

        /* 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;
        }

        /* Prepare reading */
        if(I2C_1_mstrRdBufSize < I2C_1_I2C_FIFO_SIZE) /* Reading byte-by-byte */
        {
            I2C_1_SetRxInterruptMode(I2C_1_INTR_RX_NOT_EMPTY);
        }
        else /* Receive RX FIFO chunks */
        {
            I2C_1_ENABLE_MASTER_AUTO_DATA_ACK;
            I2C_1_SetRxInterruptMode(I2C_1_INTR_RX_FULL);
        }
    }

    I2C_1_EnableInt();   /* Release lock */

    return(errStatus);
}
    /*******************************************************************************
    * Function Name: I2C_1_I2CInit
    ********************************************************************************
    *
    * Summary:
    *  Configures the SCB for I2C operation.
    *
    * Parameters:
    *  config:  Pointer to a structure that contains the following ordered list of
    *           fields. These fields match the selections available in the
    *           customizer.
    *
    * Return:
    *  None
    *
    *******************************************************************************/
    void I2C_1_I2CInit(const I2C_1_I2C_INIT_STRUCT *config)
    {
        if(NULL == config)
        {
            CYASSERT(0u != 0u); /* Halt execution due bad function parameter */
        }
        else
        {
            /* Configure pins */
            I2C_1_SetPins(I2C_1_SCB_MODE_I2C, I2C_1_DUMMY_PARAM,
                                                                    I2C_1_DUMMY_PARAM);

            /* Store internal configuration */
            I2C_1_scbMode       = (uint8) I2C_1_SCB_MODE_I2C;
            I2C_1_scbEnableWake = (uint8) config->enableWake;
            I2C_1_scbEnableIntr = (uint8) I2C_1_SCB_IRQ_INTERNAL;

            I2C_1_mode          = (uint8) config->mode;
            I2C_1_acceptAddr    = (uint8) config->acceptAddr;

            /* Configure I2C interface */
            I2C_1_CTRL_REG     = I2C_1_GET_CTRL_ADDR_ACCEPT(config->acceptAddr) |
                                            I2C_1_GET_CTRL_EC_AM_MODE (config->enableWake);

            I2C_1_I2C_CTRL_REG = I2C_1_GET_I2C_CTRL_HIGH_PHASE_OVS(config->oversampleHigh) |
                                            I2C_1_GET_I2C_CTRL_LOW_PHASE_OVS (config->oversampleLow)  |
                                            I2C_1_GET_I2C_CTRL_SL_MSTR_MODE  (config->mode)           |
                                            I2C_1_I2C_CTRL;

        #if(I2C_1_CY_SCBIP_V0)
            /* Adjust SDA filter settings. Ticket ID#150521 */
            I2C_1_SET_I2C_CFG_SDA_FILT_TRIM(I2C_1_EC_AM_I2C_CFG_SDA_FILT_TRIM);
        #endif /* (I2C_1_CY_SCBIP_V0) */

            /* Configure RX direction */
            I2C_1_RX_CTRL_REG      = I2C_1_GET_RX_CTRL_MEDIAN(config->enableMedianFilter) |
                                                I2C_1_I2C_RX_CTRL;
            I2C_1_RX_FIFO_CTRL_REG = I2C_1_CLEAR_REG;

            /* Set default address and mask */
            I2C_1_RX_MATCH_REG    = ((I2C_1_I2C_SLAVE) ?
                                                (I2C_1_GET_I2C_8BIT_ADDRESS(config->slaveAddr) |
                                                 I2C_1_GET_RX_MATCH_MASK(config->slaveAddrMask)) :
                                                (I2C_1_CLEAR_REG));


            /* Configure TX direction */
            I2C_1_TX_CTRL_REG      = I2C_1_I2C_TX_CTRL;
            I2C_1_TX_FIFO_CTRL_REG = I2C_1_CLEAR_REG;

            /* Configure interrupt with I2C handler but do not enable it */
            CyIntDisable    (I2C_1_ISR_NUMBER);
            CyIntSetPriority(I2C_1_ISR_NUMBER, I2C_1_ISR_PRIORITY);
            (void) CyIntSetVector(I2C_1_ISR_NUMBER, &I2C_1_I2C_ISR);

            /* Configure interrupt sources */
        #if(!I2C_1_CY_SCBIP_V1_I2C_ONLY)
            I2C_1_INTR_SPI_EC_MASK_REG = I2C_1_NO_INTR_SOURCES;
        #endif /* (!I2C_1_CY_SCBIP_V1_I2C_ONLY) */

            I2C_1_INTR_I2C_EC_MASK_REG = I2C_1_NO_INTR_SOURCES;
            I2C_1_INTR_RX_MASK_REG     = I2C_1_NO_INTR_SOURCES;
            I2C_1_INTR_TX_MASK_REG     = I2C_1_NO_INTR_SOURCES;

            I2C_1_INTR_SLAVE_MASK_REG  = ((I2C_1_I2C_SLAVE) ?
                                                     (I2C_1_I2C_INTR_SLAVE_MASK) :
                                                     (I2C_1_CLEAR_REG));

            I2C_1_INTR_MASTER_MASK_REG = ((I2C_1_I2C_MASTER) ?
                                                     (I2C_1_I2C_INTR_MASTER_MASK) :
                                                     (I2C_1_CLEAR_REG));

            /* Configure global variables */
            I2C_1_state = I2C_1_I2C_FSM_IDLE;

            /* Internal slave variables */
            I2C_1_slStatus        = 0u;
            I2C_1_slRdBufIndex    = 0u;
            I2C_1_slWrBufIndex    = 0u;
            I2C_1_slOverFlowCount = 0u;

            /* Internal master variables */
            I2C_1_mstrStatus     = 0u;
            I2C_1_mstrRdBufIndex = 0u;
            I2C_1_mstrWrBufIndex = 0u;
        }
    }