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