OSDN Git Service

[UI][v2.0] Add rotary-encoder feature to USER FREQ MENU.
[openi2cradio/OpenI2CRadio.git] / rencoder.c
1 /*
2  * OpenI2CRADIO
3  * Rotary encoder routine.
4  * Copyright (C) 2013-10-21 K.Ohta <whatisthis.sowhat ai gmail.com>
5  * License: GPL2+LE
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2,
10  *  or (at your option) any later version.
11  *  This library / program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  *  See the GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this library; see the file COPYING. If not, write to the
18  *  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
19  *  MA 02110-1301, USA.
20  *
21  *  As a special exception, if you link this(includeed from sdcc) library
22  *  with other files, some of which are compiled with SDCC,
23  *  to produce an executable, this library does not by itself cause
24  *  the resulting executable to be covered by the GNU General Public License.
25  *  This exception does not however invalidate any other reasons why
26  *  the executable file might be covered by the GNU General Public License.
27  */
28 #include "rencoder.h"
29
30 static unsigned char renc_state_a;
31 static unsigned char renc_state_b;
32 unsigned char renc_dir;
33 unsigned int renc_count;
34 static unsigned int renc_reset_count;
35 //static unsigned char renc_penalty;
36
37 void rencoder_init(void)
38 {
39    RENC_TRIS_A = 1;
40    RENC_TRIS_B = 1;
41    renc_count = 0;
42    renc_dir = RENC_NONE;
43    renc_state_a = RENC_PH_A;
44    renc_state_b = RENC_PH_B;
45    renc_reset_count = 0;
46 //   renc_penalty = 0;
47 }
48
49
50 void rencoder_restart(void)
51 {
52  //  T1CONbits.TMR1ON = 1;
53    T1CON = 0b10110100;// RD16, T1RUN=0, 1/32 fOSC, TNR1CS=0, TMR1ON=0;
54    TMR1H = (65536 - 600) >> 8; // Tick = 4us, Count = 600(2.4ms)
55    TMR1L = (65536 - 600) & 255;
56 //   T1CONbits.TMR1ON = 0;
57    PIR1bits.TMR1IF = 0;
58    PIE1bits.TMR1IE = 1;
59    IPR1bits.TMR1IP = 1;
60    T1CONbits.TMR1ON = 1;
61 }
62
63 void rencoder_start(void)
64 {
65     rencoder_stop();
66     rencoder_init();
67     rencoder_restart();
68 }
69
70 void rencoder_stop(void)
71 {
72    T1CON = 0b10110100;
73    TMR1H = 0;
74    TMR1L = 0;
75    PIR1bits.TMR1IF = 0;
76    PIE1bits.TMR1IE = 0;
77    IPR1bits.TMR1IP = 1;
78 //   rencoder_init();
79 }
80
81
82 void rencoder_count(void)
83 {
84    unsigned char dir = RENC_NONE;
85    unsigned char pha = RENC_PH_A;
86    unsigned char phb = RENC_PH_B;
87
88 //   if(renc_penalty != 0){
89 //       renc_penalty++;
90 //       if(renc_penalty > 1) {
91 //           renc_penalty = 0;
92 //       }
93 //       return;
94 //   }
95    /*
96     * Count sequence description of rotary-encoder:
97     * See figure of http://homepage1.nifty.com/rikiya/software/113ROTENC.htm .
98     */
99    if(pha != renc_state_a) {
100        if(pha == 1){ // A: RISE UP
101            if(phb == 0){ // B: Stable
102                dir = RENC_RIGHT;
103            } else {
104                dir = RENC_LEFT;
105            }
106         //   renc_penalty++;
107         }
108     } else if(phb != renc_state_b){
109         if(phb == 1){ // B: RISE UP
110             if(pha == 0){ // A: Stable
111                 dir = RENC_LEFT;
112             } else {
113                 dir = RENC_RIGHT;
114             }
115       //      renc_penalty++;
116         }
117     }  else {
118      renc_reset_count++;
119      if(renc_reset_count >= 5000) { // 3200ms
120         renc_count = 0;
121         renc_dir = RENC_NONE;
122         renc_state_a = 0;
123         renc_state_b = 0;
124         renc_reset_count = 0;
125         //renc_penalty = 0;
126      }
127      return;
128    }
129    renc_state_a = pha;
130    renc_state_b = phb;
131    if(dir == RENC_NONE) return;
132
133    if(dir == renc_dir) {
134      renc_count++;
135    } else {
136      renc_count = 0;
137      renc_dir = dir;
138     }
139    renc_reset_count = 0;
140 //   rencoder_up(dir);
141 }
142
143          
144