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, 2020 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, 2020 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, 2020 at 2:05
  • @Gil Thanks for your interests in my question. I have updated the question to better define "fast".
    – 7E10FC9A
    Nov 24, 2020 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, 2020 at 12:01

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.