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

📄 i2cecp.c.inc

📁 用于DRX3973或DRX39系列的芯片的控制
💻 INC
字号:
/******************************************************************************
 * FILENAME: $Id: i2cecp.c.inc,v 1.8 2005/05/04 14:25:11 carlo Exp $
 *
 * DESCRIPTION:
 * Part of bsp_i2c implementation.
 * Low level driver functions.
 *
 * This file uses the interface to the I2CECP device driver.
 *
 * USAGE:
 * Include the file in i2c.c
 * #define BSP_I2C_USE_I2CECP 1    in bsp_i2c_config.h
 *
 * NOTES:
 * $(c) 2004-2005 Micronas GmbH. All rights reserved.
 *
 * This software and related documentation (the 'Software') are intellectual
 * property owned by Micronas and are copyright of Micronas, unless specifically
 * noted otherwise.
 *
 * Any use of the Software is permitted only pursuant to the terms of the
 * license agreement, if any, which accompanies, is included with or applicable
 * to the Software ('License Agreement') or upon express written consent of
 * Micronas. Any copying, reproduction or redistribution of the Software in
 * whole or in part by any means not in accordance with the License Agreement
 * or as agreed in writing by Micronas is expressly prohibited.
 *
 * THE SOFTWARE IS WARRANTED, IF AT ALL, ONLY ACCORDING TO THE TERMS OF THE
 * LICENSE AGREEMENT. EXCEPT AS WARRANTED IN THE LICENSE AGREEMENT THE SOFTWARE
 * IS DELIVERED 'AS IS' AND MICRONAS HEREBY DISCLAIMS ALL WARRANTIES AND
 * CONDITIONS WITH REGARD TO THE SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
 * AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIT
 * ENJOYMENT, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL
 * PROPERTY OR OTHER RIGHTS WHICH MAY RESULT FROM THE USE OR THE INABILITY
 * TO USE THE SOFTWARE.
 *
 * IN NO EVENT SHALL MICRONAS BE LIABLE FOR INDIRECT, INCIDENTAL, CONSEQUENTIAL,
 * PUNITIVE, SPECIAL OR OTHER DAMAGES WHATSOEVER INCLUDING WITHOUT LIMITATION,
 * DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
 * INFORMATION, AND THE LIKE, ARISING OUT OF OR RELATING TO THE USE OF OR THE
 * INABILITY TO USE THE SOFTWARE, EVEN IF MICRONAS HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES, EXCEPT PERSONAL INJURY OR DEATH RESULTING FROM
 * MICRONAS' NEGLIGENCE.                                                        $
 *
 * AUTHOR:
 * Martin Sinot
 *
 *****************************************************************************/

#if DRXDEBUG
#define DRXFPrint(__a) fprintf __a
#else
#define DRXFPrint(__a)
#endif
#include <windows.h>
#include <malloc.h>
#include "bsp_i2c.h"
#include "i2cecp.h"


int DRX_I2C_Error_g;
static int DRX_I2C_Initialized_g = FALSE;

BOOL I2CECP_Init      (void);
void I2CECP_Terminate (void);

/******************************
 *
 * DRXStatus_t DRXBSP_I2C_Init (void)
 *
 * Prepares the platform's I2C subsystem for usage. Must be called before any
 * other I2C function is called.
 *
 * Output:
 * - DRX_STS_OK     I2C subsystem initialised
 * - DRX_STS_ERROR  something wrong
 *
 ******************************/

