打印

I2C例程

[复制链接]
1241|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
没有六一了|  楼主 | 2015-6-29 15:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
网上的一个I2C例程,大家看看
沙发
没有六一了|  楼主 | 2015-6-29 15:44 | 只看该作者
#include <device.h>

#define SLAVE_ADDR 0x4
#define DATAI2C_byteCount 0x6

uint8 writeSwitch_flag ,readSwitch_flag;


void main()
{
        uint8 index,position,I2C_byteCount;
        uint8 I2C_masterBuffer[10];
        uint8 I2C_slaveBuffer[10];       
       
        /* Message to be written*/
        uint8 message[] = {0x11,0x22,0x33,0x44,0x55,0x66};       
                               


        /* Enable I2C master and slave interrupts*/
        I2C_S_EnableInt();
        I2C_M_EnableInt();                                                       
       
        /* Initialize I2C slave read and write buffers as I2C_slaveBuffer */
        I2C_S_SlaveInitReadBuf(I2C_slaveBuffer,DATAI2C_byteCount);
        I2C_S_SlaveInitWriteBuf(I2C_slaveBuffer,DATAI2C_byteCount);
       
        /* Start all components */
        LCD_Start();
        isr_WriteSwitch_Start();
        isr_ReadSwitch_Start();
        I2C_S_Start();
        I2C_M_Start();

        /* Enable global interrupt */
        CYGlobalIntEnable;                                                        

    for(;;)
    {
                /* When Write switch is pressed write data to slave */
                if (writeSwitch_flag)
                {
                        /* Clear the writeSwitch_flag flag :writeSwitch_flag is set to 1 by Isr_WriteSlave */
                    writeSwitch_flag=0;
                       
                        /* Clear any previous status */
                        I2C_M_MasterClearStatus();
                       
                        /* Write data to the slave*/
                        I2C_M_MasterWriteBuf(SLAVE_ADDR,message,DATAI2C_byteCount,I2C_M_MODE_COMPLETE_XFER);
                       
                        /* Wait till write operation is complete*/
                        while (!(I2C_M_MasterStatus() & I2C_M_MSTAT_WR_CMPLT))
                        {
                                ;
                        }               
                       
                }/* If statement ends here */
               
                /* When Read switch is pressed read back the data written into the slave */
                if (readSwitch_flag)
                {
                        /* Clear the writeSwitch_flag flag:writeSwitch_flag is set to 2 by Isr_ReadSlave */
                        readSwitch_flag=0;
                       
                        /* Clear any previous status */
                        I2C_M_MasterClearStatus();       
                       
                        /* Get the size of data previously written by master */
                        I2C_byteCount = I2C_M_MasterGetWriteBufSize();       
                       
                        /* Read back the data */
                        I2C_M_MasterReadBuf(SLAVE_ADDR,I2C_masterBuffer,I2C_byteCount,I2C_M_MODE_COMPLETE_XFER);       
                       
                        /* Wait till read operation is complete */
                        while (!(I2C_M_MasterStatus()&I2C_M_MSTAT_RD_CMPLT))
                        {
                                ;
                        }
                       
                        /* Get the no. of bytes read by the master */
                        I2C_byteCount = I2C_M_MasterGetReadBufSize();       
                       
                        /* Display the read back data */
                        for(index=0,position=0;index<I2C_byteCount;index++,position+=2)
                        {
                                LCD_Position(0,position);
                                LCD_PrintInt8(I2C_masterBuffer[index]);
                        }/* for loop ends here */
                       
                }/* if statement ends here */
               
                /* Once write to slave is complete display the data and re-intialize the write buffer */
                if (I2C_S_SlaveStatus()& I2C_S_SSTAT_WR_CMPT)
                {
                        /* Get the no. of bytes in the slave write buffer (written by master)*/
                        I2C_byteCount = I2C_S_SlaveGetWriteBufSize();                       
                       
                        /* Re-initialize the slave write buffer index to starting of the buffer(0) */
                        I2C_S_SlaveClearWriteBuf();
                       
                        /*clear the status*/
                        I2C_S_SlaveClearWriteStatus();       
                       
                        /* Display the data written into the slave */                       
                        for(index=0,position=0;index<I2C_byteCount;index++,position+=2)
                        {
                                LCD_Position(1,position);
                                LCD_PrintInt8(I2C_slaveBuffer[index]);
                        }/* for loop ends here */

                }/* If statement ends here */
               
                /* If the master has completed the read transaction, re-initialize the read buffer*/
                if(I2C_S_SlaveStatus()& I2C_S_SSTAT_RD_CMPT)
                {                       
                        /* Re-initialize the read buffer index to  to starting of the buffer(0) */
                        I2C_S_SlaveClearReadBuf();       
                       
                        /* Clear the status */
                        I2C_S_SlaveClearReadStatus();                               

                }/* If statement ends here */
    }/* for loop ends here */

}


/* [] END OF FILE */

使用特权

评论回复
板凳
没有六一了|  楼主 | 2015-6-29 15:45 | 只看该作者
/*******************************************************************************
* File Name: I2C_M.c
* Version 3.1
*
* Description:
*  This file provides the source code of APIs for the I2C component.
*  Actual protocol and operation code resides in the interrupt service routine
*  file.
*
* Note:
*
*******************************************************************************
* Copyright 2008-2012, Cypress Semiconductor Corporation.  All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/

#include "I2C_M.h"


/**********************************
*      System variables
**********************************/

uint8 I2C_M_initVar = 0u;
extern volatile uint8 I2C_M_state;    /* Current state of I2C state machine */

/* Master variables */
#if (0u != (I2C_M_MODE & I2C_M_MODE_MASTER))
   extern volatile uint8 I2C_M_mstrStatus;          /* Master Status byte */
   extern volatile uint8 I2C_M_mstrControl;         /* Master Control byte */
   
   /* Transmit buffer variables */
   extern volatile uint8 * I2C_M_mstrRdBufPtr;      /* Pointer to Master Read buffer */
   extern volatile uint8   I2C_M_mstrRdBufSize;     /* Master Read buffer size */
   extern volatile uint8   I2C_M_mstrRdBufIndex;    /* Master Read buffer Index */
   
   /* Receive buffer variables */
   extern volatile uint8 * I2C_M_mstrWrBufPtr;      /* Pointer to Master Write buffer */
   extern volatile uint8   I2C_M_mstrWrBufSize;     /* Master Write buffer size */
   extern volatile uint8   I2C_M_mstrWrBufIndex;    /* Master Write buffer Index */
   
#endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MASTER)) */

/* Slave variables */
#if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
   extern volatile uint8 I2C_M_slStatus;            /* Slave Status  */
   
   #if (I2C_M_ADDR_DECODE == I2C_M_SW_DECODE)
      extern volatile uint8 I2C_M_slAddress;        /* Software address variable */
   #endif   /* End (I2C_M_ADDR_DECODE == I2C_M_SW_DECODE) */
   
   /* Transmit buffer variables */
   extern volatile uint8 * I2C_M_slRdBufPtr;        /* Pointer to Transmit buffer */
   extern volatile uint8   I2C_M_slRdBufSize;       /* Slave Transmit buffer size */
   extern volatile uint8   I2C_M_slRdBufIndex;      /* Slave Transmit buffer Index */

   /* Receive buffer variables */
   extern volatile uint8 * I2C_M_slWrBufPtr;        /* Pointer to Receive buffer */
   extern volatile uint8   I2C_M_slWrBufSize;       /* Slave Receive buffer size */
   extern volatile uint8   I2C_M_slWrBufIndex;      /* Slave Receive buffer Index */

#endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */

extern I2C_M_BACKUP_STRUCT I2C_M_backup;
   
/*******************************************************************************
* Function Name: I2C_M_Init
********************************************************************************
*
* Summary:
*  Initializes I2C registers with initial values provided from customizer.
*
* Parameters:  
*  None
*
* Return:
*  None
*
* Global variables:
*  None
*
* Reentrant:
*  No
*
*******************************************************************************/
void I2C_M_Init(void)
{
    #if (I2C_M_IMPLEMENTATION == I2C_M_FF)
        /* Set CFG register */
        I2C_M_CFG_REG = I2C_M_DEFAULT_CFG;
        
        /* Set XCFG register */
        I2C_M_XCFG_REG = I2C_M_DEFAULT_XCFG;
        
        /* Set devide factor */
        #if (CY_PSOC3_ES2 || CY_PSOC5_ES1)
            I2C_M_CLKDIV_REG = I2C_M_DEFAULT_DIVIDE_FACTOR;
        #else
            I2C_M_CLKDIV1_REG = LO8(I2C_M_DEFAULT_DIVIDE_FACTOR);
            I2C_M_CLKDIV2_REG = HI8(I2C_M_DEFAULT_DIVIDE_FACTOR);
        #endif /* End (CY_PSOC3_ES2 || CY_PSOC3_ES2) */
        
    #else
        uint8 enableInterrupts;
        
        /* Set CFG register */
        I2C_M_CFG_REG = I2C_M_DEFAULT_CFG;
        
        /* Set interrupt source: enable Byte Complete interrupt */
        I2C_M_INT_MASK_REG = I2C_M_BYTE_COMPLETE_IE_MASK;
        
        /* Enable interrupts from block */
        enableInterrupts = CyEnterCriticalSection();
        I2C_M_INT_ENABLE_REG |= I2C_M_INT_ENABLE_MASK;
        CyExitCriticalSection(enableInterrupts);
    #endif  /* End (I2C_M_IMPLEMENTATION == I2C_M_FF) */
   
    /* Disable Interrupt and set vector and priority */
    CyIntDisable(I2C_M_ISR_NUMBER);
    CyIntSetVector(I2C_M_ISR_NUMBER, I2C_M_ISR);
    CyIntSetPriority(I2C_M_ISR_NUMBER, I2C_M_ISR_PRIORITY);
   
    /* Put state machine in idle state */
    I2C_M_state = I2C_M_SM_IDLE;
   
    #if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
        /* Reset status and buffer index */
        I2C_M_SlaveClearReadBuf();
        I2C_M_SlaveClearWriteBuf();
        I2C_M_SlaveClearReadStatus();
        I2C_M_SlaveClearWriteStatus();
        
        /* Set default address */
        I2C_M_SlaveSetAddress(I2C_M_DEFAULT_ADDR);
   
    #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */
   
    #if (0u != (I2C_M_MODE & I2C_M_MODE_MASTER))
        /* Reset status and buffer index */
        I2C_M_MasterClearReadBuf();
        I2C_M_MasterClearWriteBuf();
        I2C_M_MasterClearStatus();
        
    #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MASTER)) */
}


