Nut/OS  4.10.3
API Reference
pca9555.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009 by Rittal GmbH & Co. KG,
00003  * Ulrich Prinz <prinz.u@rittal.de> All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY EMBEDDED IT AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EMBEDDED IT
00022  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log$
00036  *
00037  * Revision 1.0  2009/04/13 ulrichprinz
00038  * First checkin, new twi driver for pca9555 (currently SAM7X256 is tested
00039  * only)
00040  *
00041  */
00042 #include <compiler.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <memdebug.h>
00046 #include <sys/heap.h>
00047 #include <sys/event.h>
00048 
00049 #include <cfg/os.h>
00050 #include <dev/twif.h>
00051 
00052 #include <dev/gpio.h>
00053 #include <cfg/pca9555.h>
00054 #include <dev/pca9555.h>
00055 
00056 #ifndef I2C_SLA_IOEXP
00057 #define I2C_SLA_IOEXP     0x23
00058 #endif
00059 
00060 #define PCA_PINP    0   
00061 #define PCA_POUT    2   
00062 #define PCA_PINV    4   
00063 #define PCA_CONF    6   
00065 typedef struct __attribute__ ((packed))
00066 {
00067     uint8_t out[2];
00068     uint8_t pol[2];
00069     uint8_t con[2];
00070 } pca_regs_t;
00071 
00072 pca_regs_t *pca_ctrl = NULL;
00073 
00074 /*****************************************************************/
00075 int IOExpInit( void )
00076 /*****************************************************************/
00077 {
00078     pca_ctrl = malloc( sizeof( pca_regs_t));
00079     if( pca_ctrl == NULL) return -1;
00080 
00081     memset( pca_ctrl, 0, sizeof( pca_regs_t));
00082     pca_ctrl->out[0] = 0xff;
00083     pca_ctrl->out[1] = 0xff;
00084     pca_ctrl->con[0] = 0xff;
00085     pca_ctrl->con[1] = 0xff;
00086     pca_ctrl->pol[0] = 0x00;
00087     pca_ctrl->pol[1] = 0x00;
00088     
00089     if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT, 1, &pca_ctrl->out[0], 2, 50) == -1)
00090         return -1;
00091 
00092     if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_CONF , 1, &pca_ctrl->con[0], 2, 50) == -1)
00093         return -1;
00094     
00095     if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_PINV , 1, &pca_ctrl->pol[0], 2, 50) == -1)
00096         return -1;
00097 
00098         return 0;
00099 }
00100 
00101 /*****************************************************************/
00102 int IOExpPinConfigSet( int bank, int bit, uint32_t flags)
00103 /*****************************************************************/
00104 {
00105     bank &= 0xf;
00106     
00107     if( flags == 0) /* Input */
00108         pca_ctrl->con[bank] |= (1<<bit);
00109     if( flags & GPIO_CFG_OUTPUT)
00110         pca_ctrl->con[bank] &= ~(1<<bit);
00111     if( flags & GPIO_CFG_INVERT)
00112         pca_ctrl->pol[bank] |= (1<<bit);
00113     if( flags & GPIO_CFG_NORM)
00114         pca_ctrl->pol[bank] &= ~(1<<bit);
00115     
00116     if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT+bank, 1, &pca_ctrl->out[bank], 1, 50) == -1)
00117         return -1;
00118 
00119     if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_CONF+bank, 1, &pca_ctrl->con[bank], 1, 50) == -1)
00120         return -1;
00121     
00122     if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_PINV+bank, 1, &pca_ctrl->pol[bank], 1, 50) == -1)
00123         return -1;
00124 
00125     return 0;      
00126 }
00127 
00128 /*****************************************************************/
00129 int IOExpRawWrite ( int bank, int value )
00130 /*****************************************************************/
00131 {
00132     bank &= 0x0f;
00133         if ( bank > 1 ) return -1;
00134 
00135         pca_ctrl->out[bank] = value;
00136 
00137         if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT+bank, 1, &pca_ctrl->out[bank], 1, 50 ) == -1 )
00138                 return -1;
00139         return 0;
00140 }
00141 
00142 /*****************************************************************/
00143 int IOExpRawRead ( int bank, int *value )
00144 /*****************************************************************/
00145 {
00146     bank &= 0x0f;
00147         if( bank > 1 ) return -1;
00148 
00149         if( TwMasterRegRead( I2C_SLA_IOEXP, PCA_PINP+bank, 1, value, 1, 50) == -1)
00150                 return-1;
00151         return 0;
00152 }
00153 
00154 
00155 /*****************************************************************/
00156 int IOExpGetBit ( int bank, int bit, int *value )
00157 /*****************************************************************/
00158 {
00159         int val;
00160 
00161     bank &= 0x0f;
00162         if( bank > 1 ) return -1;
00163 
00164         if( TwMasterRegRead( I2C_SLA_IOEXP, PCA_PINP+bank, 1, &val, 1, 50)==-1)
00165                 return -1;
00166         else
00167                 *value = (( val & ( 1 << bit )) == 0 ) ? 0 : 1;
00168 
00169         return 0;
00170 }
00171 
00172 /*****************************************************************/
00173 int IOExpSetBitHigh( int bank, int bit )
00174 /*****************************************************************/
00175 {
00176     bank &= 0x0f;
00177         if( bank > 1 ) return -1;
00178 
00179         pca_ctrl->out[bank] |= ( 1 << bit );
00180 
00181         if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT+bank, 1, &pca_ctrl->out[bank], 1, 50 ) == -1 )
00182                 return -1;
00183         return 0;
00184 }
00185 
00186 /*****************************************************************/
00187 int IOExpSetBitLow( int bank, int bit )
00188 /*****************************************************************/
00189 {
00190     bank &= 0x0f;
00191         if( bank > 1 ) return -1;
00192 
00193         pca_ctrl->out[bank] &= ~( 1 << bit );
00194 
00195         if( TwMasterRegWrite( I2C_SLA_IOEXP, PCA_POUT+bank, 1, &pca_ctrl->out[bank], 1, 50 ) == -1 )
00196                 return -1;
00197         return 0;
00198 }
00199 
00200 /*****************************************************************/
00201 int IOExpSetBit( int bank, int bit, int value )
00202 /*****************************************************************/
00203 {
00204     if( value)
00205         return IOExpSetBitHigh( bank, bit);
00206     else
00207         return IOExpSetBitLow( bank, bit);
00208 }
00209