Xmega Application Note


qdec_signal_generator.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation. */
00072 #include "avr_compiler.h"
00073 #include "qdec_signal_generator.h"
00074 
00076 PORT_t * q_test_sig_Port;
00077 
00078 
00080 uint8_t test_lineCount;
00081 
00082 
00095 void generate_qdec_signal(PORT_t * qPort, uint8_t lineCount, uint8_t freq, bool dir)
00096 {
00097         uint16_t ticks, quarter, half_quarter;
00098 
00099         /* The following code calculates the upper boundary of the timer and the
00100          * interrupt positions to get a correct Quadrature signal of the given frequency.
00101          *
00102          * The different compare interrupts sets the phase0 and phase90 signals.
00103          * Compare A interrupt sets phase0 and clears phase90
00104          * Compare B interrupt sets phase0 and phase90
00105          * Compare C interrupt clears phase0 and sets phase90
00106          * Compare D interrupt clears phase0 and phase90.
00107          *
00108          * Ccompare A interrupt also sets the index signal when one round has passed.
00109          */
00110 
00111         /* Calculates upper boundary of timer to get desired frequency.*/
00112         ticks = F_CPU / (freq * lineCount);
00113         quarter = ticks/4;
00114         half_quarter = ticks/8;
00115 
00116         if(dir == 1){
00117                 TCE0.CCA = half_quarter;
00118                 TCE0.CCB = half_quarter+quarter;
00119                 TCE0.CCC = half_quarter+(2*quarter);
00120                 TCE0.CCD = half_quarter+(3*quarter);
00121         }else{
00122                 TCE0.CCA = half_quarter+(3*quarter);
00123                 TCE0.CCB = half_quarter+(2*quarter);
00124                 TCE0.CCC = half_quarter+quarter;
00125                 TCE0.CCD = half_quarter;
00126         }
00127 
00128         TCE0.PER = ticks;
00129         TCE0.CTRLA = TC_CLKSEL_DIV1_gc;
00130 
00131         /* Enable low level interrupt on CCA, CCB, CCC and CCD.*/
00132         TCE0.INTCTRLB = TC0_CCAINTLVL0_bm | TC0_CCBINTLVL0_bm |
00133                         TC0_CCCINTLVL0_bm | TC0_CCDINTLVL0_bm;
00134         TCC0.INTCTRLA = TC0_ERRINTLVL0_bm;
00135 
00136         qPort->DIRSET = 0xFF;
00137         q_test_sig_Port = qPort;
00138 
00139         test_lineCount = lineCount;
00140 }
00141 
00142 
00146 ISR(TCE0_CCA_vect)
00147 {
00148         static uint16_t i = 0;
00149         
00150         /* Set pin0 Phase0 signal.*/
00151         q_test_sig_Port->OUT = (q_test_sig_Port->OUT & ~0x03) | 0x01; 
00152 
00153         i++;
00154 
00155         /* Clear index.*/
00156         q_test_sig_Port->OUT = (q_test_sig_Port->OUT & ~0x04);
00157 
00158         /*  When (i = test_lineCount) one round has passed.
00159          *  Includes a check for i "bigger than" for error handling.
00160          */
00161         if(i>=test_lineCount){
00162 
00163                 /* Set index. Lasts 4 states.*/
00164                 q_test_sig_Port->OUT |= 0x04;
00165                 i = 0;
00166         }
00167 }
00168 
00169 
00173 ISR(TCE0_CCB_vect)
00174 {
00175         /* Set pin0 and pin1 phase0 and phase90 signal.*/
00176         q_test_sig_Port->OUT = (q_test_sig_Port->OUT & ~0x03) | 0x01 | 0x02;
00177 }
00178 
00179 
00183 ISR(TCE0_CCC_vect)
00184 {
00185         /* Set pin1 phase90 signal. Clear pin0 phase0 signal.*/
00186         q_test_sig_Port->OUT = (q_test_sig_Port->OUT & ~0x03) | 0x02;
00187 }
00188 
00189 
00193 ISR(TCE0_CCD_vect)
00194 {
00195         /* Clear pin0 and pin1, phase0 and phase90 signal.*/
00196         q_test_sig_Port->OUT = (q_test_sig_Port->OUT & ~0x03);
00197 }
00198 
00199 
00206 ISR(TCC0_ERR_vect)
00207 {
00208         static uint8_t j = 0;
00209         j++;
00210 
00211         /* Since index needs to initialize, one error will happen first round.
00212          * If output is desired at every error, remove if statement or set (j>0).
00213          */
00214         if(j>2){
00215 
00216                 /* To test if index works, set breakpoint here.
00217                  * It should NOT break when index is correct.
00218                  */
00219                 q_test_sig_Port->OUT = q_test_sig_Port->OUT ^ 0x40;
00220                 j=0;
00221         }
00222 }
@DOC_TITLE@
Generated on Wed Jul 30 09:22:36 2008 for AVR1600 Using the XMEGA Quadrature Decoder by doxygen 1.5.5