/*******************************************************************************
* Function Name: I2C_M_Enable
********************************************************************************
*
* Summary:
*  Enables I2C operations.
*
* Parameters:
*  None
*
* Return:
*  None
*
* Global variables:
*  None
*
*******************************************************************************/
void I2C_M_Enable(void)
{
    #if ((I2C_M_IMPLEMENTATION != I2C_M_UDB) || \
        (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)))
        uint8 enableInterrupts;
    #endif  /* End ((I2C_M_IMPLEMENTATION != I2C_M_UDB) || \
                    (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) ) */
   
    #if (I2C_M_IMPLEMENTATION == I2C_M_FF)
        enableInterrupts = CyEnterCriticalSection();
        /* Enable power to I2C Module */
        I2C_M_ACT_PWRMGR_REG  |= I2C_M_ACT_PWR_EN;
        I2C_M_STBY_PWRMGR_REG |= I2C_M_STBY_PWR_EN;
        CyExitCriticalSection(enableInterrupts);
        
    #else
        /* Enable the I2C */
        I2C_M_CFG_REG |= (I2C_M_ENABLE_MASTER | I2C_M_ENABLE_SLAVE);
        
        /* Enable bit counter */
        #if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
            enableInterrupts = CyEnterCriticalSection();
            /* Enable Counter7 */
            I2C_M_COUNTER_AUX_CTL_REG |= I2C_M_COUNTER_ENABLE_MASK;
            CyExitCriticalSection(enableInterrupts);
        #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */
        
    #endif  /* End (I2C_M_IMPLEMENTATION == I2C_M_FF) */
}


/*******************************************************************************
* Function Name: I2C_M_Start
********************************************************************************
*
* Summary:
*  Starts the I2C hardware. Enables Active mode power template bits or clock
*  gating as appropriate. It is required to be executed before I2C bus operation.
*  The I2C interrupt remains disabled after this function call.
*
* Parameters:
*  None
*
* Return:
*  None
*
* Side Effects:
*  This component automatically enables it's interrupt.  If I2C is enabled
*  without the interrupt enabled, it could lock up the I2C bus.
*
* Global variables:
*  I2C_M_initVar - used to check initial configuration, modified
*  on first function call.
*
* Reentrant:
*  No
*
*******************************************************************************/
void I2C_M_Start(void)
{
    /* Initialize I2C registers, reset I2C buffer index and clears status */
    if (0u == I2C_M_initVar)
    {
        I2C_M_Init();
        I2C_M_initVar = 1u;
    }
   
    /* Enable component */
    I2C_M_Enable();
   
    /* Enable interrupt */
    I2C_M_EnableInt();
}


/*******************************************************************************
* Function Name: I2C_M_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_M_Stop(void)
{
    #if ((I2C_M_IMPLEMENTATION != I2C_M_UDB) || \
         (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)))
        uint8 enableInterrupts;
    #endif  /* End ( (I2C_M_IMPLEMENTATION != I2C_M_FF) || \
                   (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) ) */
   
    /* Disable Interrupt */
    I2C_M_DisableInt();
   
    #if (I2C_M_IMPLEMENTATION == I2C_M_FF)
        
        #if (CY_PSOC3_ES3)
            /* Store resgisters which are held in reset when Master or Slave disabled */
            #if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
                I2C_M_backup.addr = I2C_M_ADDR_REG;
            #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */
            
            I2C_M_backup.clk_div1  = I2C_M_CLKDIV1_REG;
            I2C_M_backup.clk_div2  = I2C_M_CLKDIV2_REG;
            
            /* Reset the state machine of FF block */
            I2C_M_CFG_REG &= ~(I2C_M_ENABLE_MASTER | I2C_M_ENABLE_SLAVE);
            
            #if (I2C_M_MODE != I2C_M_MODE_SLAVE)
                CyDelayUs(2);   /* Delay required for Master reset */
            #endif /* End (I2C_M_MODE != I2C_M_MODE_SLAVE) */
            
            /* Restore registers */
            I2C_M_CFG_REG |= (I2C_M_ENABLE_MASTER | I2C_M_ENABLE_SLAVE);
            
            /* Restore registers */
            #if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
                I2C_M_ADDR_REG = I2C_M_backup.addr;
            #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */
            
            I2C_M_CLKDIV1_REG = I2C_M_backup.clk_div1;
            I2C_M_CLKDIV2_REG = I2C_M_backup.clk_div2;
            
        #endif  /* End (CY_PSOC3_ES3) */
        
        enableInterrupts = CyEnterCriticalSection();
        /* Disable power to I2C block */
        I2C_M_ACT_PWRMGR_REG  &= ~I2C_M_ACT_PWR_EN;
        I2C_M_STBY_PWRMGR_REG &= ~I2C_M_STBY_PWR_EN;
        CyExitCriticalSection(enableInterrupts);
   
    #else
        /* Clears enable bits in control register */
        I2C_M_CFG_REG &= ~(I2C_M_ENABLE_MASTER | I2C_M_ENABLE_SLAVE);
        
        /* Disable bit counter */
        #if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
            enableInterrupts = CyEnterCriticalSection();
            /* Disable Counter7 */
            I2C_M_COUNTER_AUX_CTL_REG &= ~I2C_M_COUNTER_ENABLE_MASK;
            CyExitCriticalSection(enableInterrupts);
        #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */
        
    #endif  /* End (I2C_M_IMPLEMENTATION == I2C_M_FF) */
   
    /* Clear the interrupt history */
    CyIntClearPending(I2C_M_ISR_NUMBER);
   
    /* Put state machine in IDLE state */
    I2C_M_state = I2C_M_SM_IDLE;
   
    /* Statuses and buffers are not cleared for Slave and Master */
}

使用特权

评论回复
地板
没有六一了|  楼主 | 2015-6-29 15:45 | 只看该作者
/*******************************************************************************
* Function Name: I2C_M_EnableInt
********************************************************************************
*
* Summary:
*  This function is implemented as macro in I2C_M.h file.
*  Enables I2C interrupt. Interrupts are required for most operations.
*
* Parameters:
*  None
*
* Return:
*  None
*
*******************************************************************************/


/*******************************************************************************
* Function Name: I2C_M_DisableInt
********************************************************************************
*
* Summary:
*  This function is implemented as macro in I2C_M.h file.
*  Disables I2C interrupts. Normally this function is not required since the
*  Stop function disables the interrupt. If the I2C interrupt is disabled while
*  the I2C master is still running, it may cause the I2C bus to lock up.
*
* Parameters:
*  None
*
* Return:
*  None
*
* Side Effects:
*  If the I2C interrupt is disabled and the master is addressing the current
*  slave, the bus will be locked until the interrupt is re-enabled.
*
*******************************************************************************/


