⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev_i2c_main.c

📁 i2c总线接口驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
   {      /* ERROR: Slave failed to release SCL */      return ( retcode );   }   /* Read the state of the serial data line (SDA) */   sdastate = dev_i2c_io_sdastate ();   /* If SCL was not released */   if ( sdastate != DEV_I2C_SIGNAL_ACK )   {      /* ERROR: Acknowledgement bit not received */      return ( DEV_I2C_RETCODE_NOACK );   }   else    {      /* SUCCESS: Acknowledgement received */      return ( DEV_I2C_RETCODE_SUCCESS );   }}/***************************************************************************** * * DEV_I2C_WAIT4SCLRLS - Wait for SCL Release * * PURPOSE: *    To wait for the slave device to release the SCL line to signal *    that it is ready to complete the current bus transaction. * * PARAMETERS: *    None * * RETURNS: *    DEV_I2C_RETCODE_SUCCESS   => Data sent successfully *    DEV_I2C_RETCODE_SCLRLSTO  => Error: Slave SCL release timeout error *                             (possible physical layer fault) *     * NOTE: *     A slow device may hold the SCL line low for a protracted period *     of time to achieve a quasi-'wait state' effect. *     *     It is not currently clear what the wait timeout period should *     be to accommodate a generic set of devices. *     *****************************************************************************/Int16 dev_i2c_wait4sclrls ( void ){   Word i;   /* For each 2.5 us interval in the timeout value */   for ( i = 0; i < DEV_I2C_TIMEOUT_SCLRLS; i++ )   {      /* If the slave has released the SCL signal */      if ( dev_i2c_io_sclstate () == DEV_I2C_SIGNAL_INACTIVE )      {         /* SUCCESS: SCL released */         return ( DEV_I2C_RETCODE_SUCCESS );      }   }   /* ERROR: Slave failed to release SCL */   return ( DEV_I2C_RETCODE_SCLRLSTO );}Int16 dev_i2c_Uim_read ( Byte deviceaddr, Byte *databufp ){    /* empty, for DEV build only */}void dev_uim_wakeup ( void ){    /* empty, for DEV build only */}void dev_uim_reset ( void ){    /* empty, for DEV build only */}#else  /* BOARD_PHOENIX *//****************** UIM I2C Very Slow, 80kHz clock speed for TDA8029 ********/#define DEV_I2C_CLK_WAIT        2      /* 4*5us: - 20 us *//***************************************************************************** * dev_i2c_write - Write Data to I2C Device *****************************************************************************/Int16 dev_i2c_write ( Byte deviceaddr, Byte *databufp, Word len ){    Word i;    Int16 retcode;    /* If the bus is currently in use */    if ( dev_i2c_busstate () == DEV_I2C_BUS_BUSY )    {        /* ERROR: Failed to acquire the bus */        return ( DEV_I2C_RETCODE_BUSBUSY );    }    retcode = dev_i2c_txdevaddr ( deviceaddr );    if ( retcode == DEV_I2C_RETCODE_SUCCESS )    {        /* For each byte in the message */        for ( i = 0; i < len; i++ )        {            retcode = dev_i2c_txdatabyte ( *databufp++, DEV_I2C_NOT_LAST_BYTE );            if ( retcode < 0 )            {                break;                              /* ERROR */            }        }    }    if ( retcode < 0 )    {        dev_i2c_txstopbit ();    }    else    {        return ( dev_i2c_txdatabyte ( *databufp++, DEV_I2C_LAST_BYTE ) );    }    return( retcode );}/***************************************************************************** * dev_i2c_Uim_read - Read Data from UIM I2C Device *****************************************************************************/Int16 dev_i2c_Uim_read ( Byte deviceaddr, Byte *databufp ){    Int16 retcode;                   /* return code */    Word i, length;    Byte alpar_header[4];    /* If the bus is currently in use */    if ( dev_i2c_busstate () == DEV_I2C_BUS_BUSY )    {        /* ERROR: Failed to acquire the bus */        return ( DEV_I2C_RETCODE_BUSBUSY );    }    retcode = dev_i2c_txdevaddr ( deviceaddr );    if ( retcode == DEV_I2C_RETCODE_SUCCESS )    {        /* For each byte in the message (except the last one) */        for ( i = 0; i < 4; i++ )        {            retcode = dev_i2c_rxdatabyte( DEV_I2C_NOT_LAST_BYTE );            if ( retcode < 0 )            {                break;            }            /* Add the received data byte to the buffer */            *databufp++ = (Byte) retcode;            alpar_header[i] = retcode;        }    }    if ( retcode < 0 )    {        dev_i2c_txstopbit ();        return ( retcode );    }    length = alpar_header[1]*256 + alpar_header[2];    if( length <= MAX_ALPAR_DATA_LENGTH )    {        /* For each byte in the message */        for ( i = 0; i < length; i++ )        {            /* Receive the data byte */            retcode = dev_i2c_rxdatabyte( DEV_I2C_NOT_LAST_BYTE );            if ( retcode < 0 )            {                break;            }            /* Add the received data byte to the buffer */            *databufp++ = (Byte) retcode;        }    }    else    {        retcode = DEV_I2C_RETCODE_TOOLONG;    }    if ( retcode >= 0 )    {        retcode = dev_i2c_rxdatabyte ( DEV_I2C_LAST_BYTE );        *databufp++ = (Byte) retcode;    }    dev_i2c_txstopbit ();    return ( retcode );}/***************************************************************************** * DEV_I2C_TXDEVADDR - Transmit I2C Device Address *****************************************************************************/Int16 dev_i2c_txdevaddr ( Byte deviceaddr ){    /* Send a start bit */     dev_i2c_txstartbit ();    /* Transmit the address byte, check for acknowledgement and return status */    return ( dev_i2c_txdatabyte ( deviceaddr, DEV_I2C_NOT_LAST_BYTE ) );}/***************************************************************************** * DEV_I2C_TXSTARTBIT - Send I2C Start Bit *****************************************************************************/void dev_i2c_txstartbit ( void ){   dev_i2c_io_sdalow ();   dev_i2c_wait(DEV_I2C_CLK_WAIT);   dev_i2c_io_scllow ();}/***************************************************************************** * DEV_I2C_TXSTOPBIT - Send a Stop Bit *****************************************************************************/void dev_i2c_txstopbit ( void ){   /* Drive the clock line (SCL) low */   dev_i2c_io_scllow ();   dev_i2c_wait(DEV_I2C_CLK_WAIT);   /* Drive the data line (SDA) low */   dev_i2c_io_sdalow ();   dev_i2c_wait(DEV_I2C_CLK_WAIT);   /* Tri-state the clock line (SCL) (it will be pulled high) */   dev_i2c_io_scltristate ();   dev_i2c_wait(DEV_I2C_CLK_WAIT);   /* Tri-state the data line (SDA) (it will be pulled high) */   dev_i2c_io_sdatristate ();   dev_i2c_wait(DEV_I2C_CLK_WAIT);}/***************************************************************************** * DEV_I2C_TXDATABYTE - Send Data Byte to I2C Bus *****************************************************************************/Int16 dev_i2c_txdatabyte ( Byte data, Bool Last ){    Int16 retcode;                   /* Bit transmit return code */    Word i;    /* For each bit in the data byte */    for ( i = 0; i < 8; i++ )    {        /* Send the current data bit */        dev_i2c_txdatabit ( data & 0x80 );        /* Shift the data */        data = data << 1;    }    dev_i2c_io_scllow ();    dev_i2c_wait(DEV_I2C_CLK_WAIT);    /* Tri-state the data (SDA) line */    dev_i2c_io_sdatristate ();    dev_i2c_wait(DEV_I2C_CLK_WAIT);    dev_i2c_io_scltristate ();    retcode = DEV_I2C_RETCODE_SUCCESS;    if ( Last == DEV_I2C_NOT_LAST_BYTE )    {        if ( READ_SDA() )        /* If the SDA line is high */        {            retcode = DEV_I2C_RETCODE_NOACK;     /* ... No Ack */        }            dev_i2c_wait(DEV_I2C_CLK_WAIT);        dev_i2c_io_scllow ();    }    else    {        dev_i2c_wait(DEV_I2C_CLK_WAIT);        dev_i2c_io_scllow ();        dev_i2c_wait(DEV_I2C_CLK_WAIT);        dev_i2c_io_scltristate ();        dev_i2c_wait(DEV_I2C_CLK_WAIT);        dev_i2c_txstopbit ();    }    return ( retcode );}/***************************************************************************** * DEV_I2C_TXDATABIT - Send Data Bit To I2C *****************************************************************************/void dev_i2c_txdatabit( Byte bit ){   /* Drive the clock line low */   dev_i2c_io_scllow ();   dev_i2c_wait(DEV_I2C_CLK_WAIT);   /* If the data bit is a 'high' */   if ( bit )   {      dev_i2c_io_sdatristate ();   }   else   {      dev_i2c_io_sdalow ();   }   dev_i2c_wait(DEV_I2C_CLK_WAIT);   dev_i2c_io_scltristate ();   dev_i2c_wait(DEV_I2C_CLK_WAIT);}/***************************************************************************** * DEV_I2C_RXDATABYTE - Receive Data Byte From I2C Slave *****************************************************************************/Int16 dev_i2c_rxdatabyte( Bool Last ){    Byte databyte;                   /* Received data byte */    Int16 databit;                   /* Received data bit */    Word i;    /* For each bit in the data (except the last one) */    for ( i = 0, databyte = 0; i < 7; i++ )    {        /* Receive the current data bit */        databit = dev_i2c_rxdatabit ();        /* Add the current data bit to the accumulation */        databyte |= databit;        /* Shift the data */        databyte = databyte << 1;    }    /* Receive the last bit */    databyte |= dev_i2c_rxdatabit ();    /* Send Ack To Slave */    dev_i2c_io_scllow ();    if ( Last == DEV_I2C_NOT_LAST_BYTE )    {        dev_i2c_io_sdalow ();    }    else    {        dev_i2c_io_sdatristate ();    }        dev_i2c_wait(DEV_I2C_CLK_WAIT);    dev_i2c_io_scltristate ();    dev_i2c_wait(DEV_I2C_CLK_WAIT);    dev_i2c_io_scllow ();   /* Return the received data */   return ( databyte );}/***************************************************************************** * DEV_I2C_RXDATABIT - Receive Data Bit From I2C *****************************************************************************/Int16 dev_i2c_rxdatabit ( void ){    Bool databit;    dev_i2c_wait(DEV_I2C_CLK_WAIT);    dev_i2c_io_scllow ();    dev_i2c_wait(DEV_I2C_CLK_WAIT);    dev_i2c_io_sdatristate ();    dev_i2c_wait(DEV_I2C_CLK_WAIT);    dev_i2c_io_scltristate ();    dev_i2c_wait(DEV_I2C_CLK_WAIT);    databit = dev_i2c_io_sdastate ();    dev_i2c_wait(DEV_I2C_CLK_WAIT);    /* Return the data line state */    return ( ( databit ? DEV_I2C_SIGNAL_HIGH : DEV_I2C_SIGNAL_LOW ) );}/***************************************************************************** * DEV_UIM_RESET - Reset UIM *****************************************************************************/#define UIM_RESET_WAIT          30  /* 0.1 ms */#define CLKGEN_CPUSS_RESET      0xFFFF9020#define RESET_OUT_B             4void dev_uim_reset ( void ){    REG32( CLKGEN_CPUSS_RESET ) |= BIT(RESET_OUT_B);  /* Pull up Reset_Out_B */        dev_i2c_wait(UIM_RESET_WAIT);    REG32( CLKGEN_CPUSS_RESET ) &= ~BIT(RESET_OUT_B); /* Pull down Reset_Out_B */    }/***************************************************************************** * DEV_UIM_WAKEUP - Wake UIM *****************************************************************************/#define UIM_WAKEUP_WAIT         100  /* 0.5 ms */void dev_uim_wakeup ( void ){    dev_i2c_wait(UIM_WAKEUP_WAIT);    DEV_PIO_WRITE_LOW(UIM_WAKEUP_SLAVE);    dev_i2c_wait(UIM_WAKEUP_WAIT);    DEV_PIO_WRITE_HIGH(UIM_WAKEUP_SLAVE);}#endif /* BOARD PHOENIX *//***************************************************************************** * * DEV_I2C_WAIT - Wait * * PURPOSE: *    To Adjust Timing * * PARAMETERS: *    microSec - wait time in microseconds * * RETURNS: *    None * *****************************************************************************/void dev_i2c_wait(Int16 five_microSec){#define FIVE_MICRO_SEC_LOOP 2    Int16 i, j;    for( i=0; i<five_microSec; i++ )    {        for( j=0; j<FIVE_MICRO_SEC_LOOP; j++ )        {        }    }}/***************************************************************************** * * DEV_I2C_BUSSTATE - Get I2C Bus State * * PURPOSE: *    To check the I2C bus for availability. The current SDA and SCL signal *    states are examined as they indicate bus activity. * * PARAMETERS: *    None * * RETURNS: *    DEV_I2C_BUS_IDLE => Bus is ready *    DEV_I2C_BUS_BUSY => Bus is busy * * NOTE: *    Both the SDA and the SCL signals must be de-asserted for the bus to *    to be considered free. * *****************************************************************************/Bool dev_i2c_busstate ( void ){   /* If neither the serial data nor the clock line is being driven */   if ( ( dev_i2c_io_sclstate () == DEV_I2C_SIGNAL_INACTIVE ) &&        ( dev_i2c_io_sdastate () == DEV_I2C_SIGNAL_INACTIVE ) )   {      /* The I2C bus is inactive */      return ( DEV_I2C_BUS_IDLE );   }   else    {      /* The I2C bus is being accessed */      return ( DEV_I2C_BUS_BUSY );   }}#endif /* NOT_HOST_BUILD */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -