Caddy
A 2005 Roborodentia entry with vision and path planning capability
 All Data Structures Files Functions Variables Typedefs Macros Pages
encoder.c
Go to the documentation of this file.
1 /*
2  * This file is part of Caddy.
3  *
4  * Caddy is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Caddy is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Caddy. If not, see <http://www.gnu.org/licenses/>.
16  */
18 //*****************************************************************************
19 //
20 // File Name : 'encoder.c'
21 // Title : Quadrature Encoder reader/driver
22 // Author : Pascal Stang - Copyright (C) 2003-2004
23 // Created : 2003.01.26
24 // Revised : 2004.06.25
25 // Version : 0.3
26 // Target MCU : Atmel AVR Series
27 // Editor Tabs : 4
28 //
29 // NOTE: This code is currently below version 1.0, and therefore is considered
30 // to be lacking in some functionality or documentation, or may not be fully
31 // tested. Nonetheless, you can expect most functions to work.
32 //
33 // This code is distributed under the GNU Public License
34 // which can be found at http://www.gnu.org/licenses/gpl.txt
35 //
36 //*****************************************************************************
37 #ifndef WIN32
38 #include <avr/io.h>
39 #include <avr/interrupt.h>
40 #endif
41 
42 #include "global.h"
43 #include "encoder.h"
44 
45 // Program ROM constants
46 
47 // Global variables
48 volatile EncoderStateType EncoderState[NUM_ENCODERS];
49 
50 // Functions
51 
52 // encoderInit() initializes hardware and encoder position readings
53 // Run this init routine once before using any other encoder functions.
54 inline void encoderInit(void)
55 {
56  uint8_t i;
57 
58  // initialize/clear encoder data
59  for (i = 0; i < NUM_ENCODERS; i++)
60  {
61  EncoderState[i].position = 0;
62  //EncoderState[i].velocity = 0; // NOT CURRENTLY USED
63  }
64 
65  // configure direction and interrupt I/O pins:
66  // - for input
67  // - apply pullup resistors
68  // - any-edge interrupt triggering
69  // - enable interrupt
70 
71 #ifdef ENC0_SIGNAL
72  // set interrupt pins to input and apply pullup resistor
73  cbi(ENC0_PHASEA_DDR, ENC0_PHASEA_PIN);
74  sbi(ENC0_PHASEA_PORT, ENC0_PHASEA_PIN);
75  // configure interrupts for any-edge triggering
76  sbi(ENC0_ICR, ENC0_ISCX0);
77  cbi(ENC0_ICR, ENC0_ISCX1);
78  // enable interrupts
79  sbi(IMSK, ENC0_INT);
80  // ISMK is auto-defined in encoder.h
81 #endif
82 #ifdef ENC1_SIGNAL
83  // set interrupt pins to input and apply pullup resistor
84  cbi(ENC1_PHASEA_DDR, ENC1_PHASEA_PIN);
85  sbi(ENC1_PHASEA_PORT, ENC1_PHASEA_PIN);
86  // configure interrupts for any-edge triggering
87  sbi(ENC1_ICR, ENC1_ISCX0);
88  cbi(ENC1_ICR, ENC1_ISCX1);
89  // enable interrupts
90  sbi(IMSK, ENC1_INT);
91  // ISMK is auto-defined in encoder.h
92 #endif
93 #ifdef ENC2_SIGNAL
94  // set interrupt pins to input and apply pullup resistor
95  cbi(ENC2_PHASEA_DDR, ENC2_PHASEA_PIN);
96  sbi(ENC2_PHASEA_PORT, ENC2_PHASEA_PIN);
97  // configure interrupts for any-edge triggering
98  sbi(ENC2_ICR, ENC2_ISCX0);
99  cbi(ENC2_ICR, ENC2_ISCX1);
100  // enable interrupts
101  sbi(IMSK, ENC2_INT);// ISMK is auto-defined in encoder.h
102 #endif
103 #ifdef ENC3_SIGNAL
104  // set interrupt pins to input and apply pullup resistor
105  cbi(ENC3_PHASEA_DDR, ENC3_PHASEA_PIN);
106  sbi(ENC3_PHASEA_PORT, ENC3_PHASEA_PIN);
107  // set encoder direction pin for input and apply pullup resistor
108  cbi(ENC3_PHASEB_DDR, ENC3_PHASEB_PIN);
109  sbi(ENC3_PHASEB_PORT, ENC3_PHASEB_PIN);
110  // configure interrupts for any-edge triggering
111  sbi(ENC3_ICR, ENC3_ISCX0);
112  cbi(ENC3_ICR, ENC3_ISCX1);
113  // enable interrupts
114  sbi(IMSK, ENC3_INT);// ISMK is auto-defined in encoder.h
115 #endif
116 
117  // enable global interrupts
118  sei();
119 }
120 
121 // encoderGetPosition() reads the current position of the encoder
122 uint16_t encoderGetPosition(uint8_t encoderNum)
123 {
124  // sanity check
125  if (encoderNum < NUM_ENCODERS)
126  return EncoderState[encoderNum].position;
127  else
128  return 0;
129 }
130 
131 // encoderSetPosition() sets the current position of the encoder
132 void encoderSetPosition(uint8_t encoderNum, uint16_t position)
133 {
134  // sanity check
135  if (encoderNum < NUM_ENCODERS)
136  EncoderState[encoderNum].position = position;
137  // else do nothing
138 }
139 
140 #ifdef ENC0_SIGNAL
141 
142 SIGNAL(ENC0_SIGNAL)
143 {
144  /********************************************/
145  /* Modified by Taylor */
146  /********************************************/
147  EncoderState[0].position++;
148 }
149 #endif
150 
151 #ifdef ENC1_SIGNAL
152 
153 SIGNAL(ENC1_SIGNAL)
154 {
155  /********************************************/
156  /* Modified by Taylor */
157  /********************************************/
158  EncoderState[1].position++;
159 }
160 #endif
161 
162 #ifdef ENC2_SIGNAL
163 
164 SIGNAL(ENC2_SIGNAL)
165 {
166  // encoder has generated a pulse
167  // check the relative phase of the input channels
168  // and update position accordingly
169  if( ((inb(ENC2_PHASEA_PORTIN) & (1<<ENC2_PHASEA_PIN)) == 0) ^
170  ((inb(ENC2_PHASEB_PORTIN) & (1<<ENC2_PHASEB_PIN)) == 0) )
171  {
172  EncoderState[2].position++;
173  }
174  else
175  {
176  EncoderState[2].position--;
177  }
178 }
179 #endif
180 
181 #ifdef ENC3_SIGNAL
182 
183 SIGNAL(ENC3_SIGNAL)
184 {
185  // encoder has generated a pulse
186  // check the relative phase of the input channels
187  // and update position accordingly
188  if( ((inb(ENC3_PHASEA_PORTIN) & (1<<ENC3_PHASEA_PIN)) == 0) ^
189  ((inb(ENC3_PHASEB_PORTIN) & (1<<ENC3_PHASEB_PIN)) == 0) )
190  {
191  EncoderState[3].position++;
192  }
193  else
194  {
195  EncoderState[3].position--;
196  }
197 }
198 #endif