00001
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
00122 if(useIndex){
00123 if(qPin > 5){
00124 return false;
00125 }
00126 qPort->DIRCLR = (0x07<<qPin);
00127
00128
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
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
00168 EVSYS.CH0MUX = qPinInput;
00169 EVSYS.CH0CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;
00170 if(useIndex){
00171
00172
00173
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
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
00238 EVSYS.CH2MUX = qPinInput;
00239 EVSYS.CH2CTRL = EVSYS_DIGFILT_4SAMPLES_gc;
00240
00241
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 }