| AVR1600 Using the XMEGA Quadrature Decoder

Functions
qdec_driver.c File Reference

The XMEGA Quadrature Decoder driver source file. More...

`#include "qdec_driver.h"`
Include dependency graph for qdec_driver.c:

Go to the source code of this file.

## Functions
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. More...
uint8_t | QDEC_Get_Direction (TC0_t *qTimer)
| This function return the direction of the counter/QDEC. More...
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. More...
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 from the event system. More...
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 measurement from the event system. More...
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. More...

## Detailed Description

The XMEGA Quadrature Decoder driver source file.

This file contains the function prototypes and enumerator definitions for various configuration parameters for the XMEGA Quadrature Decoder.

The driver is not intended for size and/or speed critical code. The driver is intended for rapid prototyping and documentation purposes for getting started with the XMEGA Quadrature Decoder.

For size and/or speed critical code, it is recommended to copy the function contents directly into your application instead of making a function call.

Several functions use the following construct: "some_register = ... | (some_parameter ? SOME_BIT_bm : 0) | ..." Although the use of the ternary operator ( if ? then : else ) is discouraged, in some occasions the operator makes it possible to write pretty clean and neat code. In this driver, the construct is used to set or not set a configuration bit based on a boolean input parameter, such as the "some_parameter" in the example above.

Application note:
  AVR1600: Using the XMEGA Quadrature Decoder

Documentation
  For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html

Author
  Atmel Corporation, now Microchip Technology Inc.: http://www.microchip.com

Revision
  7623

Date
  2017-09-06 14:57:02 +0200 (on, 06 sep 2017)

Copyright (c) 2012, Atmel Corporation All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file qdec_driver.c.

## Function Documentation

## ◆ QDEC_EVSYS_Setup()

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.

Parameters

  qEvMux | Which event channel to use. Only 0, 2 and 4 is available.
  qPinInput | The pin input of QDPH0 to the EVSYS.CHMUX .
  useIndex | True if an optional Index pin is used.
  qIndexState | In which state the index signal will trigger.

Returns
  bool True if setup was ok, false if any errors.

Definition at line 158 of file qdec_driver.c.

Referenced by QDEC_Total_Setup().

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 }

## ◆ QDEC_Get_Direction()

uint8_t QDEC_Get_Direction | ( | TC0_t * | qTimer | ) |

This function return the direction of the counter/QDEC.

Parameters

  qTimer | The timer used for QDEC.

Return values

  CW_DIR | if clockwise/up counting,
  CCW_DIR | if counter clockwise/down counting.

Definition at line 255 of file qdec_driver.c.

References CCW_DIR, and CW_DIR.

256 {
257 if (qTimer->CTRLFSET & TC0_DIR_bm){
258 return CW_DIR;
259 }else{
260 return CCW_DIR;
261 }
262 }
CW_DIR
#define CW_DIR
Definition: qdec_driver.h:63
CCW_DIR
#define CCW_DIR
Definition: qdec_driver.h:64

## ◆ QDEC_Port_Setup()

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.

Parameters

  qPort | The port to use.
  qPin | The first input pin (QDPH0) to use (0 - 5/6).
  useIndex | True if an optional Index pin is used.
  invIO | True if IO pins should be inverted.

Returns
  bool True if setup was ok, false if any errors.

Definition at line 118 of file qdec_driver.c.

Referenced by QDEC_Total_Setup().

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 }

## ◆ QDEC_TC_Dec_Setup()

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 from the event system.

Parameters

  qTimer | The timer to use for QDEC.
  qEventChannel | The event channel to listen to.
  lineCount | The number of lines in the quadrature encoder.

Definition at line 210 of file qdec_driver.c.

Referenced by QDEC_Total_Setup().

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 }
lineCount
uint8_t lineCount
Number of lines in the quadrature encoder.
Definition: qdec_example.c:72

## ◆ QDEC_TC_Freq_Setup()

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 measurement from the event system.

Note
  The real frequency of rotation can be calculated from the capture register by using the folowing function. FREQ = ( F_CPU / clk_div ) / ( CAPTURE * lineCount )

Parameters

  qTimer | The timer to use for QDEC.
  qEventChannel | The event channel to listen to.
  qPinInput | The pin input of QDPH0 to the EVSYS.CHMUX.
  clksel | The clk div to use for timer.

Definition at line 231 of file qdec_driver.c.

Referenced by main().

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 }

## ◆ QDEC_Total_Setup()

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.

This function combines the following functions for a total setup: QDEC_Port_Setup, QDEC_EVSYS_Setup and QDEC_TC_Dec_Setup.

Parameters

  qPort | The port to use.
  qPin | The first input pin (QDPH0) to use (0 - 5/6).
  invIO | True if IO pins should be inverted.
  qEvMux | Which event channel to use. Only 0, 2 and 4 is available.
  qPinInput | The pin input of QDPH0 to the EVSYS.CHMUX .
  useIndex | True if an optional Index pin is used.
  qIndexState | In which state the index signal will trigger.
  qTimer | The timer to use for QDEC.
  qEventChannel | The event channel to listen to.
  lineCount | The number of lines in the quadrature encoder.

Returns
  bool True if setup was ok, false if any errors.

Definition at line 87 of file qdec_driver.c.

References QDEC_EVSYS_Setup(), QDEC_Port_Setup(), and QDEC_TC_Dec_Setup().

Referenced by main().

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 }
QDEC_EVSYS_Setup
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
QDEC_Port_Setup
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
lineCount
uint8_t lineCount
Number of lines in the quadrature encoder.
Definition: qdec_example.c:72
QDEC_TC_Dec_Setup
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
Here is the call graph for this function:
@DOC_TITLE@