?? pca9539.c
字號:
/****************************************************************************/
/* TEXAS INSTRUMENTS PROPRIETARY INFORMATION */
/* */
/* (c) Copyright, Texas Instruments Incorporated, 2006. */
/* All Rights Reserved. */
/* */
/* Property of Texas Instruments Incorporated. Restricted Rights - */
/* Use, duplication, or disclosure is subject to restrictions set */
/* forth in TI's program license agreement and associated documentation. */
/****************************************************************************/
/****************************************************************************/
/* pca9539.c */
/* */
/* 16-Bit IO expander device driver. */
/****************************************************************************/
#include "common.h"
#include "ddp2230_rtos_include.h"
#include "tmr.h"
#include "i2c.h"
#include "ioExpander.h"
/****************************************************/
/* Local constants and definitions. */
/****************************************************/
#define DEVBASE 0x74 /* unshifted i2c device address */
#define PINPERCHIP 16 /* number of IO pins per chip */
#define PINPERREG 8 /* number of IO pins per chip register */
#define CMD_INPORT 0x00 /* read input register */
#define CMD_OUTPORT 0x02 /* read/write output register */
#define CMD_POLARITY 0x04 /* read/write polarity register */
#define CMD_CONFIG 0x06 /* read/write configuration register */
/****************************************************/
/* Local data. */
/****************************************************/
static int32 semTicks; /* semaphore acquisition timeout */
static uint32 semID; /* IO expander i2c semaphore ID */
static I2CPORT iPort; /* ASIC i2c controller port */
static IOXCC _ccTestRtn( int08 APIcc );
/****************************************************************************/
/* Open the IOX device driver. */
/* */
/* All pins are programmed to inputs. This is done to ensure the device is */
/* in a known state during debug. This is not necessary in production code */
/* since a power-up automatically configures the pins. */
/****************************************************************************/
IOXCC ioxdd_open( IOXINITSTRUCT *pInit )
{
iPort = pInit -> xPort; /* i2c port number */
semTicks = TMR_ConvertMSToTicks( pInit -> xTimeout ); /* tick timeout */
I2C_GetSemaphoreID( iPort, &semID); /* i2c semaphore ID */
return IOXCC_PASS;
}
/****************************************************************************/
/* Configure a pca9539 pin. */
/****************************************************************************/
IOXCC ioxdd_configPin( uint08 pinCfg )
{
int08 cc = PASS; /* API completion code */
int08 pin = IOX_GETPIN( pinCfg );
int08 chipNo = pin / PINPERCHIP;
int08 regNo = pin / PINPERREG;
uint08 writeCmd[2]; /* write command/register */
uint32 numTran;
if( RTA_SUCCESS != RTA_SemReserve( semID, semTicks ))
return IOXCC_FAIL;
/****************************************************/
/* Update ioxDirection, */
/****************************************************/
if( IOX_IN == IOX_GETDIR( pinCfg ))
ioxDirection |= ( 0x00000001 << pin ); /* update global direction */
else
ioxDirection &= ~( 0x00000001 << IOX_GETPIN( pinCfg ));
/****************************************************/
/* Update ioxState, */
/****************************************************/
if( IOX_GETVAL( pinCfg ))
ioxState |= ( 0x00000001 << pin );
else
ioxState &= ~( 0x00000001 << pin );
/****************************************************/
/* Update state before direction to avoid glitching */
/* the output on direction change to output, */
/****************************************************/
if( IOX_OUT == IOX_GETDIR( pinCfg ))
{
writeCmd[0] = CMD_OUTPORT | ( regNo & 1 );
writeCmd[1] = (uint08)( ioxState >> ( regNo * PINPERREG ));
cc = I2C_MasterWrite( iPort, ( DEVBASE + chipNo ) << 1, 2,
writeCmd, 0, 0, &numTran );
}
/****************************************************/
/* Set pin direction, */
/****************************************************/
if( PASS )
{
writeCmd[0] = CMD_CONFIG | ( regNo & 1 );
writeCmd[1] = (uint08)( ioxDirection >> ( regNo * PINPERREG ));
cc = I2C_MasterWrite( iPort, ( DEVBASE + chipNo ) << 1, 2,
writeCmd, 0, 0, &numTran );
}
return _ccTestRtn( cc );
}
/****************************************************************************/
/* Drive a pca9539 pin to the indicated state. */
/****************************************************************************/
IOXCC ioxdd_drivePin( int08 pin, BOOL state )
{
int08 cc; /* API completion code */
int08 chipNo = pin / PINPERCHIP;
int08 regNo = pin / PINPERREG;
uint08 writeCmd[2]; /* write command/register */
uint32 numTran;
if( RTA_SUCCESS != RTA_SemReserve( semID, semTicks ))
return IOXCC_FAIL;
/****************************************************/
/* Update ioxState, */
/****************************************************/
if( state )
ioxState |= ( 0x00000001 << pin );
else
ioxState &= ~( 0x00000001 << pin );
/****************************************************/
/* Update state, */
/****************************************************/
writeCmd[0] = CMD_OUTPORT | ( regNo & 1 );
writeCmd[1] = (uint08)( ioxState >> ( regNo * PINPERREG ));
cc = I2C_MasterWrite( iPort, ( DEVBASE + chipNo ) << 1, 2,
writeCmd, 0, 0, &numTran );
return _ccTestRtn( cc );
}
/****************************************************************************/
/* Read a pca9539 pin. */
/****************************************************************************/
IOXCC ioxdd_readPin( int08 pin, BOOL *state )
{
int08 cc; /* API completion code */
int08 chipNo = pin / PINPERCHIP;
int08 regNo = pin / PINPERREG;
uint08 mask = 0x01 << ( pin % PINPERREG );
uint08 writeCmd[2]; /* write command/register */
uint08 readState; /* read state */
uint32 numTran;
if( RTA_SUCCESS != RTA_SemReserve( semID, semTicks ))
return IOXCC_FAIL;
writeCmd[0] = CMD_INPORT | ( regNo & 1 );
cc = I2C_MasterWriteRestartRead( iPort, ( DEVBASE + chipNo ) << 1,
1, writeCmd, 0, 1, &readState, 0, &numTran, &numTran );
*state = ( mask == ( readState & mask ));
return _ccTestRtn( cc );
}
/****************************************************************************/
/* Return device type. */
/****************************************************************************/
IOXTYPE ioxdd_type( void )
{
return IOXTYPE_PCA9539;
}
/****************************************************************************/
/* Test completion code and reset i2c configuration on error. */
/* */
/* This function is called when exiting any function that has reserved the */
/* i2c semaphore. An API completion code is passed in and examined for */
/* error. If an error is seen, the port is reset. */
/****************************************************************************/
static IOXCC _ccTestRtn( int08 APIcc )
{
I2CINIT saveConfig; /*saved i2c configuration */
if( PASS != APIcc ) /* if an API error occurred */
{
I2C_GetConfig( iPort, &saveConfig );
I2C_Reset( iPort );
I2C_SetConfig( iPort, &saveConfig );
}
RTA_SemRelease( semID );
return ( PASS == APIcc ) ? IOXCC_PASS : IOXCC_APIERROR;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -