OSDN Git Service

[SCHEMATIC] Modify SW/MW/LW Preamp, insert galbanic-isolator replace of common-mode...
[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 unsigned char renc_flag;
37
38
39 void rencoder_init(void)
40 {
41    RENC_TRIS_A = 1;
42    RENC_TRIS_B = 1;
43    renc_count = 0;
44    renc_dir = RENC_NONE;
45    renc_state_a = RENC_PH_A;
46    renc_state_b = RENC_PH_B;
47    renc_reset_count = 0;
48    renc_flag = 0;
49 //   renc_penalty = 0;
50 }
51
52
53 void rencoder_restart(void)
54 {
55  //  T1CONbits.TMR1ON = 1;
56    T1CON = 0b10110100;// RD16, T1RUN=0, 1/32 fOSC, TNR1CS=0, TMR1ON=0;
57    TMR1H = (65536 - 400) >> 8; // Tick = 4us, Count = 600(2.4ms)
58    TMR1L = (65536 - 400) & 255;
59 //   T1CONbits.TMR1ON = 0;
60    PIR1bits.TMR1IF = 0;
61    PIE1bits.TMR1IE = 1;
62    IPR1bits.TMR1IP = 1;
63    T1CONbits.TMR1ON = 1;
64 }
65
66 void rencoder_start(void)
67 {
68     rencoder_stop();
69     rencoder_init();
70 //    rencoder_restart();
71     IOCB = 0b01100000; // RB5,RB6
72     INTCONbits.RBIF = 0;
73     INTCONbits.RBIE = 1;
74     INTCONbits.GIE = 1;
75     INTCONbits.PEIE = 1;
76
77 }
78
79 void rencoder_inthook(void)
80 {
81 //    IOCB = 0b01100000;
82 //    IOCBbits.IOCB4 = 1;
83     INTCONbits.RBIF = 0;
84     if(renc_flag != 0) return;
85 //    renc_state_a = RENC_PH_A;
86 //    renc_state_b = RENC_PH_B;
87     renc_flag = 0xff;
88     rencoder_restart();
89     rencoder_count();
90     INTCONbits.RBIE = 1;
91 }
92
93 void rencoder_tmrhook(void)
94 {
95     renc_flag = 0;
96     rencoder_count();
97     IOCB = 0b01100000;
98     INTCONbits.RBIF = 0;
99     INTCONbits.RBIE = 1;
100
101    PIR1bits.TMR1IF = 0;
102    PIE1bits.TMR1IE = 0;
103    IPR1bits.TMR1IP = 1;
104
105 }
106
107 void rencoder_stop(void)
108 {
109    T1CON = 0b10110100;
110    TMR1H = 0;
111    TMR1L = 0;
112    PIR1bits.TMR1IF = 0;
113    PIE1bits.TMR1IE = 0;
114    IPR1bits.TMR1IP = 1;
115     IOCB = 0b00000000; // RB5,RB6
116     INTCONbits.RBIE = 0;
117     INTCONbits.RBIF = 0;
118 //   rencoder_init();
119 }
120
121
122 void rencoder_count(void)
123 {
124    unsigned char dir = RENC_NONE;
125    unsigned char pha = RENC_PH_A;
126    unsigned char phb = RENC_PH_B;
127
128   // if(renc_flag != 0) return;
129 //   if(renc_penalty != 0){
130 //       renc_penalty++;
131 //       if(renc_penalty > 1) {
132 //           renc_penalty = 0;
133 //       }
134 //       return;
135 //   }
136    /*
137     * Count sequence description of rotary-encoder:
138     * See figure of http://homepage1.nifty.com/rikiya/software/113ROTENC.htm .
139     */
140    if(pha != renc_state_a) {
141        if(pha == 1){ // A: RISE UP
142            if(phb == 0){ // B: Stable
143                dir = RENC_RIGHT;
144            } else {
145                dir = RENC_LEFT;
146            }
147         //   renc_penalty++;
148         }
149     } else if(phb != renc_state_b){
150         if(phb == 1){ // B: RISE UP
151             if(pha == 0){ // A: Stable
152                 dir = RENC_LEFT;
153             } else {
154                 dir = RENC_RIGHT;
155             }
156       //      renc_penalty++;
157         }
158     }  else {
159      renc_reset_count++;
160      if(renc_reset_count >= 5000) { // 3200ms
161         renc_count = 0;
162         renc_dir = RENC_NONE;
163         renc_state_a = 0;
164         renc_state_b = 0;
165         renc_reset_count = 0;
166         //renc_penalty = 0;
167      }
168      return;
169    }
170    renc_state_a = pha;
171    renc_state_b = phb;
172    if(dir == RENC_NONE) return;
173
174    if(dir == renc_dir) {
175      renc_count++;
176    } else {
177      renc_count = 0;
178      renc_dir = dir;
179     }
180    renc_reset_count = 0;
181 //   rencoder_up(dir);
182 }
183
184          
185