Go Down

Topic: Arm M0 (Arduino Zero / Adafruit M0) micros() value Error (Read 355 times) previous topic - next topic

gfvalvo

however the literature I can find suggests that:

Code: [Select]
1  Reset
 2  External Interrupt Request 0  (pin D2)          (INT0_vect)
 3  External Interrupt Request 1  (pin D3)          (INT1_vect)
 4  Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
 5  Pin Change Interrupt Request 1 (pins A0 to A5)  (PCINT1_vect)
 6  Pin Change Interrupt Request 2 (pins D0 to D7)  (PCINT2_vect)
 7  Watchdog Time-out Interrupt                     (WDT_vect)
 8  Timer/Counter2 Compare Match A                  (TIMER2_COMPA_vect)
 9  Timer/Counter2 Compare Match B                  (TIMER2_COMPB_vect)
10  Timer/Counter2 Overflow                         (TIMER2_OVF_vect)
11  Timer/Counter1 Capture Event                    (TIMER1_CAPT_vect)
12  Timer/Counter1 Compare Match A                  (TIMER1_COMPA_vect)
13  Timer/Counter1 Compare Match B                  (TIMER1_COMPB_vect)
14  Timer/Counter1 Overflow                         (TIMER1_OVF_vect)
15  Timer/Counter0 Compare Match A                  (TIMER0_COMPA_vect)
16  Timer/Counter0 Compare Match B                  (TIMER0_COMPB_vect)
17  Timer/Counter0 Overflow                         (TIMER0_OVF_vect)
18  SPI Serial Transfer Complete                    (SPI_STC_vect)
19  USART Rx Complete                               (USART_RX_vect)
20  USART, Data Register Empty                      (USART_UDRE_vect)
21  USART, Tx Complete                              (USART_TX_vect)
22  ADC Conversion Complete                         (ADC_vect)
23  EEPROM Ready                                    (EE_READY_vect)
24  Analog Comparator                               (ANALOG_COMP_vect)
25  2-wire Serial Interface  (I2C)                  (TWI_vect)
26  Store Program Memory Ready                      (SPM_READY_vect)


If the same holds true for SAMD-based architectures, then the input pin interrupts definitely take priority over the SysTick interrupt (TIMER0, correct?)
That looks like it's for AVR processors, so it's not at all applicable.

Quote
I used NVIC_GetPriority to obtain the priority of the SysTick overflow, which returned a priority of 2.

I do not know how many priority levels the SAMD21 has, however I tried setting the priority of the SysTick overflow to 0, and that eliminates the bad pulse readings.

While this is technically a fix for my problem, I'm sure that setting priorities like this can be dangerous and can carry other unwanted side-effects. Do you know what kind of side-effects it could have?
Rather than messing with the SysTick interrupt, I'd lower the EIC's priority:
Code: [Select]
NVIC_SetPriority(EIC_IRQn, 3);

If your pulse widths are all under 1ms, you could leave the priorities alone and record the raw (24-bit) SysTick values in the ISR. They count backwards at 48MHz from 47999 to 0 then reset.

Otherwise, I'd look into using the hardware timers and input capture features. I've only done low-level timer programming on Teensy (Freescale K20 / M3 Core) and AVR. So, you'll have to research it in the SAMD datasheet.
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

molimo140

That looks like it's for AVR processors, so it's not at all applicable.
Rather than messing with the SysTick interrupt, I'd lower the EIC's priority:
Code: [Select]
NVIC_SetPriority(EIC_IRQn, 3);

If your pulse widths are all under 1ms, you could leave the priorities alone and record the raw (24-bit) SysTick values in the ISR. They count backwards at 48MHz from 47999 to 0 then reset.

Otherwise, I'd look into using the hardware timers and input capture features. I've only done low-level timer programming on Teensy (Freescale K20 / M3 Core) and AVR. So, you'll have to research it in the SAMD datasheet.
I'm kind of thinking that changing the interrupt priorities at all is more of a kludge than an actual fix.. although if the kludge gets me where I need to be without introducing other problems, I'm fine with it.

Decreasing the priority of the EIC, interestingly, does not work. I still see the timing offset problem.

I was looking at hardware timer counters, but the datasheets are fairly obtuse and don't provide the information in a way which is easy to understand. What is available online is also sort of above my head... my knowledge level being fairly novice-level when it comes to microprocessor architectures and programming :)

I think for now I'm going to settle for increasing the SysTick priority and doing some extensive testing with my system to see if it introduces any additional problems.

I really appreciate all of your input up to this point, I have definitely learned several new things that weren't straight forward before!

westfw

The SAMD micros() code tries to compensate for a "pending" sysTick interrupt; perhaps there is something wrong with the logic there...

Here's the Interrupt vector table for SAMD - it is much different than the AVR's...


molimo140

The SAMD micros() code tries to compensate for a "pending" sysTick interrupt; perhaps there is something wrong with the logic there...
This was my original assumption, although I tend to think the library designers know what they are doing. I think some other interrupt taking control and messing up the SysTick timing momentarily is a more likely culprit.

Go Up