DRXStatus_t DRXBSP_I2C_Init (void)
{
    int   drv_ver;
    char *drv_str;
#if DRXDEBUG
    int   drv_cfg;
    int   drv_mod;
#endif

    DRX_I2C_Error_g = I2CECP_STATUS_OK;

    if (DRX_I2C_Initialized_g)
    {
        return DRX_STS_OK;  /* already initialized - no error */
    }


    if (!I2CECP_Init ())
    {
        DRXFPrint ((stderr, "SP7_I2C_Init: I2CECP DLL not found\n"));
        DRX_I2C_Error_g = I2CECP_STATUS_ILLEGAL_COMMAND;
        return DRX_STS_ERROR;
    }
    if (!I2CECP_IsPresent())
    {
        DRXFPrint ((stderr, "SP7_SPI2C_Init: _IsPresent: not present.\n"));
        DRX_I2C_Error_g = I2CECP_STATUS_ILLEGAL_COMMAND;
        return DRX_STS_ERROR;
    }

    drv_ver = I2CECP_GetVersion();
    if (drv_ver < 0)
    {
        DRXFPrint ((stderr, "SP7_SPI2C_Init: _GetVersion failed.\n"));
        DRX_I2C_Error_g = I2CECP_STATUS_ILLEGAL_COMMAND;
        return DRX_STS_ERROR;
    }

    drv_str = I2CECP_GetVersionString();
    if (!drv_str)
    {
        DRXFPrint ((stderr, "SP7_SPI2C_Init: _GetVersionString failed.\n"));
        DRX_I2C_Error_g = I2CECP_STATUS_ILLEGAL_COMMAND;
        return DRX_STS_ERROR;
    }

    if (I2CECP_AbortECP() != I2CECP_STATUS_OK)
    {
        DRXFPrint ((stderr, "SP7_SPI2C_Init: _AbortECP failed.\n"));
        DRX_I2C_Error_g = I2CECP_STATUS_ILLEGAL_COMMAND;
        return DRX_STS_ERROR;
    }

    if (I2CECP_CloseECP() != I2CECP_STATUS_OK)
    {
        DRXFPrint ((stderr, "SP7_SPI2C_Init: _CloseECP failed.\n"));
        DRX_I2C_Error_g = I2CECP_STATUS_ILLEGAL_COMMAND;
        return DRX_STS_ERROR;
    }

#if DRXDEBUG
    drv_cfg = I2CECP_Config();
    drv_mod = I2CECP_GetMode();

    DRXFPrint ((stderr, "\n\n"));
    DRXFPrint ((stderr, "SP7_SPI2C_Init: Driver:  %d.%d present. (%s)\n",
                    ((drv_ver>>8) & 0xff), (drv_ver & 0xff), drv_str));

    DRXFPrint ((stderr, "SP7_SPI2C_Init: Config: %s%s%s%s.\n",
                    ((drv_cfg & DRIVER_HAS_ECP) ? " may use Ecp" : ""),
                    ((drv_cfg & DRIVER_HAS_INT) ? " uses Irq's" : ""),
                    ((drv_cfg & DRIVER_HAS_DMA) ? " uses Dma" : ""),
                    ((drv_cfg & DRIVER_PIO_FORCED) ? " uses programmed IO" : "")));

    DRXFPrint ((stderr, "SP7_SPI2C_Init:   Mode: %s\n",
                    (drv_mod == DM_I2CECP ?   " Pro-kit ECP+I2C pinning" :
                    (drv_mod == DM_Paraclip ? " Reference kit I2C paraclip pinning" :
                                             " Unknown mode"))));

    DRXFPrint ((stderr, "SP7_SPI2C_Init: Timing: %d ms.\n", I2CECP_GetDelay()));
    DRXFPrint ((stderr, "\n\n"));
#endif

    I2CECP_ResetI2C();

    DRX_I2C_Initialized_g = TRUE;
    return DRX_STS_OK;
}


/******************************
 *
 * DRXStatus_t DRXBSP_I2C_Term (void)
 *
 * Shuts down the I2C subsystem of the target platform. After this, I2C
 * functions must no longer be called, until the system is initialised
 * again.
 *
 * Output:
 * - DRX_STS_OK     I2C subsystem shut down
 * - DRX_STS_ERROR  something wrong
 *
 ******************************/

DRXStatus_t DRXBSP_I2C_Term (void)
{
    DRX_I2C_Error_g = I2CECP_STATUS_OK;
    DRX_I2C_Initialized_g = FALSE;
    I2CECP_Terminate ();
    return DRX_STS_OK;
}


/******************************
 *
 * DRXStatus_t DRXBSP_I2C_WriteRead  (
 *             pI2CDeviceAddr_t wDevAddr,     -- Device to write to
 *             u16_t            wcount,       -- nr of bytes to write
 *             pu8_t            wdata,        -- the data to write
 *             pI2CDeviceAddr_t rDevAddr,     -- Device to read from
 *             u16_t            rcount,       -- nr of bytes to read
 *             pu8_t            rdata)        -- buffer receiving the data
 *
 * Writes data to I2C device, then receives back specified number of bytes.
 * This function can be used to only write or only read, by setting
 * wDevAddr or rDevAddr to NULL.
 * Make sure that rdata is large enough to receive the requested data.
 *
 * Output:
 * - DRX_STS_OK           data successfully transferred
 *                        in that case: data received is in rdata
 * - DRX_STS_INVALID_ARG  invalid arguments passed to this function
 * - DRX_STS_ERROR        something wrong in the transfer
 *
 ******************************/

