AVR1600 Using the XMEGA Quadrature Decoder
qdec_driver.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation. */
65 #include "qdec_driver.h"
66 
87 bool QDEC_Total_Setup(PORT_t * qPort,
88  uint8_t qPin,
89  bool invIO,
90  uint8_t qEvMux,
91  EVSYS_CHMUX_t qPinInput,
92  bool useIndex,
93  EVSYS_QDIRM_t qIndexState,
94  TC0_t * qTimer,
95  TC_EVSEL_t qEventChannel,
96  uint8_t lineCount)
97 {
98  if( !QDEC_Port_Setup(qPort, qPin, useIndex, invIO) )
99  return false;
100  if( !QDEC_EVSYS_Setup(qEvMux, qPinInput, useIndex, qIndexState ) )
101  return false;
102  QDEC_TC_Dec_Setup(qTimer, qEventChannel, lineCount);
103 
104  return true;
105 }
106 
107 
118 bool QDEC_Port_Setup(PORT_t * qPort, uint8_t qPin, bool useIndex, bool invIO)
119 {
120  /* Make setup depending on if Index signal is used. */
121  if(useIndex){
122  if(qPin > 5){
123  return false;
124  }
125  qPort->DIRCLR = (0x07<<qPin);
126 
127  /* Configure Index signal sensing. */
128  PORTCFG.MPCMASK = (0x04<<qPin);
129  qPort->PIN0CTRL = (qPort->PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_BOTHEDGES_gc
130  | (invIO ? PORT_INVEN_bm : 0);
131 
132 
133  }else{
134  if(qPin > 6){
135  return false;
136  }
137  qPort->DIRCLR = (0x03<<qPin);
138  }
139 
140  /* Set QDPH0 and QDPH1 sensing level. */
141  PORTCFG.MPCMASK = (0x03<<qPin);
142  qPort->PIN0CTRL = (qPort->PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_LEVEL_gc
143  | (invIO ? PORT_INVEN_bm : 0);
144 
145  return true;
146 }
147 
148 
158 bool QDEC_EVSYS_Setup(uint8_t qEvMux,
159  EVSYS_CHMUX_t qPinInput,
160  bool useIndex,
161  EVSYS_QDIRM_t qIndexState )
162 {
163  switch (qEvMux){
164  case 0:
165 
166  /* Configure event channel 0 for quadrature decoding of pins. */
167  EVSYS.CH0MUX = qPinInput;
168  EVSYS.CH0CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;
169  if(useIndex){
170  /* Configure event channel 1 as index channel. Note
171  * that when enabling Index in channel n, the channel
172  * n+1 must be configured for the index signal.*/
173  EVSYS.CH1MUX = qPinInput + 2;
174  EVSYS.CH1CTRL = EVSYS_DIGFILT_2SAMPLES_gc;
175  EVSYS.CH0CTRL |= (uint8_t) qIndexState | EVSYS_QDIEN_bm;
176 
177  }
178  break;
179  case 2:
180  EVSYS.CH2MUX = qPinInput;
181  EVSYS.CH2CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;
182  if(useIndex){
183  EVSYS.CH3MUX = qPinInput + 2;
184  EVSYS.CH3CTRL = EVSYS_DIGFILT_2SAMPLES_gc;
185  EVSYS.CH2CTRL |= (uint8_t) qIndexState | EVSYS_QDIEN_bm;
186  }
187  break;
188  case 4:
189  EVSYS.CH4MUX = qPinInput;
190  EVSYS.CH4CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;
191  if(useIndex){
192  EVSYS.CH5MUX = qPinInput + 2;
193  EVSYS.CH5CTRL = EVSYS_DIGFILT_2SAMPLES_gc;
194  EVSYS.CH4CTRL |= (uint8_t) qIndexState | EVSYS_QDIEN_bm;
195  }
196  break;
197  default:
198  return false;
199  }
200  return true;
201 }
202 
210 void QDEC_TC_Dec_Setup(TC0_t * qTimer, TC_EVSEL_t qEventChannel, uint8_t lineCount)
211 {
212  /* Configure TC as a quadrature counter. */
213  qTimer->CTRLD = (uint8_t) TC_EVACT_QDEC_gc | qEventChannel;
214  qTimer->PER = (lineCount * 4) - 1;
215  qTimer->CTRLA = TC_CLKSEL_DIV1_gc;
216 }
217 
218 
231 void QDEC_TC_Freq_Setup(TC0_t * qTimer,
232  TC_EVSEL_t qEventChannel,
233  EVSYS_CHMUX_t qPinInput,
234  TC_CLKSEL_t clksel)
235 {
236  /* Configure channel 2 to input pin for freq calculation. */
237  EVSYS.CH2MUX = qPinInput;
238  EVSYS.CH2CTRL = EVSYS_DIGFILT_4SAMPLES_gc;
239 
240  /* Configure TC to capture frequency. */
241  qTimer->CTRLD = (uint8_t) TC_EVACT_FRQ_gc | qEventChannel;
242  qTimer->PER = 0xFFFF;
243  qTimer->CTRLB = TC0_CCAEN_bm;
244  qTimer->CTRLA = clksel;
245 }
246 
247 
255 uint8_t QDEC_Get_Direction(TC0_t * qTimer)
256 {
257  if (qTimer->CTRLFSET & TC0_DIR_bm){
258  return CW_DIR;
259  }else{
260  return CCW_DIR;
261  }
262 }
bool QDEC_EVSYS_Setup(uint8_t qEvMux, EVSYS_CHMUX_t qPinInput, bool useIndex, EVSYS_QDIRM_t qIndexState)
This function configure the event system for quadrature decoding.
Definition: qdec_driver.c:158
uint8_t QDEC_Get_Direction(TC0_t *qTimer)
This function return the direction of the counter/QDEC.
Definition: qdec_driver.c:255
bool QDEC_Port_Setup(PORT_t *qPort, uint8_t qPin, bool useIndex, bool invIO)
This function set up the needed configuration for the port used for the quadrature decoding...
Definition: qdec_driver.c:118
The XMEGA Quadrature Decoder driver header file.
bool QDEC_Total_Setup(PORT_t *qPort, uint8_t qPin, bool invIO, uint8_t qEvMux, EVSYS_CHMUX_t qPinInput, bool useIndex, EVSYS_QDIRM_t qIndexState, TC0_t *qTimer, TC_EVSEL_t qEventChannel, uint8_t lineCount)
Wrapperfunction to set up all parameters for the quadrature decoder.
Definition: qdec_driver.c:87
uint8_t lineCount
Number of lines in the quadrature encoder.
Definition: qdec_example.c:72
void QDEC_TC_Dec_Setup(TC0_t *qTimer, TC_EVSEL_t qEventChannel, uint8_t lineCount)
This function set up the needed configuration for the Timer/Counter to handle the quadrature decoding...
Definition: qdec_driver.c:210
#define CW_DIR
Definition: qdec_driver.h:63
void QDEC_TC_Freq_Setup(TC0_t *qTimer, TC_EVSEL_t qEventChannel, EVSYS_CHMUX_t qPinInput, TC_CLKSEL_t clksel)
This function set up the needed configuration for a Timer/Counter to handle the frequency/speed measu...
Definition: qdec_driver.c:231
#define CCW_DIR
Definition: qdec_driver.h:64
@DOC_TITLE@
Generated on Thu Oct 26 2017 13:33:37 for AVR1600 Using the XMEGA Quadrature Decoder by doxygen 1.8.13