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

hitechnic-protoboard.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: hitechnic-protoboard.h 133 2013-03-10 15:15:38Z xander $
00009  */
00010 
00011 #ifndef __HTPB_H__
00012 #define __HTPB_H__
00013 /** \file hitechnic-protoboard.h
00014  * \brief HiTechnic Prototype Board driver
00015  *
00016  * hitechnic-protoboard.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 3.59 AND HIGHER. 
00039 
00040  * \author Xander Soldaat (xander_at_botbench.com)
00041  * \date 24 September 2009
00042  * \version 0.9
00043  * \example hitechnic-protoboard-test1.c
00044  * \example hitechnic-protoboard-test2.c
00045  * \example hitechnic-protoboard-test3.c
00046  * \example hitechnic-protoboard-SMUX-test1.c
00047  * \example hitechnic-protoboard-SMUX-test2.c
00048  * \example hitechnic-protoboard-exp1.c
00049  * \example hitechnic-protoboard-exp2.c
00050  * \example hitechnic-protoboard-exp3.c
00051  * \example hitechnic-protoboard-exp4.c
00052  * \example hitechnic-protoboard-exp5.c
00053  * \example hitechnic-protoboard-exp6a.c
00054  * \example hitechnic-protoboard-exp6b.c
00055  * \example hitechnic-protoboard-exp7.c
00056  * \example hitechnic-protoboard-exp8.c
00057  */
00058 
00059 #pragma systemFile
00060 
00061 #ifndef __COMMON_H__
00062 #include "common.h"
00063 #endif
00064 
00065 #define HTPB_I2C_ADDR 0x02      /*!< Protoboard I2C device address */
00066 #define HTPB_OFFSET   0x42
00067 #define HTPB_A0_U     0x00      /*!< Address of upper bits of first ADC, bits 9-2 */
00068 #define HTPB_A0_L     0x01      /*!< Address of lower bits of first ADC, bits 1-0 */
00069 #define HTPB_DIGIN    0x0A      /*!< Address of digital inputs */
00070 #define HTPB_DIGOUT   0x0B      /*!< Address of digital outputs */
00071 #define HTPB_DIGCTRL  0x0C      /*!< Controls direction of digital ports */
00072 #define HTPB_SRATE    0x0D      /*!< Controls sample rate, default set to 10ms */
00073 
00074 tByteArray HTPB_I2CRequest;    /*!< Array to hold I2C command data */
00075 tByteArray HTPB_I2CReply;      /*!< Array to hold I2C reply data */
00076 
00077 ubyte HTPBreadIO(tSensors link, ubyte mask);
00078 bool HTPBwriteIO(tSensors link, ubyte mask);
00079 bool HTPBsetupIO(tSensors link, ubyte mask);
00080 int HTPBreadADC(tSensors link, byte channel, byte width);
00081 bool HTPBreadAllADC(tSensors link, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width);
00082 bool HTPBsetSamplingTime(tSensors link, byte interval);
00083 
00084 #ifdef __HTSMUX_SUPPORT__
00085 ubyte HTPBreadIO(tMUXSensor muxsensor, ubyte mask);
00086 int HTPBreadADC(tMUXSensor muxsensor, byte channel, byte width);
00087 bool HTPBreadAllADC(tMUXSensor muxsensor, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width);
00088 
00089 tConfigParams HTPB_config = {HTSMUX_CHAN_I2C + HTSMUX_CHAN_9V, 14, 0x02, 0x42}; /*!< Array to hold SMUX config data for sensor */
00090 #endif // __HTSMUX_SUPPORT__
00091 
00092 /**
00093  * Read the values of the digital inputs as specified by the mask.
00094  * @param link the HTPB port number
00095  * @param mask the specified digital ports
00096  */
00097 ubyte HTPBreadIO(tSensors link, ubyte mask) {
00098   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00099 
00100   HTPB_I2CRequest[0] = 2;                         // Message size
00101   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;             // I2C Address
00102   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_DIGIN;  // Start digital output read address
00103 
00104   writeI2C(link, HTPB_I2CRequest, HTPB_I2CReply, 1);
00105 
00106   return HTPB_I2CReply[0] & mask;
00107 }
00108 
00109 
00110 /**
00111  * Read the values of the digital inputs as specified by the mask.
00112  * @param muxsensor the SMUX sensor port number
00113  * @param mask the specified digital ports
00114  */
00115 #ifdef __HTSMUX_SUPPORT__
00116 ubyte HTPBreadIO(tMUXSensor muxsensor, ubyte mask) {
00117         memset(HTPB_I2CReply, 0, sizeof(tByteArray));
00118 
00119   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00120     HTSMUXconfigChannel(muxsensor, HTPB_config);
00121 
00122   if (!HTSMUXreadPort(muxsensor, HTPB_I2CReply, 1, HTPB_DIGIN))
00123     return 0;
00124 
00125   return HTPB_I2CReply[0] & mask;
00126 }
00127 #endif // __HTSMUX_SUPPORT__
00128 
00129 
00130 /**
00131  * Write the values the digital outpus as specified by the mask.
00132  * @param link the HTPB port number
00133  * @param mask the specified digital ports
00134  * @return true if no error occured, false if it did
00135  */
00136 bool HTPBwriteIO(tSensors link, ubyte mask) {
00137   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00138 
00139   HTPB_I2CRequest[0] = 3;                         // Message size
00140   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;             // I2C Address
00141   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_DIGOUT; // Start digital output read address
00142   HTPB_I2CRequest[3] = mask;                      // The specified digital ports
00143 
00144 
00145   return writeI2C(link, HTPB_I2CRequest);
00146 }
00147 
00148 
00149 /**
00150  * Configure the ports for input or output according to the mask.
00151  * @param link the HTPB port number
00152  * @param mask the specified digital ports, 0 = input, 1 = output
00153  * @return true if no error occured, false if it did
00154  */
00155 bool HTPBsetupIO(tSensors link, ubyte mask) {
00156   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00157 
00158   HTPB_I2CRequest[0] = 3;                           // Message size
00159   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;               // I2C Address
00160   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_DIGCTRL;  // Start digital input/output control address
00161   HTPB_I2CRequest[3] = mask;                        // The specified digital ports
00162 
00163   return writeI2C(link, HTPB_I2CRequest);
00164 }
00165 
00166 
00167 /**
00168  * Read the value of the specified analogue channel.
00169  * @param link the HTPB port number
00170  * @param channel the specified ADC channel
00171  * @param width the bit width of the result, can be either 8 or 10
00172  * @return the value of the ADC channel, or -1 if an error occurred
00173  */
00174 int HTPBreadADC(tSensors link, byte channel, byte width) {
00175   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00176 
00177   int _adcVal = 0;
00178   HTPB_I2CRequest[0] = 2;                                       // Message size
00179   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;                           // I2C Address
00180   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_A0_U + (channel * 2); // Start digital output read address
00181                                                                     // with channel offset
00182   if (!writeI2C(link, HTPB_I2CRequest, HTPB_I2CReply, 2))
00183     return -1;
00184 
00185   // Convert the bytes into and int
00186   // 1st byte contains bits 9-2 of the channel's value
00187   // 2nd byte contains bits 1-0 of the channel's value
00188   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00189   // If 8 bits is all we want, we just return the first byte and be done with it.
00190   if (width == 8)
00191     _adcVal = HTPB_I2CReply[0];
00192   else
00193     _adcVal = (HTPB_I2CReply[0] * 4) + HTPB_I2CReply[1];
00194 
00195   return _adcVal;
00196 }
00197 
00198 
00199 /**
00200  * Read the value of the specified analogue channel.
00201  * @param muxsensor the SMUX sensor port number
00202  * @param channel the specified ADC channel
00203  * @param width the bit width of the result, can be either 8 or 10
00204  * @return the value of the ADC channel, or -1 if an error occurred
00205  */
00206 #ifdef __HTSMUX_SUPPORT__
00207 int HTPBreadADC(tMUXSensor muxsensor, byte channel, byte width) {
00208   int _adcVal = 0;
00209         memset(HTPB_I2CReply, 0, sizeof(tByteArray));
00210 
00211   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00212     HTSMUXconfigChannel(muxsensor, HTPB_config);
00213 
00214   if (!HTSMUXreadPort(muxsensor, HTPB_I2CReply, 2, HTPB_A0_U + (channel * 2)))
00215     return -1;
00216 
00217   // Convert the bytes into and int
00218   // 1st byte contains bits 9-2 of the channel's value
00219   // 2nd byte contains bits 1-0 of the channel's value
00220   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00221   // If 8 bits is all we want, we just return the first byte and be done with it.
00222   if (width == 8)
00223     _adcVal = HTPB_I2CReply[0];
00224   else
00225     _adcVal = (HTPB_I2CReply[0] * 4) + HTPB_I2CReply[1];
00226 
00227   return _adcVal;
00228 }
00229 #endif // __HTSMUX_SUPPORT__
00230 
00231 
00232 /**
00233  * This function read the value of all of the analogue channels.
00234  * @param link the HTPB port number
00235  * @param adch0 parameter to hold value for ad channel 0
00236  * @param adch1 parameter to hold value for ad channel 1
00237  * @param adch2 parameter to hold value for ad channel 2
00238  * @param adch3 parameter to hold value for ad channel 3
00239  * @param adch4 parameter to hold value for ad channel 4
00240  * @param width the bit width of the result, can be either 8 or 10
00241  * @return true if no error occured, false if it did
00242  */
00243 bool HTPBreadAllADC(tSensors link, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width) {
00244   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00245 
00246   HTPB_I2CRequest[0] = 2;                       // Message size
00247   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;           // I2C Address
00248   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_A0_U; // Start digital output read address
00249 
00250   if (!writeI2C(link, HTPB_I2CRequest, HTPB_I2CReply, 10))
00251     return false;
00252 
00253   // Convert the bytes into and int
00254   // 1st byte contains bits 9-2 of the channel's value
00255   // 2nd byte contains bits 1-0 of the channel's value
00256   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00257   // If 8 bits is all we want, we just return the first byte and be done with it.
00258   if (width == 8) {
00259     adch0 = (int)HTPB_I2CReply[0];
00260     adch1 = (int)HTPB_I2CReply[2];
00261     adch2 = (int)HTPB_I2CReply[4];
00262     adch3 = (int)HTPB_I2CReply[6];
00263     adch4 = (int)HTPB_I2CReply[8];
00264   } else {
00265     adch0 = ((int)HTPB_I2CReply[0] << 2) + (int)HTPB_I2CReply[1];
00266     adch1 = ((int)HTPB_I2CReply[2] << 2) + (int)HTPB_I2CReply[3];
00267     adch2 = ((int)HTPB_I2CReply[4] << 2) + (int)HTPB_I2CReply[5];
00268     adch3 = ((int)HTPB_I2CReply[6] << 2) + (int)HTPB_I2CReply[7];
00269     adch4 = ((int)HTPB_I2CReply[8] << 2) + (int)HTPB_I2CReply[9];
00270   }
00271   return true;
00272 }
00273 
00274 
00275 /**
00276  * This function read the value of all of the analogue channels.
00277  * @param muxsensor the SMUX sensor port number
00278  * @param adch0 parameter to hold value for ad channel 0
00279  * @param adch1 parameter to hold value for ad channel 1
00280  * @param adch2 parameter to hold value for ad channel 2
00281  * @param adch3 parameter to hold value for ad channel 3
00282  * @param adch4 parameter to hold value for ad channel 4
00283  * @param width the bit width of the result, can be either 8 or 10
00284  * @return true if no error occured, false if it did
00285  */
00286 #ifdef __HTSMUX_SUPPORT__
00287 bool HTPBreadAllADC(tMUXSensor muxsensor, int &adch0, int &adch1, int &adch2, int &adch3, int &adch4, byte width) {
00288         memset(HTPB_I2CReply, 0, sizeof(tByteArray));
00289 
00290   if (HTSMUXSensorTypes[muxsensor] != HTSMUXSensorCustom)
00291     HTSMUXconfigChannel(muxsensor, HTPB_config);
00292 
00293   if (!HTSMUXreadPort(muxsensor, HTPB_I2CReply, 10, HTPB_A0_U))
00294     return false;
00295 
00296   // Convert the bytes into and int
00297   // 1st byte contains bits 9-2 of the channel's value
00298   // 2nd byte contains bits 1-0 of the channel's value
00299   // We'll need to shift the 1st byte left by 2 and or 2nd byte onto it.
00300   // If 8 bits is all we want, we just return the first byte and be done with it.
00301   if (width == 8) {
00302     adch0 = (int)HTPB_I2CReply[0];
00303     adch1 = (int)HTPB_I2CReply[2];
00304     adch2 = (int)HTPB_I2CReply[4];
00305     adch3 = (int)HTPB_I2CReply[6];
00306     adch4 = (int)HTPB_I2CReply[8];
00307   } else {
00308     adch0 = ((int)HTPB_I2CReply[0] << 2) + (int)HTPB_I2CReply[1];
00309     adch1 = ((int)HTPB_I2CReply[2] << 2) + (int)HTPB_I2CReply[3];
00310     adch2 = ((int)HTPB_I2CReply[4] << 2) + (int)HTPB_I2CReply[5];
00311     adch3 = ((int)HTPB_I2CReply[6] << 2) + (int)HTPB_I2CReply[7];
00312     adch4 = ((int)HTPB_I2CReply[8] << 2) + (int)HTPB_I2CReply[9];
00313   }
00314   return true;
00315 }
00316 #endif // __HTSMUX_SUPPORT__
00317 
00318 
00319 /**
00320  * This function configured the time between samples. This value is not stored permanently.
00321  * @param link the HTPB port number
00322  * @param interval a value between 4 and 100ms, default is 10ms
00323  * @return true if no error occured, false if it did
00324  */
00325 bool HTPBsetSamplingTime(tSensors link, byte interval) {
00326   memset(HTPB_I2CRequest, 0, sizeof(tByteArray));
00327 
00328   // Correct the value of the interval if it is out of bounds
00329   if (interval < 4) interval = 4;
00330   if (interval > 100) interval = 100;
00331 
00332   HTPB_I2CRequest[0] = 3;                       // Message size
00333   HTPB_I2CRequest[1] = HTPB_I2C_ADDR;           // I2C Address
00334   HTPB_I2CRequest[2] = HTPB_OFFSET + HTPB_A0_U; // Start sampling time address
00335   HTPB_I2CRequest[3] = interval;                // Sample time interval
00336 
00337   // Correct the value of the interval if it is out of bounds
00338   if (interval < 4) HTPB_I2CRequest[3] = 4;
00339   if (interval > 100) HTPB_I2CRequest[3] = 100;
00340 
00341   if (!writeI2C(link, HTPB_I2CRequest))
00342     return false;
00343 
00344   return true;
00345 }
00346 
00347 #endif // __HTPB_H__
00348 
00349 /*
00350  * $Id: hitechnic-protoboard.h 133 2013-03-10 15:15:38Z xander $
00351  */
00352 /* @} */
00353 /* @} */