DRXStatus_t DRXBSP_I2C_WriteRead( pI2CDeviceAddr_t wDevAddr,
                                  u16_t            wCount,
                                  pu8_t            wData,
                                  pI2CDeviceAddr_t rDevAddr,
                                  u16_t            rCount,
                                  pu8_t            rData)
{
    unsigned bufsz = 0, wbuf, rbuf;

    pu8_t buf, bufp;

    /* Check init BSP */
    if ( DRX_I2C_Initialized_g == FALSE )
    {
        DRX_I2C_Error_g = I2CECP_STATUS_NOT_INITIALIZED;
        return (DRX_STS_ERROR);
    }

    if (wDevAddr)
    {
        /* Buffer error! */
        if (!wData && wCount)
        {
            return DRX_STS_INVALID_ARG;
        }
        /*       S   addr wdata    writes                       P */
        bufsz += 1 + 4  + wCount + ((wCount + 254) / 255) * 2 + 1;
    }
    if (rDevAddr)
    {
        /* Buffer error! */
        if (!rData && rCount)
        {
            return DRX_STS_INVALID_ARG;
        }
        /*       S   addr rdata                        P */
        bufsz += 1 + 3  + ((rCount + 254) / 255) * 2 + 1;
    }
    if (!bufsz)
    {
        /* Nothing to do! */
        return DRX_STS_INVALID_ARG;
    }
    buf = bufp = (pu8_t) malloc (bufsz);
    if (!buf)
    {
        /* Buffer error! */
        return DRX_STS_INVALID_ARG;
    }
    /* Always begin with start condition */
    *bufp++ = I2C_Start;

    /* Write data (possibly address only) */
    if (wDevAddr)
    {
        *bufp++ = I2C_WriteN;
        if (IS_I2C_10BIT (wDevAddr->i2cAddr))
        {
            *bufp++ = 2;
            *bufp++ = (u8_t) wDevAddr->i2cAddr & 0xFE;
            *bufp++ = (u8_t) (wDevAddr->i2cAddr >> 8);
        }
        else
        {
            *bufp++ = 1;
            *bufp++ = (u8_t) wDevAddr->i2cAddr & 0xFE;
        }
        for (wbuf = 0; wbuf < wCount; wbuf += 255)
        {
            unsigned todo = wCount - wbuf;
            if (todo > 255)
            {
                todo = 255;
            }
            *bufp++ = I2C_WriteN;
            *bufp++ = todo;
            memcpy (bufp, &wData[wbuf], todo);
            bufp += todo;
        }
        if (rDevAddr)
        {
            *bufp++ = I2C_RepStart;
        }
    }

    /* Read data (possible address only) */
    if (rDevAddr)
    {
        *bufp++ = I2C_WriteN;
        *bufp++ = 1;            /* 10-bit addresses only write the first byte */
        *bufp++ = (u8_t) rDevAddr->i2cAddr | 1;
        for (rbuf = 0; rbuf < rCount; rbuf += 255)
        {
            unsigned todo = rCount - rbuf;
            if (todo > 255)
            {
                todo = 255;
            }
            *bufp++ = I2C_ReadN;
            *bufp++ = todo;
        }
    }

    /* Always end with stop condition */
    *bufp++ = I2C_Stop;

    /* Send I2C transaction */
    DRX_I2C_Error_g = I2CECP_I2C (buf,
                                  bufp - buf,
                                  (rDevAddr ? rData  : NULL),
                                  (rDevAddr ? rCount : 0));
    free (buf);
    if ( DRX_I2C_Error_g < 0 )
    {
        return DRX_STS_ERROR;
    }
    return DRX_STS_OK;
}

/******************************
 *
 * char* DRXBSP_I2C_ErrorText()
 *
 * Returns a human readable error.
 * Counter part of numerical DRX_I2C_Error_g.
 *
 * Output:
 * -Pointer to string containing description of the error.
 *
 ******************************/
char* DRXBSP_I2C_ErrorText( void )
{
   switch (DRX_I2C_Error_g)
   {
      case I2CECP_STATUS_OK:
         return "I2CECP_STATUS_OK";
         break;
      case I2CECP_STATUS_IO_PENDING:
         return "I2CECP_STATUS_IO_PENDING";
         break;
      case I2CECP_STATUS_ILLEGAL_COMMAND:
         return "I2CECP_STATUS_ILLEGAL_COMMAND";
         break;
      case I2CECP_STATUS_I2C_BUSY:
         return "I2CECP_STATUS_I2C_BUSY";
         break;
      case I2CECP_STATUS_I2C_TIMEOUT:
         return "I2CECP_STATUS_I2C_TIMEOUT";
         break;
      case I2CECP_STATUS_I2C_NAK:
         return "I2CECP_STATUS_I2C_NAK";
         break;
      case I2CECP_STATUS_LOCKED:
         return "I2CECP_STATUS_LOCKED";
         break;
      case I2CECP_STATUS_CANCELLED:
         return "I2CECP_STATUS_CANCELLED";
         break;
      case I2CECP_STATUS_NOT_INITIALIZED:
         return "I2CECP_STATUS_NOT_INITIALIZED";
         break;
      default:
         return "Unknown error";
         break;
   }

   return "Very unknown error!";
}

⌨️ 快捷键说明

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