Xmega Application Note


qdec_driver.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation. */
00066 #include "qdec_driver.h"
00067 
00088 bool QDEC_Total_Setup(PORT_t * qPort,
00089                       uint8_t qPin,
00090                       bool invIO,
00091                       uint8_t qEvMux,
00092                       EVSYS_CHMUX_t qPinInput,
00093                       bool useIndex,
00094                       EVSYS_QDIRM_t qIndexState,
00095                       TC0_t * qTimer,
00096                       TC_EVSEL_t qEventChannel,
00097                       uint8_t lineCount)
00098 {
00099         if( !QDEC_Port_Setup(qPort, qPin, useIndex, invIO) )
00100                 return false;
00101         if( !QDEC_EVSYS_Setup(qEvMux, qPinInput, useIndex, qIndexState ) )
00102                 return false;
00103         QDEC_TC_Dec_Setup(qTimer, qEventChannel, lineCount);
00104 
00105         return true;
00106 }
00107 
00108 
00119 bool QDEC_Port_Setup(PORT_t * qPort, uint8_t qPin, bool useIndex, bool invIO)
00120 {
00121         /* Make setup depending on if Index signal is used. */
00122         if(useIndex){
00123                 if(qPin > 5){
00124                         return false;
00125                 }
00126                 qPort->DIRCLR = (0x07<<qPin);
00127 
00128                 /* Configure Index signal sensing. */
00129                 PORTCFG.MPCMASK = (0x04<<qPin);
00130                 qPort->PIN0CTRL = (qPort->PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_BOTHEDGES_gc
00131                                   | (invIO ? PORT_INVEN_bm : 0);
00132 
00133 
00134         }else{
00135                 if(qPin > 6){
00136                         return false;
00137                 }
00138                 qPort->DIRCLR = (0x03<<qPin);
00139         }
00140 
00141         /* Set QDPH0 and QDPH1 sensing level. */
00142         PORTCFG.MPCMASK = (0x03<<qPin);
00143         qPort->PIN0CTRL = (qPort->PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_LEVEL_gc
00144                           | (invIO ? PORT_INVEN_bm : 0);
00145 
00146         return true;
00147 }
00148 
00149 
00159 bool QDEC_EVSYS_Setup(uint8_t qEvMux,
00160                       EVSYS_CHMUX_t qPinInput,
00161                       bool useIndex,
00162                       EVSYS_QDIRM_t qIndexState )
00163 {
00164         switch (qEvMux){
00165                 case 0:
00166                     
00167                 /* Configure event channel 0 for quadrature decoding of pins. */
00168                 EVSYS.CH0MUX = qPinInput;
00169                 EVSYS.CH0CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;
00170                 if(useIndex){
00171                         /*  Configure event channel 1 as index channel. Note
00172                          *  that when enabling Index in channel n, the channel
00173                          *  n+1 must be configured for the index signal.*/
00174                         EVSYS.CH1MUX = qPinInput + 2;
00175                         EVSYS.CH1CTRL = EVSYS_DIGFILT_2SAMPLES_gc;
00176                         EVSYS.CH0CTRL |= (uint8_t) qIndexState | EVSYS_QDIEN_bm;
00177 
00178                 }
00179                 break;
00180                 case 2:
00181                 EVSYS.CH2MUX = qPinInput;
00182                 EVSYS.CH2CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;
00183                 if(useIndex){
00184                         EVSYS.CH3MUX = qPinInput + 2;
00185                         EVSYS.CH3CTRL = EVSYS_DIGFILT_2SAMPLES_gc;
00186                         EVSYS.CH2CTRL |= (uint8_t) qIndexState | EVSYS_QDIEN_bm;
00187                 }
00188                 break;
00189                 case 4:
00190                 EVSYS.CH4MUX = qPinInput;
00191                 EVSYS.CH4CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;
00192                 if(useIndex){
00193                         EVSYS.CH5MUX = qPinInput + 2;
00194                         EVSYS.CH5CTRL = EVSYS_DIGFILT_2SAMPLES_gc;
00195                         EVSYS.CH4CTRL |= (uint8_t) qIndexState | EVSYS_QDIEN_bm;
00196                 }
00197                 break;
00198                 default:
00199                 return false;
00200         }
00201         return true;
00202 }
00203 
00211 void QDEC_TC_Dec_Setup(TC0_t * qTimer, TC_EVSEL_t qEventChannel, uint8_t lineCount)
00212 {
00213         /* Configure TC as a quadrature counter. */
00214         qTimer->CTRLD = (uint8_t) TC_EVACT_QDEC_gc | qEventChannel;
00215         qTimer->PER = (lineCount * 4) - 1;
00216         qTimer->CTRLA = TC_CLKSEL_DIV1_gc;
00217 }
00218 
00219 
00232 void QDEC_TC_Freq_Setup(TC0_t * qTimer,
00233                         TC_EVSEL_t qEventChannel,
00234                         EVSYS_CHMUX_t qPinInput,
00235                         TC_CLKSEL_t clksel)
00236 {
00237         /* Configure channel 2 to input pin for freq calculation. */
00238         EVSYS.CH2MUX = qPinInput;
00239         EVSYS.CH2CTRL = EVSYS_DIGFILT_4SAMPLES_gc;
00240 
00241         /* Configure TC to capture frequency. */
00242         qTimer->CTRLD = (uint8_t) TC_EVACT_FRW_gc | qEventChannel;
00243         qTimer->PER = 0xFFFF;
00244         qTimer->CTRLB = TC0_CCAEN_bm;
00245         qTimer->CTRLA = clksel;
00246 }
00247 
00248 
00256 uint8_t QDEC_Get_Direction(TC0_t * qTimer)
00257 {
00258         if (qTimer->CTRLFSET & TC0_DIR_bm){
00259                 return CW_DIR;
00260         }else{
00261                 return CCW_DIR;
00262         }
00263 }
@DOC_TITLE@
Generated on Wed Jul 30 09:22:36 2008 for AVR1600 Using the XMEGA Quadrature Decoder by doxygen 1.5.5