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

digitalout.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 digitalout.c  
00021   Library of functions for the Make Application Board's Digital Outputs.
00022 */
00023 
00024 #include "io.h"
00025 #include "digitalout.h"
00026 #include "config.h"
00027 
00028 #include "AT91SAM7X256.h"
00029 
00030 #define DIGITALOUT_COUNT 8 
00031 
00032 #if ( APPBOARD_VERSION == 50 )
00033   #define DIGITALOUT_0_IO IO_PA02
00034   #define DIGITALOUT_1_IO IO_PA02
00035   #define DIGITALOUT_2_IO IO_PA02
00036   #define DIGITALOUT_3_IO IO_PA02
00037   #define DIGITALOUT_4_IO IO_PA02
00038   #define DIGITALOUT_5_IO IO_PA02
00039   #define DIGITALOUT_6_IO IO_PA02
00040   #define DIGITALOUT_7_IO IO_PA02
00041   #define DIGITALOUT_01_ENABLE IO_PA02
00042   #define DIGITALOUT_23_ENABLE IO_PA02
00043   #define DIGITALOUT_45_ENABLE IO_PA02
00044   #define DIGITALOUT_67_ENABLE IO_PA02
00045 #endif
00046 
00047 #if ( APPBOARD_VERSION == 90 )
00048   #define DIGITALOUT_0_IO IO_PB23
00049   #define DIGITALOUT_1_IO IO_PA26
00050   #define DIGITALOUT_2_IO IO_PA25
00051   #define DIGITALOUT_3_IO IO_PB25
00052   #define DIGITALOUT_4_IO IO_PA02
00053   #define DIGITALOUT_5_IO IO_PA06
00054   #define DIGITALOUT_6_IO IO_PA05
00055   #define DIGITALOUT_7_IO IO_PA24
00056   #define DIGITALOUT_01_ENABLE IO_PB19
00057   #define DIGITALOUT_23_ENABLE IO_PB20
00058   #define DIGITALOUT_45_ENABLE IO_PB21
00059   #define DIGITALOUT_67_ENABLE IO_PB22
00060 #endif
00061 #if ( APPBOARD_VERSION == 95 || APPBOARD_VERSION == 100 )
00062 
00063   #define DIGITALOUT_0_IO IO_PA24
00064   #define DIGITALOUT_1_IO IO_PA05
00065   #define DIGITALOUT_2_IO IO_PA06
00066   #define DIGITALOUT_3_IO IO_PA02
00067   #define DIGITALOUT_4_IO IO_PB25
00068   #define DIGITALOUT_5_IO IO_PA25
00069   #define DIGITALOUT_6_IO IO_PA26
00070   #define DIGITALOUT_7_IO IO_PB23
00071   #define DIGITALOUT_01_ENABLE IO_PB19
00072   #define DIGITALOUT_23_ENABLE IO_PB20
00073   #define DIGITALOUT_45_ENABLE IO_PB21
00074   #define DIGITALOUT_67_ENABLE IO_PB22
00075 #endif
00076 
00077 static int DigitalOut_Start( int index );
00078 static int DigitalOut_Stop( int index );
00079 
00080 int DigitalOut_GetIo( int index );
00081 int DigitalOut_GetEnableIo( int enableIndex );
00082 
00083 int DigitalOut_users[ DIGITALOUT_COUNT ];
00084 int DigitalOut_enableUsers[ DIGITALOUT_COUNT >> 1 ];
00085 
00086 /** \defgroup DigitalOut Digital Outputs
00087 * The Digital Out subsystem sends digital values out the 8 high current outputs - 1 (on) or 0 (off).
00088   
00089   If you've previously used any of the other systems on the outputs (steppers, motors, etc.), you'll need
00090   to set them to \b inactive to unlock the IO lines and use the Digital Outs.
00091   
00092   See the <a href="http://www.makingthings.com/documentation/tutorial/application-board-overview/digital-outputs">
00093   Digital Out section</a> of the Application Board overview for more details.
00094 * \ingroup Libraries
00095 * @{
00096 */
00097 
00098 /**
00099   Enable or disable a DigitalOut.
00100   This is automatically called, setting the channel active, the first time DigitalOut_SetValue() is called.
00101   However, the channel must be explicitly set to inactive in order for any other devices to access the I/O lines. 
00102   @param index An integer specifying which Digital Out (0-7).
00103   @param state An integer specifying the state - on (1) or off (0).
00104   @return Zero on success.
00105   
00106   \b Example
00107   \code
00108   // Enable DigitalOut 6
00109   DigitalOut_SetActive( 6, 1 );
00110   \endcode
00111 */
00112 int DigitalOut_SetActive( int index, int state )
00113 {
00114   if ( index < 0 || index >= DIGITALOUT_COUNT )
00115     return CONTROLLER_ERROR_ILLEGAL_INDEX;
00116 
00117   if ( state )
00118     return DigitalOut_Start( index );
00119   else
00120     return DigitalOut_Stop( index );
00121 }
00122 
00123 /**
00124   Read whether a DigitalOut is active.
00125   @param index An integer specifying which Digital Out (0-7).
00126   @return Nonzero when active, 0 when inactive
00127   
00128   \b Example
00129   \code
00130   if( DigitalOut_GetActive( 5 ) )
00131   {
00132     // DigitalOut 5 is active
00133   }
00134   else
00135   {
00136     // DigitalOut 5 is inactive
00137   }
00138   \endcode
00139 */
00140 int DigitalOut_GetActive( int index )
00141 {
00142   if ( index < 0 || index >= DIGITALOUT_COUNT )
00143     return false;
00144   return DigitalOut_users[ index ] > 0;
00145 }
00146 
00147 /** 
00148   Turn a Digital Out on or off.
00149   @param index An integer specifying which Digital Out (0-7).
00150   @param state An integer specifying the state - on (1) or off (0).
00151   @return Zero on success.
00152   
00153   \b Example
00154   \code
00155   // Turn digital out 2 on
00156   DigitalOut_SetValue( 2, 1 );
00157   \endcode
00158 */
00159 int DigitalOut_SetValue( int index, int state )
00160 {
00161   if ( index < 0 || index >= DIGITALOUT_COUNT )
00162     return CONTROLLER_ERROR_ILLEGAL_INDEX;
00163 
00164   if ( DigitalOut_users[ index ] < 1 )
00165   {
00166     int status = DigitalOut_Start( index );
00167     if ( status != CONTROLLER_OK )
00168       return status;
00169   }
00170 
00171   int io = DigitalOut_GetIo( index );
00172   if ( state )
00173     Io_SetValue( io, true );
00174   else 
00175     Io_SetValue( io, false );
00176 
00177   return CONTROLLER_OK;
00178 }
00179 
00180 /** 
00181   Read whether a DigitalOut is on or off.
00182   @param index An integer specifying which Digital Out (0-7).
00183   @return The value - on (1) or off (0).
00184   
00185   \b Example
00186   \code
00187   if( DigitalOut_GetValue( 2 ) )
00188   {
00189     // DigitalOut 2 is high
00190   }
00191   else
00192   {
00193     // DigitalOut 2 is low
00194   }
00195   \endcode
00196 */
00197 int DigitalOut_GetValue( int index )
00198 {
00199   if ( index < 0 || index >= DIGITALOUT_COUNT )
00200     return CONTROLLER_ERROR_ILLEGAL_INDEX;
00201 
00202   if ( DigitalOut_users[ index ] < 1 )
00203   {
00204     int status = DigitalOut_Start( index );
00205     if ( status != CONTROLLER_OK )
00206       return status;
00207   }
00208 
00209   int io = DigitalOut_GetIo( index );
00210 
00211   return Io_GetValue( io );
00212 
00213   return CONTROLLER_OK;
00214 }
00215 
00216 
00217 /** @}
00218 */
00219 
00220 int DigitalOut_Start( int index )
00221 {
00222   int status;
00223   int enableIndex = index >> 1;
00224 
00225   if ( index < 0 || index >= DIGITALOUT_COUNT )
00226     return CONTROLLER_ERROR_ILLEGAL_INDEX;
00227 
00228   if ( DigitalOut_users[ index ]++ == 0 )
00229   {
00230     int enableIo = DigitalOut_GetEnableIo( enableIndex );
00231     if ( DigitalOut_enableUsers[ enableIndex ]++ == 0 )
00232     {
00233       status = Io_Start( enableIo, true );
00234       if ( status != CONTROLLER_OK )
00235       {
00236         DigitalOut_enableUsers[ enableIndex ]--;
00237         DigitalOut_users[ index ]--;
00238         return CONTROLLER_ERROR_CANT_LOCK;
00239       }
00240       Io_SetValue( enableIo, true );
00241     }
00242 
00243     int io = DigitalOut_GetIo( index );
00244 
00245     status = Io_Start( io, true );
00246     if ( status != CONTROLLER_OK )
00247     {
00248       DigitalOut_users[ index ]--;
00249       return CONTROLLER_ERROR_CANT_LOCK;
00250     }
00251 
00252     // Got it, now set the io up right
00253     Io_SetPio( io, true );
00254     Io_SetValue( io, false );
00255 
00256     Io_SetDirection( io, IO_OUTPUT );
00257   }
00258 
00259   return CONTROLLER_OK;
00260 }
00261 
00262 int DigitalOut_Stop( int index )
00263 {
00264   if ( index < 0 || index >= DIGITALOUT_COUNT )
00265     return CONTROLLER_ERROR_ILLEGAL_INDEX;
00266 
00267   if ( DigitalOut_users[ index ] < 1 )
00268     return CONTROLLER_ERROR_TOO_MANY_STOPS;
00269 
00270   if ( --DigitalOut_users[ index ] == 0 )
00271   {
00272     int io = DigitalOut_GetIo( index );
00273     Io_Stop( io );
00274 
00275     int enableIndex = index >> 1;
00276     if ( --DigitalOut_enableUsers[ enableIndex ] == 0 )
00277     {
00278       int enableIo = DigitalOut_GetEnableIo( enableIndex );
00279       Io_Stop( enableIo );
00280     }
00281 
00282   }
00283   return CONTROLLER_OK;
00284 }
00285 
00286 int DigitalOut_GetIo( int index )
00287 {
00288   int io = -1;
00289   switch ( index )
00290   {
00291     case 0:
00292       io = DIGITALOUT_0_IO;
00293       break;
00294     case 1:
00295       io = DIGITALOUT_1_IO;
00296       break;
00297     case 2:
00298       io = DIGITALOUT_2_IO;
00299       break;
00300     case 3:
00301       io = DIGITALOUT_3_IO;
00302       break;
00303     case 4:
00304       io = DIGITALOUT_4_IO;
00305       break;
00306     case 5:
00307       io = DIGITALOUT_5_IO;
00308       break;
00309     case 6:
00310       io = DIGITALOUT_6_IO;
00311       break;
00312     case 7:
00313       io = DIGITALOUT_7_IO;
00314       break;
00315   }
00316   return io;
00317 }
00318 
00319 int DigitalOut_GetEnableIo( int enableIndex )
00320 {
00321   int enableIo = -1;
00322   switch ( enableIndex )
00323   {
00324     case 0:
00325       enableIo = DIGITALOUT_01_ENABLE;
00326       break;
00327     case 1:
00328       enableIo = DIGITALOUT_23_ENABLE;
00329       break;
00330     case 2:
00331       enableIo = DIGITALOUT_45_ENABLE;
00332       break;
00333     case 3:
00334       enableIo = DIGITALOUT_67_ENABLE;
00335       break;
00336   }
00337   return enableIo;
00338 }
00339 
00340 #ifdef OSC
00341 
00342 /** \defgroup DigitalOutOSC Digital Out - OSC
00343   Control the Application Board's Digital Outs via OSC.
00344   \ingroup OSC
00345   
00346   \section devices Devices
00347   There are 8 Digital Outs on the Make Application Board, numbered <b>0 - 7</b>.
00348   
00349   \section properties Properties
00350   The Digital Outs have two properties:
00351   - value
00352   - active
00353 
00354   \par Value
00355   The \b value property corresponds to the on/off value of a given Digital Out.
00356   For example, to turn on the fifth Digital Out, send a message like
00357   \verbatim /digitalout/6/value 1\endverbatim
00358   Turn it off by sending the message \verbatim /digitalout/6/value 0\endverbatim
00359   
00360   \par Active
00361   The \b active property corresponds to the active state of a Digital Out.
00362   If a Digital Out is set to be active, no other tasks will be able to
00363   write to that Digital Out.  If you're not seeing appropriate
00364   responses to your messages to the Digital Out, check the whether a Digital Out is 
00365   locked by sending a message like
00366   \verbatim /digitalout/0/active \endverbatim
00367   \par
00368   You can set the active flag by sending
00369   \verbatim /digitalout/0/active 1 \endverbatim
00370 */
00371 
00372 #include "osc.h"
00373 #include "string.h"
00374 #include "stdio.h"
00375 
00376 // Need a list of property names
00377 // MUST end in zero
00378 static char* DigitalOutOsc_Name = "digitalout";
00379 static char* DigitalOutOsc_PropertyNames[] = { "active", "value", 0 }; // must have a trailing 0
00380 
00381 int DigitalOutOsc_PropertySet( int index, int property, int value );
00382 int DigitalOutOsc_PropertyGet( int index, int property );
00383 
00384 // Returns the name of the subsystem
00385 const char* DigitalOutOsc_GetName( )
00386 {
00387   return DigitalOutOsc_Name;
00388 }
00389 
00390 // Now getting a message.  This is actually a part message, with the first
00391 // part (the subsystem) already parsed off.
00392 int DigitalOutOsc_ReceiveMessage( int channel, char* message, int length )
00393 {
00394   int status = Osc_IndexIntReceiverHelper( channel, message, length, 
00395                                            DIGITALOUT_COUNT, DigitalOutOsc_Name,
00396                                            DigitalOutOsc_PropertySet, DigitalOutOsc_PropertyGet, 
00397                                            DigitalOutOsc_PropertyNames );
00398                                      
00399   if ( status != CONTROLLER_OK )
00400     return Osc_SendError( channel, DigitalOutOsc_Name, status );
00401   return CONTROLLER_OK;
00402 }
00403 
00404 // Set the index LED, property with the value
00405 int DigitalOutOsc_PropertySet( int index, int property, int value )
00406 {
00407   switch ( property )
00408   {
00409     case 0: 
00410       DigitalOut_SetActive( index, value );
00411       break;      
00412     case 1: 
00413       DigitalOut_SetValue( index, value );
00414       break;
00415   }
00416   return CONTROLLER_OK;
00417 }
00418 
00419 // Get the index LED, property
00420 int DigitalOutOsc_PropertyGet( int index, int property )
00421 {
00422   int value = 0;
00423   switch ( property )
00424   {
00425     case 0:
00426       value = DigitalOut_GetActive( index );
00427       break;
00428     case 1:
00429       value = DigitalOut_GetValue( index );
00430       break;
00431   }
00432   
00433   return value;
00434 }
00435 
00436 #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.