00001 /********************************************************************************* 00002 00003 Copyright 2006-2008 MakingThings 00004 00005 Licensed under the Apache License, 00006 Version 2.0 (the "License"); you may not use this file except in compliance 00007 with the License. You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software distributed 00012 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00013 CONDITIONS OF ANY KIND, either express or implied. See the License for 00014 the specific language governing permissions and limitations under the License. 00015 00016 *********************************************************************************/ 00017 00018 // MakingThings - Make Controller Kit - 2006 00019 00020 /** \file digitalin.c 00021 Digital In. 00022 Library of functions for the Make Application Board's Digital Output section. 00023 */ 00024 00025 #include "io.h" 00026 #include "digitalin.h" 00027 #include "analogin.h" 00028 #include "config.h" 00029 00030 #include "AT91SAM7X256.h" 00031 00032 // This number is 4 because the a/d converter is sitting on the IO's 4 - 7 00033 // this means that we'll need to use the A/d converter to get the digital value. 00034 // Crazy, eh? And slow. Whew. 00035 #define DIGITALIN_COUNT 8 00036 00037 //#if ( APPBOARD_VERSION == 90 ) 00038 #define DIGITALIN_0_IO IO_PB27 00039 #define DIGITALIN_1_IO IO_PB28 00040 #define DIGITALIN_2_IO IO_PB29 00041 #define DIGITALIN_3_IO IO_PB30 00042 #define DIGITALIN_4_IO -4 00043 #define DIGITALIN_5_IO -5 00044 #define DIGITALIN_6_IO -6 00045 #define DIGITALIN_7_IO -7 00046 //#endif 00047 00048 static int DigitalIn_Start( int index ); 00049 static int DigitalIn_Stop( int index ); 00050 00051 static int DigitalIn_GetIo( int index ); 00052 00053 static int DigitalIn_users[ DIGITALIN_COUNT ]; 00054 00055 00056 /** \defgroup DigitalIn Digital Inputs 00057 * Read the 8 inputs on the Make Controller as digital values - 1 (on) or 0 (off). 00058 The 8 inputs can be either read as digital inputs by DigitalIn or as \ref AnalogIn. 00059 Because inputs 4-7 are actually AnalogIn lines, there's no performance gain to reading 00060 those as DigitalIns. 00061 * \ingroup Libraries 00062 * @{ 00063 */ 00064 00065 /** 00066 Sets whether the specified Digital In is active. 00067 @param index An integer specifying which Digital In (0-7). 00068 @param state An integer specifying the state - 1 (active) or 0 (inactive). 00069 @return Zero on success. 00070 00071 \b Example 00072 \code 00073 // Enable DigitalIn 3 00074 DigitalIn_SetActive(3, 1); 00075 \endcode 00076 */ 00077 int DigitalIn_SetActive( int index, int state ) 00078 { 00079 if ( index < 0 || index >= DIGITALIN_COUNT ) 00080 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00081 00082 if ( state ) 00083 return DigitalIn_Start( index ); 00084 else 00085 return DigitalIn_Stop( index ); 00086 } 00087 00088 /** 00089 Returns the active state of the Digital In. 00090 @param index An integer specifying which Digital In (0-7). 00091 @return Zero if inactive, non-zero if active. 00092 00093 \b Example 00094 \code 00095 if( DigitalIn_GetActive(3) ) 00096 { 00097 // DigitalIn 3 is active 00098 } 00099 else 00100 { 00101 // DigitalIn 3 is inactive 00102 } 00103 \endcode 00104 */ 00105 int DigitalIn_GetActive( int index ) 00106 { 00107 if ( index < 0 || index >= DIGITALIN_COUNT ) 00108 return false; 00109 return DigitalIn_users[ index ] > 0; 00110 } 00111 00112 /** 00113 Read the value of a Digital Input on the MAKE Application Board. 00114 If the voltage on the input is greater than ~0.6V, the Digital In will read high. 00115 @param index An integer specifying which Digital In (0-7). 00116 @return Non-zero when high, 0 when low 00117 00118 \b Example 00119 \code 00120 if( DigitalIn_GetValue(5) ) 00121 { 00122 // DigitalIn 5 is high 00123 } 00124 else 00125 { 00126 // DigitalIn 5 is low 00127 } 00128 \endcode 00129 */ 00130 int DigitalIn_GetValue( int index ) 00131 { 00132 if ( index < 0 || index >= DIGITALIN_COUNT ) 00133 return 0; 00134 00135 if ( DigitalIn_users[ index ] < 1 ) 00136 { 00137 int status = DigitalIn_Start( index ); 00138 if ( status != CONTROLLER_OK ) 00139 return status; 00140 } 00141 00142 int io = DigitalIn_GetIo( index ); 00143 00144 if ( io >= 0 ) 00145 return Io_GetValue( io ); 00146 else 00147 return AnalogIn_GetValue( -io ) > 200; 00148 } 00149 00150 /** @} 00151 */ 00152 00153 int DigitalIn_Start( int index ) 00154 { 00155 int status; 00156 00157 if ( index < 0 || index >= DIGITALIN_COUNT ) 00158 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00159 00160 if ( DigitalIn_users[ index ]++ == 0 ) 00161 { 00162 int io = DigitalIn_GetIo( index ); 00163 00164 if ( io > 0 ) 00165 { 00166 status = Io_Start( io, false ); 00167 if ( status != CONTROLLER_OK ) 00168 { 00169 DigitalIn_users[ index ]--; 00170 return CONTROLLER_ERROR_CANT_LOCK; 00171 } 00172 00173 // Got it, now set the io up right 00174 Io_SetPio( io, true ); 00175 Io_SetDirection( io, IO_INPUT ); 00176 } 00177 else 00178 return AnalogIn_SetActive( -io, 1 ); 00179 } 00180 00181 return CONTROLLER_OK; 00182 } 00183 00184 int DigitalIn_Stop( int index ) 00185 { 00186 if ( index < 0 || index >= DIGITALIN_COUNT ) 00187 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00188 00189 if ( DigitalIn_users[ index ] < 1 ) 00190 return CONTROLLER_ERROR_TOO_MANY_STOPS; 00191 00192 if ( --DigitalIn_users[ index ] == 0 ) 00193 { 00194 int io = DigitalIn_GetIo( index ); 00195 Io_Stop( io ); 00196 } 00197 return CONTROLLER_OK; 00198 } 00199 00200 int DigitalIn_GetIo( int index ) 00201 { 00202 int io = -1; 00203 switch ( index ) 00204 { 00205 case 0: 00206 io = DIGITALIN_0_IO; 00207 break; 00208 case 1: 00209 io = DIGITALIN_1_IO; 00210 break; 00211 case 2: 00212 io = DIGITALIN_2_IO; 00213 break; 00214 case 3: 00215 io = DIGITALIN_3_IO; 00216 break; 00217 case 4: 00218 io = DIGITALIN_4_IO; 00219 break; 00220 case 5: 00221 io = DIGITALIN_5_IO; 00222 break; 00223 case 6: 00224 io = DIGITALIN_6_IO; 00225 break; 00226 case 7: 00227 io = DIGITALIN_7_IO; 00228 break; 00229 } 00230 return io; 00231 } 00232 00233 #ifdef OSC 00234 00235 /** \defgroup DigitalInOSC Digital In - OSC 00236 Read the Application Board's Digital Inputs via OSC. 00237 \ingroup OSC 00238 00239 \section devices Devices 00240 There are 8 Digital Inputs on the Make Application Board, numbered <b>0 - 7</b>. 00241 00242 The Digital Ins are physically the same as the Analog Ins - they're on the same 00243 signal lines and the same connectors - but reading them as Digital Ins is 00244 slightly more efficient/quicker. 00245 00246 If the voltage on the input is greater than <b>~0.6V</b>, the Digital In will read high. 00247 00248 \section properties Properties 00249 The Digital Ins have two properties 00250 - value 00251 - active 00252 00253 \par Value 00254 The \b value property corresponds to the on/off value of a Digital In. 00255 Because you can only ever \b read the value of an input, you'll never 00256 want to include an argument at the end of your OSC message to read the value. 00257 To read the third Digital In, send the message 00258 \verbatim /digitalin/2/value \endverbatim 00259 00260 \par Active 00261 The \b active property corresponds to the active state of a Digital In. 00262 If a Digital In is set to be active, no other tasks will be able to 00263 read from it as an Analog In. If you're not seeing appropriate 00264 responses to your messages to the Digital In, check the whether it's 00265 locked by sending a message like 00266 \verbatim /digitalin/0/active \endverbatim 00267 \par 00268 You can set the active flag by sending 00269 \verbatim /digitalin/0/active 0 \endverbatim 00270 */ 00271 00272 #include "osc.h" 00273 #include "string.h" 00274 #include "stdio.h" 00275 00276 // Need a list of property names 00277 // MUST end in zero 00278 static char* DigitalInOsc_Name = "digitalin"; 00279 static char* DigitalInOsc_PropertyNames[] = { "active", "value", 0 }; // must have a trailing 0 00280 00281 int DigitalInOsc_PropertySet( int index, int property, int value ); 00282 int DigitalInOsc_PropertyGet( int index, int property ); 00283 00284 // Returns the name of the subsystem 00285 const char* DigitalInOsc_GetName( ) 00286 { 00287 return DigitalInOsc_Name; 00288 } 00289 00290 // Now getting a message. This is actually a part message, with the first 00291 // part (the subsystem) already parsed off. 00292 int DigitalInOsc_ReceiveMessage( int channel, char* message, int length ) 00293 { 00294 int status = Osc_IndexIntReceiverHelper( channel, message, length, 00295 DIGITALIN_COUNT, DigitalInOsc_Name, 00296 DigitalInOsc_PropertySet, DigitalInOsc_PropertyGet, 00297 DigitalInOsc_PropertyNames ); 00298 00299 00300 if ( status != CONTROLLER_OK ) 00301 return Osc_SendError( channel, DigitalInOsc_Name, status ); 00302 return CONTROLLER_OK; 00303 } 00304 00305 // Set the index LED, property with the value 00306 int DigitalInOsc_PropertySet( int index, int property, int value ) 00307 { 00308 switch ( property ) 00309 { 00310 case 0: 00311 DigitalIn_SetActive( index, value ); 00312 break; 00313 } 00314 return CONTROLLER_OK; 00315 } 00316 00317 // Get the index LED, property 00318 int DigitalInOsc_PropertyGet( int index, int property ) 00319 { 00320 int value = 0; 00321 switch ( property ) 00322 { 00323 case 0: 00324 value = DigitalIn_GetActive( index ); 00325 break; 00326 case 1: 00327 value = DigitalIn_GetValue( index ); 00328 break; 00329 } 00330 00331 return value; 00332 } 00333 00334 #endif
The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.