示例#1
0
void I2C_SetMode(I2C_CHANNEL eCh, I2C_MODE eMode)
{
	HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) &= ~(0x1 << 4);			// Disable I2C
	
	HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) &= ~(0x3 << 6);			// Clear Mode

	I2C_ClearIntStatus(eCh);
	I2C_DisableInt(eCh);								// Disable Interrupt
	
	switch (eMode)
	{
		case MASTER_TX_MODE:
			HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x3 << 6);	// Set Mode
			break;

		case MASTER_RX_MODE:
			HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x2 << 6);	// Set Mode
			break;

		case SLAVE_TX_MODE:
			HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x1 << 6);	// Set Mode
			break;

		case SLAVE_RX_MODE:
			HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x0 << 6);	// Set Mode
			break;

		default:
			return;
	}

	I2C_EnableInt(eCh);
	HW_REG32(g_aI2c[eCh].uBase, I2C_STAT) |= (0x1 << 4);			// Enable I2C
}
示例#2
0
/*******************************************************************************
* Function Name: I2C_I2CMasterClearWriteBuf
********************************************************************************
*
* Summary:
*  Resets the write buffer pointer back to the first byte in the buffer.
*
* Parameters:
*  None
*
* Return:
*  None
*
* Global variables:
*  I2C_mstrRdBufIndex - used to current index within master read
*   buffer.
*  I2C_mstrStatus - used to store current status of I2C Master.
*
*******************************************************************************/
void I2C_I2CMasterClearWriteBuf(void)
{
    I2C_DisableInt();  /* Lock from interruption */

    I2C_mstrWrBufIndex = 0u;
    I2C_mstrStatus    &= (uint16) ~I2C_I2C_MSTAT_WR_CMPLT;

    I2C_EnableInt();   /* Release lock */
}
示例#3
0
void I2C0_Close(void)
{
    /* Disable I2C0 interrupt and clear corresponding NVIC bit */
    I2C_DisableInt(I2C0);
    NVIC_DisableIRQ(I2C0_IRQn);

    /* Disable I2C0 and close I2C0 clock */
    I2C_Close(I2C0);
    CLK_DisableModuleClock(I2C0_MODULE);
}
示例#4
0
/*******************************************************************************
* Function Name: I2C_I2CMasterClearStatus
********************************************************************************
*
* Summary:
*  Clears all status flags and returns the master status.
*
* Parameters:
*  None
*
* Return:
*  Current status of I2C master.
*
* Global variables:
*  I2C_mstrStatus - used to store current status of I2C Master.
*
*******************************************************************************/
uint32 I2C_I2CMasterClearStatus(void)
{
    uint32 status;

    I2C_DisableInt();  /* Lock from interruption */

    /* Read and clear master status */
    status = (uint32) I2C_mstrStatus;
    I2C_mstrStatus = I2C_I2C_MSTAT_CLEAR;

    I2C_EnableInt();   /* Release lock */

    return(status);
}
示例#5
0
/*******************************************************************************
* Function Name: I2C_I2CMasterStatus
********************************************************************************
*
* Summary:
*  Returns the master's communication status.
*
* Parameters:
*  None
*
* Return:
*  Current status of I2C master.
*
* Global variables:
*  I2C_mstrStatus - used to store current status of I2C Master.
*
*******************************************************************************/
uint32 I2C_I2CMasterStatus(void)
{
    uint32 status;

    I2C_DisableInt();  /* Lock from interruption */

    status = (uint32) I2C_mstrStatus;

    if (I2C_CHECK_I2C_MASTER_ACTIVE)
    {
        /* Add status of master pending transaction: MSTAT_XFER_INP */
        status |= (uint32) I2C_I2C_MSTAT_XFER_INP;
    }

    I2C_EnableInt();   /* Release lock */

    return(status);
}
示例#6
0
void HandleI2CNotifications(CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T *I2CDataNotification)
{
	uint8 i;
	
	/* Check if its I2C read notitifications */
    if(I2CDataNotification->handleValPair.attrHandle == I2CReadDataCharHandle)
    {
		/* Disable I2C interrupts before updating the data */
		I2C_DisableInt();
        
		/* Update I2C read registers with the notification data*/
		for(i=0;i<I2CDataNotification->handleValPair.value.len;i++)
			rdBuf[i] = I2CDataNotification->handleValPair.value.val[i];
		
		/* Enable I2C interrupts after updating the data */	
		I2C_EnableInt();	
    }
}
示例#7
0
/*******************************************************************************
* Function Name: I2C_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_mstrStatus  - used to store current status of I2C Master.
*  I2C_state       - used to store current state of software FSM.
*  I2C_mstrControl - used to control master end of transaction with
*  or without the Stop generation.
*  I2C_mstrWrBufPtr - used to store pointer to master write buffer.
*  I2C_mstrWrBufIndex - used to current index within master write
*  buffer.
*  I2C_mstrWrBufSize - used to store master write buffer size.
*
*******************************************************************************/
uint32 I2C_I2CMasterWriteBuf(uint32 slaveAddress, uint8 * wrData, uint32 cnt, uint32 mode)
{
    uint32 errStatus;

    errStatus = I2C_I2C_MSTR_NOT_READY;

    if(NULL != wrData)  /* Check buffer pointer */
    {
        /* Check FSM state and bus before generating Start/ReStart condition */
        if(I2C_CHECK_I2C_FSM_IDLE)
        {
            I2C_DisableInt();  /* Lock from interruption */

            /* Check bus state */
            errStatus = I2C_CHECK_I2C_STATUS(I2C_I2C_STATUS_BUS_BUSY) ?
                            I2C_I2C_MSTR_BUS_BUSY : I2C_I2C_MSTR_NO_ERROR;
        }
        else if(I2C_CHECK_I2C_FSM_HALT)
        {
            I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_XFER_HALT;
                              errStatus  = I2C_I2C_MSTR_NO_ERROR;
        }
        else
        {
            /* Unexpected FSM state: exit */
        }
    }

    /* Check if master is ready to start  */
    if(I2C_I2C_MSTR_NO_ERROR == errStatus) /* No error proceed */
    {
    #if (!I2C_CY_SCBIP_V0 && \
        I2C_I2C_MULTI_MASTER_SLAVE_CONST && I2C_I2C_WAKE_ENABLE_CONST)
            I2C_I2CMasterDisableEcAm();
    #endif /* (!I2C_CY_SCBIP_V0) */

        /* Set up write transaction */
        I2C_state = I2C_I2C_FSM_MSTR_WR_ADDR;
        I2C_mstrWrBufIndexTmp = 0u;
        I2C_mstrWrBufIndex    = 0u;
        I2C_mstrWrBufSize     = cnt;
        I2C_mstrWrBufPtr      = (volatile uint8 *) wrData;
        I2C_mstrControl       = (uint8) mode;

        slaveAddress = I2C_GET_I2C_8BIT_ADDRESS(slaveAddress);

        I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_WR_CMPLT;

        I2C_ClearMasterInterruptSource(I2C_INTR_MASTER_ALL);
        I2C_ClearTxInterruptSource(I2C_INTR_TX_UNDERFLOW);

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

        /* Enable interrupt source to catch when address is sent */
        I2C_SetTxInterruptMode(I2C_INTR_TX_UNDERFLOW);

        /* Generate Start or ReStart */
        if(I2C_CHECK_I2C_MODE_RESTART(mode))
        {
            I2C_I2C_MASTER_GENERATE_RESTART;
            I2C_TX_FIFO_WR_REG = slaveAddress;
        }
        else
        {
            I2C_TX_FIFO_WR_REG = slaveAddress;
            I2C_I2C_MASTER_GENERATE_START;
        }
    }

    I2C_EnableInt();   /* Release lock */

    return(errStatus);
}
示例#8
0
/*******************************************************************************
* Function Name: I2C_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:
*  Error status.
*
* Global variables:
*  I2C_state - used to store current state of software FSM.
*
*******************************************************************************/
uint32 I2C_I2CMasterSendStart(uint32 slaveAddress, uint32 bitRnW)
{
    uint32  resetIp;
    uint32 errStatus;

    resetIp   = 0u;
    errStatus = I2C_I2C_MSTR_NOT_READY;

    /* Check FSM state before generating Start condition */
    if(I2C_CHECK_I2C_FSM_IDLE)
    {
        /* If bus is free, generate Start condition */
        if(I2C_CHECK_I2C_STATUS(I2C_I2C_STATUS_BUS_BUSY))
        {
            errStatus = I2C_I2C_MSTR_BUS_BUSY;
        }
        else
        {
            I2C_DisableInt();  /* Lock from interruption */

        #if (!I2C_CY_SCBIP_V0 && \
            I2C_I2C_MULTI_MASTER_SLAVE_CONST && I2C_I2C_WAKE_ENABLE_CONST)
            I2C_I2CMasterDisableEcAm();
        #endif /* (!I2C_CY_SCBIP_V0) */

            slaveAddress = I2C_GET_I2C_8BIT_ADDRESS(slaveAddress);

            if(0u == bitRnW) /* Write direction */
            {
                I2C_state = I2C_I2C_FSM_MSTR_WR_DATA;
            }
            else /* Read direction */
            {
                I2C_state = I2C_I2C_FSM_MSTR_RD_DATA;
                         slaveAddress |= I2C_I2C_READ_FLAG;
            }

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

            I2C_TX_FIFO_WR_REG = slaveAddress; /* Put address in TX FIFO */
            I2C_ClearMasterInterruptSource(I2C_INTR_MASTER_ALL);

            I2C_I2C_MASTER_GENERATE_START;


            while(!I2C_CHECK_INTR_MASTER(I2C_INTR_MASTER_I2C_ACK      |
                                                      I2C_INTR_MASTER_I2C_NACK     |
                                                      I2C_INTR_MASTER_I2C_ARB_LOST |
                                                      I2C_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_CHECK_INTR_MASTER(I2C_INTR_MASTER_I2C_ACK))
            {
                errStatus = I2C_I2C_MSTR_NO_ERROR;
            }
            else if(I2C_CHECK_INTR_MASTER(I2C_INTR_MASTER_I2C_NACK))
            {
                errStatus = I2C_I2C_MSTR_ERR_LB_NAK;
            }
            else if(I2C_CHECK_INTR_MASTER(I2C_INTR_MASTER_I2C_ARB_LOST))
            {
                I2C_state = I2C_I2C_FSM_IDLE;
                             errStatus = I2C_I2C_MSTR_ERR_ARB_LOST;
                             resetIp   = I2C_I2C_RESET_ERROR;
            }
            else /* I2C_INTR_MASTER_I2C_BUS_ERROR set is else condition */
            {
                I2C_state = I2C_I2C_FSM_IDLE;
                             errStatus = I2C_I2C_MSTR_ERR_BUS_ERR;
                             resetIp   = I2C_I2C_RESET_ERROR;
            }

            I2C_ClearMasterInterruptSource(I2C_INTR_MASTER_I2C_ACK      |
                                                        I2C_INTR_MASTER_I2C_NACK     |
                                                        I2C_INTR_MASTER_I2C_ARB_LOST |
                                                        I2C_INTR_MASTER_I2C_BUS_ERROR);

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

    return(errStatus);
}
示例#9
0
/*******************************************************************************
* Function Name: I2C_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_mstrStatus  - used to store current status of I2C Master.
*  I2C_state       - used to store current state of software FSM.
*  I2C_mstrControl - used to control master end of transaction with
*  or without the Stop generation.
*  I2C_mstrRdBufPtr - used to store pointer to master write buffer.
*  I2C_mstrRdBufIndex - used to current index within master write
*  buffer.
*  I2C_mstrRdBufSize - used to store master write buffer size.
*
*******************************************************************************/
uint32 I2C_I2CMasterReadBuf(uint32 slaveAddress, uint8 * rdData, uint32 cnt, uint32 mode)
{
    uint32 errStatus;

    errStatus = I2C_I2C_MSTR_NOT_READY;

    if(NULL != rdData)
    {
        /* Check FSM state and bus before generating Start/ReStart condition */
        if(I2C_CHECK_I2C_FSM_IDLE)
        {
            I2C_DisableInt();  /* Lock from interruption */

            /* Check bus state */
            errStatus = I2C_CHECK_I2C_STATUS(I2C_I2C_STATUS_BUS_BUSY) ?
                            I2C_I2C_MSTR_BUS_BUSY : I2C_I2C_MSTR_NO_ERROR;
        }
        else if(I2C_CHECK_I2C_FSM_HALT)
        {
            I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_XFER_HALT;
                              errStatus  =  I2C_I2C_MSTR_NO_ERROR;
        }
        else
        {
            /* Unexpected FSM state: exit */
        }
    }

    /* Check master ready to proceed */
    if(I2C_I2C_MSTR_NO_ERROR == errStatus) /* No error proceed */
    {
        #if (!I2C_CY_SCBIP_V0 && \
        I2C_I2C_MULTI_MASTER_SLAVE_CONST && I2C_I2C_WAKE_ENABLE_CONST)
            I2C_I2CMasterDisableEcAm();
        #endif /* (!I2C_CY_SCBIP_V0) */

        /* Set up read transaction */
        I2C_state = I2C_I2C_FSM_MSTR_RD_ADDR;
        I2C_mstrRdBufIndex = 0u;
        I2C_mstrRdBufSize  = cnt;
        I2C_mstrRdBufPtr   = (volatile uint8 *) rdData;
        I2C_mstrControl    = (uint8) mode;

        slaveAddress = (I2C_GET_I2C_8BIT_ADDRESS(slaveAddress) | I2C_I2C_READ_FLAG);

        I2C_mstrStatus &= (uint16) ~I2C_I2C_MSTAT_RD_CMPLT;

        I2C_ClearMasterInterruptSource(I2C_INTR_MASTER_ALL);

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

        /* Prepare reading */
        if(I2C_mstrRdBufSize < I2C_I2C_FIFO_SIZE)
        {
            /* Reading byte-by-byte */
            I2C_SetRxInterruptMode(I2C_INTR_RX_NOT_EMPTY);
        }
        else
        {
            /* Receive RX FIFO chunks */
            I2C_ENABLE_MASTER_AUTO_DATA_ACK;
            I2C_SetRxInterruptMode(I2C_INTR_RX_FULL);
        }

        /* Generate Start or ReStart */
        if(I2C_CHECK_I2C_MODE_RESTART(mode))
        {
            I2C_I2C_MASTER_GENERATE_RESTART;
            I2C_TX_FIFO_WR_REG = (slaveAddress);
        }
        else
        {
            I2C_TX_FIFO_WR_REG = (slaveAddress);
            I2C_I2C_MASTER_GENERATE_START;
        }
    }

    I2C_EnableInt();   /* Release lock */

    return(errStatus);
}
示例#10
0
void AppCallBack(uint32 event, void *eventParam)
{
	uint8 i;
	CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
    
   	switch (event)
   	{
	    case CYBLE_EVT_STACK_ON:
			/* start advertising */
	        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			
			if(apiResult == CYBLE_ERROR_OK)
			{
				
#ifdef 	LED_INDICATION	
				ADV_LED_ON();
#endif	/* LED_INDICATION */ 

			}
	        break;

	    case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
			
			sendNotifications = 0;
			
#ifdef	 ENABLE_I2C_ONLY_WHEN_CONNECTED	
			/* Stop I2C Slave operation */
			I2C_Stop();
			
#endif			
			
#ifdef 	LED_INDICATION
		    /* Indicate disconnect event to user */
			DISCON_LED_ON();
			
			CyDelay(3000); 
#endif	/* LED_INDICATION */ 

			/* start advertising */
	        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			
			if(apiResult == CYBLE_ERROR_OK)
			{
#ifdef 	LED_INDICATION	
				ADV_LED_ON();
#endif	/* LED_INDICATION */ 
			}	
	        break;    
     
	    case CYBLE_EVT_GATT_CONNECT_IND:
			
#ifdef 	LED_INDICATION	
			CONNECT_LED_ON();
#endif	/* LED_INDICATION */ 	
	        
#ifdef	 ENABLE_I2C_ONLY_WHEN_CONNECTED	
			/* Start I2C Slave operation */
			I2C_Start();
			
			/* Initialize I2C write buffer */
			I2C_I2CSlaveInitWriteBuf((uint8 *) wrBuf, I2C_WRITE_BUFFER_SIZE);
			
			/* Initialize I2C read buffer */
			I2C_I2CSlaveInitReadBuf((uint8 *) rdBuf, I2C_READ_BUFFER_SIZE);
#endif	
			break;
        
	    /* Client may do Write Value or Write Value without Response. Handle both */   
	    case CYBLE_EVT_GATTS_WRITE_REQ:
	    case CYBLE_EVT_GATTS_WRITE_CMD_REQ:
	        wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;
			
	        /* Handling Notification Enable */
			if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
	        {
				CYBLE_GATT_HANDLE_VALUE_PAIR_T    I2CNotificationCCDHandle;
				uint8 I2CCCDValue[2];
				
	            /* Extract CCCD Notification enable flag */
	            sendNotifications = wrReqParam->handleValPair.value.val[0];
				
				/* Write the present I2C notification status to the local variable */
				I2CCCDValue[0] = sendNotifications;
				
				I2CCCDValue[1] = 0x00;
				
				/* Update CCCD handle with notification status data*/
				I2CNotificationCCDHandle.attrHandle = CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE;
				
				I2CNotificationCCDHandle.value.val = I2CCCDValue;
				
				I2CNotificationCCDHandle.value.len = 2;
				
				/* Report data to BLE component for sending data when read by Central device */
				CyBle_GattsWriteAttributeValue(&I2CNotificationCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);			
	        }
				
	        /* Handling Write data from Client */
	        else if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_WRITE_I2C_WRITE_DATA_CHAR_HANDLE)
	        {
				/* Turn off I2C interrupt before updating read registers */
				I2C_DisableInt();
				
		        /*The data received from I2C client is extracted */
				for(i=0;i<(wrReqParam->handleValPair.value.len);i++)	
		        	rdBuf[i] = wrReqParam->handleValPair.value.val[i];
					
				/* Turn on I2C interrupt after updating read registers */
				I2C_EnableInt();	
	        }
	            
	        if (event == CYBLE_EVT_GATTS_WRITE_REQ)
			{
	            CyBle_GattsWriteRsp(cyBle_connHandle);
			}
	        break;
     
		default:
			break;
    }
}
示例#11
0
/*******************************************************************************
* Function Name: I2C_Stop
********************************************************************************
*
* Summary:
*  Disables I2C hardware and disables I2C interrupt. Disables Active mode power
*  template bits or clock gating as appropriate.
*
* Parameters:
*  None
*
* Return:
*  None
*
*******************************************************************************/
void I2C_Stop(void) 
{
    #if((I2C_FF_IMPLEMENTED)  || \
        (I2C_UDB_IMPLEMENTED && I2C_MODE_SLAVE_ENABLED))
        uint8 enableInterrupts;
    #endif /* ((I2C_FF_IMPLEMENTED)  || \
               (I2C_UDB_IMPLEMENTED && I2C_MODE_SLAVE_ENABLED)) */

    I2C_DisableInt();

    I2C_DISABLE_INT_ON_STOP;   /* Interrupt on Stop can be enabled by write */
    (void) I2C_CSR_REG;        /* Clear CSR reg */
    
    #if(I2C_TIMEOUT_ENABLED)
        I2C_TimeoutStop();
    #endif  /* End (I2C_TIMEOUT_ENABLED) */

    #if(I2C_FF_IMPLEMENTED)
        #if(CY_PSOC3 || CY_PSOC5LP)
            /* Store registers which are held in reset when Master and Slave bits are cleared */
            #if(I2C_MODE_SLAVE_ENABLED)
                I2C_backup.addr = I2C_ADDR_REG;
            #endif /* (I2C_MODE_SLAVE_ENABLED) */

            I2C_backup.clkDiv1  = I2C_CLKDIV1_REG;
            I2C_backup.clkDiv2  = I2C_CLKDIV2_REG;


            /* Reset FF block */
            I2C_CFG_REG &= ((uint8) ~I2C_ENABLE_MS);
            CyDelayUs(I2C_FF_RESET_DELAY);
            I2C_CFG_REG |= ((uint8)  I2C_ENABLE_MS);


            /* Restore registers */
            #if(I2C_MODE_SLAVE_ENABLED)
                I2C_ADDR_REG = I2C_backup.addr;
            #endif /* (I2C_MODE_SLAVE_ENABLED) */

            I2C_CLKDIV1_REG = I2C_backup.clkDiv1;
            I2C_CLKDIV2_REG = I2C_backup.clkDiv2;

        #endif /* (CY_PSOC3 || CY_PSOC5LP) */

        /* Disable power to I2C block */
        enableInterrupts = CyEnterCriticalSection();
        I2C_ACT_PWRMGR_REG  &= ((uint8) ~I2C_ACT_PWR_EN);
        I2C_STBY_PWRMGR_REG &= ((uint8) ~I2C_STBY_PWR_EN);
        CyExitCriticalSection(enableInterrupts);

    #else

        #if(I2C_MODE_SLAVE_ENABLED)
            /* Disable slave bit counter */
            enableInterrupts = CyEnterCriticalSection();
            I2C_COUNTER_AUX_CTL_REG &= ((uint8) ~I2C_CNT7_ENABLE);
            CyExitCriticalSection(enableInterrupts);
        #endif /* (I2C_MODE_SLAVE_ENABLED) */

        I2C_CFG_REG &= ((uint8) ~I2C_ENABLE_MS);

    #endif /* (I2C_FF_IMPLEMENTED) */

    I2C_ClearPendingInt();  /* Clear interrupt triggers on reset */

    I2C_state = I2C_SM_IDLE;  /* Reset software FSM */
}
示例#12
0
文件: I2C.c 项目: Hsue66/Zumo-PSoC
/*******************************************************************************
* Function Name: I2C_Stop
********************************************************************************
*
* Summary:
*  Disables I2C hardware and disables I2C interrupt. Disables Active mode power
*  template bits or clock gating as appropriate.
*
* Parameters:
*  None.
*
* Return:
*  None.
*
*******************************************************************************/
void I2C_Stop(void) 
{
    I2C_DisableInt();

#if (I2C_TIMEOUT_ENABLED)
    I2C_TimeoutStop();
#endif  /* End (I2C_TIMEOUT_ENABLED) */

#if (I2C_FF_IMPLEMENTED)
    {
        uint8 intState;
        uint16 blockResetCycles;

        /* Store registers effected by block disable */
        I2C_backup.addr    = I2C_ADDR_REG;
        I2C_backup.clkDiv1 = I2C_CLKDIV1_REG;
        I2C_backup.clkDiv2 = I2C_CLKDIV2_REG;

        /* Calculate number of cycles to reset block */
        blockResetCycles = ((uint16) ((uint16) I2C_CLKDIV2_REG << 8u) | I2C_CLKDIV1_REG) + 1u;

        /* Disable block */
        I2C_CFG_REG &= (uint8) ~I2C_CFG_EN_SLAVE;
        /* Wait for block reset before disable power */
        CyDelayCycles((uint32) blockResetCycles);

        /* Disable power to block */
        intState = CyEnterCriticalSection();
        I2C_ACT_PWRMGR_REG  &= (uint8) ~I2C_ACT_PWR_EN;
        I2C_STBY_PWRMGR_REG &= (uint8) ~I2C_STBY_PWR_EN;
        CyExitCriticalSection(intState);

        /* Enable block */
        I2C_CFG_REG |= (uint8) I2C_ENABLE_MS;

        /* Restore registers effected by block disable. Ticket ID#198004 */
        I2C_ADDR_REG    = I2C_backup.addr;
        I2C_ADDR_REG    = I2C_backup.addr;
        I2C_CLKDIV1_REG = I2C_backup.clkDiv1;
        I2C_CLKDIV2_REG = I2C_backup.clkDiv2;
    }
#else

    /* Disable slave or master bits */
    I2C_CFG_REG &= (uint8) ~I2C_ENABLE_MS;

#if (I2C_MODE_SLAVE_ENABLED)
    {
        /* Disable bit counter */
        uint8 intState = CyEnterCriticalSection();
        I2C_COUNTER_AUX_CTL_REG &= (uint8) ~I2C_CNT7_ENABLE;
        CyExitCriticalSection(intState);
    }
#endif /* (I2C_MODE_SLAVE_ENABLED) */

    /* Clear interrupt source register */
    (void) I2C_CSR_REG;
#endif /* (I2C_FF_IMPLEMENTED) */

    /* Disable interrupt on stop (enabled by write transaction) */
    I2C_DISABLE_INT_ON_STOP;
    I2C_ClearPendingInt();

    /* Reset FSM to default state */
    I2C_state = I2C_SM_IDLE;

    /* Clear busy statuses */
#if (I2C_MODE_SLAVE_ENABLED)
    I2C_slStatus &= (uint8) ~(I2C_SSTAT_RD_BUSY | I2C_SSTAT_WR_BUSY);
#endif /* (I2C_MODE_SLAVE_ENABLED) */
}
示例#13
0
/*******************************************************************************
* Function Name: I2C_MasterSendStart
********************************************************************************
*
* Summary:
*  Generates Start condition and sends slave address with read/write bit.
*
* Parameters:
*  slaveAddress:  7-bit slave address.
*  R_nW:          Zero, send write command, non-zero send read command.
*
* Return:
*  Status error - zero means no errors.
*
* Side Effects:
*  This function is entered without a 'byte complete' bit set in the I2C_CSR
*  register. It does not exit until it will be set.
*
* Global variables:
*  I2C_state - used to store current state of software FSM.
*
* Reentrant:
*  No
*
*******************************************************************************/
uint8 I2C_MasterSendStart(uint8 slaveAddress, uint8 R_nW)
      
{
    uint8 errStatus;

    errStatus = I2C_MSTR_NOT_READY;

    /* If IDLE, check if bus is free */
    if(I2C_SM_IDLE == I2C_state)
    {
        /* If bus is free, generate Start condition */
        if(I2C_CHECK_BUS_FREE(I2C_MCSR_REG))
        {
            I2C_DisableInt();  /* Disable ISR for Manual functions */

            slaveAddress = ((uint8) (slaveAddress << I2C_SLAVE_ADDR_SHIFT)); /* Set Address */
            if(0u != R_nW)                                      /* Set the Read/Write flag */
            {
                slaveAddress |= I2C_READ_FLAG;
                I2C_state = I2C_SM_MSTR_RD_ADDR;
            }
            else
            {
                I2C_state = I2C_SM_MSTR_WR_ADDR;
            }
            I2C_DATA_REG = slaveAddress;   /* Write address to data reg */


            I2C_GENERATE_START;
            while(I2C_WAIT_BYTE_COMPLETE(I2C_CSR_REG))
            {
                ; /* Wait for the address to be transfered */
            }

            #if(I2C_MODE_MULTI_MASTER_SLAVE_ENABLED)
                if(I2C_CHECK_START_GEN(I2C_MCSR_REG))
                {
                    I2C_CLEAR_START_GEN;

                    /* Start condition was not generated: reset FSM to IDLE */
                    I2C_state = I2C_SM_IDLE;
                    errStatus = I2C_MSTR_ERR_ABORT_START_GEN;
                }
                else
            #endif /* (I2C_MODE_MULTI_MASTER_SLAVE_ENABLED) */

            #if(I2C_MODE_MULTI_MASTER_ENABLED)

                if(I2C_CHECK_LOST_ARB(I2C_CSR_REG))
                {
                    I2C_BUS_RELEASE;

                    /* Master lost arbitrage: reset FSM to IDLE */
                    I2C_state = I2C_SM_IDLE;
                    errStatus = I2C_MSTR_ERR_ARB_LOST;
                }
                else
            #endif /* (I2C_MODE_MULTI_MASTER_ENABLED) */

                if(I2C_CHECK_ADDR_NAK(I2C_CSR_REG))
                {
                    /* Address has been NACKed: reset FSM to IDLE */
                    I2C_state = I2C_SM_IDLE;
                    errStatus = I2C_MSTR_ERR_LB_NAK;
                }
                else
                {
                    /* Start was sent witout errors */
                    errStatus = I2C_MSTR_NO_ERROR;
                }
        }
        else
        {
            errStatus = I2C_MSTR_BUS_BUSY; /* Bus is busy */
        }
    }

    return(errStatus);
}
示例#14
0
/*******************************************************************************
* Function Name: I2C_SaveConfig
********************************************************************************
*
* Summary:
*  Wakeup on address match enabled: disables I2C Master(if was enabled before go
*  to sleep), enables I2C backup regulator. Waits while on-going transaction be
*  will completed and I2C will be ready go to sleep. All incoming transaction
*  will be NACKed till power down will be asserted. The address match event
*  wakes up the chip.
*  Wakeup on address match disabled: saves I2C configuration and non-retention
*  register values.
*
* Parameters:
*  None
*
* Return:
*  None
*
* Global Variables:
*  I2C_backup - used to save component configuration and
*       none-retention registers before enter sleep mode.
*
* Reentrant:
*  No
*
*******************************************************************************/
void I2C_SaveConfig(void) 
{
    #if(I2C_FF_IMPLEMENTED)
        #if(I2C_WAKEUP_ENABLED)
            uint8 enableInterrupts;
        #endif /* (I2C_WAKEUP_ENABLED) */

        /* Store regiters in either Sleep mode */
        I2C_backup.cfg  = I2C_CFG_REG;
        I2C_backup.xcfg = I2C_XCFG_REG;

        #if(I2C_MODE_SLAVE_ENABLED)
            I2C_backup.addr = I2C_ADDR_REG;
        #endif /* (I2C_MODE_SLAVE_ENABLED) */

        #if(CY_PSOC5A)
            I2C_backup.clkDiv   = I2C_CLKDIV_REG;
        #else
            I2C_backup.clkDiv1  = I2C_CLKDIV1_REG;
            I2C_backup.clkDiv2  = I2C_CLKDIV2_REG;
        #endif /* (CY_PSOC5A) */

        #if(I2C_WAKEUP_ENABLED)
            /* Need to disable Master */
            I2C_CFG_REG &= ((uint8) ~I2C_ENABLE_MASTER);

            /* Enable the I2C regulator backup */
            enableInterrupts = CyEnterCriticalSection();
            I2C_PWRSYS_CR1_REG |= I2C_PWRSYS_CR1_I2C_REG_BACKUP;
            CyExitCriticalSection(enableInterrupts);

            /* 1) Set force NACK to ignore I2C transactions
               2) Wait while I2C will be ready go to Sleep
               3) These bits are cleared on wake up */
            I2C_XCFG_REG |= I2C_XCFG_FORCE_NACK;
            while(0u == (I2C_XCFG_REG & I2C_XCFG_RDY_TO_SLEEP))
            {
                ; /* Wait when block is ready to Sleep */
            }

            /* Setup wakeup interrupt */
            I2C_DisableInt();
            (void) CyIntSetVector(I2C_ISR_NUMBER, &I2C_WAKEUP_ISR);
            I2C_wakeupSource = 0u;
            I2C_EnableInt();

        #endif /* (I2C_WAKEUP_ENABLED) */

    #else
        /* Store only address match bit */
        I2C_backup.control = (I2C_CFG_REG & I2C_CTRL_ANY_ADDRESS_MASK);

        #if(CY_UDB_V0)
            /* Store interrupt mask bits */
            I2C_backup.intMask = I2C_INT_MASK_REG;

            #if(I2C_MODE & I2C_MODE_SLAVE)
                I2C_backup.addr = I2C_ADDR_REG;
            #endif /* (I2C_MODE & I2C_MODE_SLAVE) */

        #endif /* (CY_UDB_V0) */

    #endif /* (I2C_FF_IMPLEMENTED) */

    #if(I2C_TIMEOUT_ENABLED)
        I2C_TimeoutSaveConfig();   /* Save Timeout config */
    #endif /* (I2C_TIMEOUT_ENABLED) */
}
示例#15
0
/*******************************************************************************
* Function Name: I2C_RestoreConfig
********************************************************************************
*
* Summary:
*  Wakeup on address match enabled: enables I2C Master (if was enabled before go
*  to sleep), disables I2C backup regulator.
*  Wakeup on address match disabled: Restores I2C configuration and
*  non-retention register values.
*
* Parameters:
*  None
*
* Return:
*  None
*
* Global Variables:
*  I2C_backup - used to save component configuration and
*  none-retention registers before exit sleep mode.
*
*******************************************************************************/
void I2C_RestoreConfig(void) 
{
    #if(I2C_FF_IMPLEMENTED)
        uint8 enableInterrupts;

        if(I2C_CHECK_PWRSYS_I2C_BACKUP)    /* Enabled if was in Sleep */
        {
            /* Disable back-up regulator */
            enableInterrupts = CyEnterCriticalSection();
            I2C_PWRSYS_CR1_REG &= ((uint8) ~I2C_PWRSYS_CR1_I2C_REG_BACKUP);
            CyExitCriticalSection(enableInterrupts);

            /* Re-enable Master */
            I2C_CFG_REG = I2C_backup.cfg;
        }
        else /* The I2C_REG_BACKUP was cleaned by PM API: it means Hibernate or wake-up not set */
        {
            #if(I2C_WAKEUP_ENABLED)
                /* Disable power to I2C block before register restore */
                enableInterrupts = CyEnterCriticalSection();
                I2C_ACT_PWRMGR_REG  &= ((uint8) ~I2C_ACT_PWR_EN);
                I2C_STBY_PWRMGR_REG &= ((uint8) ~I2C_STBY_PWR_EN);
                CyExitCriticalSection(enableInterrupts);

                /* Enable component after restore complete */
                I2C_backup.enableState = I2C_ENABLE;
            #endif /* (I2C_WAKEUP_ENABLED) */

            /* Restore component registers: Hibernate disable power */
            I2C_XCFG_REG = I2C_backup.xcfg;
            I2C_CFG_REG  = I2C_backup.cfg;

            #if(I2C_MODE_SLAVE_ENABLED)
                I2C_ADDR_REG = I2C_backup.addr;
            #endif /* (I2C_MODE_SLAVE_ENABLED) */

            #if(CY_PSOC5A)
                I2C_CLKDIV_REG  = I2C_backup.clkDiv;
            #else
                I2C_CLKDIV1_REG = I2C_backup.clkDiv1;
                I2C_CLKDIV2_REG = I2C_backup.clkDiv2;
            #endif /* (CY_PSOC5A) */
        }

        #if(I2C_WAKEUP_ENABLED)
            I2C_DisableInt();
            (void) CyIntSetVector(I2C_ISR_NUMBER, &I2C_ISR);
            if(0u != I2C_wakeupSource)
            {
                I2C_SetPendingInt();   /* Generate interrupt to process incomming transcation */
            }
            I2C_EnableInt();
        #endif /* (I2C_WAKEUP_ENABLED) */

    #else

        #if(CY_UDB_V0)
            uint8 enableInterrupts;

            I2C_INT_MASK_REG |= I2C_backup.intMask;

            enableInterrupts = CyEnterCriticalSection();
            I2C_INT_ENABLE_REG |= I2C_INT_ENABLE_MASK;
            CyExitCriticalSection(enableInterrupts);

            #if(I2C_MODE_MASTER_ENABLED)
                /* Restore Master Clock generator */
                I2C_MCLK_PRD_REG = I2C_DEFAULT_MCLK_PRD;
                I2C_MCLK_CMP_REG = I2C_DEFAULT_MCLK_CMP;
            #endif /* (I2C_MODE_MASTER_ENABLED) */

            #if(I2C_MODE_SLAVE_ENABLED)
                I2C_ADDR_REG = I2C_backup.addr;

                /* Restore slave bit counter period */
                I2C_PERIOD_REG = I2C_DEFAULT_PERIOD;
            #endif /* (I2C_MODE_SLAVE_ENABLED) */

        #endif /* (CY_UDB_V0) */

        I2C_CFG_REG = I2C_backup.control;

    #endif /* (I2C_FF_IMPLEMENTED) */

    #if(I2C_TIMEOUT_ENABLED)
        I2C_TimeoutRestoreConfig();
    #endif /* (I2C_TIMEOUT_ENABLED) */
}
示例#16
0
/*******************************************************************************
* Function Name: I2C_SaveConfig
********************************************************************************
*
* Summary:
*  Wakeup on address match enabled: disables I2C Master(if was enabled before go
*  to sleep), enables I2C backup regulator. Waits while on-going transaction be 
*  will completed and I2C will be ready go to sleep. All incoming transaction 
*  will be NACKed till power down will be asserted. The address match event 
*  wakes up the chip. 
*  Wakeup on address match disabled: saves I2C configuration and non-retention 
*  register values.
*
* Parameters:
*  None
*
* Return:
*  None
*
* Global Variables:
*  I2C_backup - used to save component configuration and none-retention
*  registers before enter sleep mode.
*
* Reentrant:
*  No
*
*******************************************************************************/
void I2C_SaveConfig(void) 
{
    #if (I2C_IMPLEMENTATION == I2C_FF)
        #if (I2C_ENABLE_WAKEUP)
            uint8 enableInterrupts;
        #endif  /* End (I2C_ENABLE_WAKEUP) */
        
        /* Store regiters in either Sleep mode */
        I2C_backup.cfg  = I2C_CFG_REG;
        I2C_backup.xcfg = I2C_XCFG_REG;
        
            #if (0u != (I2C_MODE & I2C_MODE_SLAVE))
                I2C_backup.addr = I2C_ADDR_REG;
            #endif  /* End (0u != (I2C_MODE & I2C_MODE_SLAVE)) */
            
            #if (CY_PSOC3_ES2 || CY_PSOC5_ES1)
                I2C_backup.clk_div  = I2C_CLKDIV_REG;
            
            #else
                I2C_backup.clk_div1  = I2C_CLKDIV1_REG;
                I2C_backup.clk_div2  = I2C_CLKDIV2_REG;
            #endif  /* End (CY_PSOC3_ES2 || CY_PSOC5_ES1) */
        
        #if (I2C_ENABLE_WAKEUP)
            /* Need to disable Master */
            #if (0u != (I2C_MODE & I2C_MODE_MASTER))
                if (0u != (I2C_CFG_REG & I2C_ENABLE_MASTER))
                {
                    I2C_CFG_REG &= ~I2C_ENABLE_MASTER;
                    
                    /* Store state of I2C Master */
                    I2C_backup.enableState = I2C_ENABLE_MASTER;
                }
            #endif  /* ((0u != (I2C_MODE & I2C_MODE_MASTER)) */
            
            /* Enable the I2C regulator backup */
            enableInterrupts = CyEnterCriticalSection();
            I2C_PWRSYS_CR1_REG |= I2C_PWRSYS_CR1_I2C_REG_BACKUP;
            CyExitCriticalSection(enableInterrupts);
            
            /* 1) Set force NACK to ignore I2C transactions 
               2) Wait while I2C will be ready go to Sleep 
               3) These bits are cleared on wake up */
            I2C_XCFG_REG |= I2C_XCFG_FORCE_NACK;
            while (0u == (I2C_XCFG_REG  & I2C_XCFG_RDY_TO_SLEEP));
            
        #endif  /* End (I2C_ENABLE_WAKEUP) */
        
    #else
        /* Store only address match bit */
        I2C_backup.control = (I2C_CFG_REG & I2C_CTRL_ANY_ADDRESS_MASK);
        
        #if (CY_PSOC3_ES2 || CY_PSOC5_ES1)
            /* Store interrupt mask bits */
            I2C_backup.int_mask = I2C_INT_MASK_REG;
            
            #if (I2C_MODE & I2C_MODE_SLAVE)
                /* Store slave address */
                I2C_backup.addr = I2C_ADDR_REG;
            #endif  /* End (I2C_MODE & I2C_MODE_SLAVE) */
            
        #else
            /* Retention registers for ES3:
                - Status Int mask: int_mask;
                - D0 register: addr;
                - Auxiliary Control: aux_ctl;
                - Period Register: always 7;
                - D0 and D1: clock generator 7, 15;
            */
        #endif  /* End (CY_PSOC3_ES2 || CY_PSOC5_ES1) */
        
    #endif  /* End (I2C_IMPLEMENTATION == I2C_FF) */
    
    /* Disable interrupts */
    I2C_DisableInt();
}