- 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.