/* * Copyright (C) 2009 by Rittal GmbH & Co. KG, * Ulrich Prinz All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY EMBEDDED IT AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EMBEDDED IT * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * For additional information see http://www.ethernut.de/ * */ /* * $Log$ * * Revision 1.0 2009/04/13 ulrichprinz * First checkin, new twi driver for pca9555 (currently SAM7X256 is tested * only) * */ #include #include #include #include #include #include #include #include #include #include #include #ifndef I2C_SLA_IOEXP #define I2C_SLA_IOEXP 0x23 #endif #define PCA_PINP 0 /**< PCA Input register offset */ #define PCA_POUT 2 /**< PCA Output register offset */ #define PCA_PINV 4 /**< PCA Polarity inversion register offset */ #define PCA_CONF 6 /**< PCA Configuration register offset */ typedef struct NUT_PACKED_TYPE { uint8_t out[2]; uint8_t pol[2]; uint8_t con[2]; } pca_regs_t; pca_regs_t *pca_ctrl = NULL; /*****************************************************************/ int IOExpInit( void ) /*****************************************************************/ { pca_ctrl = malloc( sizeof( pca_regs_t)); if( pca_ctrl == NULL) return -1; memset( pca_ctrl, 0, sizeof( pca_regs_t)); pca_ctrl->out[0] = 0xff; pca_ctrl->out[1] = 0xff; pca_ctrl->con[0] = 0xff; pca_ctrl->con[1] = 0xff; pca_ctrl->pol[0] = 0x00; pca_ctrl->pol[1] = 0x00; if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT, 1, &pca_ctrl->out[0], 2, 50) == -1) return -1; if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_CONF , 1, &pca_ctrl->con[0], 2, 50) == -1) return -1; if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_PINV , 1, &pca_ctrl->pol[0], 2, 50) == -1) return -1; return 0; } /*****************************************************************/ int IOExpPinConfigSet( int bank, int bit, uint32_t flags) /*****************************************************************/ { bank &= 0xf; if( flags == 0) /* Input */ pca_ctrl->con[bank] |= (1<con[bank] &= ~(1<pol[bank] |= (1<pol[bank] &= ~(1<out[bank], 1, 50) == -1) return -1; if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_CONF+bank, 1, &pca_ctrl->con[bank], 1, 50) == -1) return -1; if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_PINV+bank, 1, &pca_ctrl->pol[bank], 1, 50) == -1) return -1; return 0; } /*****************************************************************/ int IOExpRawWrite ( int bank, int value ) /*****************************************************************/ { bank &= 0x0f; if ( bank > 1 ) return -1; pca_ctrl->out[bank] = value; if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT+bank, 1, &pca_ctrl->out[bank], 1, 50 ) == -1 ) return -1; return 0; } /*****************************************************************/ int IOExpRawRead ( int bank, int *value ) /*****************************************************************/ { bank &= 0x0f; if( bank > 1 ) return -1; if( TwMasterRegRead( I2C_SLA_IOEXP, PCA_PINP+bank, 1, value, 1, 50) == -1) return-1; return 0; } /*****************************************************************/ int IOExpGetBit ( int bank, int bit, int *value ) /*****************************************************************/ { int val; bank &= 0x0f; if( bank > 1 ) return -1; if( TwMasterRegRead( I2C_SLA_IOEXP, PCA_PINP+bank, 1, &val, 1, 50)==-1) return -1; else *value = (( val & ( 1 << bit )) == 0 ) ? 0 : 1; return 0; } /*****************************************************************/ int IOExpSetBitHigh( int bank, int bit ) /*****************************************************************/ { bank &= 0x0f; if( bank > 1 ) return -1; pca_ctrl->out[bank] |= ( 1 << bit ); if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT+bank, 1, &pca_ctrl->out[bank], 1, 50 ) == -1 ) return -1; return 0; } /*****************************************************************/ int IOExpSetBitLow( int bank, int bit ) /*****************************************************************/ { bank &= 0x0f; if( bank > 1 ) return -1; pca_ctrl->out[bank] &= ~( 1 << bit ); if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT+bank, 1, &pca_ctrl->out[bank], 1, 50 ) == -1 ) return -1; return 0; } /*****************************************************************/ int IOExpSetBit( int bank, int bit, int value ) /*****************************************************************/ { if( value) return IOExpSetBitHigh( bank, bit); else return IOExpSetBitLow( bank, bit); }