#if (0u != (I2C_M_MODE & I2C_M_MODE_MASTER))
    /*******************************************************************************
    * Function Name: I2C_M_MasterStatus
    ********************************************************************************
    *
    * Summary:
    *  Returns the master's communication status.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Current status of I2C master.
    *
    * Global variables:
    *  I2C_M_mstrStatus - used to store current status of I2C Master.
    *
    *******************************************************************************/
    uint8 I2C_M_MasterStatus(void)
    {
        uint8 status;
        
        status = I2C_M_mstrStatus;
        
        /* When in Master state only transaction is in progress */
        if (0u != (I2C_M_state & I2C_M_SM_MASTER))
        {
            /* Add transaction in progress activity to master status */
            status |= I2C_M_MSTAT_XFER_INP;
        }
        else
        {
            /* Current master status is valid */
        }
        
        return (status);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterClearStatus
    ********************************************************************************
    *
    * Summary:
    *  Clears all status flags and returns the master status.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Current status of I2C master.
    *
    * Global variables:
    *  I2C_M_mstrStatus - used to store current status of I2C Master.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_MasterClearStatus(void)
    {
        /* Current master status */
        uint8 status;
        
        /* Read and clear master status */
        status = I2C_M_mstrStatus;
        I2C_M_mstrStatus = I2C_M_MSTAT_CLEAR;
        
        return (status);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterWriteBuf
    ********************************************************************************
    *
    * 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 in byte by byte mode.
    *
    * 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:
    *  Status error - zero means no errors.
    *
    * Side Effects:
    *  The included ISR will start transfer after start or restart condition will
    *  be generated.
    *
    * Global variables:
    *  I2C_M_mstrStatus  - used to store current status of I2C Master.
    *  I2C_M_state       - used to store current state of software FSM.
    *  I2C_M_mstrControl - used to control master end of transaction with
    *  or without the Stop generation.
    *  I2C_M_mstrWrBufPtr - used to store pointer to master write buffer.
    *  I2C_M_mstrWrBufIndex - used to current index within master write
    *  buffer.
    *  I2C_M_mstrWrBufSize - used to store master write buffer size.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_MasterWriteBuf(uint8 slaveAddress, uint8 * xferData, uint8 cnt, uint8 mode)
           
    {
        uint8 errStatus = I2C_M_MSTR_NOT_READY;
        
        /* Check for proper buffer */
        if (NULL != xferData)
        {
            /* Check if I2C in proper state to generate Start/ReStart condition */
            if ((I2C_M_state == I2C_M_SM_IDLE) ||
               (I2C_M_state == I2C_M_SM_MSTR_HALT))
            {
                /* If IDLE, check if bus is free */
                if (I2C_M_state == I2C_M_SM_IDLE)
                {
                    /* If Bus is free proceed, no exist */
                    if (I2C_M_CHECK_BUS_FREE(I2C_M_MCSR_REG))
                    {
                        errStatus = I2C_M_MSTR_NO_ERROR;
                    }
                    else
                    {
                        errStatus = I2C_M_MSTR_BUS_BUSY;
                    }
                }
                else   /* Bus halted waiting for restart */
                {
                    CyIntClearPending(I2C_M_ISR_NUMBER);
                    I2C_M_mstrStatus &= ~I2C_M_MSTAT_XFER_HALT;
                    errStatus = I2C_M_MSTR_NO_ERROR;
                }
               
                /* If no errors, generate start */
                if (errStatus == I2C_M_MSTR_NO_ERROR)
                {
                    /* Determine whether or not to generate a Stop condition at the end of write */
                    if (0u != (mode & I2C_M_MODE_NO_STOP))
                    {
                        I2C_M_mstrControl |= I2C_M_MSTR_NO_STOP;  /* Without a Stop */
                    }
                    else
                    {
                        I2C_M_mstrControl &= ~I2C_M_MSTR_NO_STOP; /* Generate a Stop */
                    }
                    
                    I2C_M_state = I2C_M_SM_MSTR_WR_ADDR;  /* Start from address write state */
                    slaveAddress <<= I2C_M_SLAVE_ADDR_SHIFT;         /* Set Address */
                    I2C_M_DATA_REG = slaveAddress;                   /* Write address to data reg */
                    
                    I2C_M_mstrWrBufIndex = 0u;       /* Start buffer at zero */
                    I2C_M_mstrWrBufSize  = cnt;      /* Set buffer size */
                    I2C_M_mstrWrBufPtr   = (volatile uint8 *) xferData; /* Set buffer pointer */
                    
                    /* Generate a Start or ReStart depending on flag passed */
                    if (0u != (mode & I2C_M_MODE_REPEAT_START))
                    {
                        I2C_M_GENERATE_RESTART;  /* Generate a ReStart */
                    }
                    else
                    {
                        I2C_M_GENERATE_START;    /* Generate a Start */
                    }
                    
                    /* Enable interrupts to process transfer */
                    I2C_M_EnableInt();
                    
                    /* Clear write complete flag */
                    I2C_M_mstrStatus &= ~I2C_M_MSTAT_WR_CMPLT;
                }
            }
        }
        
        return (errStatus);
    }

使用特权

评论回复
5
没有六一了|  楼主 | 2015-6-29 15:46 | 只看该作者
    /*******************************************************************************
    * Function Name: I2C_M_MasterReadBuf
    ********************************************************************************
    *
    * 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 in byte by byte mode.  
    *
    * 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:
    *  Status error - zero means no errors.
    *
    * Side Effects:
    *  The included ISR will start transfer after start or restart condition will
    *  be generated.
    *
    * Global variables:
    *  I2C_M_mstrStatus  - used to store current status of I2C Master.
    *  I2C_M_state       - used to store current state of software FSM.
    *  I2C_M_mstrControl - used to control master end of transaction with
    *  or without the Stop generation.
    *  I2C_M_mstrRdBufPtr - used to store pointer to master write buffer.
    *  I2C_M_mstrRdBufIndex - used to current index within master write
    *  buffer.
    *  I2C_M_mstrRdBufSize - used to store master write buffer size.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_MasterReadBuf(uint8 slaveAddress, uint8 * xferData, uint8 cnt, uint8 mode)
         
    {
        uint8 errStatus = I2C_M_MSTR_NOT_READY;
        
        /* Check for proper buffer */
        if (NULL != xferData)
        {
            /* Check if I2C in proper state to generate Start/ReStart condition */
            if ((I2C_M_state == I2C_M_SM_IDLE) ||
               (I2C_M_state == I2C_M_SM_MSTR_HALT))
            {
                /* If IDLE, check if bus is free */
                if (I2C_M_state == I2C_M_SM_IDLE)
                {
                    /* If Bus is free proceed, no exist */
                    if (I2C_M_CHECK_BUS_FREE(I2C_M_MCSR_REG))
                    {
                        errStatus = I2C_M_MSTR_NO_ERROR;
                    }
                    else
                    {
                        errStatus = I2C_M_MSTR_BUS_BUSY;
                    }
                }
                else   /* Bus halted waiting for restart */
                {
                    CyIntClearPending(I2C_M_ISR_NUMBER);
                    I2C_M_mstrStatus &= ~I2C_M_MSTAT_XFER_HALT;
                    errStatus = I2C_M_MSTR_NO_ERROR;
                }
               
                /* If no error, generate Start/ReStart condition */
                if (errStatus == I2C_M_MSTR_NO_ERROR)
                {
                    /* Determine whether or not to generate a Stop condition at the end of read */
                    if (0u != (mode & I2C_M_MODE_NO_STOP))
                    {
                        I2C_M_mstrControl |= I2C_M_MSTR_NO_STOP;   /* Without Stop */
                    }
                    else
                    {
                        I2C_M_mstrControl &= ~I2C_M_MSTR_NO_STOP; /* Generate a Stop */
                    }
                    
                    I2C_M_state = I2C_M_SM_MSTR_RD_ADDR;  /* Start from address read state */
                    slaveAddress <<= I2C_M_SLAVE_ADDR_SHIFT;         /* Set Address */
                    slaveAddress |= I2C_M_READ_FLAG;                 /* Set the Read flag */
                    I2C_M_DATA_REG = slaveAddress;                   /* Write address to data reg */
                    
                    I2C_M_mstrRdBufIndex  = 0u;      /* Start buffer at zero */
                    I2C_M_mstrRdBufSize   = cnt;     /* Set buffer size */
                    I2C_M_mstrRdBufPtr    = (volatile uint8 *) xferData; /* Set buffer pointer */
                    
                    /* Generate a Start or ReStart depending on flag passed */
                    if (0u != (mode & I2C_M_MODE_REPEAT_START))
                    {
                        I2C_M_GENERATE_RESTART;  /* Generate a ReStart */
                    }
                    else
                    {
                        I2C_M_GENERATE_START;    /* Generate a Start */
                    }
                    
                    /* Enable interrupts to process transfer */
                    I2C_M_EnableInt();
                    
                    /* Clear read complete flag */
                    I2C_M_mstrStatus &= ~I2C_M_MSTAT_RD_CMPLT;
                }
            }
        }
        
        return (errStatus);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_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_M_state - used to store current state of software FSM.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_MasterSendStart(uint8 slaveAddress, uint8 R_nW)
         
    {
        uint8 errStatus = I2C_M_MSTR_NOT_READY;
        
        /* If IDLE, check if bus is free */
        if (I2C_M_state == I2C_M_SM_IDLE)
        {
            /* If bus is free, generate Start condition */
            if (I2C_M_CHECK_BUS_FREE(I2C_M_MCSR_REG))
            {
                /* Disable ISR for Manual functions */
                I2C_M_DisableInt();
               
                slaveAddress <<= I2C_M_SLAVE_ADDR_SHIFT; /* Set Address */
                if (0u != R_nW)                                      /* Set the Read/Write flag */
                {
                    slaveAddress |= I2C_M_READ_FLAG;
                    I2C_M_state = I2C_M_SM_MSTR_RD_ADDR;
                }
                else
                {
                    I2C_M_state = I2C_M_SM_MSTR_WR_ADDR;
                }
                I2C_M_DATA_REG = slaveAddress;   /* Write address to data reg */
               
                /* Generates a START */
                I2C_M_GENERATE_START;
               
                /* Wait for the address to be transfered */
                while (I2C_M_WAIT_BYTE_COMPLETE(I2C_M_CSR_REG));
               
                #if (I2C_M_MODE == I2C_M_MODE_MULTI_MASTER_SLAVE)
                    if (I2C_M_CHECK_START_GEN(I2C_M_MCSR_REG))
                    {
                        /* Clear Start Gen bit */
                        I2C_M_CLEAR_START_GEN;
                        
                        /* Arbitration has been lost, reset state machine to IDLE */
                        I2C_M_state = I2C_M_SM_IDLE;
                        errStatus = I2C_M_MSTR_ERR_ABORT_START_GEN;
                    }
                    else
                #endif  /* End (I2C_M_MODE == I2C_M_MULTI_MASTER_ENABLE) */
                    
                #if (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE))
                    /* Check for loss of arbitration */
                    if (I2C_M_CHECK_LOST_ARB(I2C_M_CSR_REG))
                    {
                        /* Arbitration has been lost, reset state machine to IDLE */
                        I2C_M_state = I2C_M_SM_IDLE;
                        errStatus = I2C_M_MSTR_ERR_ARB_LOST; /* Master lost arbitrage */
                    }
                    else
                #endif  /* (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE)) */
                    
                    if (I2C_M_CHECK_ADDR_NAK(I2C_M_CSR_REG))
                    {
                        /* Address has been NACKed, reset state machine to IDLE */
                        I2C_M_state = I2C_M_SM_IDLE;
                        errStatus = I2C_M_MSTR_ERR_LB_NAK;    /* No device ACKed the Master */
                    }
                    else
                    {
                        errStatus = I2C_M_MSTR_NO_ERROR;     /* Send Start witout errors */
                    }
            }
            else
            {
                errStatus = I2C_M_MSTR_BUS_BUSY;     /* Bus is busy */
            }
        }
        
        return (errStatus);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterSendRestart
    ********************************************************************************
    *
    * Summary:
    *  Generates ReStart 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_M_state - used to store current state of software FSM.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_MasterSendRestart(uint8 slaveAddress, uint8 R_nW)
         
    {
        uint8 errStatus = I2C_M_MSTR_NOT_READY;
        
        /* Check if START condition was generated */
        if (I2C_M_CHECK_MASTER_MODE(I2C_M_MCSR_REG))
        {
            slaveAddress <<= I2C_M_SLAVE_ADDR_SHIFT; /* Set Address */
            if (0u != R_nW)                                      /* Set the Read/Write flag */
            {
                slaveAddress |= I2C_M_READ_FLAG;
                I2C_M_state = I2C_M_SM_MSTR_RD_ADDR;
            }
            else
            {
                I2C_M_state = I2C_M_SM_MSTR_WR_ADDR;
            }
            I2C_M_DATA_REG = slaveAddress;    /* Write address to data reg */
            
            /* Generates RESTART */
            I2C_M_GENERATE_RESTART;
            #if (I2C_M_IMPLEMENTATION == I2C_M_UDB)
                while (I2C_M_CHECK_BYTE_COMPLETE(I2C_M_CSR_REG));
            #endif /* End (I2C_M_IMPLEMENTATION == I2C_M_UDB) */
            
            /* Wait for the address to be transfered */
            while (I2C_M_WAIT_BYTE_COMPLETE(I2C_M_CSR_REG));
            
            #if (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE))
                /* Check for loss of arbitration */
                if (I2C_M_CHECK_LOST_ARB(I2C_M_CSR_REG))
                {
                    /* Arbitration has been lost, reset state machine to IDLE */
                    I2C_M_state = I2C_M_SM_IDLE;
                    errStatus = I2C_M_MSTR_ERR_ARB_LOST; /* Master lost arbitrage */
                }
                else
            #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE)) */   
            
                /* Check ACK address if Master mode */
                if (I2C_M_CHECK_ADDR_NAK(I2C_M_CSR_REG))
                {
                    /* Address has been NACKed, reset state machine to IDLE */
                    I2C_M_state = I2C_M_SM_IDLE;
                    errStatus = I2C_M_MSTR_ERR_LB_NAK;    /* No device ACKed the Master */
                }
                else
                {
                    errStatus = I2C_M_MSTR_NO_ERROR;     /* Send START witout errors */
                }
        }
        
        return (errStatus);
    }
   

使用特权

评论回复
6
没有六一了|  楼主 | 2015-6-29 15:46 | 只看该作者
/*******************************************************************************
    * Function Name: I2C_M_MasterSendStop
    ********************************************************************************
    *
    * Summary:
    *  Generates I2C Stop condition on bus. Function do nothing if Start or Restart
    *  condition was failed before call this function.
    *
    * Parameters:  
    *  None
    *
    * Return:
    *  Status error - zero means no errors.
    *
    * Side Effects:
    *  The Stop generation is required to complete transaction.
    *  This function does not wait while Stop condition will be generated.
    *
    * Global variables:
    *  I2C_M_state - used to store current state of software FSM.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_MasterSendStop(void)
    {
        uint8 errStatus = I2C_M_MSTR_NOT_READY;
        
        /* Check if START condition was generated */
        if (I2C_M_CHECK_MASTER_MODE(I2C_M_MCSR_REG))
        {
            I2C_M_GENERATE_STOP;                     /* Generate STOP */
            I2C_M_state = I2C_M_SM_IDLE; /* Reset state to IDLE */
            errStatus = I2C_M_MSTR_NO_ERROR;         /* Start send STOP witout errors */
               
            /* Wait for STOP generation or BYTE COMPLETE (lost arbitrage) */
            #if (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE))
               
                #if (I2C_M_IMPLEMENTATION == I2C_M_UDB)
                    while (I2C_M_CHECK_BYTE_COMPLETE(I2C_M_CSR_REG));
                #endif /* End (I2C_M_IMPLEMENTATION == I2C_M_UDB) */
               
                while (0u == (I2C_M_CSR_REG & (I2C_M_CSR_BYTE_COMPLETE |
                                                         I2C_M_CSR_STOP_STATUS)));
               
                /* Check LOST ARBITRAGE */
                if (I2C_M_CHECK_LOST_ARB(I2C_M_CSR_REG))
                {
                    errStatus = I2C_M_MSTR_ERR_ARB_LOST; /* NACK was generated instead Stop */
                }
                /* STOP condition generated */
                else
                {
                    errStatus = I2C_M_MSTR_NO_ERROR;     /* Stop was generated */
                }
            #else
                /* Wait till Stop will be generated */
                while (0u == (I2C_M_CSR_REG & I2C_M_CSR_STOP_STATUS));
            #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE)) */
        }
        
        return (errStatus);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterWriteByte
    ********************************************************************************
    *
    * Summary:
    *  Sends one byte to a slave. A valid Start or ReStart condition must be
    *  generated before this call this function. Function do nothing if Start or
    *  Restart condition was failed before call this function.
    *
    * Parameters:
    *  data:  The data byte to send to the slave.
    *
    * 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_M_state - used to store current state of software FSM.
    *
    *******************************************************************************/
    uint8 I2C_M_MasterWriteByte(uint8 theByte)
    {
        uint8 errStatus = I2C_M_MSTR_NOT_READY;
        
        /* Check if START condition was generated */
        if (I2C_M_CHECK_MASTER_MODE(I2C_M_MCSR_REG))
        {
            I2C_M_DATA_REG = theByte;                        /* Write DATA register */
            I2C_M_TRANSMIT_DATA;                             /* Set transmit mode */
            I2C_M_state = I2C_M_SM_MSTR_WR_DATA;  /* Set state WR_DATA */
            #if (I2C_M_IMPLEMENTATION == I2C_M_UDB)
                while (I2C_M_CHECK_BYTE_COMPLETE(I2C_M_CSR_REG));
            #endif
            
            /* Make sure the last byte has been transfered first */
            while (I2C_M_WAIT_BYTE_COMPLETE(I2C_M_CSR_REG));
            
            #if (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE))
                /* Check for LOST ARBITRATION */
                if (I2C_M_CHECK_LOST_ARB(I2C_M_CSR_REG))
                {
                    /* Arbitration has been lost, reset state machine to IDLE */
                    I2C_M_state = I2C_M_SM_IDLE;          /* Reset state to IDLE */
                    errStatus = I2C_M_MSTR_ERR_ARB_LOST;             /* The Master LOST ARBITRAGE */
                }
                /* Check LRB bit */
                else
            #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE)) */
            
                if (I2C_M_CHECK_DATA_ACK(I2C_M_CSR_REG))
                {
                    I2C_M_state = I2C_M_SM_MSTR_HALT;     /* Set state to HALT */
                    errStatus = I2C_M_MSTR_NO_ERROR;                 /* The LRB was ACKed */
                }
                else
                {
                    I2C_M_state = I2C_M_SM_MSTR_HALT;     /* Set state to HALT */
                    errStatus = I2C_M_MSTR_ERR_LB_NAK;               /* The LRB was NACKed */
                }
        }
        
        return (errStatus);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterReadByte
    ********************************************************************************
    *
    * Summary:
    *  Reads one byte from a slave and ACK or NACK the transfer. A valid Start or
    *  ReStart condition must be generated before this call this function. Function
    *  do nothing if Start or Restart condition was failed before call this
    *  function.
    *
    * Parameters:
    *  acknNack:  Zero, response with NACK, if non-zero response with ACK.
    *
    * Return:
    *  Byte read from slave.
    *
    * 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_M_state - used to store current state of software FSM.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_MasterReadByte(uint8 acknNak)
    {
        uint8 theByte = 0u;
        
        /* Check if START condition was generated */
        if (I2C_M_CHECK_MASTER_MODE(I2C_M_MCSR_REG))
        {
            /* When address phase need release the bus and receive the byte, then decide ACK or NACK */
            if (I2C_M_state == I2C_M_SM_MSTR_RD_ADDR)
            {
                I2C_M_READY_TO_READ;
                I2C_M_state = I2C_M_SM_MSTR_RD_DATA;
                #if (I2C_M_IMPLEMENTATION == I2C_M_UDB)
                    while (I2C_M_CHECK_BYTE_COMPLETE(I2C_M_CSR_REG));
                #endif /* End (I2C_M_IMPLEMENTATION == I2C_M_UDB) */
            }
            
            while (I2C_M_WAIT_BYTE_COMPLETE(I2C_M_CSR_REG));
            
            theByte = I2C_M_DATA_REG;
            
            /* Now if the ACK flag was set, ACK the data which will release the bus and start the next byte in
               otherwise do NOTHING to the CSR reg.
               This will allow the calling routine to generate a repeat start or a stop depending on it's preference. */
            if (acknNak != 0u)   /* Do ACK */
            {
                I2C_M_ACK_AND_RECEIVE;
                #if (I2C_M_IMPLEMENTATION == I2C_M_UDB)
                    while (I2C_M_CHECK_BYTE_COMPLETE(I2C_M_CSR_REG));
                #endif /* End (I2C_M_IMPLEMENTATION == I2C_M_UDB) */
            }
            else                /* Do NACK */
            {
                /* Do nothing to be able work with ReStart */
                I2C_M_state = I2C_M_SM_MSTR_HALT;
            }
        }
        
        return (theByte);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterGetReadBufSize
    ********************************************************************************
    *
    * Summary:
    *  Returns the amount of bytes that has been transferred with an
    *  I2C_MasterReadBuf command.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Byte count of transfer. If the transfer is not yet complete, it will return
    *  the byte count transferred so far.
    *
    * Global variables:
    *  I2C_M_mstrRdBufIndex - used to current index within master read
    *  buffer.
    *
    *******************************************************************************/
    uint16 I2C_M_MasterGetReadBufSize(void)
    {
        return (I2C_M_mstrRdBufIndex);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterGetWriteBufSize
    ********************************************************************************
    *
    * Summary:
    *  Returns the amount of bytes that has been transferred with an
    *  I2C_MasterWriteBuf command.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Byte count of transfer. If the transfer is not yet complete, it will return
    *  the byte count transferred so far.
    *
    * Global variables:
    *  I2C_M_mstrWrBufIndex - used to current index within master write
    *  buffer.
    *
    *******************************************************************************/
    uint16 I2C_M_MasterGetWriteBufSize(void)
    {
        return (I2C_M_mstrWrBufIndex);
    }
   

使用特权

评论回复
7
没有六一了|  楼主 | 2015-6-29 15:46 | 只看该作者
/*******************************************************************************
    * Function Name: I2C_M_MasterClearReadBuf
    ********************************************************************************
    *
    * Summary:
    *  Resets the read buffer pointer back to the first byte in the buffer.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  None
    *
    * Global variables:
    *  I2C_M_mstrRdBufIndex - used to current index within master read
    *   buffer.
    *  I2C_M_mstrStatus - used to store current status of I2C Master.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_MasterClearReadBuf(void)
    {
        I2C_M_mstrRdBufIndex = 0u;
        I2C_M_mstrStatus &= ~I2C_M_MSTAT_RD_CMPLT;
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_MasterClearWriteBuf
    ********************************************************************************
    *
    * Summary:
    *  Resets the write buffer pointer back to the first byte in the buffer.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  None
    *
    * Global variables:
    *  I2C_M_mstrRdBufIndex - used to current index within master read
    *   buffer.
    *  I2C_M_mstrStatus - used to store current status of I2C Master.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_MasterClearWriteBuf(void)
    {
        I2C_M_mstrWrBufIndex = 0u;
        I2C_M_mstrStatus &= ~I2C_M_MSTAT_WR_CMPLT;
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_Workaround
    ********************************************************************************
    *
    * Summary:
    *  Do nothing. This fake fuction use as workaround for CDT 78083.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  None
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_Workaround(void)
    {
   
    }
   
#endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MASTER)) */


#if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))

    /*******************************************************************************
    * Function Name: I2C_M_SlaveStatus
    ********************************************************************************
    *
    * Summary:
    *  Returns I2C slave's communication status.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Current status of I2C slave.
    *
    * Global variables:
    *  I2C_M_slStatus  - used to store current status of I2C slave.
    *
    *******************************************************************************/
    uint8 I2C_M_SlaveStatus(void)
    {
        return (I2C_M_slStatus);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveClearReadStatus
    ********************************************************************************
    *
    * Summary:
    *  Clears the read status flags and returns they values. No other status flags
    *  are affected.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Current read status of I2C slave.
    *
    * Global variables:
    *  I2C_M_slStatus  - used to store current status of I2C slave.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_SlaveClearReadStatus(void)
    {
        uint8 status;
        
        /* Mask of transfer complete flag and Error status */
        status = I2C_M_slStatus & I2C_M_SSTAT_RD_MASK;
        I2C_M_slStatus &= ~I2C_M_SSTAT_RD_CLEAR;
        
        return (status);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveClearWriteStatus
    ********************************************************************************
    *
    * Summary:
    *  Clears the write status flags and returns they values. No other status flags
    *  are affected.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Current write status of I2C slave.
    *
    * Global variables:
    *  I2C_M_slStatus  - used to store current status of I2C slave.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    uint8 I2C_M_SlaveClearWriteStatus(void)
    {
        uint8 status;
        
        /* Mask of transfer complete flag and Error status */
        status = I2C_M_slStatus & I2C_M_SSTAT_WR_MASK;
        I2C_M_slStatus &= ~I2C_M_SSTAT_WR_CLEAR;
        
        return (status);
    }
   

使用特权

评论回复
8
没有六一了|  楼主 | 2015-6-29 15:47 | 只看该作者
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveSetAddress
    ********************************************************************************
    *
    * 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
    *
    * Global variables:
    *  I2C_M_Address  - used to store I2C slave address for the primary
    *  device when software address detect feature is used.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_SlaveSetAddress(uint8 address)
    {
        #if (I2C_M_ADDR_DECODE == I2C_M_HDWR_DECODE)
            I2C_M_ADDR_REG = address & I2C_M_SLAVE_ADDR_MASK; /* Set I2C Address register */
        #else
            I2C_M_slAddress = address & I2C_M_SLAVE_ADDR_MASK;  /* Set Address variable */
        #endif  /* End (I2C_M_ADDR_DECODE == I2C_M_HDWR_DECODE) */
    }

   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveInitReadBuf
    ********************************************************************************
    *
    * Summary:
    *  Sets the buffer pointer and size of the read buffer. This function also
    *  resets the transfer count returned with the I2C_SlaveGetReadBufSize function.
    *
    * Parameters:
    *  readBuf:  Pointer to the data buffer to be read by the master.
    *  bufSize:  Size of the read buffer exposed to the I2C master.
    *
    * Return:
    *  None
    *
    * Global variables:
    *  I2C_M_slRdBufPtr   - used to store pointer to slave read buffer.
    *  I2C_M_slRdBufSize  - used to store salve read buffer size.
    *  I2C_M_slRdBufIndex - used to store current index within slave
    *  read buffer.
    *
    * Side Effects:
    *  If this function is called during a bus transaction, data from the previous
    *  buffer location and the beginning of current buffer may be transmitted.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_SlaveInitReadBuf(uint8 * readBuf, uint8 bufSize)
         
    {
        /* Check for proper buffer */
        if (NULL != readBuf)
        {
            I2C_M_slRdBufPtr   = (volatile uint8 *) readBuf;    /* Set buffer pointer */
            I2C_M_slRdBufSize  = bufSize;    /* Set buffer size */
            I2C_M_slRdBufIndex = 0u;         /* Clears buffer index */
        }
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveInitWriteBuf
    ********************************************************************************
    *
    * Summary:
    *  Sets the buffer pointer and size of the read buffer. This function also
    *  resets the transfer count returned with the I2C_SlaveGetReadBufSize function.
    *
    * Parameters:
    *  writeBuf:  Pointer to the data buffer to be read by the master.
    *  bufSize:  Size of the buffer exposed to the I2C master.
    *
    * Return:
    *  None
    *
    * Global variables:
    *  I2C_M_slWrBufPtr   - used to store pointer to slave write buffer.
    *  I2C_M_slWrBufSize  - used to store salve write buffer size.
    *  I2C_M_slWrBufIndex - used to store current index within slave
    *  write buffer.
    *
    * Side Effects:
    *  If this function is called during a bus transaction, data from the previous
    *  buffer location and the beginning of current buffer may be transmitted.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_SlaveInitWriteBuf(uint8 * writeBuf, uint8 bufSize)
         
    {
        /* Check for proper buffer */
        if (NULL != writeBuf)
        {
            I2C_M_slWrBufPtr   = (volatile uint8 *) writeBuf;  /* Set buffer pointer */
            I2C_M_slWrBufSize  = bufSize;   /* Set buffer size */
            I2C_M_slWrBufIndex = 0u;        /* Clears buffer index */
        }
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveGetReadBufSize
    ********************************************************************************
    *
    * Summary:
    *  Returns the number of bytes read by the I2C master since an
    *  I2C_SlaveInitReadBuf or I2C_SlaveClearReadBuf function was executed.
    *  The maximum return value will be the size of the read buffer.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Bytes read by master.
    *
    * Global variables:
    *  I2C_M_slRdBufIndex - used to store current index within slave
    *  read buffer.
    *
    *******************************************************************************/
    uint8 I2C_M_SlaveGetReadBufSize(void)
    {
        return (I2C_M_slRdBufIndex);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveGetWriteBufSize
    ********************************************************************************
    *
    * Summary:
    *  Returns the number of bytes written by the I2C master since an
    *  I2C_SlaveInitWriteBuf or I2C_SlaveClearWriteBuf function was executed.
    *  The maximum return value will be the size of the write buffer.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  Bytes written by master.
    *
    * Global variables:
    *  I2C_M_slWrBufIndex - used to store current index within slave
    *  write buffer.
    *
    *******************************************************************************/
    uint8 I2C_M_SlaveGetWriteBufSize(void)
    {
        return (I2C_M_slWrBufIndex);
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveClearReadBuf
    ********************************************************************************
    *
    * Summary:
    *  Resets the read pointer to the first byte in the read buffer. The next byte
    *  read by the master will be the first byte in the read buffer.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  None
    *
    * Global variables:
    *  I2C_M_slRdBufIndex - used to store current index within slave
    *  read buffer.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_SlaveClearReadBuf(void)  
    {
        I2C_M_slRdBufIndex = 0u;
    }
   
   
    /*******************************************************************************
    * Function Name: I2C_M_SlaveClearRxBuf
    ********************************************************************************
    *
    * Summary:
    *  Resets the write pointer to the first byte in the write buffer. The next byte
    *  written by the master will be the first byte in the write buffer.
    *
    * Parameters:
    *  None
    *
    * Return:
    *  None
    *
    * Global variables:
    *  I2C_M_slWrBufIndex - used to store current index within slave
    *  write buffer.
    *
    * Reentrant:
    *  No
    *
    *******************************************************************************/
    void I2C_M_SlaveClearWriteBuf(void)  
    {
        I2C_M_slWrBufIndex = 0u;
    }

#endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */


/* [] END OF FILE */

使用特权

评论回复
9
没有六一了|  楼主 | 2015-6-29 15:48 | 只看该作者
/*******************************************************************************
* Function Name: I2C_M_ISR
********************************************************************************
*
* Summary:
*  Handle Interrupt Service Routine.  
*
* Parameters:  
*  void
*
* Return:
*  void
*
* Reentrant:
*  No
*
*******************************************************************************/
CY_ISR(I2C_M_ISR)
{
    #if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
       static uint8  tmp8;    /* Making these static so not wasting time allocating */
    #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */
   
    static uint8  tmpCsr;  /* on the stack each time and no one else can see them */
   
    /* Entry from interrupt */
    /* In hardware address compare mode, we can assume we only get interrupted when */
    /* a valid address is recognized. In software address compare mode, we have to  */
    /* check every address after a start condition.                                 */
   
    tmpCsr = I2C_M_CSR_REG;          /* Make temp copy so that we can check */
                                                /* for stop condition after we are done */
   
    /* Check if Start Condition was generated */
    #if (I2C_M_MODE == I2C_M_MODE_MULTI_MASTER_SLAVE)
        if (I2C_M_CHECK_START_GEN(I2C_M_MCSR_REG))
        {
            /* Clear Start Gen bit */
            I2C_M_CLEAR_START_GEN;
            
            /* Check State for READ one: SM_MSTR_RD_ADDR or SM_MSTR_RD_DATA */
            if (0u != (I2C_M_state & I2C_M_SM_MSTR_RD))
            {
                /* Set READ complete, but was aborted */
                I2C_M_mstrStatus |= (I2C_M_MSTAT_RD_CMPLT | I2C_M_MSTAT_ERR_XFER);
            }
            else /* All other: should be only write states */
            {
                /* Set WRITE complete, but was aborted */
                I2C_M_mstrStatus |= (I2C_M_MSTAT_WR_CMPLT | I2C_M_MSTAT_ERR_XFER);
            }
            
            /* Reset State Machine to IDLE to enable the Slave */
            I2C_M_state = I2C_M_SM_IDLE;
        }
    #endif  /* End (I2C_M_MODE == I2C_M_MULTI_MASTER_ENABLE) */
   
    #if (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE))
        /* Check for lost of arbitration  */
        if (I2C_M_CHECK_LOST_ARB(tmpCsr))
        {
            /* MultiMaster-Slave */
            #if (I2C_M_MODE == I2C_M_MODE_MULTI_MASTER_SLAVE)
                /* Check on which state of transaction lost ARBITRAGE:
                  Address    - if Address and pass control to Slave
                  No Address - release the bus */
                if (0u == (tmpCsr & I2C_M_CSR_ADDRESS))
                {
            #endif  /* End (I2C_M_MODE == I2C_M_MULTI_MASTER_ENABLE) */
            
                    /* Lost ARBITRAGE:
                       Data - reset state machine to IDLE, Disable Slave enable event */
                    
                    /* Disable interrupt on STOP in case that it was READ */
                    I2C_M_DISABLE_INT_ON_STOP;
                    
                    /* Clear CSR to release the bus, if MultiMaster */
                    I2C_M_READY_TO_READ;
            
            #if (I2C_M_MODE == I2C_M_MODE_MULTI_MASTER_SLAVE)
                    /* Clean up the Slave enable events: Byte Complete and Stop */
                    tmpCsr &= ~ (I2C_M_CSR_BYTE_COMPLETE | I2C_M_CSR_STOP_STATUS);
                }
            #endif  /* End (I2C_M_MODE == I2C_M_MULTI_MASTER_ENABLE) */
            
            /* Check State for READ one: SM_MSTR_RD_ADDR or SM_MSTR_RD_DATA */
            if (0u != (I2C_M_state & I2C_M_SM_MSTR_RD))
            {
                /* Set READ complete */
                I2C_M_mstrStatus |= I2C_M_MSTAT_RD_CMPLT;
            }
            else /* All other: should be only write states */
            {
                /* Set WRITE complete */
                I2C_M_mstrStatus |= I2C_M_MSTAT_WR_CMPLT;
            }
            
            /* Set status error transfer and arbitration lost */
            I2C_M_mstrStatus |= (I2C_M_MSTAT_ERR_ARB_LOST |
                                            I2C_M_MSTAT_ERR_XFER);
            
            /* Reset State Machine to IDLE */
            I2C_M_state = I2C_M_SM_IDLE;
        }
    #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MULTI_MASTER_ENABLE)) */
     
    /* Check for Master operation mode */
    if (0u != (I2C_M_state & I2C_M_SM_MASTER))
    {
        #if (0u != (I2C_M_MODE & I2C_M_MODE_MASTER))
            
            /* Enter Master state machine */
            if (I2C_M_CHECK_BYTE_COMPLETE(tmpCsr))
            {
                /* Clear external or previous stop event */
                tmpCsr &= ~I2C_M_CSR_STOP_STATUS;  /* Clear STOP bit */
               
                switch (I2C_M_state)
                {
                    case I2C_M_SM_MSTR_WR_ADDR:    /* After address is sent, WRITE some data */
                    case I2C_M_SM_MSTR_RD_ADDR:    /* After address is sent, READ some data */
                    
                        /* Check for Slave address ACK */
                        if (I2C_M_CHECK_ADDR_ACK(tmpCsr))  /* Check ACK */
                        {
                            /* Setup for transmit or receive of data */
                            if (I2C_M_state == I2C_M_SM_MSTR_WR_ADDR)   /* TRANSMIT data */
                            {
                                if (I2C_M_mstrWrBufSize > 0u)    /* Check if at least one byte is transfered */
                                {
                                    /* Load first data byte */
                                    I2C_M_DATA_REG = I2C_M_mstrWrBufPtr[0u];
                                    I2C_M_TRANSMIT_DATA;            /* Transmit data */
                                    I2C_M_mstrWrBufIndex = 1u;      /* Set index to 2nd location */
                                    
                                    /* Set transmit state until done */
                                    I2C_M_state = I2C_M_SM_MSTR_WR_DATA;
                                }
                                else   /* No data to tranfer */
                                {
                                    /* Handles 0 bytes transfer - Not HALT is allowed */
                                    #if (CY_PSOC3_ES2 || CY_PSOC5_ES1)
                                        I2C_M_GENERATE_STOP;     /* Generate STOP */
                                       
                                        /* Set WRITE complete */
                                        I2C_M_mstrStatus |= I2C_M_MSTAT_WR_CMPLT;
                                       
                                        /* Reset State Machine to IDLE */
                                        I2C_M_state  = I2C_M_SM_IDLE;
                                       
                                    #else  /* The PSoC3 ES3 only handles this well */
                                        if (I2C_M_CHECK_NO_STOP(I2C_M_mstrControl))
                                        {
                                            /* Reset State Machine to HALT, expect RESTART */
                                            I2C_M_state  = I2C_M_SM_MSTR_HALT;
                                            
                                            /* Set WRITE complete and Master HALTED */
                                            I2C_M_mstrStatus |= (I2C_M_MSTAT_WR_CMPLT |
                                                                            I2C_M_MSTAT_XFER_HALT);
                                            
                                            I2C_M_DisableInt();
                                        }
                                        else  /* Do normal STOP */
                                        {
                                            I2C_M_ENABLE_INT_ON_STOP;    /* Enable interrupt on STOP, to catch it */
                                            I2C_M_GENERATE_STOP;         /* Generate STOP */
                                        }
                                       
                                    #endif  /* End (CY_PSOC3_ES2 || CY_PSOC5_ES1) */
                                }
                            }
                            else  /* Master Receive data */
                            {
                                I2C_M_READY_TO_READ;     /* Ready to READ data */
                                
                                /* Set state machine to READ data */
                                I2C_M_state  = I2C_M_SM_MSTR_RD_DATA;
                            }
                        }
                        /* Check for Slave address NAK */
                        else if (I2C_M_CHECK_ADDR_NAK(tmpCsr))  /* Check NACK */
                        {
                            if (I2C_M_CHECK_NO_STOP(I2C_M_mstrControl))
                            {
                                /* Check State for READ one: SM_MSTR_RD_ADDR or SM_MSTR_RD_DATA */
                                if (0u != (I2C_M_state & I2C_M_SM_MSTR_RD))
                                {
                                    /* Set READ complete */
                                    I2C_M_mstrStatus |= I2C_M_MSTAT_RD_CMPLT;
                                }
                                else /* All other: should be only write states */
                                {
                                    /* Set WRITE complete */
                                    I2C_M_mstrStatus |= I2C_M_MSTAT_WR_CMPLT;
                                }
                                
                                /* Set Address NAK Error and Master HALTED */
                                I2C_M_mstrStatus |= (I2C_M_MSTAT_XFER_HALT |
                                                                I2C_M_MSTAT_ERR_ADDR_NAK |
                                                                I2C_M_MSTAT_ERR_XFER);
                                                               
                                /* Reset State Machine to HALT, expect RESTART */
                                I2C_M_state  = I2C_M_SM_MSTR_HALT;
                                I2C_M_DisableInt();
                            }
                            else  /* Do normal Stop */
                            {
                                I2C_M_ENABLE_INT_ON_STOP;    /* Enable interrupt on STOP, to catch it */
                                I2C_M_GENERATE_STOP;         /* Generate STOP */
                                
                                /* Set Address NAK and ERR transfer */
                                I2C_M_mstrStatus |= (I2C_M_MSTAT_ERR_ADDR_NAK |
                                                                I2C_M_MSTAT_ERR_XFER);
                            }
                        }
                        /* Should never gets here: Address status is NOT set */
                        else
                        {
                            CYASSERT(0);
                        }
                        break;
                        
                    case I2C_M_SM_MSTR_WR_DATA:    /* Write data to slave */
                        
                        if (I2C_M_CHECK_DATA_ACK(tmpCsr))       /* Check ACK */
                        {
                            /* Check if end buffer */
                            if (I2C_M_mstrWrBufIndex  < I2C_M_mstrWrBufSize)
                            {
                                 /* Load first data byte  */
                                I2C_M_DATA_REG = I2C_M_mstrWrBufPtr[I2C_M_mstrWrBufIndex];
                                I2C_M_TRANSMIT_DATA;     /* Transmit */
                                
                                I2C_M_mstrWrBufIndex++;  /* Advance to data location */
                            }
                            else   /* Last byte was transmitted, send STOP */
                            {
                                if (I2C_M_CHECK_NO_STOP(I2C_M_mstrControl))
                                {
                                    /* Reset State Machine to HALT, expect RESTART */
                                    I2C_M_state  = I2C_M_SM_MSTR_HALT;
                                    
                                    /* Set WRITE complete and Master HALTED */
                                    I2C_M_mstrStatus |= (I2C_M_MSTAT_WR_CMPLT |
                                                                    I2C_M_MSTAT_XFER_HALT);
                                    
                                    I2C_M_DisableInt();
                                }
                                else  /* Do normal STOP */
                                {
                                    I2C_M_Workaround();          /* Workaround for CDT 78083 */
                                    I2C_M_ENABLE_INT_ON_STOP;    /* Enable interrupt on STOP, to catch it */
                                    I2C_M_GENERATE_STOP;         /* Generate STOP */
                                }
                            }
                        }
                        else /* If last byte NAKed, stop transmit and send STOP */
                        {
                            /* Check STOP generation */
                            if (I2C_M_CHECK_NO_STOP(I2C_M_mstrControl))
                            {
                                /* Reset State Machine to HALT, expect RESTART */
                                I2C_M_state  = I2C_M_SM_MSTR_HALT;
                                
                                /* Set WRITE complete, SHORT transfer and Master HALTED */
                                I2C_M_mstrStatus |= (I2C_M_MSTAT_WR_CMPLT |
                                                                I2C_M_MSTAT_XFER_HALT |
                                                                I2C_M_MSTAT_ERR_SHORT_XFER |
                                                                I2C_M_MSTAT_ERR_XFER);
                                
                                I2C_M_DisableInt();
                            }
                            else  /* Do normal STOP */
                            {
                                I2C_M_ENABLE_INT_ON_STOP;    /* Enable interrupt on STOP, to catch it */
                                I2C_M_GENERATE_STOP;         /* Generate STOP */
                                                               
                                /* Set SHORT and ERR transfer */
                                I2C_M_mstrStatus |= (I2C_M_MSTAT_ERR_SHORT_XFER |
                                                                I2C_M_MSTAT_ERR_XFER);
                            }
                        }
                        break;
                        
                    case I2C_M_SM_MSTR_RD_DATA:    /* Data received */
                        
                        I2C_M_mstrRdBufPtr[I2C_M_mstrRdBufIndex] = I2C_M_DATA_REG;
                        I2C_M_mstrRdBufIndex++;      /* Inc pointer */
                        /* Check if end of buffer */
                        if (I2C_M_mstrRdBufIndex < I2C_M_mstrRdBufSize)
                        {
                            I2C_M_ACK_AND_RECEIVE;       /* ACK and receive */
                        }
                        else   /* End of data, generate a STOP */
                        {
                            if (I2C_M_CHECK_NO_STOP(I2C_M_mstrControl)) /* Check STOP generation */
                            {
                                /* Reset State Machine to HALT, expect RESTART */
                                I2C_M_state = I2C_M_SM_MSTR_HALT;
                                
                                /* Set READ complete and Master HALTED */
                                I2C_M_mstrStatus |= (I2C_M_MSTAT_RD_CMPLT |
                                                                I2C_M_MSTAT_XFER_HALT );
                            }
                            else   /* Do normal STOP */
                            {
                                I2C_M_ENABLE_INT_ON_STOP;        /* Enable interrupt on STOP, to catch it */
                                I2C_M_NAK_AND_RECEIVE;           /* NACK and TRY to generate STOP */
                            }
                        }
                        break;
                        
                    default: /* This is an invalid state and should not occur */
                        
                        CYASSERT(0);
                        break;
                }
            }
            
            /* Check if STOP was detected */
            if (I2C_M_CHECK_STOP_STS(tmpCsr))
            {
                /* Check State for READ one: SM_MSTR_RD_ADDR or SM_MSTR_RD_DATA */
                if (0u != (I2C_M_state & I2C_M_SM_MSTR_RD))
                {
                    /* Set READ complete */
                    I2C_M_mstrStatus |= I2C_M_MSTAT_RD_CMPLT;
                }
                else /* All other: should be only write states */
                {
                    /* Set WRITE complete */
                    I2C_M_mstrStatus |= I2C_M_MSTAT_WR_CMPLT;
                }
               
                /* Catch STOP, disable the interrupt on STOP */
                I2C_M_DISABLE_INT_ON_STOP;
                I2C_M_state = I2C_M_SM_IDLE;  /* Set state to IDLE */
            }
        #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_MASTER)) */
    }

使用特权

评论回复
10
没有六一了|  楼主 | 2015-6-29 15:49 | 只看该作者
   else    /* Slave */
    {
        #if (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE))
            /* Check to see if a Start/Address is detected */
            if (0u != (tmpCsr & I2C_M_CSR_ADDRESS))
            {
                /* Clears STOP status bit. This status bit sets by ANY of STOP condition detection on the bus */
                tmpCsr &= ~I2C_M_CSR_STOP_STATUS;  /* Clear STOP bit */
               
                /* This is a Start or ReStart. Reset the state machine and check for a Read/Write condition */
               
                /* Check for software address detection */
                #if (I2C_M_ADDR_DECODE == I2C_M_SW_DECODE)
                    tmp8 = ((I2C_M_DATA_REG >> I2C_M_SLAVE_ADDR_SHIFT) &
                             I2C_M_SLAVE_ADDR_MASK);
                    if (tmp8 == I2C_M_slAddress)   /* Check for address match */
                    {
                        /* Check for read or write command */
                        if (0u != (I2C_M_DATA_REG & I2C_M_READ_FLAG))
                        {
                            /*        Place code to prepare read buffer here           */
                            /* `#START I2C_M_SW_PREPARE_READ_BUF_interrupt` */

                            /* `#END` */
                           
                            /* Prepare next opeation to read, get data and place in data register */
                            if (I2C_M_slRdBufIndex < I2C_M_slRdBufSize)
                            {
                                /* Load first data byte */
                                I2C_M_DATA_REG = I2C_M_slRdBufPtr[I2C_M_slRdBufIndex];
                                I2C_M_ACK_AND_TRANSMIT;  /* ACK and transmit */
                                I2C_M_slRdBufIndex++;    /* Advance to data location */
                                
                                /* Set READ activity */
                                I2C_M_slStatus |= I2C_M_SSTAT_RD_BUSY;
                            }
                            else    /* Data overflow */
                            {
                                I2C_M_DATA_REG = 0xFFu;    /* Out of range, send 0xFF */
                                I2C_M_ACK_AND_TRANSMIT;    /* ACK and transmit */
                                
                                /* Set READ activity with OVERFLOW */
                                I2C_M_slStatus  |= (I2C_M_SSTAT_RD_BUSY |
                                                               I2C_M_SSTAT_RD_ERR_OVFL);
                            }
                           
                            I2C_M_state = I2C_M_SM_SL_RD_DATA; /* Prepare for Read transaction */
                        }
                        else  /* Start of a Write transaction, ready to write of the first byte */
                        {
                            /* Prepare to write the first byte */
                            I2C_M_ACK_AND_RECEIVE;
                            I2C_M_state = I2C_M_SM_SL_WR_DATA; /* Prepare for Write transaction */
                           
                            /* Set WRITE activity */
                            I2C_M_slStatus |= I2C_M_SSTAT_WR_BUSY;
                            I2C_M_ENABLE_INT_ON_STOP;    /* Enable interrupt on Stop */
                        }
                    }
                    else   /* No address match */
                    {
                        /*     Place code to compare for additional address here    */
                        /* `#START I2C_M_SW_ADDR_COMPARE_interruptStart` */

                        /* `#END` */
                        
                            I2C_M_NAK_AND_RECEIVE;   /* NAK address */
                        
                        /* Place code to end of condition for NACK generation here */
                        /* `#START I2C_M_SW_ADDR_COMPARE_interruptEnd`  */

                        /* `#END` */
                    }
                    
                #else  /* Hardware address detection */
                    /* Check for read or write command */
                    if (0u != (I2C_M_DATA_REG & I2C_M_READ_FLAG))
                    {
                        /*          Place code to prepare read buffer here         */
                        /* `#START I2C_M_HW_PREPARE_READ_BUF_interrupt` */

                        /* `#END` */
                        
                        /* Prepare next opeation to read, get data and place in data register */
                        if (I2C_M_slRdBufIndex < I2C_M_slRdBufSize)
                        {
                            /* Load first data byte */
                            I2C_M_DATA_REG = I2C_M_slRdBufPtr[I2C_M_slRdBufIndex];
                            I2C_M_ACK_AND_TRANSMIT;  /* ACK and transmit */
                            I2C_M_slRdBufIndex++;    /* Advance to data location */
                           
                            /* Set READ activity */
                            I2C_M_slStatus  |= I2C_M_SSTAT_RD_BUSY;
                        }
                        else    /* Data overflow */
                        {
                            I2C_M_DATA_REG = 0xFFu;    /* Out of range, send 0xFF  */
                            I2C_M_ACK_AND_TRANSMIT;    /* ACK and transmit */
                           
                            /* Set READ activity with OVERFLOW */
                            I2C_M_slStatus  |= (I2C_M_SSTAT_RD_BUSY |
                                                           I2C_M_SSTAT_RD_ERR_OVFL);
                        }
                        
                        I2C_M_state = I2C_M_SM_SL_RD_DATA;    /* Prepare for Read transaction */
                    }
                    else  /* Start of a Write transaction, ready to write of the first byte */
                    {
                        /* Prepare to write the first byte */
                        I2C_M_ACK_AND_RECEIVE;       /* ACK and ready to receive addr */
                        I2C_M_state = I2C_M_SM_SL_WR_DATA;    /* Prepare for write transaction */
                        
                        /* Set WRITE activity */
                        I2C_M_slStatus |= I2C_M_SSTAT_WR_BUSY;
                        I2C_M_ENABLE_INT_ON_STOP;    /* Enable interrupt on Stop */
                    }
                    
                #endif  /* End (I2C_M_ADDR_DECODE == I2C_M_SW_DECODE) */
            }
            /* Check for data transfer */
            else if (I2C_M_CHECK_BYTE_COMPLETE(tmpCsr))  
            {
                /* Data write from Master to Slave */
                if (I2C_M_state == I2C_M_SM_SL_WR_DATA)
                {
                    if (I2C_M_slWrBufIndex < I2C_M_slWrBufSize)       /* Check for valid range */
                    {
                        tmp8 = I2C_M_DATA_REG;                        /* Get data, to ACK quickly */
                        I2C_M_ACK_AND_RECEIVE;                        /* ACK and ready to receive */
                        I2C_M_slWrBufPtr[I2C_M_slWrBufIndex] = tmp8; /* Write data to array */
                        I2C_M_slWrBufIndex++;                        /* Inc pointer */
                    }
                    else
                    {
                        I2C_M_NAK_AND_RECEIVE;       /* NAK cause beyond write area */
                        
                        /* Set OVERFLOW, write completes on Stop */
                        I2C_M_slStatus |= I2C_M_SSTAT_WR_ERR_OVFL;
                    }
                }
                /* Data Read from Slave to Master */
                else if (I2C_M_state == I2C_M_SM_SL_RD_DATA)
                {
                    if (I2C_M_CHECK_DATA_ACK(tmpCsr))
                    {
                        if (I2C_M_slRdBufIndex < I2C_M_slRdBufSize)
                        {
                             /* Get data from array */
                            I2C_M_DATA_REG = I2C_M_slRdBufPtr[I2C_M_slRdBufIndex];
                            I2C_M_TRANSMIT_DATA;         /* Send Data */
                            I2C_M_slRdBufIndex++;        /* Inc pointer */
                        }
                        else   /* Over flow */
                        {
                            I2C_M_DATA_REG = 0xFFu;  /* Send 0xFF at the end of the buffer */
                            I2C_M_TRANSMIT_DATA;     /* Send Data */
                           
                            /* Set OVERFLOW */
                            I2C_M_slStatus |= I2C_M_SSTAT_RD_ERR_OVFL;
                        }
                    }
                    else  /* Last byte NAKed, done */
                    {
                        I2C_M_DATA_REG = 0xFFu;  /* End of read transaction */
                        I2C_M_NAK_AND_TRANSMIT;  /* Clear transmit bit at the end of read transaction */
                        
                        I2C_M_slStatus &= ~I2C_M_SSTAT_RD_BUSY;   /* Clear RD_BUSY Flag */
                        I2C_M_slStatus |= I2C_M_SSTAT_RD_CMPLT;    /* Set RD_CMPLT Flag */
                        
                        I2C_M_state = I2C_M_SM_IDLE;  /* Return to IDLE state */
                    }
                }
                /* This is an invalid state and should not occur */
                else
                {
                    CYASSERT(0);
                }   /* End Transfer mode */
            }
            /* EMPTY else: there is no Slave enable event. */
            else
            {
                /* The Multi-Master-Slave exist here when arbitrage happen on other than
                   address stage of transaction == No Slave enable event. */
            }
            
            /* Check if STOP was detected */
            if (I2C_M_CHECK_STOP_STS(tmpCsr))
            {
                /* The Write transaction only IE on STOP, so Read never gets here */
                /* The WR_BUSY flag will be cleared at the end of "Write-ReStart-Read-Stop" transaction */
               
                I2C_M_slStatus &= ~I2C_M_SSTAT_WR_BUSY;   /* Clear WR_BUSY Flag */
                I2C_M_slStatus |= I2C_M_SSTAT_WR_CMPLT;    /* Set WR_CMPT Flag */
               
                I2C_M_DISABLE_INT_ON_STOP;               /* Disable interrupt on STOP */
                I2C_M_state = I2C_M_SM_IDLE;  /* Return to IDLE */
            }
        
        #endif  /* End (0u != (I2C_M_MODE & I2C_M_MODE_SLAVE)) */
    }
   
    #if (CY_PSOC3_ES2 && (I2C_M_I2C_IRQ__ES2_PATCH))
        I2C_M_ISR_PATCH();
    #endif  /* End (CY_PSOC3_ES2 && (I2C_M_I2C_IRQ__ES2_PATCH)) */
}

使用特权

评论回复
11
给力芯片| | 2015-6-29 16:03 | 只看该作者
程序太多,能给个压缩包吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

47

主题

389

帖子

0

粉丝