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.