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.