Mindstorms 3rd Party ROBOTC Drivers RobotC
[Home] [Download] [Submit a bug/suggestion] [ROBOTC Forums] [Blog] [Support this project]

HTPB-driver.h

Go to the documentation of this file.
00001 /*!@addtogroup HiTechnic
00002  * @{
00003  * @defgroup htpb Prototype Board
00004  * HiTechnic Prototype Board
00005  * @{
00006  */
00007 /*
00008  * $Id: HTPB-driver.h 48 2011-02-13 20:35:38Z xander $
00009  */
00010 
00011 #ifndef __HTPB_H__
00012 #define __HTPB_H__
00013 /** \file HTPB-driver.h
00014  * \brief HiTechnic Prototype Board driver
00015  *
00016  * HTPB-driver.h provides an API for the HiTechnic Proto Board.
00017  *
00018  * Changelog:
00019  * - 0.1: Initial release
00020  * - 0.2: Minor bug fixes
00021  * - 0.3: Major rewrite to make use of common.h for common API
00022  * - 0.4: Work around no longer needed and removed, error handling is now done in common.h
00023  * - 0.5: Fixed bugs in HTPBReadIO()
00024  * - 0.6: Added SMUX functions
00025  *        Renamed HTPBReadIO to HTPBreadIO
00026  *        Renamed HTPBWriteIO to HTPBwriteIO
00027  *        Renamed HTPBSetupIO to HTPBsetupIO
00028  *        Renamed HTPBReadADC to HTPBreadADC
00029  *        Renamed HTPBReadAllADC to HTPBreadAllADC
00030  *        Renamed HTPBSetSamplingTime to HTPBsetSamplingTime
00031  * - 0.7: Changed HTPBreadAllADC to use pass by reference instead of tIntArray to reduce memory overhead.<br>
00032  *        Removed HTPB_SMUXData, reuses HTPB_I2CReply to reduce memory overhead.
00033  * - 0.8: Changed type of masks from signed byte to unsigned byte to prevent truncation in ROBOTC 1.9x
00034  * - 0.9: Replaced functions requiring SPORT/MPORT macros
00035  *
00036  * License: You may use this code as you wish, provided you give credit where its due.
00037  *
00038  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 2.00 AND HIGHER.
00039  * \author Xander Soldaat (mightor_at_gmail.com)
00040  * \date 24 September 2009
00041  * \version 0.9
00042  * \example HTPB-test1.c
00043  * \example HTPB-test2.c
00044  * \example HTPB-test3.c
00045  * \example HTPB-SMUX-test1.c
00046  * \example HTPB-SMUX-test2.c
00047  * \example HTPB-exp1.c
00048  * \example HTPB-exp2.c
00049  * \example HTPB-exp3.c
00050  * \example HTPB-exp4.c
00051  * \example HTPB-exp5.c
00052  * \example HTPB-exp6a.c
00053  * \example HTPB-exp6b.c
00054  * \example HTPB-exp7.c
00055  * \example HTPB-exp8.c
00056  */
00057 
00058 #pragma systemFile
00059 
00060 #ifndef __COMMON_H__
00061 #include "common.h"
00062 #endif
00063 
00064 #define HTPB_I2C_ADDR 0x02      /*!< Protoboard I2C device address */
00065 #define HTPB_OFFSET   0x42
00066 #define HTPB_A0_U     0x00      /*!< Address of upper bits of first ADC, bits 9-2 */
00067 #define HTPB_A0_L     0x01      /*!< Address of lower bits of first ADC, bits 1-0 */
00068 #define HTPB_DIGIN    0x0A      /*!< Address of digital inputs */
00069 #define HTPB_DIGOUT   0x0B      /*!< Address of digital outputs */
00070 #define HTPB_DIGCTRL  0x0C      /*!< Controls direction of digital ports */
00071 #define HTPB_SRATE    0x0D      /*!< Controls sample rate, default set to 10ms */
00072 
00073 tByteArray HTPB_I2CRequest;    /*!< Array to hold I2C command data */
00074 tByteArray HTPB_I2CReply;      /*!< Array to hold I2C reply data */
00075 
00076 ubyte HTPBreadIO(tSensors link, ubyte mask);
00077 bool HTPBwriteIO(tSensors link, ubyte mask);
00078 bool HTPBsetupIO(tSensors link, ubyte mask);
00079 int HTPBreadADC(tSensors link, byte channel, byte width);
00080 bool HTPBreadAllADC(tSensors link, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width);
00081 bool HTPBsetSamplingTime(tSensors link, byte interval);
00082 
00083 #ifdef __HTSMUX_SUPPORT__
00084 ubyte HTPBreadIO(tMUXSensor muxsensor, ubyte mask);
00085 int HTPBreadADC(tMUXSensor muxsensor, byte channel, byte width);
00086 bool HTPBreadAllADC(tMUXSensor muxsensor, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width);
00087 
00088 tConfigParams HTPB_config = {HTSMUX_CHAN_I2C + HTSMUX_CHAN_9V, 14, 0x02, 0x42}; /*!< Array to hold SMUX config data for sensor */
00089 #endif // __HTSMUX_SUPPORT__
00090 
00091 /**
00092  * Read the values of the digital inputs as specified by the mask.
00093  * @param link the HTPB port number
00094  * @param mask the specified digital ports
00095  */
00096 ubyte HTPBreadIO(tSensors link, ubyte mask) {
00097   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00098 
00099   HTPB_I2CRequest[0] = 2;                         // Message size
00100   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;             // I2C Address
00101   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_DIGIN;  // Start digital output read address
00102 
00103   writeI2C(link, HTPB_I2CRequest, 1);
00104 
00105   readI2C(link, HTPB_I2CReply, 1);
00106 
00107   return HTPB_I2CReply[0] & mask;
00108 }
00109 
00110 
00111 /**
00112  * Read the values of the digital inputs as specified by the mask.
00113  * @param muxsensor the SMUX sensor port number
00114  * @param mask the specified digital ports
00115  */
00116 #ifdef __HTSMUX_SUPPORT__
00117 ubyte HTPBreadIO(tMUXSensor muxsensor, ubyte mask) {
00118         memset(HTPB_I2CReply, 0, sizeof(tByteArray));
00119 
00120   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00121     HTSMUXconfigChannel(muxsensor, HTPB_config);
00122 
00123   if (!HTSMUXreadPort(muxsensor, HTPB_I2CReply, 1, HTPB_DIGIN))
00124     return 0;
00125 
00126   return HTPB_I2CReply[0] & mask;
00127 }
00128 #endif // __HTSMUX_SUPPORT__
00129 
00130 
00131 /**
00132  * Write the values the digital outpus as specified by the mask.
00133  * @param link the HTPB port number
00134  * @param mask the specified digital ports
00135  * @return true if no error occured, false if it did
00136  */
00137 bool HTPBwriteIO(tSensors link, ubyte mask) {
00138   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00139 
00140   HTPB_I2CRequest[0] = 3;                         // Message size
00141   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;             // I2C Address
00142   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_DIGOUT; // Start digital output read address
00143   HTPB_I2CRequest[3] = mask;                      // The specified digital ports
00144 
00145 
00146   return writeI2C(link, HTPB_I2CRequest, 0);
00147 }
00148 
00149 
00150 /**
00151  * Configure the ports for input or output according to the mask.
00152  * @param link the HTPB port number
00153  * @param mask the specified digital ports, 0 = input, 1 = output
00154  * @return true if no error occured, false if it did
00155  */
00156 bool HTPBsetupIO(tSensors link, ubyte mask) {
00157   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00158 
00159   HTPB_I2CRequest[0] = 3;                           // Message size
00160   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;               // I2C Address
00161   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_DIGCTRL;  // Start digital input/output control address
00162   HTPB_I2CRequest[3] = mask;                        // The specified digital ports
00163 
00164   return writeI2C(link, HTPB_I2CRequest, 0);
00165 }
00166 
00167 
00168 /**
00169  * Read the value of the specified analogue channel.
00170  * @param link the HTPB port number
00171  * @param channel the specified ADC channel
00172  * @param width the bit width of the result, can be either 8 or 10
00173  * @return the value of the ADC channel, or -1 if an error occurred
00174  */
00175 int HTPBreadADC(tSensors link, byte channel, byte width) {
00176   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00177 
00178   int _adcVal = 0;
00179   HTPB_I2CRequest[0] = 2;                                       // Message size
00180   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;                           // I2C Address
00181   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_A0_U + (channel * 2); // Start digital output read address
00182                                                                     // with channel offset
00183   if (!writeI2C(link, HTPB_I2CRequest, 2))
00184     return -1;
00185 
00186   if (!readI2C(link, HTPB_I2CReply, 2))
00187     return -1;
00188 
00189   // Convert the bytes into and int
00190   // 1st byte contains bits 9-2 of the channel's value
00191   // 2nd byte contains bits 1-0 of the channel's value
00192   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00193   // If 8 bits is all we want, we just return the first byte and be done with it.
00194   if (width == 8)
00195     _adcVal = HTPB_I2CReply[0];
00196   else
00197     _adcVal = (HTPB_I2CReply[0] * 4) + HTPB_I2CReply[1];
00198 
00199   return _adcVal;
00200 }
00201 
00202 
00203 /**
00204  * Read the value of the specified analogue channel.
00205  * @param muxsensor the SMUX sensor port number
00206  * @param channel the specified ADC channel
00207  * @param width the bit width of the result, can be either 8 or 10
00208  * @return the value of the ADC channel, or -1 if an error occurred
00209  */
00210 #ifdef __HTSMUX_SUPPORT__
00211 int HTPBreadADC(tMUXSensor muxsensor, byte channel, byte width) {
00212   int _adcVal = 0;
00213         memset(HTPB_I2CReply, 0, sizeof(tByteArray));
00214 
00215   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00216     HTSMUXconfigChannel(muxsensor, HTPB_config);
00217 
00218   if (!HTSMUXreadPort(muxsensor, HTPB_I2CReply, 2, HTPB_A0_U + (channel * 2)))
00219     return -1;
00220 
00221   // Convert the bytes into and int
00222   // 1st byte contains bits 9-2 of the channel's value
00223   // 2nd byte contains bits 1-0 of the channel's value
00224   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00225   // If 8 bits is all we want, we just return the first byte and be done with it.
00226   if (width == 8)
00227     _adcVal = HTPB_I2CReply[0];
00228   else
00229     _adcVal = (HTPB_I2CReply[0] * 4) + HTPB_I2CReply[1];
00230 
00231   return _adcVal;
00232 }
00233 #endif // __HTSMUX_SUPPORT__
00234 
00235 
00236 /**
00237  * This function read the value of all of the analogue channels.
00238  * @param link the HTPB port number
00239  * @param adch0 parameter to hold value for ad channel 0
00240  * @param adch1 parameter to hold value for ad channel 1
00241  * @param adch2 parameter to hold value for ad channel 2
00242  * @param adch3 parameter to hold value for ad channel 3
00243  * @param adch4 parameter to hold value for ad channel 4
00244  * @param width the bit width of the result, can be either 8 or 10
00245  * @return true if no error occured, false if it did
00246  */
00247 bool HTPBreadAllADC(tSensors link, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width) {
00248   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00249 
00250   HTPB_I2CRequest[0] = 2;                       // Message size
00251   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;           // I2C Address
00252   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_A0_U; // Start digital output read address
00253 
00254   if (!writeI2C(link, HTPB_I2CRequest, 10))
00255     return false;
00256 
00257   if(!readI2C(link, HTPB_I2CReply, 10))
00258     return false;
00259 
00260   // Convert the bytes into and int
00261   // 1st byte contains bits 9-2 of the channel's value
00262   // 2nd byte contains bits 1-0 of the channel's value
00263   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00264   // If 8 bits is all we want, we just return the first byte and be done with it.
00265   if (width == 8) {
00266     adch0 = (int)HTPB_I2CReply[0];
00267     adch1 = (int)HTPB_I2CReply[2];
00268     adch2 = (int)HTPB_I2CReply[4];
00269     adch3 = (int)HTPB_I2CReply[6];
00270     adch4 = (int)HTPB_I2CReply[8];
00271   } else {
00272     adch0 = ((int)HTPB_I2CReply[0] << 2) + (int)HTPB_I2CReply[1];
00273     adch1 = ((int)HTPB_I2CReply[2] << 2) + (int)HTPB_I2CReply[3];
00274     adch2 = ((int)HTPB_I2CReply[4] << 2) + (int)HTPB_I2CReply[5];
00275     adch3 = ((int)HTPB_I2CReply[6] << 2) + (int)HTPB_I2CReply[7];
00276     adch4 = ((int)HTPB_I2CReply[8] << 2) + (int)HTPB_I2CReply[9];
00277   }
00278   return true;
00279 }
00280 
00281 
00282 /**
00283  * This function read the value of all of the analogue channels.
00284  * @param muxsensor the SMUX sensor port number
00285  * @param adch0 parameter to hold value for ad channel 0
00286  * @param adch1 parameter to hold value for ad channel 1
00287  * @param adch2 parameter to hold value for ad channel 2
00288  * @param adch3 parameter to hold value for ad channel 3
00289  * @param adch4 parameter to hold value for ad channel 4
00290  * @param width the bit width of the result, can be either 8 or 10
00291  * @return true if no error occured, false if it did
00292  */
00293 #ifdef __HTSMUX_SUPPORT__
00294 bool HTPBreadAllADC(tMUXSensor muxsensor, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width) {
00295         memset(HTPB_I2CReply, 0, sizeof(tByteArray));
00296 
00297   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00298     HTSMUXconfigChannel(muxsensor, HTPB_config);
00299 
00300   if (!HTSMUXreadPort(muxsensor, HTPB_I2CReply, 10, HTPB_A0_U))
00301     return false;
00302 
00303   // Convert the bytes into and int
00304   // 1st byte contains bits 9-2 of the channel's value
00305   // 2nd byte contains bits 1-0 of the channel's value
00306   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00307   // If 8 bits is all we want, we just return the first byte and be done with it.
00308   if (width == 8) {
00309     adch0 = (int)HTPB_I2CReply[0];
00310     adch1 = (int)HTPB_I2CReply[2];
00311     adch2 = (int)HTPB_I2CReply[4];
00312     adch3 = (int)HTPB_I2CReply[6];
00313     adch4 = (int)HTPB_I2CReply[8];
00314   } else {
00315     adch0 = ((int)HTPB_I2CReply[0] << 2) + (int)HTPB_I2CReply[1];
00316     adch1 = ((int)HTPB_I2CReply[2] << 2) + (int)HTPB_I2CReply[3];
00317     adch2 = ((int)HTPB_I2CReply[4] << 2) + (int)HTPB_I2CReply[5];
00318     adch3 = ((int)HTPB_I2CReply[6] << 2) + (int)HTPB_I2CReply[7];
00319     adch4 = ((int)HTPB_I2CReply[8] << 2) + (int)HTPB_I2CReply[9];
00320   }
00321   return true;
00322 }
00323 #endif // __HTSMUX_SUPPORT__
00324 
00325 
00326 /**
00327  * This function configured the time between samples. This value is not stored permanently.
00328  * @param link the HTPB port number
00329  * @param interval a value between 4 and 100ms, default is 10ms
00330  * @return true if no error occured, false if it did
00331  */
00332 bool HTPBsetSamplingTime(tSensors link, byte interval) {
00333   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00334 
00335   // Correct the value of the interval if it is out of bounds
00336   if (interval < 4) interval = 4;
00337   if (interval > 100) interval = 100;
00338 
00339   HTPB_I2CRequest[0] = 3;                       // Message size
00340   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;           // I2C Address
00341   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_A0_U; // Start sampling time address
00342   HTPB_I2CRequest[3] = interval;                // Sample time interval
00343 
00344   // Correct the value of the interval if it is out of bounds
00345   if (interval < 4) HTPB_I2CRequest[3] = 4;
00346   if (interval > 100) HTPB_I2CRequest[3] = 100;
00347 
00348   if (!writeI2C(link, HTPB_I2CRequest, 0))
00349     return false;
00350 
00351   return true;
00352 }
00353 
00354 #endif // __HTPB_H__
00355 
00356 /*
00357  * $Id: HTPB-driver.h 48 2011-02-13 20:35:38Z xander $
00358  */
00359 /* @} */
00360 /* @} */