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

poly.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 /** \file poly.c  
00019   Poly Functions.
00020   Functions for permitting the Make Controller Board perform simple functions without
00021   programming or any computer intervention at all.
00022 */
00023 
00024 #include "stdlib.h"
00025 #include "config.h"
00026 #include "poly.h" 
00027 #include "eeprom.h"
00028 
00029 void Poly_LineInit( void );
00030 
00031 void PolyTask( void* p );
00032 
00033 //
00034 // Top level Poly routines
00035 // 
00036 void  Poly_DeInit( int function, void* voidStruct );
00037 void* Poly_Init( int function, int bank );
00038 void  Poly_Run( int function, void* data, int ms, int readConstants );
00039 
00040 typedef struct
00041 {
00042   int mode0;
00043   int mode1;
00044   int running;
00045   int readContants;
00046 } PolyStruct;
00047 
00048 PolyStruct Poly;
00049 
00050 //
00051 // 1 - Timer stuff
00052 //
00053 void* Timer_Init( int bank );
00054 void Timer_Run( void* timerVP, int ms, int readConstants );
00055 void Timer_DeInit( void* voidStruct );
00056 
00057 typedef struct
00058 {
00059   int bank; // 0 or 1
00060   int baseIn;
00061   int baseOut;
00062   int baseAux;
00063  
00064   int timerSoFar;
00065   int timerDuration;
00066   int timerDurationHalf;
00067   int timerDurationQuarter;
00068   int lastPotValue;
00069   
00070   int lastIn0;
00071   int lastIn1;
00072   
00073   int timerState;
00074   int timerStateHalf;
00075   int timerStateQuarter;
00076 
00077   int readConstants;
00078 
00079   int sustainMode;
00080   int sustainState;
00081 } TimerStruct;
00082 
00083 void Timer_SaveConstants( TimerStruct *tp );
00084 
00085 //
00086 // 2 - Follower stuff
00087 //
00088 void* Follower_Init( int bank );
00089 void Follower_Run( void* followerVP, int ms, int readConstants );
00090 void Follower_DeInit( void* follower );
00091 
00092 typedef struct
00093 {
00094   int bank;
00095   int baseIn;
00096   int baseOut;
00097   int baseAux;
00098 
00099   float output;
00100   float rate;
00101   int lastRateValue;
00102   int input;
00103 
00104   int peak;
00105   int readConstants;
00106 
00107 } FollowerStruct;
00108 
00109 void Follower_SaveConstants( FollowerStruct *fp );
00110 
00111 
00112 //
00113 // 3 - Oscillator stuff
00114 //
00115 
00116 void* Oscillator_Init( int bank );
00117 void Oscillator_Run( void* OscillatorP, int ms, int readConstants );
00118 void Oscillator_DeInit( void* Oscillator );
00119 
00120 typedef struct
00121 {
00122   int bank;
00123   int baseIn;
00124   int baseOut;
00125   int baseAux;
00126 
00127   int state;
00128   float current;
00129   float periodOn;
00130   float periodOff;
00131 
00132   int periodOnRaw;
00133   int periodOffRaw;
00134 
00135   int readConstants;
00136 
00137 } OscillatorStruct;
00138 
00139 void Oscillator_SaveConstants( OscillatorStruct *fp );
00140 
00141 /*
00142   Poly Function - pre-cooked behaviors for experimentation.
00143 
00144   4 ins & 4 outs for each function
00145   2 banks: 3 DIP switch spots select which function
00146   Each function has an integer index (0-7):
00147     0 - Timer
00148     1 - Follower
00149     etc.
00150 */
00151 
00152 /* \defgroup Poly Poly
00153   The Poly subsystem controls onboard pre-baked functions.
00154 * \ingroup Controller
00155 * @{
00156 */
00157 
00158 /**
00159   Sets whether the Poly subsystem is active.
00160   @param value An integer specifying the active state of the subsystem - 1 (on) or 0 (off).
00161   @return CONTROLLER_OK (0) on success.
00162 */
00163 int Poly_SetActive( int value )
00164 {
00165   if ( value ) 
00166   {  
00167     if ( !Poly.running )
00168     {
00169       Poly.running = true;
00170       // Poly.readConstants = false;
00171       Poly.mode0 = -1;
00172       Poly.mode1 = -1;
00173       TaskCreate( PolyTask, "Poly", 1600, NULL, 2 );
00174     }
00175   }
00176   else
00177     Poly.running = false;
00178 
00179   return CONTROLLER_OK;
00180 }
00181 
00182 int Poly_GetActive( )
00183 {
00184   return Poly.running;
00185 }
00186 
00187 #define POLY_SLEEP 20
00188 
00189 void PolyTask( void* p )
00190 {
00191   (void)p;
00192   int newDipSwitch;
00193   int oldDipSwitch = -1;
00194   void* data0 = NULL;
00195   void* data1 = NULL;
00196   int readConstants = false;
00197 
00198   // Make sure everything is off
00199   Poly_LineInit();
00200 
00201   while( Poly.running )
00202   {
00203     newDipSwitch = DipSwitch_GetValue( );
00204     if( newDipSwitch != oldDipSwitch )
00205     {
00206       int newMode0;
00207       int newMode1;
00208       
00209       if ( !( newDipSwitch & 0x80 ) )
00210       {
00211         newMode0 = 0;
00212         newMode1 = 0;
00213       }
00214       else
00215       {
00216         newMode0 = (newDipSwitch & 0x0E) >> 1;
00217         newMode1 = (newDipSwitch & 0x70) >> 4;
00218       }
00219 
00220       readConstants = ( newDipSwitch & 0x01 ) ? 1 : 0;
00221 
00222       if( newMode0 != Poly.mode0 )
00223       {
00224         Poly_DeInit( Poly.mode0, data0 );
00225         data0 = Poly_Init( newMode0, 0 );
00226         Poly.mode0 = newMode0;
00227       }
00228 
00229       if( newMode1 != Poly.mode1 )
00230       {
00231         Poly_DeInit( Poly.mode1, data1 );
00232         data1 = Poly_Init( newMode1, 1 );
00233         Poly.mode1 = newMode1;
00234       }
00235 
00236       oldDipSwitch = newDipSwitch;
00237     }
00238 
00239     Poly_Run( Poly.mode0, data0, POLY_SLEEP, readConstants );
00240     Poly_Run( Poly.mode1, data1, POLY_SLEEP, readConstants );
00241 
00242     if ( Poly.mode0 == 0 && Poly.mode1 == 0 )
00243       Sleep( POLY_SLEEP * 20 );
00244     else
00245       Sleep( POLY_SLEEP );
00246   }
00247 
00248   TaskDelete( 0 );
00249 }
00250 
00251 void* Poly_Init( int function, int bank )
00252 {
00253   switch( function )
00254   {
00255     case 1: // Timer
00256       return Timer_Init( bank );
00257       break;
00258     case 2: // Follower
00259       return Follower_Init( bank );
00260       break;
00261     case 3: // Oscillator
00262       return Oscillator_Init( bank );
00263       break;
00264     default:
00265       break;
00266   }
00267 
00268   return 0;
00269 }
00270 
00271 void Poly_DeInit( int function, void* data )
00272 {
00273   switch( function )
00274   {
00275     case 1: // Timer
00276       Timer_DeInit( data );
00277       break;
00278     case 2: // Follower
00279       Follower_DeInit( data );
00280       break;
00281     case 3: // Oscillator
00282       Oscillator_DeInit( data );
00283       break;
00284     default:
00285       break;
00286   }
00287 }
00288 
00289 void Poly_Run( int function, void* data, int ms, int readConstants )
00290 {
00291   switch( function )
00292   {
00293     case 1: // Timer
00294       Timer_Run( data, ms, readConstants );
00295       break;
00296     case 2: // Follower
00297       Follower_Run( data, ms, readConstants );
00298       break;
00299     case 3: // Oscillator
00300       Oscillator_Run( data, ms, readConstants );
00301       break;
00302   }
00303 }
00304 
00305 //
00306 // 1 - Timer Routines
00307 //
00308 
00309 // TimerStruct Timer[2];  // temporary...debug malloc.
00310 
00311 void* Timer_Init( int bank )
00312 {
00313   TimerStruct* timer;   //create a pointer to a new TimerStruct
00314   timer = (TimerStruct*)Malloc( sizeof( TimerStruct ) );
00315   //timer = &Timer[bank];
00316   
00317   timer->bank = bank;
00318   timer->baseIn = bank * 4;
00319   timer->baseOut = ( 1 - bank ) * 4;
00320   timer->baseAux = bank * 2;
00321 
00322   Eeprom_Read( EEPROM_POLY_0_TIMER_DURATION + ( bank * 8 ), (unsigned char*)&timer->timerDuration, 4 );
00323   Eeprom_Read( EEPROM_POLY_0_TIMER_SUSTAIN + ( bank * 8 ), (unsigned char*)&timer->sustainMode, 4 );
00324   if ( timer->sustainMode )
00325     timer->sustainMode = 1;
00326   else
00327     timer->sustainMode = 0;
00328 
00329   timer->timerSoFar = 0;
00330   timer->timerDurationHalf = 0;
00331   timer->timerDurationQuarter = 0;
00332   timer->lastPotValue = 0;
00333   
00334   timer->lastIn0 = 0;
00335   timer->lastIn1 = 0;
00336   
00337   timer->timerState = 1;
00338   timer->timerStateHalf = 1;
00339   timer->timerStateQuarter = 1;
00340   
00341   // make sure the outputs are initialized properly
00342   DigitalOut_SetValue( timer->baseOut, 0 );
00343   int i;
00344   for( i = 1; i < 4; i++ )
00345     DigitalOut_SetValue( timer->baseOut + i, 1 );
00346   AppLed_SetState( timer->baseAux, 0 );
00347   AppLed_SetState( timer->baseAux + 1, 1 );
00348   Servo_SetPosition( timer->baseAux, 0 );
00349   Servo_SetPosition( timer->baseAux + 1, 0 );
00350 
00351   return (void*)timer;
00352 }
00353 
00354 void Timer_Run( void* timerVP, int ms, int readConstants )
00355 {
00356   TimerStruct* tp = (TimerStruct*)timerVP;
00357   // Deal with current pulse
00358   if ( !tp->timerState  ) // if the timer is not expired
00359   { 
00360     tp->timerSoFar += ms;
00361 
00362     if ( tp->timerSoFar > tp->timerDuration )
00363       tp->timerSoFar = tp->timerDuration ;
00364 
00365     // Calculate servo positions
00366     int position = 2048 * tp->timerSoFar / tp->timerDuration;
00367     Servo_SetPosition( tp->baseAux, ( position >> 2 ) );
00368     int position1 = ( position < 1023) ? position : 2048 - position;
00369     Servo_SetPosition( tp->baseAux + 1, position1 );
00370     
00371     if ( !tp->timerStateHalf && tp->timerSoFar >= tp->timerDurationHalf )
00372     {
00373       DigitalOut_SetValue( tp->baseOut + 3, 1 );  // set the "timer half-expired" output
00374       AppLed_SetState( tp->baseAux + 1, 1 ); 
00375       tp->timerStateHalf = 1;    // and set the flag accordingly
00376     }
00377     
00378     if ( !tp->timerStateQuarter && tp->timerSoFar >= tp->timerDurationQuarter )
00379     {
00380       DigitalOut_SetValue( tp->baseOut + 2, 1 );  // set the "timer quarter-expired" output
00381       tp->timerStateQuarter = 1;
00382     }
00383     
00384     if ( tp->timerSoFar >= tp->timerDuration  )
00385     {
00386       DigitalOut_SetValue( tp->baseOut, 0 );  // turn off the "time remaining" output
00387       DigitalOut_SetValue( tp->baseOut + 1, 1 );  // turn on the "time expired" output
00388       AppLed_SetState( tp->baseAux, 0 ); 
00389       tp->timerState = 1;      
00390     }
00391   }
00392   
00393   // if we're authorized to read constants from inputs
00394   if ( readConstants )
00395   {
00396     // Deal with changing time 
00397     int newPotValue = AnalogIn_GetValue( tp->baseIn + 3 );    // assuming the pot jumper is connected...
00398     if ( newPotValue != tp->lastPotValue )  // if the value has changed
00399     {
00400       tp->lastPotValue = newPotValue; // save it for next time
00401       
00402       // need to adjust scale - make sure we're not dividing by zero
00403       // potvalue squared seems right, but then divided by something that will
00404       // give good control.  If the poly system works on 5ms intervals, squared
00405       // and divided by 1000, gives 2.5s at half, 10s at full on an exponential
00406       // scale.
00407       tp->timerDuration = newPotValue * newPotValue / 50;
00408       if( tp->timerDuration == 0 )
00409         tp->timerDuration = 1;
00410       
00411       tp->timerDurationHalf = tp->timerDuration / 2;
00412       if( tp->timerDurationHalf == 0 )
00413         tp->timerDurationHalf = 1;
00414       
00415       tp->timerDurationQuarter = tp->timerDuration - tp->timerDuration / 4;
00416       if( tp->timerDurationQuarter == 0 )
00417         tp->timerDurationQuarter = 1;
00418       
00419       if ( tp->timerState && tp->timerSoFar > tp->timerDuration )
00420         tp->timerSoFar = tp->timerDuration - 1;
00421     }
00422 
00423     // Read sustain mode
00424     tp->sustainMode = DigitalIn_GetValue( tp->baseIn + 2 );
00425   }
00426   else
00427   {
00428     // If the switch is off, save the constants
00429     if ( tp->readConstants )
00430       Timer_SaveConstants( tp );
00431   }
00432   tp->readConstants = readConstants;
00433   
00434   // Check for new triggers
00435   int trigger = 0;
00436   int newIn0 = DigitalIn_GetValue( tp->baseIn ); 
00437   if ( newIn0 != tp->lastIn0 || tp->sustainMode )
00438   {
00439     if ( newIn0 == 1 )    // if the main trigger input is high
00440       trigger = 1;
00441     tp->lastIn0 = newIn0;
00442   }
00443   
00444   int newIn1 = DigitalIn_GetValue( tp->baseIn + 1 );
00445   if ( newIn1 != tp->lastIn1 || tp->sustainMode )
00446   {
00447     if ( newIn1 == 0 )  // if the "inverted trigger" drops to 0
00448       trigger = 1;
00449     tp->lastIn1 = newIn1;
00450   }
00451 
00452   if ( trigger )
00453   {
00454     // set all the outputs to off except the "time expired" output
00455     DigitalOut_SetValue( tp->baseOut, 1 );
00456     AppLed_SetState( tp->baseAux, 1 );
00457     AppLed_SetState( tp->baseAux + 1, 0 );
00458     int i;
00459     for( i = (tp->baseOut + 1); i < (tp->baseOut + 4); i++ )
00460       DigitalOut_SetValue( i, 0 );
00461     tp->timerState = 0;
00462     tp->timerStateHalf = 0;
00463     tp->timerStateQuarter = 0;
00464     tp->timerSoFar = 0;   // reset the timer count
00465   }
00466 }
00467 
00468 // Set all the subsystems we've used to inactive
00469 // so the IO lines can be used by the next function
00470 void Timer_DeInit( void* voidStruct )
00471 {
00472   TimerStruct* tp = (TimerStruct*)voidStruct;
00473   if ( tp != NULL )
00474   {
00475     int i;
00476     for( i = tp->baseIn; i < tp->baseIn + 4; i++ )
00477     {
00478       DigitalIn_SetActive( i, 0 );
00479       AnalogIn_SetActive( i, 0 );
00480     }
00481     for( i = tp->baseOut; i < tp->baseOut + 4; i++ )
00482     {
00483       DigitalOut_SetValue( i, 0 );
00484       DigitalOut_SetActive( i, 0 );
00485     }
00486     AppLed_SetState( tp->baseAux, 0 );
00487     AppLed_SetState( tp->baseAux + 1, 0 );
00488     AppLed_SetActive( tp->baseAux, 0 );
00489     AppLed_SetActive( tp->baseAux + 1, 0 );
00490 
00491     Servo_SetActive( tp->baseAux, 0 );
00492     Servo_SetActive( tp->baseAux + 1, 0 );
00493 
00494     if ( tp->readConstants )
00495       Timer_SaveConstants( tp );
00496 
00497     Free( tp );
00498   }
00499   // eventually free() the TimerStruct instances once malloc is working...?
00500 }
00501 
00502 void Timer_SaveConstants( TimerStruct *tp )
00503 {
00504   Eeprom_Write( EEPROM_POLY_0_TIMER_DURATION + ( tp->bank * 8 ), (unsigned char *)&tp->timerDuration, 4 );
00505   Eeprom_Write( EEPROM_POLY_0_TIMER_SUSTAIN + ( tp->bank * 8 ), (unsigned char *)&tp->sustainMode, 4 );
00506 }
00507 
00508 //
00509 // 2 - Follower Routines
00510 //
00511 
00512 //FollowerStruct Follower[2]; // eventually put these on the heap...
00513 
00514 void* Follower_Init( int bank )
00515 {
00516   int i;
00517 
00518   //FollowerStruct* follower = &Follower[bank];
00519   FollowerStruct* follower = (FollowerStruct*)Malloc( sizeof( FollowerStruct ) );
00520 
00521   follower->bank = bank;
00522 
00523   follower->baseIn = bank * 4;
00524   follower->baseOut = ( 1 - bank ) * 2;
00525   follower->baseAux = bank * 2;
00526 
00527   follower->output = 0;
00528   follower->rate = 0;
00529   follower->lastRateValue = -2048;
00530   follower->input = 0;
00531 
00532   Eeprom_Read( EEPROM_POLY_0_FOLLOWER_RATE + ( bank * 8 ), (unsigned char*)&follower->rate, 4 );
00533   Eeprom_Read( EEPROM_POLY_0_FOLLOWER_PEAK + ( bank * 8 ), (unsigned char*)&follower->peak, 4 );
00534 
00535   if ( follower->peak )
00536     follower->peak = 1;
00537   else
00538     follower->peak = 0;
00539   
00540   // set up the PWM outs as inverted pairs, so we can use them to drive motors, etc.
00541   for( i = follower->baseOut; i < (follower->baseOut + 2); i++) //2 PWMs for each bank of 4 outputs
00542   {
00543     PwmOut_SetInvertA( i, 0 );
00544     PwmOut_SetInvertB( i, 1 );
00545     PwmOut_SetDuty( i, 0 ); //initialize the outputs to 0
00546   }
00547 
00548   AppLed_SetState( follower->baseAux, 0 );
00549   AppLed_SetState( follower->baseAux + 1, 0 );
00550   Servo_SetPosition( i, 0 );
00551   Servo_SetPosition( i + 1, 512 );
00552 
00553   return (void*)follower;
00554 }
00555 
00556 void Follower_Run( void* followerVP, int ms, int readConstants )
00557 {
00558   FollowerStruct* fp = (FollowerStruct*)followerVP;
00559   
00560   if ( readConstants )
00561   {
00562     // For pair zero, read the rate
00563     int newRateValue = AnalogIn_GetValue( fp->baseIn + 3 );
00564     if ( newRateValue != fp->lastRateValue )
00565     {
00566       fp->lastRateValue = newRateValue;
00567       if ( newRateValue == 0 )
00568         newRateValue = 1;
00569       if ( newRateValue > 1020 )
00570         fp->rate = 0;
00571       else
00572         fp->rate = ( 10 * 1024.0 ) / (newRateValue * newRateValue );
00573     }    
00574     fp->peak = DigitalIn_GetValue( fp->baseIn + 2 );
00575   }
00576   else
00577   {
00578     if ( fp->readConstants )
00579       Follower_SaveConstants( fp );
00580   }
00581   fp->readConstants = readConstants;
00582 
00583   int set = DigitalIn_GetValue( fp->baseIn + 1 );
00584 
00585   // Now read the position
00586   int input = AnalogIn_GetValue( fp->baseIn );
00587 
00588   int diff = input - fp->output;
00589   float change = fp->rate * (float)ms;
00590         
00591   if( diff != 0 ) // if the input has changed
00592   {
00593     if( diff > 0 )  // if the input is higher than last time
00594     {
00595       fp->output += change; // increment the output by the rate
00596       if( fp->output > input || fp->peak || set )
00597         fp->output = input; // just set it to the input if it would otherwise be too high
00598       if ( diff > 1  )
00599       {
00600         AppLed_SetState( fp->baseAux, 1 );     
00601         AppLed_SetState( fp->baseAux + 1, 0 );     
00602       }
00603       PwmOut_SetAll( fp->baseOut + 1, diff, 0, 1 );
00604     }
00605     else  // the input is lower than last time
00606     {
00607       fp->output -= change; 
00608       if( fp->output < input || set )
00609         fp->output = input;
00610       if ( diff < -1  )
00611       {
00612         AppLed_SetState( fp->baseAux + 1, 1 );     
00613         AppLed_SetState( fp->baseAux, 0 );     
00614       }
00615       PwmOut_SetAll( fp->baseOut + 1, -diff, 1, 0 );
00616     }
00617 
00618     int diff2 = diff / 2;
00619     Servo_SetPosition( fp->baseAux + 1, 512 + diff2 );
00620              
00621     int out = (int)fp->output;
00622     PwmOut_SetDuty( fp->baseOut, out );
00623     Servo_SetPosition( fp->baseAux, out );
00624   }
00625   else
00626   {
00627     AppLed_SetState( fp->baseAux, 0 );
00628     AppLed_SetState( fp->baseAux + 1, 0 );
00629     PwmOut_SetDuty( fp->baseOut + 1, 0 );
00630     Servo_SetPosition( fp->baseAux + 1, 512 );
00631   }
00632 
00633 }
00634 
00635 void Follower_DeInit( void* follower )
00636 {
00637   FollowerStruct* fp = (FollowerStruct*)follower;
00638   if ( fp != NULL )
00639   {
00640     int i;
00641 
00642     if ( fp->readConstants )
00643       Follower_SaveConstants( fp );
00644 
00645     AnalogIn_SetActive( 0, 0 );
00646     AnalogIn_SetActive( 3, 0 );
00647     DigitalIn_SetActive( 1, 0 );
00648     DigitalIn_SetActive( 2, 0 );
00649 
00650     for( i = fp->baseOut; i < fp->baseOut + 2; i++ )
00651     {
00652       PwmOut_SetDuty( i, 0 );
00653       PwmOut_SetActive( i, 0 );
00654     }
00655     for( i = fp->baseAux; i < fp->baseAux + 2; i++ )
00656     {
00657       AppLed_SetState( i, 0 );
00658       AppLed_SetActive( i, 0 );
00659       Servo_SetPosition( i, 0 );
00660       Servo_SetActive( i, 0 );
00661     }
00662 
00663     Free( fp );
00664   }
00665 }
00666 
00667 void Follower_SaveConstants( FollowerStruct *fp )
00668 {
00669   Eeprom_Write( EEPROM_POLY_0_FOLLOWER_RATE + ( fp->bank * 8 ), (unsigned char *)&fp->rate, 4 );
00670   Eeprom_Write( EEPROM_POLY_0_FOLLOWER_PEAK + ( fp->bank * 8 ), (unsigned char *)&fp->peak, 4 );
00671 }
00672 
00673 //
00674 // 3 - Oscillator Routines
00675 //
00676 
00677 //  int state;
00678 //  float current;
00679 
00680 //  float periodOn;
00681 //  float periodOff;
00682 //  int periodOnRaw;
00683 //  int periodOffRaw;
00684 
00685 // OscillatorStruct Oscillator[2]; // eventually put these on the heap...
00686 
00687 void* Oscillator_Init( int bank )
00688 {
00689   int i;
00690 
00691   OscillatorStruct* op = (OscillatorStruct*)Malloc( sizeof( OscillatorStruct ) );
00692 
00693   op->bank = bank;
00694 
00695   op->baseIn = bank * 4;
00696   op->baseOut = ( 1 - bank ) * 4;
00697   op->baseAux = bank * 2;
00698 
00699   op->state = 0;
00700   op->current = 0.0;
00701 
00702   Eeprom_Read( EEPROM_POLY_0_OSCILLATOR_PERIODON + ( bank * 8 ), (unsigned char*)&op->periodOn, 4 );
00703   Eeprom_Read( EEPROM_POLY_0_OSCILLATOR_PERIODOFF + ( bank * 8 ), (unsigned char*)&op->periodOff, 4 );
00704   
00705   for( i = op->baseOut; i < (op->baseOut + 4); i++)
00706     DigitalOut_SetValue( i, 0 );
00707 
00708   AppLed_SetState( op->baseAux, 1 );
00709   AppLed_SetState( op->baseAux + 1, 0 );
00710   Servo_SetPosition( op->baseAux, 512 );
00711 
00712   return (void*)op;
00713 }
00714 
00715 void Oscillator_Run( void* oscillatorVP, int ms, int readConstants )
00716 {
00717   OscillatorStruct* op = (OscillatorStruct*)oscillatorVP;
00718   
00719   if ( readConstants )
00720   {
00721     int periodOffRaw = AnalogIn_GetValue( op->baseIn + 3 );
00722     if ( periodOffRaw != op->periodOffRaw )
00723     {
00724       op->periodOffRaw = periodOffRaw;
00725       op->periodOff = (float)( periodOffRaw * periodOffRaw ) / 50.0;
00726     }
00727     int periodOnRaw = AnalogIn_GetValue( op->baseIn + 2 );
00728     if ( periodOnRaw != op->periodOnRaw )
00729     {
00730       op->periodOnRaw = periodOnRaw;
00731       if ( periodOnRaw < 2 )
00732         op->periodOn = op->periodOff;
00733       else
00734         op->periodOn = (float)( periodOnRaw * periodOffRaw ) / 50.0;
00735     }
00736     else
00737     {
00738       if ( periodOnRaw < 2 )
00739         op->periodOn = op->periodOff;
00740     }
00741   }
00742   else
00743   {
00744     if ( op->readConstants )
00745       Oscillator_SaveConstants( op );
00746   }
00747   op->readConstants = readConstants;
00748 
00749   int setOn = DigitalIn_GetValue( op->baseIn + 0 );
00750   int setOff = DigitalIn_GetValue( op->baseIn + 1 );
00751 
00752   int stateNew = op->state;
00753   if ( setOn )
00754   {
00755     stateNew = 1;
00756     op->current = 0.0;
00757   }
00758   if ( setOff )
00759   {
00760     stateNew = 0;
00761     op->current = 0.0;
00762   }
00763 
00764   op->current += ms;
00765  
00766   if ( op->current > ( ( stateNew ) ? op->periodOn : op->periodOff ) )
00767   {
00768     stateNew = !stateNew;
00769     op->current = 0.0;
00770   }
00771 
00772   if ( stateNew != op->state )
00773   {
00774     if ( stateNew )
00775     {
00776       AppLed_SetState( op->baseAux, 0 );     
00777       AppLed_SetState( op->baseAux + 1, 1 );     
00778       DigitalOut_SetValue( op->baseOut, 1 );
00779       DigitalOut_SetValue( op->baseOut + 1, 0 );
00780     }
00781     else
00782     {
00783       AppLed_SetState( op->baseAux, 1 );     
00784       AppLed_SetState( op->baseAux + 1, 0 );     
00785       DigitalOut_SetValue( op->baseOut, 0 );
00786       DigitalOut_SetValue( op->baseOut + 1, 1 );
00787       Servo_SetPosition( op->baseAux, 0 );
00788       Servo_SetPosition( op->baseAux + 1, 0 );
00789     }
00790   }
00791 
00792   if ( stateNew )
00793   {
00794     int position = 2048 * op->current / op->periodOn;
00795     Servo_SetPosition( op->baseAux, ( position >> 2 ) );
00796     int position1 = ( position < 1023) ? position : 2048 - position;
00797     Servo_SetPosition( op->baseAux + 1, position1 );
00798   }
00799 
00800   op->state = stateNew;
00801 }
00802 
00803 void Oscillator_DeInit( void* Oscillator )
00804 {
00805   OscillatorStruct* op = (OscillatorStruct*)Oscillator;
00806   if ( op != NULL )
00807   {
00808     int i;
00809 
00810     if ( op->readConstants )
00811       Oscillator_SaveConstants( op );
00812 
00813     DigitalIn_SetActive( 0, 0 );
00814     DigitalIn_SetActive( 1, 0 );
00815     AnalogIn_SetActive( 2, 0 );
00816     AnalogIn_SetActive( 3, 0 );
00817 
00818     for( i = op->baseOut; i < op->baseOut + 4; i++ )
00819     {
00820       DigitalOut_SetValue( i, 0 );
00821       DigitalOut_SetActive( i, 0 );
00822     }
00823 
00824     for( i = op->baseAux; i < op->baseAux + 2; i++ )
00825     {
00826       AppLed_SetState( i, 0 );
00827       AppLed_SetActive( i, 0 );
00828       Servo_SetPosition( i, 0 );
00829       Servo_SetActive( i, 0 );
00830     }
00831 
00832     Free( op );
00833   }
00834 }
00835 
00836 void Oscillator_SaveConstants( OscillatorStruct *op )
00837 {
00838   Eeprom_Write( EEPROM_POLY_0_OSCILLATOR_PERIODOFF + ( op->bank * 8 ), (unsigned char *)&op->periodOn, 4 );
00839   Eeprom_Write( EEPROM_POLY_0_OSCILLATOR_PERIODON + ( op->bank * 8 ), (unsigned char *)&op->periodOff, 4 );
00840 }
00841 
00842 #if ( APPBOARD_VERSION == 50 )
00843   #define DIGITALOUT_0_IO IO_PA02
00844   #define DIGITALOUT_1_IO IO_PA02
00845   #define DIGITALOUT_2_IO IO_PA02
00846   #define DIGITALOUT_3_IO IO_PA02
00847   #define DIGITALOUT_4_IO IO_PA02
00848   #define DIGITALOUT_5_IO IO_PA02
00849   #define DIGITALOUT_6_IO IO_PA02
00850   #define DIGITALOUT_7_IO IO_PA02
00851   #define DIGITALOUT_01_ENABLE IO_PA02
00852   #define DIGITALOUT_23_ENABLE IO_PA02
00853   #define DIGITALOUT_45_ENABLE IO_PA02
00854   #define DIGITALOUT_67_ENABLE IO_PA02
00855 #endif
00856 
00857 #if ( APPBOARD_VERSION == 90 )
00858   #define DIGITALOUT_0_IO IO_PB23
00859   #define DIGITALOUT_1_IO IO_PA26
00860   #define DIGITALOUT_2_IO IO_PA25
00861   #define DIGITALOUT_3_IO IO_PB25
00862   #define DIGITALOUT_4_IO IO_PA02
00863   #define DIGITALOUT_5_IO IO_PA06
00864   #define DIGITALOUT_6_IO IO_PA05
00865   #define DIGITALOUT_7_IO IO_PA24
00866   #define DIGITALOUT_01_ENABLE IO_PB19
00867   #define DIGITALOUT_23_ENABLE IO_PB20
00868   #define DIGITALOUT_45_ENABLE IO_PB21
00869   #define DIGITALOUT_67_ENABLE IO_PB22
00870 #endif
00871 #if ( APPBOARD_VERSION == 95 || APPBOARD_VERSION == 100 )
00872 
00873   #define DIGITALOUT_0_IO IO_PA24
00874   #define DIGITALOUT_1_IO IO_PA05
00875   #define DIGITALOUT_2_IO IO_PA06
00876   #define DIGITALOUT_3_IO IO_PA02
00877   #define DIGITALOUT_4_IO IO_PB25
00878   #define DIGITALOUT_5_IO IO_PA25
00879   #define DIGITALOUT_6_IO IO_PA26
00880   #define DIGITALOUT_7_IO IO_PB23
00881   #define DIGITALOUT_01_ENABLE IO_PB19
00882   #define DIGITALOUT_23_ENABLE IO_PB20
00883   #define DIGITALOUT_45_ENABLE IO_PB21
00884   #define DIGITALOUT_67_ENABLE IO_PB22
00885 #endif
00886 
00887 int Poly_Ios[] =
00888 {
00889   DIGITALOUT_0_IO,
00890   DIGITALOUT_1_IO, 
00891   DIGITALOUT_2_IO, 
00892   DIGITALOUT_3_IO, 
00893   DIGITALOUT_4_IO, 
00894   DIGITALOUT_5_IO, 
00895   DIGITALOUT_6_IO, 
00896   DIGITALOUT_7_IO, 
00897   0
00898 };
00899 
00900 int Poly_Enables[] =
00901 {
00902   DIGITALOUT_01_ENABLE, 
00903   DIGITALOUT_23_ENABLE, 
00904   DIGITALOUT_45_ENABLE, 
00905   DIGITALOUT_67_ENABLE,
00906   0
00907 };
00908 
00909 void Poly_LineInit()
00910 {
00911   // Lines OFF
00912   int* piop = Poly_Ios;
00913   while ( *piop )
00914     Io_SetFalse( *piop++ );
00915 
00916   // ENABLES ON
00917   piop = Poly_Enables;
00918   while ( *piop )
00919     Io_SetTrue( *piop++ );
00920 }
00921 
00922 /** @}
00923   */
00924 

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.