input.c

Go to the documentation of this file.
00001 // ////////////////////////////////////////////////////////////////////////////
00002 // ////////////////////////////////////////////////////////////////////////////
00013 // ////////////////////////////////////////////////////////////////////////////
00014 // ////////////////////////////////////////////////////////////////////////////
00015 
00016     #define     INPUT_C
00017     #include    "input.h"
00018 
00019 
00020 // ////////////////////////////////////////////////////////////////////////////
00021 // Local Defines
00022 // ////////////////////////////////////////////////////////////////////////////
00023 
00024 #define BTSM_START          0x00 // Waiting for a released button.
00025 #define BTSM_IDLE           0x01 // Button is idle.
00026 #define BTSM_PRESSED_FIRST  0x02 // Button pressed first, waiting for release.
00027 #define BTSM_RELEASED_FIRST 0x04 // Button released the first time.
00028 #define BTSM_PRESSED_SECOND 0x08 // Button pressed second, waiting for release.
00029 #define BTSM_DOUBLE_MASK    0x10 // Double push recognized.
00030 #define BTSM_PUSH_MASK      0x20 
00031 #define BTSM_PUSH_TEST_MASK 0x22
00032 #define BTSM_LONG_PUSH_MASK 0x40
00033 
00034 
00035 // ////////////////////////////////////////////////////////////////////////////
00036 // Local Variables
00037 // ////////////////////////////////////////////////////////////////////////////
00038 
00039 static BYTE _u8BtnDebounce[BTN_COUNT];
00040 static BYTE _u8BtnSM[BTN_COUNT];
00041 static BYTE _u8PwrSM;
00042 static WORD _u16PwrTimer;
00043 static WORD _u16BtnTimer[BTN_COUNT];
00044 
00045 static WORD _u16Enc;
00046 static SHORT _s16EncVal;
00047 static BYTE _u8EncFlags;
00048 static SHORT _s16EncMin;
00049 static SHORT _s16EncMax;
00050 static SHORT _s16EncLastVal;
00051 static SHORT _u16EncMaxInc;
00052 
00053 static BOOL _bEncTurning;
00054 static WORD _u16EncIncrement;
00055 static BOOL _bEncDirection;
00056 static BOOL _bEncTrigger;
00057 static BYTE _u8EncPause;
00058 
00059 // ////////////////////////////////////////////////////////////////////////////
00060 // Local function prototypes
00061 // ////////////////////////////////////////////////////////////////////////////
00062 
00063 static BOOL _bCheckPush(eButtonID eBtn);
00064 static void initTimer(void);
00065 
00066 
00067 // ////////////////////////////////////////////////////////////////////////////
00068 // Function implementations
00069 // ////////////////////////////////////////////////////////////////////////////
00070 
00071 void InputInit(void)
00072 {
00073     int i = 0;
00074 
00075     PORTE = 0xFF;           // 8 buttons.
00076     TRISE = 0xFF;
00077 
00078     PORTB |= 0x30;
00079     TRISB |= 0x30;
00080 
00081     PORTD = 0xFF;           // Rotary encoder.
00082     TRISD = 0xFF;
00083 
00084     // Enable pullups!
00085     INTCON2bits.RBPU = 0;   // For PORTB
00086     LATAbits.REPU = 1;      // For PORTE
00087     LATAbits.RDPU = 1;      // For PORTD
00088 
00089     // Initialize the state machines:
00090     for (i = 0; i < BTN_COUNT; i++)
00091     {
00092         _u8BtnDebounce[i] = 0xFF;
00093         _u8BtnSM[i] = BTSM_START;
00094         _u16BtnTimer[i] = 0;
00095     }
00096     _u8PwrSM = BTSM_START;
00097 
00098     _u16Enc = 0x0F;
00099     _bEncTurning = FALSE;
00100     _u16EncIncrement = 1;
00101     _u8EncPause = 0;
00102     _bEncTrigger = FALSE;
00103 
00104     initTimer();
00105 }
00106 
00107 // ////////////////////////////////////////////////////////////////////////////
00108 // ////////////////////////////////////////////////////////////////////////////
00109 
00110 void InputMain(void)
00111 {
00112     // Reading from all the input devices and shift them into the state 
00113     //registers.
00114     BYTE i = 0;
00115     for (i = 0; i < BTN_COUNT; i++)
00116     {
00117         _u8BtnDebounce[i] = _u8BtnDebounce[i] << 1;
00118     }
00119     
00120     _u8BtnDebounce[PWR_BTN] |= PORTEbits.RE0;
00121     _u8BtnDebounce[SEL_BTN] |= PORTEbits.RE1;
00122     _u8BtnDebounce[ACC_BTN] |= PORTEbits.RE2;
00123     _u8BtnDebounce[FL_BTN] |= PORTEbits.RE3;
00124     _u8BtnDebounce[F1_BTN] |= PORTEbits.RE4;
00125     _u8BtnDebounce[F2_BTN] |= PORTEbits.RE5;
00126     _u8BtnDebounce[F3_BTN] |= PORTBbits.RB4;
00127     _u8BtnDebounce[F4_BTN] |= PORTBbits.RB5;
00128     _u8BtnDebounce[ENC_BTN] |= PORTDbits.RD0;
00129 
00130 
00131     // The button state machines:
00132     for (i = 0; i < BTN_COUNT; i++)
00133     {
00134         // The power button always will be checked for a long push separately 
00135         // because that's the signal for eWicht to turn off.
00136         if (i == PWR_BTN)
00137         {
00138             if ((_u8PwrSM == BTSM_START) && (_u8BtnDebounce[PWR_BTN] == 0xFF))
00139             {
00140                 // After reseting the state machine the SM waits for a released
00141                 // button (Release = 80 ms an inactive button).
00142                 _u8PwrSM = BTSM_IDLE;
00143             }
00144 
00145             switch (_u8PwrSM)
00146             {
00147                 case BTSM_IDLE:
00148                     // Waiting for a pushed button (pushed = 80 ms active).
00149                     if (_u8BtnDebounce[PWR_BTN] == 0x00)
00150                     {
00151                         // Push detected!
00152                         _u8PwrSM = BTSM_PRESSED_FIRST;
00153                         // Measure the push time to detect a long push:
00154                         _u16PwrTimer = BTN_LONG_PUSH_TIME;
00155                     }
00156                     break;          
00157 
00158                 case BTSM_PRESSED_FIRST:
00159                     if (_u8BtnDebounce[PWR_BTN] == 0xFF)
00160                     {
00161                         // Not long enough pushed for a long pushed, reset the
00162                         // state machine and start again.
00163                         _u8PwrSM = BTSM_START;
00164                     }
00165                     else if ( _u16PwrTimer == 0 )
00166                     {
00167                         // Long push detected!
00168                         _u8PwrSM = BTSM_LONG_PUSH_MASK;
00169                     }
00170                     else
00171                     {
00172                         // Waiting...
00173                         _u16PwrTimer--;
00174                     }
00175                     break;
00176             }
00177         }
00178 
00179         if ((_u8BtnSM[i] == BTSM_START) && (_u8BtnDebounce[i] == 0xFF))
00180         {
00181             // After reseting the state machine the SM waits for a released
00182             // button (Release = 80 ms an inactive button).
00183             _u8BtnSM[i] = BTSM_IDLE;
00184         }
00185         else
00186         {
00187             switch(_u8BtnSM[i] & 0x0F)
00188             {
00189                 case BTSM_IDLE:
00190                     // Waiting for a pushed button (pushed = 80 ms active).
00191                     if (_u8BtnDebounce[i] == 0x00)
00192                     {
00193                         // Push detected!
00194                         _u8BtnSM[i] = BTSM_PRESSED_FIRST;
00195                         // Wait for releasing the button (longer pushes
00196                         // lead to the set of the flag BTSM_LONG_PUSH_MASK).
00197                         _u16BtnTimer[i] = BTN_LONG_PUSH_TIME;
00198                     }
00199                     break;
00200 
00201                 case BTSM_PRESSED_FIRST:
00202                     // First button push is recognized, waiting for a button
00203                     // release now (Release = 80 ms an inactive button).
00204                     if (_u8BtnDebounce[i] == 0xFF)
00205                     {
00206                         // Set the flag for a detected single push and enter
00207                         // the next state.
00208                         _u8BtnSM[i] = BTSM_RELEASED_FIRST | BTSM_PUSH_MASK;
00209                         // Wait some time for a second push:
00210                         _u16BtnTimer[i] = BTN_DOUBLE_PUSH_TIME;
00211                     }
00212                     else if (_u16BtnTimer[i] == 0)
00213                     {
00214                         // Time for a long push has elapsed, set the flag for a
00215                         // long push. This flag is set independently of the 
00216                         // button state machine. 
00217                         _u8BtnSM[i] = BTSM_LONG_PUSH_MASK;
00218                     }
00219                     else
00220                     {
00221                         // Decrease the timer until zero.
00222                         _u16BtnTimer[i]--;
00223                     }
00224                     break;
00225 
00226                 case BTSM_RELEASED_FIRST:
00227                     if (_u8BtnDebounce[i] == 0x00)
00228                     {
00229                         // The second push was detected. Enter the next state 
00230                         // but without affecting the flags which may be set
00231                         // like the single and long push flags.
00232                         _u8BtnSM[i] &= ~BTSM_RELEASED_FIRST;
00233                         _u8BtnSM[i] |= BTSM_PRESSED_SECOND;
00234                     }
00235                     else if (_u16BtnTimer[i] == 0)
00236                     {
00237                         // The time for a double push has elapsed, reset the
00238                         // state machine (state = BTSM_START).
00239                         _u8BtnSM[i] &= 0xF0;
00240                     }
00241                     else
00242                     {
00243                         // Waiting...
00244                         _u16BtnTimer[i]--;
00245                     }
00246                     break;
00247 
00248                 case BTSM_PRESSED_SECOND:
00249                     if (_u8BtnDebounce[i] == 0xFF)
00250                     {
00251                         // The double push event is perfect, the user has 
00252                         // released the button a second time.
00253 
00254                         // Set the flag for the double push event and reset the
00255                         // state machine (state = BTSM_START).
00256                         _u8BtnSM[i] &= 0xF0;
00257                         _u8BtnSM[i] |= BTSM_DOUBLE_MASK;
00258                     }
00259                     break;
00260             }
00261         }
00262     }
00263 }
00264 
00265 // ////////////////////////////////////////////////////////////////////////////
00266 // ////////////////////////////////////////////////////////////////////////////
00267 
00268 void InputButtonReset(eButtonID eBtn)
00269 {
00270     if (eBtn == ALL_BTN)
00271     {
00272         BYTE i = 0;
00273         for ( ; i < BTN_COUNT; i++)
00274         {
00275             _u8BtnSM[i] = BTSM_START;
00276         }
00277     }
00278     else
00279     {   
00280         _u8BtnSM[eBtn] = BTSM_START;
00281     }
00282 }
00283 
00284 // ////////////////////////////////////////////////////////////////////////////
00285 // ////////////////////////////////////////////////////////////////////////////
00286 
00287 BOOL bInputButtonPushedOnce(eButtonID eBtn)
00288 {
00289     if ((_u8BtnSM[eBtn] & BTSM_PUSH_TEST_MASK) == BTSM_PUSH_MASK)
00290     {
00291         return TRUE;
00292     }
00293     else
00294     {
00295         return FALSE;
00296     }
00297 }
00298 
00299 // ////////////////////////////////////////////////////////////////////////////
00300 // ////////////////////////////////////////////////////////////////////////////
00301 
00302 void InputResetButtonPush(eButtonID eBtn)
00303 {
00304     _u8BtnSM[eBtn] &= ~BTSM_PUSH_MASK;
00305 }
00306 
00307 // ////////////////////////////////////////////////////////////////////////////
00308 // ////////////////////////////////////////////////////////////////////////////
00309 
00310 void InputResetPowerButton(void)
00311 {
00312     _u8PwrSM = BTSM_START;
00313     _u8BtnSM[PWR_BTN] = BTSM_START;
00314 }
00315 
00316 // ////////////////////////////////////////////////////////////////////////////
00317 // ////////////////////////////////////////////////////////////////////////////
00318 
00319 BOOL bInputButtonPushedTwice(eButtonID eBtn)
00320 {
00321     if (_u8BtnSM[eBtn] & BTSM_DOUBLE_MASK)
00322     {
00323         return TRUE;
00324     }
00325     else
00326     {
00327         return FALSE;
00328     }
00329 }
00330 
00331 // ////////////////////////////////////////////////////////////////////////////
00332 // ////////////////////////////////////////////////////////////////////////////
00333 
00334 BOOL bInputButtonPushedLong(eButtonID eBtn)
00335 {
00336     if (eBtn == PWR_BTN)
00337     {
00338         if (_u8PwrSM == BTSM_LONG_PUSH_MASK)
00339         {
00340             return TRUE;
00341         }
00342     }
00343     else
00344     {
00345         if (_u8BtnSM[eBtn] == BTSM_LONG_PUSH_MASK)
00346         {
00347             return TRUE;
00348         }
00349     }
00350     return FALSE;
00351 }
00352 
00353 // ////////////////////////////////////////////////////////////////////////////
00354 // ////////////////////////////////////////////////////////////////////////////
00355 
00356 BYTE u8InputButtonQuickPushed(void)
00357 {
00358     if (_bCheckPush(F1_BTN))
00359     {
00360         return 0;
00361     }
00362     if (_bCheckPush(F2_BTN))
00363     {
00364         return 1;
00365     }
00366     if (_bCheckPush(F3_BTN))
00367     {
00368         return 2;
00369     }
00370     if (_bCheckPush(F4_BTN))
00371     {
00372         return 3;
00373     }   
00374 
00375     return 0xFF;
00376 }
00377 
00378 // ////////////////////////////////////////////////////////////////////////////
00379 // ////////////////////////////////////////////////////////////////////////////
00380 
00381 static BOOL _bCheckPush(eButtonID eBtn)
00382 {
00383     if (eBtn == ALL_BTN)
00384     {
00385         return FALSE;
00386     }
00387     else if ((_u8BtnSM[eBtn] & (BTSM_DOUBLE_MASK | BTSM_PUSH_MASK)) || 
00388         (_u8BtnSM[eBtn] == BTSM_LONG_PUSH_MASK))
00389     {
00390         return TRUE;
00391     }
00392     else
00393     {
00394         return FALSE;
00395     }
00396 }
00397 
00398 // ////////////////////////////////////////////////////////////////////////////
00399 // ////////////////////////////////////////////////////////////////////////////
00400 
00401 BOOL bInputButtonPressed(eButtonID eBtn)
00402 {
00403     if (_u8BtnDebounce[eBtn] == 0x00)
00404     {
00405         return TRUE;
00406     }
00407     
00408     return FALSE;
00409 }
00410 
00411 // ////////////////////////////////////////////////////////////////////////////
00412 // ////////////////////////////////////////////////////////////////////////////
00413 
00414 BOOL bInputButtonPushed(eButtonID eBtn)
00415 {
00416     if (eBtn == ALL_BTN)
00417     {
00418         eButtonID i = 0;
00419         for (i=PWR_BTN; i <= ENC_BTN; i++)
00420         {
00421             if(_bCheckPush(i)==TRUE)
00422             {
00423                 return TRUE;
00424             }
00425         }
00426         return FALSE;
00427     }
00428     else 
00429     {
00430         return _bCheckPush(eBtn);
00431     }
00432 }
00433 
00434 // ////////////////////////////////////////////////////////////////////////////
00435 // ////////////////////////////////////////////////////////////////////////////
00436 
00437 void InputEncoderInit(SHORT s16Val, SHORT s16Min, SHORT s16Max, BYTE u8Flags)
00438 {
00439     BOOL tmp = PIE1bits.CCP1IE;     // Remember current interrupt state.
00440 
00441     // Thread safe access.
00442     PIE1bits.CCP1IE = 0;
00443 
00444     if (u8Flags & ENC_NOCHANGE_MASK)
00445     {
00446         InputEncoderSetValue(s16Val, FALSE);
00447     }
00448     else
00449     {
00450         InputEncoderSetValue(s16Val, TRUE);
00451     }
00452 
00453     _s16EncMin = s16Min;
00454     _s16EncMax = s16Max;
00455     _u8EncFlags = u8Flags;
00456 
00457     if (((s16Max - s16Min) <= 30) || ((u8Flags & ENC_TURBO_MASK)==0))
00458     {
00459         _u16EncMaxInc = 1;
00460     }
00461     else if ((s16Max - s16Min) <= 99)
00462     {
00463         _u16EncMaxInc = 5;
00464     }
00465     else
00466     {
00467         _u16EncMaxInc = 10;
00468     }
00469 
00470     // Reset interrupt to last state.
00471     PIE1bits.CCP1IE = tmp;
00472 }
00473 
00474 // ////////////////////////////////////////////////////////////////////////////
00475 // ////////////////////////////////////////////////////////////////////////////
00476 
00477 SHORT s16InputEncoderGetValue(void)
00478 {
00479     SHORT tmpEncVal;
00480     BOOL tmp = PIE1bits.CCP1IE;     // Remember current interrupt state.
00481 
00482     // Thread safe access.
00483     PIE1bits.CCP1IE = 0;
00484 
00485     _s16EncLastVal = _s16EncVal;
00486      tmpEncVal = _s16EncVal;
00487 
00488     // Reset interrupt to last state.
00489     PIE1bits.CCP1IE = tmp;
00490 
00491     return tmpEncVal;
00492 }
00493 
00494 // ////////////////////////////////////////////////////////////////////////////
00495 // ////////////////////////////////////////////////////////////////////////////
00496 
00497 void InputEncoderSetValue(short s16NewVal, BOOL bRemember)
00498 {
00499     BOOL tmp = PIE1bits.CCP1IE;     // Remember current interrupt state.
00500 
00501     // Thread safe access.
00502     PIE1bits.CCP1IE = 0;
00503 
00504     _s16EncVal = s16NewVal;
00505     if (bRemember == TRUE)
00506     {
00507         _s16EncLastVal = s16NewVal+1;// For requesting bInputEncoderValueChanged()
00508     }
00509     else
00510     {
00511         _s16EncLastVal = s16NewVal;
00512     }
00513 
00514     // Reset interrupt to last state.
00515     PIE1bits.CCP1IE = tmp;
00516 }
00517 
00518 // ////////////////////////////////////////////////////////////////////////////
00519 // ////////////////////////////////////////////////////////////////////////////
00520 
00521 BOOL bInputEncoderValueChanged(void)
00522 {
00523     BOOL ret = TRUE;
00524     BOOL tmp = PIE1bits.CCP1IE;     // Remember current interrupt state.
00525     PIE1bits.CCP1IE = 0;            // Thread safe access.
00526 
00527     if (_s16EncLastVal == _s16EncVal)
00528     {
00529         ret = FALSE;
00530     }
00531 
00532     // Reset interrupt to last state.
00533     PIE1bits.CCP1IE = tmp;
00534 
00535     return ret;
00536 }
00537 
00538 // ////////////////////////////////////////////////////////////////////////////
00539 // ////////////////////////////////////////////////////////////////////////////
00540 
00541 void InputForceChangedEncoderValue(void)
00542 {
00543     BOOL tmp = PIE1bits.CCP1IE;     // Remember current interrupt state.
00544     PIE1bits.CCP1IE = 0;            // Thread safe access.
00545 
00546     _s16EncLastVal = _s16EncVal+1;
00547 
00548     // Reset interrupt to last state.
00549     PIE1bits.CCP1IE = tmp;
00550 }
00551 
00552 // ////////////////////////////////////////////////////////////////////////////
00553 // ////////////////////////////////////////////////////////////////////////////
00554 
00555 BOOL InputEncoderGetDirection(void)
00556 {
00557     return _bEncDirection;
00558 }
00559 
00560 // ////////////////////////////////////////////////////////////////////////////
00561 // ////////////////////////////////////////////////////////////////////////////
00562 
00563 BOOL IsEncoderTurning(void)
00564 {
00565     return _bEncTurning;
00566 }
00567 
00568 // ////////////////////////////////////////////////////////////////////////////
00569 // ////////////////////////////////////////////////////////////////////////////
00570 
00571 
00572 #if 0
00573 
00574 static BYTE u8EncTestSM = 0;
00575 
00576 void InputEncoderTest(void)
00577 {
00578     switch(u8EncTestSM)
00579     {
00580     case 0:
00581         InputEncoderInit(0, 0, 10000, ENC_TURBO_MASK);
00582         u8EncTestSM++;
00583         // Intended fall through.
00584 
00585     case 1:
00586         if (bInputEncoderValueChanged() == TRUE)
00587         {
00588             lcd_addr1 = 0;
00589             sprintf(lcdram_row2, (ROM char *) "%hu", s16InputEncoderGetValue());
00590             lcd_addr2 = 0;
00591             lcd_status = LCD_CLR_MASK | LCD_ROW2_MASK;
00592         }
00593     }
00594     return;
00595 }
00596 
00597 #endif
00598 
00599 // ////////////////////////////////////////////////////////////////////////////
00600 // ////////////////////////////////////////////////////////////////////////////
00601 
00602 static void initTimer(void)
00603 {
00604     // Init the 10 ms timer:
00605     T3CON = 0;  // Timer1 as clock source for CCP1
00606     T1CON = 0;  // Stop timer.
00607     // Init the periode register for a 10 ms duration and 1:2 prescaler...
00608     CCPR1H = (GetPeripheralClock() * 0.002) / 256;
00609     CCPR1L = (GetPeripheralClock() * 0.002);
00610     CCP1CON = 0x0A;     // Compare mode, generate software interrupt on match.
00611     IPR1bits.CCP1IP = 0;    // Low interrupt priority.
00612     PIE1bits.CCP1IE = 0;    // Disable the interrupt flag.
00613 
00614     PIR1bits.CCP1IF = 0;    // Clearing the compare match interrupt flag.
00615     TMR1H = 0;              // Clearing the 
00616     TMR1L = 0;              // timer values.
00617     T1CON = 0x81;           // 16 Bit | 1:1 Prescaler | internal source | on
00618     PIE1bits.CCP1IE = 1;    // Enable the interrupt.
00619 }
00620 
00621 // ////////////////////////////////////////////////////////////////////////////
00622 // ////////////////////////////////////////////////////////////////////////////
00623 
00624 // Define the encoder periodic of timer in units of ms:
00625 #define ENCODER_CYCLE   2u
00626 
00627 #define ENCODER_PAUSE                       (250u)
00628 #define ENCODER_PAUSE_CYCLE                 (10u)
00629 #define ENCODER_FIRST_ACCELERATION_STEP     (30u)
00630 #define ENCODER_SECOND_ACCELERATION_STEP    (10u)
00631 
00632 
00633 
00634 // Calculation defines, do not change!
00635 #define ENCODER_PAUSE_CALCED    (ENCODER_PAUSE / ENCODER_CYCLE)
00636 #define ENCODER_PAUSE_CYCLE_CALCED  (ENCODER_PAUSE_CYCLE / ENCODER_CYCLE)
00637 #define ENCODER_FIRST_ACCELERATION_STEP_CALCED  (ENCODER_FIRST_ACCELERATION_STEP / ENCODER_CYCLE)
00638 #define ENCODER_SECOND_ACCELERATION_STEP_CALCED (ENCODER_SECOND_ACCELERATION_STEP / ENCODER_CYCLE)
00639 
00640 
00641 void InputInterruptHandler(void)
00642 {
00643     if (PIR1bits.CCP1IF == 0)
00644     {
00645         return;
00646     }
00647 
00648 
00649     // ////////////////////////////////////////////////////////////////////////
00650     // Rotary encoder input handling
00651     // ////////////////////////////////////////////////////////////////////////
00652 
00653     if (_bEncTurning == TRUE)
00654     {
00655         if (_bEncTrigger == FALSE)
00656         {
00657             if (_u8EncPause++ > ENCODER_PAUSE_CALCED)
00658             {
00659                 _bEncTurning = FALSE;
00660                 _u16EncIncrement = 1;
00661                 _u8EncPause = 0;
00662             }
00663         }
00664         else
00665         {
00666             if ((_u8EncPause == 0) || (_u8EncPause > ENCODER_FIRST_ACCELERATION_STEP_CALCED))
00667             {
00668                 // First step || big delay between the triggers: Small step.
00669                 _u16EncIncrement = 1;
00670             }
00671             else if (_u8EncPause > ENCODER_SECOND_ACCELERATION_STEP_CALCED)
00672             {
00673                 // Middle delay between the triggers: Middle step.
00674                 if (_u16EncMaxInc >= 10)
00675                 {
00676                     _u16EncIncrement = 5;
00677                 }
00678                 else
00679                 {
00680                     _u16EncIncrement = _u16EncMaxInc;
00681                 }
00682             }
00683             else
00684             {
00685                 // Small delay between the triggers: Big step.
00686                 _u16EncIncrement = _u16EncMaxInc;
00687             }
00688 
00689             _u8EncPause = ENCODER_PAUSE_CYCLE_CALCED;
00690         }
00691     }
00692 
00693 
00694     // Read in the rotary encoder inputs:
00695     _u16Enc = (_u16Enc << 2) & 0x0C;
00696     _u16Enc |= (PORTD >> 1) & 0x03;
00697 
00698     
00699     // Check for any pushes on the encoder button. If detected, abort the 
00700     // rotary input processing for a better usage.
00701     if(_u8BtnSM[ENC_BTN] <= BTSM_IDLE)
00702     {
00703     
00704         // ////////////////////////////////////////////////////////////////////////
00705         // Analysing the encoder value (Greycode statemachine):
00706         // -> Bit 3 and bit 2 are the old states, bit 1 and bit 0 are the new ones.
00707         // -> State transitions, which are not allowed in greycode are ignored. 
00708         // -> State transitions, where the old state is equal the new state are 
00709         //    ignored.
00710         // State table (4 bit means 16 possibilities):
00711         // Index |      Old      |      New      |  Addend for
00712         //       | Bit 3 | Bit 2 | Bit 1 | Bit 0 | encoder value
00713         //       | RIGHT | LEFT  | RIGHT | LEFT  |
00714         //   0   |   0   |   0   |   0   |   0   |       0     
00715         //   1   |   0   |   0   |   0   |   1   |       0   
00716         //   2   |   0   |   0   |   1   |   0   |       0
00717         //   3   |   0   |   0   |   1   |   1   |      -1
00718         //   4   |   0   |   1   |   0   |   0   |       0
00719         //   5   |   0   |   1   |   0   |   1   |       0
00720         //   6   |   0   |   1   |   1   |   0   |       0
00721         //   7   |   0   |   1   |   1   |   1   |       0 
00722         //   8   |   1   |   0   |   0   |   0   |      -1
00723         //   9   |   1   |   0   |   0   |   1   |       0
00724         //  10   |   1   |   0   |   1   |   0   |       0
00725         //  11   |   1   |   0   |   1   |   1   |      +1
00726         //  12   |   1   |   1   |   0   |   0   |      +1
00727         //  13   |   1   |   1   |   0   |   1   |       0
00728         //  14   |   1   |   1   |   1   |   0   |       0
00729         //  15   |   1   |   1   |   1   |   1   |       0
00730         // It appears from the indices when increment the encoder value: 12, 11.
00731         // And the decrement indices are: 3, 8. The rest of the indices are
00732         // don't cares.
00733     
00734     
00735         _bEncTrigger = FALSE;
00736     
00737         switch(_u16Enc)
00738         {
00739         case 12:
00740         case 11:
00741             if ((_bEncTurning == FALSE) || (_bEncDirection==FALSE))
00742             {
00743                 // Only jump in here if the encoder wheel is already turning
00744                 // or if turning the direction is left.
00745     
00746                 _s16EncVal += _u16EncIncrement;
00747                 _bEncTurning = TRUE;
00748                 _bEncDirection = FALSE;
00749                 _bEncTrigger = TRUE;
00750     
00751                 if (_s16EncVal > _s16EncMax)
00752                 {
00753                     if (_u8EncFlags & ENC_ENDSTOP_MASK)
00754                     {
00755                         _s16EncVal = _s16EncMax;
00756                     }
00757                     else
00758                     {
00759                         _s16EncVal = _s16EncMin;
00760                     }
00761                 }
00762             }
00763             break;
00764     
00765         case 3:
00766         case 8:
00767             if ((_bEncTurning == FALSE)||(_bEncDirection==TRUE))
00768             {
00769                 // Only jump in here if the encoder wheel is already turning
00770                 // or if turning the direction is right.
00771     
00772                 _s16EncVal -= _u16EncIncrement;
00773                 _bEncTurning = TRUE;
00774                 _bEncDirection = TRUE;
00775                 _bEncTrigger = TRUE;
00776     
00777                 if (_s16EncMin > _s16EncVal)
00778                 {
00779                     if (_u8EncFlags & ENC_ENDSTOP_MASK)
00780                     {
00781                         _s16EncVal = _s16EncMin;
00782                     }
00783                     else
00784                     {
00785                         _s16EncVal = _s16EncMax;
00786                     }
00787                 }
00788             }
00789             break;
00790         }
00791     }
00792 
00794     // Clear interrupt flag before leaving:
00795     PIR1bits.CCP1IF = 0;
00796 }
00797 
00798 // ////////////////////////////////////////////////////////////////////////////
00799 // ////////////////////////////////////////////////////////////////////////////

Generated on Sun Nov 27 20:02:38 2011 for eWicht by  doxygen 1.5.5