Hi folks, summarizing from above, this is the minimal setup for using a two pin encoder as a knob on channel TC 0, Channel 0:
void setup() {
pmc_enable_periph_clk(ID_TC0);
TC_Configure(TC0,0, TC_CMR_TCCLKS_XC0);
TC0->TC_BMR = TC_BMR_QDEN // Enable QDEC (filter, edge detection and quadrature decoding)
| TC_BMR_POSEN // Enable the position measure on channel 0
//| TC_BMR_EDGPHA // Edges are detected on PHA only
//| TC_BMR_SWAP // Swap PHA and PHB if necessary (reverse acting)
| TC_BMR_FILTER // Enable filter
| TC_BMR_MAXFILT(63) // Set MAXFILT value
;
// Enable and trigger reset
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN;
}
void loop() {
int16_t count = REG_TC0_CV0;
}
This will return a positive or negative count. Note it will roll over at plus or minus 32767. In theory, you can avoid rollover by resetting the count to zero by calling
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN;
But in reality, this does not seem to quite get back to zero all the time. I just check to see if I am above 32000, or below -32000, and reset.
Hope this helps.
Doug