-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incomplete samd51 implementation #21
Comments
@facchinm heya would y'all take a PR to fix this? |
Hi @ladyada , we are going to merge the PR, no problem 😉 |
I’m on it. It’s a little more involved than just the sync registers, but I should have something this afternoon. |
A pull request has been made to arduino-libraries:master. If you need it sooner than the next merge, can be downloaded here: https://github.com/PaintYourDragon/Servo |
Thank you for the fix, this has been driving me crazy for weeks! Was about to attempt to write my own PWM class. It is compiling for me now. |
Please note, in your existing sketch, copy the servo.h from this updated library which you will download and place in your Arduino libraries folder under servo-master, into whatever sketch you are using. |
I tried this, but I still get a number of compiler errors when compiling for the Adafruit ItsyBitsy M4 (SAMD51).
I get the same for a number of other macro definitions. The list is much shorter than before updating the library, but I still can't compile successfully. Any thoughts? |
Tc4 needs to be a declared variable? At top add : const int TC4;
TC4 = 4; |
Hi, since I'm working on Marlin and I integrated Grand Central M4 into it, this servo library will be very helpful if integrated into libraries (Marlin uses platformIO but I think this is not a problem). |
There seem to be a number of issues yet to resolve to support the SAMD51 (compiles fine for the SAMD21 though). Here's the complete list of compiler messages when compiling for the Adafruit ItsyBitsy M4:
|
@richard-pepe that sound weird, I temporary added #28 in Marlin and it compile fine for samd51 (don't know if it works because I don't have proper H/W to test) |
I gave it a shot, but still doesn't compile.
|
Looks like the timer function is not properly populating. In `servo.cpp` comment out function `void tc4_handler()`
|
In marlin I have done some job on it and now it should works. Maybe some hints may be got from there |
Not working for me. A number of things aren't defined (TC4, ID_TC4, TC4_IRQn) along with other issues:
|
I am starting to think that the issues are chipset compatibility issues with the newer samd. Those functions may require cosimg updates in the libraries.
|
I grabbed the fork that @PaintYourDragon posted, and that compiled fine for me. However, it only seems to work with the first servo object defined. If, for example, I have code like this:
the servo attached to pin 3 responds appropriately and my scope shows what looks like a reasonable PWM signal, but the servo on pin 4 doesn't move and the signal on the scope is not at all the same. If I change the order, so s2 is defined before s1, then s2 works and s1 doesn't. The issue seems to be related only to the order in which the objects are instantiated, and doesn't have anything to do with what pins are in use. It also doesn't seem to matter whether I call the attach method on the first servo or not; the second servo still doesn't get the right signal. At a suggestion from adafruit_support_bill, I've copied this comment from a post I made over on the Adafruit forum, where there's a screenshot from my scope showing the signals being generated. Happy to help troubleshoot from here if I can. |
hiya please try |
multiple-servos also fixed |
Not sure if it works (I don't have a valid shield to test) and/or may be usefull. This is what I did in Marlin to support both timers: HAL_SERVO_TIMER_ISR() {
Tc * const tc = TimerConfig[SERVO_TC].pTimer;
const timer16_Sequence_t timer =
#ifndef _useTimer1
_timer2
#elif !defined(_useTimer2)
_timer1
#else
(tc->COUNT16.INTFLAG.reg & tc->COUNT16.INTENSET.reg & TC_INTFLAG_MC0) ? _timer1 : _timer2
#endif
;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
if (currentServoIndex[timer] < 0) {
#if defined(_useTimer1) && defined(_useTimer2)
if (currentServoIndex[timer ^ 1] >= 0) {
// Wait for both channels
// Clear the interrupt
tc->COUNT16.INTFLAG.reg = (tcChannel == 0) ? TC_INTFLAG_MC0 : TC_INTFLAG_MC1;
return;
}
#endif
tc->COUNT16.COUNT.reg = TC_COUNTER_START_VAL;
SYNC(tc->COUNT16.SYNCBUSY.bit.COUNT);
}
else if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive)
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated
// Select the next servo controlled by this timer
currentServoIndex[timer]++;
if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) {
if (SERVO(timer, currentServoIndex[timer]).Pin.isActive) // check if activated
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
tc->COUNT16.CC[tcChannel].reg = getTimerCount() - (uint16_t)SERVO(timer, currentServoIndex[timer]).ticks;
}
else {
// finished all channels so wait for the refresh period to expire before starting over
currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
const uint16_t tcCounterValue = getTimerCount();
if ((TC_COUNTER_START_VAL - tcCounterValue) + 4UL < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed
tc->COUNT16.CC[tcChannel].reg = TC_COUNTER_START_VAL - (uint16_t)usToTicks(REFRESH_INTERVAL);
else
tc->COUNT16.CC[tcChannel].reg = (uint16_t)(tcCounterValue - 4UL); // at least REFRESH_INTERVAL has elapsed
}
if (tcChannel == 0) {
SYNC(tc->COUNT16.SYNCBUSY.bit.CC0);
// Clear the interrupt
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0;
}
else {
SYNC(tc->COUNT16.SYNCBUSY.bit.CC1);
// Clear the interrupt
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC1;
}
|
we're doing something similar here, we wanted to be as close to the samd21 implementation as possible |
yes but SAMD51 CC0 and CC1 share the same timer count, so something different must be done |
hiya please explain in more detail. we're using all of TC0, for now just CC0 but it doesnt matter because CC1 wont be usable by anything else anyways. please reference the PR - we want to make this as similar as possible to the SAMD21 code so that means not refactoring the ISR |
I'll try to explain, but it's not easy due to the fact English is not my natural language. |
oh yes it seems..but how can it works on samd21? |
oh how stupid I am...I read it but I was thinking only at samd51...but 21 is also samd... |
Hi,
The implementation for the samd servo library doesn't work on samd51.
The syncbusy bit and clock management are different on this new chip so the code here need to be adapted for samd51.
For example when I try to compile the sweep example for the Feather M4 I get this :
The text was updated successfully, but these errors were encountered: