1

Problem:

  • I'm using Due's QDEC function to decode a 32bit quadrature encoder.
  • I need to pipe out the counter value as fast as possible to another instrument's DIO.
  • The rear strip is selected as digital output because it's easy to slap an IDC connector on it.
#define QA 2
#define QB 13
const unsigned int mask_QA = digitalPinToBitMask(QA);
const unsigned int mask_QB = digitalPinToBitMask(QB);

void setup() {
    Serial.begin(115200); 
    delay(100);
   
    // QDEC block
    REG_PIOB_PDR = mask_QA;     // activate peripheral function 
    REG_PIOB_ABSR |= mask_QA;   // choose peripheral option B   
    REG_PIOB_PDR = mask_QB;
    REG_PIOB_ABSR |= mask_QB;  
   
    REG_PMC_PCER0 = (1<<27);                                // activate clock for TC0 (PID27)
    REG_TC0_CMR0 = (1 << 0) | (1 << 2) | (1<<8) | (1<<10);  // config clock
    REG_TC0_BMR = (1<<9)|(1<<8)|(1<<12);                    // activate QDEC   
    REG_TC0_CCR0 = 5;                                       // enable the clock and reset counter

    //PIO BLOCK
    // mask write, the rear strip of Arduino Due
    REG_PIOA_OWER = 0x0018c808; // A 7 14 15 19 20
    REG_PIOB_OWER = 0x04204000; // B 14 21 26
    REG_PIOC_OWER = 0x000FF3FE; // C 1-9 12-19
    REG_PIOD_OWER = 0x0000064F; // D 0 1 2 3 6 9 10
}   
void loop() {

  // data write
  REG_PIOA_ODSR = REG_TC0_CV0;
  REG_PIOB_ODSR = REG_TC0_CV0;
  REG_PIOC_ODSR = REG_TC0_CV0;
  REG_PIOD_ODSR = REG_TC0_CV0;
}
  • This code is untested as I don't have access to the hardware right now.
  • Basically 4 bit masks (for PIO ABCD) are created to map the 32bit REG_TC0_CV0 onto the rear strip.

Requirement:

  • [Priority] As little delay as possible, every clock cycle matters.
  • [Secondary] Output bandwidth should match the update rate of REG_TC0_CV0, which I didn't manage to find in the manual. The output should also provide a latch for the receiving equipment to sync sampling.

Question:

  • Would disabling peripheral functions for all 32 pins on the rear strip interfere with the core functionality that this program depends on (timer/counter etc) ?
  • Are there other ways that can accomplish this faster ?
  • I would like to use the main CPU tread for serial interface. It is possible to attach the four ODSR writing instructions to a timer ISR so it does not interfere with void loop()?

Thanks in advance !

5
  • please post a link to the quadrature encoder .... it actually makes no sense that it would require a 32 bit interface – jsotola Nov 22 '20 at 23:01
  • @jsotola The quadrature encoder is from a scientific-grade brushless linear motor. I don't know the exact part number but the linear motor has the precision of 20000 counts/mm, and the max travel of the motor is 220mm. So the top count is 4400000, which requires at least 23 bits. Also the output format of REG_TC0_CV0 is 32 bits. – 7E10FC9A Nov 23 '20 at 11:04
  • Define as fast as possible? once per second, a 100,000,000 times a second, both are possible but there is a upper limit to what you can do with a processor, additional hardware may be needed. More Information Please? – Gil Nov 24 '20 at 2:05
  • @Gil Thanks for your interests in my question. I have updated the question to better define "fast". – 7E10FC9A Nov 24 '20 at 11:42
  • @Gil 100MHz possible ? I thought the MCK is 84MHz. However that's irrelevant as the output should be attached to ISR for when REG_TC0_CV0 became available. – 7E10FC9A Nov 24 '20 at 12:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.