📄 i2cecp.c.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 + -