MakingThings
  • Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

digitalin.c

Go to the documentation of this file.
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.