00001 //////////////////////////////////////////////////////////////////////////////// 00002 // 00003 // Package: botsense 00004 // 00005 // File: proxdev_i2c.c 00006 // 00007 /*! \file 00008 * 00009 * \version $LastChangedDate$ $Rev$ 00010 * 00011 * \brief I2C proxied device operations. 00012 * 00013 * All operations are multi-threaded protected by a mutual exclusion. 00014 * 00015 * \author Robin Knight (robin.knight@roadnarrows.com) 00016 * 00017 * \par Copyright: 00018 * (C) 2007. RoadNarrows LLC. 00019 * (http://www.roadnarrows.com) 00020 * \n All Rights Reserved 00021 */ 00022 // Permission is hereby granted, without written agreement and without 00023 // license or royalty fees, to use, copy, modify, and distribute this 00024 // software and its documentation for any purpose, provided that 00025 // (1) The above copyright notice and the following two paragraphs 00026 // appear in all copies of the source code and (2) redistributions 00027 // including binaries reproduces these notices in the supporting 00028 // documentation. Substantial modifications to this software may be 00029 // copyrighted by their authors and need not follow the licensing terms 00030 // described here, provided that the new terms are clearly indicated in 00031 // all files where they apply. 00032 // 00033 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES 00034 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY 00035 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL 00036 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 00037 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF 00038 // THE POSSIBILITY OF SUCH DAMAGE. 00039 // 00040 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES, 00041 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00042 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN 00043 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO 00044 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 00045 // 00046 //////////////////////////////////////////////////////////////////////////////// 00047 00048 #include <stdio.h> 00049 #include <stdlib.h> 00050 #include <string.h> 00051 00052 #include "rnr/rnrconfig.h" 00053 #include "rnr/log.h" 00054 00055 #include "i2ccom.h" 00056 00057 #include "bsproxy.h" 00058 00059 00060 // --------------------------------------------------------------------------- 00061 // Private Interface 00062 // --------------------------------------------------------------------------- 00063 00064 #ifdef ARCH_armpxa 00065 #define I2C_DEV_NAME_DFT "/dev/i2c/0" ///< default I2C device 00066 #else 00067 #define I2C_DEV_NAME_DFT "/dev/i2c-0" ///< default I2C device 00068 #endif 00069 00070 // 00071 // Data 00072 // 00073 static byte_t i2c_scanned_dev[128]; ///< scanned device vector 00074 static byte_t i2c_scanned_cnt; ///< scanned device count 00075 00076 /*! 00077 * \brief Scanned device callback. 00078 * 00079 * \param pI2C libi2c interface. 00080 * \param addr I2C discovered address 00081 * \param context Scan context (not used). 00082 * 00083 * \return Returns 1 for success. 00084 */ 00085 static int cb_i2c_scan(i2c_t *pI2C, i2c_dev_t addr, void *context) 00086 { 00087 i2c_scanned_dev[i2c_scanned_cnt++] = (byte_t)addr; 00088 return 1; 00089 } 00090 00091 00092 // --------------------------------------------------------------------------- 00093 // Public Interface 00094 // --------------------------------------------------------------------------- 00095 00096 /*! 00097 * \brief Scan I<sup>2</sup>C Bus for attached address. 00098 * 00099 * The addresses of all discovered devices are returned. 00100 * 00101 * \param pProxDev Proxied device. 00102 * \param[out] bufScan Vector of addresses of discovered devices from scan. 00103 * \param sizeBuf Size of scan buffer. 00104 * 00105 * \return Returns number of discovered devices. 00106 */ 00107 int ProxDevI2CScan(BsProxyDev_T *pProxDev, byte_t bufScan[], size_t sizeBuf) 00108 { 00109 i2c_t i2c; 00110 int n; 00111 00112 pthread_mutex_lock(&pProxDev->m_mutDev); 00113 00114 i2c.fd = pProxDev->m_unDevSpec.i2c.m_fd; 00115 i2c.dev = 0; 00116 00117 i2c_scanned_cnt = 0; 00118 00119 i2c_scan(&i2c, cb_i2c_scan, NULL); 00120 00121 for(n=0; n<i2c_scanned_cnt && n<sizeBuf; ++n) 00122 { 00123 bufScan[n] = i2c_scanned_dev[n]; 00124 } 00125 00126 pthread_mutex_unlock(&pProxDev->m_mutDev); 00127 00128 return n; 00129 } 00130 00131 /*! 00132 * \brief Perform a write/read transaction between an I<sup>2</sup>C device. 00133 * 00134 * \param pProxDev Proxied device. 00135 * \param i2cAddr I<sup>2</sup>C address. 00136 * \param bufWrite Write buffer. 00137 * \param countWrite Number of bytes to write from write buffer to device. 00138 * \param[out] bufRead Read buffer. 00139 * \param countRead Number of bytes to read from device to read buffer. 00140 * 00141 * \return Returns number of bytes read on success, <=0 on error. 00142 */ 00143 int ProxDevI2CTrans(BsProxyDev_T *pProxDev, uint_t i2cAddr, 00144 byte_t bufWrite[], size_t countWrite, 00145 byte_t bufRead[], size_t countRead) 00146 { 00147 i2c_t i2c; 00148 int n; 00149 00150 pthread_mutex_lock(&pProxDev->m_mutDev); 00151 00152 i2c.fd = pProxDev->m_unDevSpec.i2c.m_fd; 00153 i2c.dev = i2cAddr; 00154 00155 n = i2c_lltransfer(&i2c, i2cAddr, 00156 (char *)bufWrite, (uint_t)countWrite, 00157 (char *)bufRead, (uint_t)countRead); 00158 00159 if( n <= 0 ) 00160 { 00161 LOGSYSERROR("%s: i2c_lltransfer(0x%02x...)", pProxDev->m_sDevName, i2cAddr); 00162 } 00163 00164 pthread_mutex_unlock(&pProxDev->m_mutDev); 00165 00166 return n; 00167 } 00168 00169 /*! 00170 * \brief Write buffer to an I<sup>2</sup>C device. 00171 * 00172 * \param pProxDev Proxied device. 00173 * \param i2cAddr I<sup>2</sup>C address. 00174 * \param bufWrite Write buffer. 00175 * \param countWrite Number of bytes to write from write buffer to device. 00176 * 00177 * \return Returns number of bytes written on success, <=0 on error. 00178 */ 00179 int ProxDevI2CWrite(BsProxyDev_T *pProxDev, uint_t i2cAddr, 00180 byte_t bufWrite[], size_t countWrite) 00181 { 00182 i2c_t i2c; 00183 int n; 00184 00185 pthread_mutex_lock(&pProxDev->m_mutDev); 00186 00187 i2c.fd = pProxDev->m_unDevSpec.i2c.m_fd; 00188 i2c.dev = 0; 00189 00190 n = i2c_llwrite(&i2c, i2cAddr, (char *)bufWrite, (uint_t)countWrite); 00191 00192 if( n <= 0 ) 00193 { 00194 LOGSYSERROR("%s: i2c_llwrite(0x%02x...)", pProxDev->m_sDevName, i2cAddr); 00195 } 00196 00197 pthread_mutex_unlock(&pProxDev->m_mutDev); 00198 00199 return n; 00200 } 00201 00202 /*! 00203 * \brief Read bytes from an I<sup>2</sup>C device. 00204 * 00205 * \param pProxDev Proxied device. 00206 * \param i2cAddr I<sup>2</sup>C address. 00207 * \param[out] bufRead Read buffer. 00208 * \param countRead Number of bytes to read from device to read buffer. 00209 * 00210 * \return Returns number of bytes read on success, <=0 on error. 00211 */ 00212 int ProxDevI2CRead(BsProxyDev_T *pProxDev, uint_t i2cAddr, 00213 byte_t bufRead[], size_t countRead) 00214 { 00215 i2c_t i2c; 00216 int n; 00217 00218 pthread_mutex_lock(&pProxDev->m_mutDev); 00219 00220 i2c.fd = pProxDev->m_unDevSpec.i2c.m_fd; 00221 i2c.dev = 0; 00222 00223 n = i2c_llread(&i2c, i2cAddr, (char *)bufRead, (uint_t)countRead); 00224 00225 if( n <= 0 ) 00226 { 00227 LOGSYSERROR("%s: i2c_llread(0x%02x...)", pProxDev->m_sDevName, i2cAddr); 00228 } 00229 00230 pthread_mutex_unlock(&pProxDev->m_mutDev); 00231 00232 return n; 00233 }
1.4.6