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