[Libmaple] pinmode () отключает таймер, даже если не включается режим ШИМ

RMDMOBA
Чт 11 мая 2017 г. 11:09
Привет,
Я некоторое время использую STM32Duino и улучшил свою библиотеку Model-RailReaders для работы на STM32.
Эта библиотека разгибается использует таймер 4 и сравнивает прерывания. Он не использует связанные выводы ШИМ.
Иногда моя библиотека останавливалась, чтобы работать, и я обнаружил, что это всегда так, когда команда PinMode () работает на одном из контактов, которые можно использовать с PWM и таймером 4.

Причиной является этот фрагмент кода в Wirish_digital_f1.CPP: gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode); if (PIN_MAP[pin].timer_device != NULL) { /* Enable/disable timer channels if we're switching into or * out of PWM. */ timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, pwm ? TIMER_PWM : TIMER_DISABLED); }

Rogerclark
Чт 11 мая 2017 г., 22:59
Спасибо, что сообщили об этом.

Если у вас есть учетная запись GitHub, (или может создать ее), лучший способ подать исправление - через запрос на вытягивание на GitHub.

Я создам проблему на GitHub, чтобы отслеживать это как можно скорее.

Эдогальдо
Пт 12 мая 2017 г., 7:13
Rmdmoba написал:Таймер должен быть коснулся только в том случае, если последний режим был режимом ШИМ, или если режим, который должен быть установлен, является режим ШИМ. Во всех других случаях таймер должен оставаться нетронутым.

Я попробовал с этим кодом, и он отлично работал в моих тестах: // remember old mode to see whether we have to change timer mode gpio_pin_mode oldMode = gpio_get_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit); gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode); if (PIN_MAP[pin].timer_device != NULL) { /* Enable/disable timer channels if we're switching into or * out of PWM. */ if ( pwm || oldMode == GPIO_AF_OUTPUT_OD || oldMode == GPIO_AF_OUTPUT_PP ) { timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, pwm ? TIMER_PWM : TIMER_DISABLED); } }

RMDMOBA
Пт 12 мая 2017 г. 12:37
Ну, может быть, решение тоже. Функция gpio_set_mode () отключает вывод из вывода таймера, если установлен какой -либо стандартный выходной сигнал (нет альтернативной функции). Может быть, этого достаточно, и таймер может быть оставлено нетронутым в целом при настройке любого невысокого режима.

victor_pv
Пт 12 мая 2017 г. 15:17
Эдогальдо написал:Rmdmoba написал:Таймер должен быть коснулся только в том случае, если последний режим был режимом ШИМ, или если режим, который должен быть установлен, является режим ШИМ. Во всех других случаях таймер должен оставаться нетронутым.

Я попробовал с этим кодом, и он отлично работал в моих тестах: // remember old mode to see whether we have to change timer mode gpio_pin_mode oldMode = gpio_get_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit); gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode); if (PIN_MAP[pin].timer_device != NULL) { /* Enable/disable timer channels if we're switching into or * out of PWM. */ if ( pwm || oldMode == GPIO_AF_OUTPUT_OD || oldMode == GPIO_AF_OUTPUT_PP ) { timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, pwm ? TIMER_PWM : TIMER_DISABLED); } }

Rogerclark
Пт 12 мая 2017 г., 21:34
Я согласен.

Вообще не кажется несчастным отключить таймер (ы) вообще.

Единственным недостатком, о котором я могу придумать, это повышение энергопотребления, но повлияет только на любого, кто работает от батарей, в то время как они, вероятно, напишут свой собственный дополнительный код, чтобы убедиться, что любое неиспользованное оборудование закрыто.

RMDMOBA
Сб 13 мая 2017 г. 20:49
Всем привет,
Если мы решим никогда не отключать таймер в функции PinMode, исправление еще более просто:
gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode); if (pwm && PIN_MAP[pin].timer_device != NULL) { /* Enable timer channels if we're switching into PWM. */ timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM); }

Rogerclark
Сб 13 мая 2017 г. 9:15 вечера
Спасибо

RMDMOBA
Чт 18 мая 2017 г. 15:39
Всем здравствуйте,
Я сделал несколько тестов, и мое исправление до сих пор сработало. Но я нашел какое -то странное поведение с булавками, которые обеспечивают две альтернативные функции, e.глин. ШИМ и серийный или ШИМ и SPI. Если после активации SPI или сериала (а затем деактивировано с помощью метода конечного). Наоборот, раунд в порядке: при запуске ШИМ, а затем запускаю SPI или серийный, это работает, но переход обратно на SWM невозможно. Это так с обоими вариантами - оригинал и с моим исправлением.
Я до сих пор не мог найти причину. В STM32F1-ссылках я не нашел способ точно подключить штифт к той или другой альтернативной функции. В рег GPIO вы можете только подключить контакт с альтернативными функциями. И вы можете включить или отключить эти функции (даже оба одновременно). SPI или Serial, кажется, имеют приоритет по сравнению с ШИМ, и если они когда -то были подключены к булавке, нет возвращения до сброса. Знает ли что -нибудь больше об этом?

Может на практике это не на самом деле проблема. Я думаю, что будет редко, что кто -то позволяет SPI на штифте, а затем выведет сигнал ШИМ в том же пинке.

victor_pv
Чт 18 мая 2017 г. 15:54
Rmdmoba написал:Всем здравствуйте,
Я сделал несколько тестов, и мое исправление до сих пор сработало. Но я нашел какое -то странное поведение с булавками, которые обеспечивают две альтернативные функции, e.глин. ШИМ и серийный или ШИМ и SPI. Если после активации SPI или сериала (а затем деактивировано с помощью метода конечного). Наоборот, раунд в порядке: при запуске ШИМ, а затем запускаю SPI или серийный, это работает, но переход обратно на SWM невозможно. Это так с обоими вариантами - оригинал и с моим исправлением.
Я до сих пор не мог найти причину. В STM32F1-ссылках я не нашел способ точно подключить штифт к той или другой альтернативной функции. В рег GPIO вы можете только подключить контакт с альтернативными функциями. И вы можете включить или отключить эти функции (даже оба одновременно). SPI или Serial, кажется, имеют приоритет по сравнению с ШИМ, и если они когда -то были подключены к булавке, нет возвращения до сброса. Знает ли что -нибудь больше об этом?

Может на практике это не на самом деле проблема. Я думаю, что будет редко, что кто -то позволяет SPI на штифте, а затем выведет сигнал ШИМ в том же пинке.

Эдогальдо
Чт 18 мая 2017 г. 16:39
Просто идея: Revoking pinmode () не решает проблему?

RMDMOBA
Чт 18 мая 2017 г. 8:34 вечера
victor_pv написал:Я подозреваю, что случай может заключаться в том, что когда SPI или серийный конец не настраиваются полностью обратно на по умолчанию, и может быть сделано что -то дополнительное.

Rogerclark
Чт 18 мая 2017 г. 20:43
Вы можете опубликовать свой тестовый код

Эдогальдо
Чт 18 мая 2017 г. 20:59
Кстати, я только что заметил, что этот поток находится в разделе «STM Core: Bugs and Unferancements».
Если мы имеем в виду ядро ​​кленового ядра, я бы посоветовал переместить его в другом месте..
Слишком много ядра в наши дни... :? :ржу не могу:

RMDMOBA
Чт 18 мая 2017 г., 21:01
Я проверил вывод на PA7 с прицелом: // Test PWM on maplemini pin 4 / PA7 ( general Output / SPI and PWM ) #include const byte Led1P = 16; // Led active during PWM Output const byte test1P = 4; // = port A7 ( SPI1-MOSI or TIM3 Ch2 ) SPIClass mySPI(1); void setup() { // put your setup code here, to run once: pinMode( Led1P, OUTPUT ); digitalWrite( Led1P, HIGH ); delay(1000); pinMode( test1P, INPUT_PULLUP ); delay( 1000 ); digitalWrite( Led1P, LOW ); pinMode( test1P, PWM ); // This PWM Sequence works fine for ( byte i=0; i<220; i++ ) { //analogWrite( test1P, i ); pwmWrite( test1P, i*257 ); delay( 20 ); } digitalWrite( Led1P, HIGH ); delay( 1000 ); pinMode( test1P, OUTPUT ); // General IO - works fine too for ( byte i=0; i<11; i++ ) { digitalWrite(test1P, i&1 ); delay( 5 ); } pinMode( test1P, INPUT ); delay(1000); mySPI.begin(); // SPI output - works fine mySPI.beginTransaction(SPISettings(550000, MSBFIRST, SPI_MODE0, DATA_SIZE_16BIT)); for ( byte i=0; i<11; i++ ) { mySPI.write(0x5555); delay( 5 ); } mySPI.endTransaction(); mySPI.end(); delay(1000); pinMode( test1P, OUTPUT ); // general OUTPUT - it works digitalWrite( test1P, LOW ); delay(500); digitalWrite( test1P, HIGH ); delay(1000); digitalWrite( Led1P, LOW ); pinMode( test1P, PWM ); // The following PWM sequence doesn't work for ( int i=220; i>0; i-- ) { // pin test1P seems to be in high impedance //analogWrite( test1P, i ); // state pwmWrite( test1P, i*257 ); delay( 20 ); } digitalWrite( Led1P, HIGH ); delay(1000); mySPI.begin(); // This again works mySPI.beginTransaction(SPISettings(550000, MSBFIRST, SPI_MODE0, DATA_SIZE_16BIT)); for ( int i=0; i<11; i++ ) { mySPI.write(0x5555); delay( 5 ); } mySPI.endTransaction(); mySPI.end(); /* Serial1.begin( 1200 ); delay( 1000); Serial1.println("start-dimming"); delay(1000); */ } void loop() { // put your main code here, to run repeatedly: }

victor_pv
Чт 18 мая 2017 г., 21:27
Rmdmoba написал:Я проверил вывод на PA7 с прицелом: // Test PWM on maplemini pin 4 / PA7 ( general Output / SPI and PWM ) #include const byte Led1P = 16; // Led active during PWM Output const byte test1P = 4; // = port A7 ( SPI1-MOSI or TIM3 Ch2 ) SPIClass mySPI(1); void setup() { // put your setup code here, to run once: pinMode( Led1P, OUTPUT ); digitalWrite( Led1P, HIGH ); delay(1000); pinMode( test1P, INPUT_PULLUP ); delay( 1000 ); digitalWrite( Led1P, LOW ); pinMode( test1P, PWM ); // This PWM Sequence works fine for ( byte i=0; i<220; i++ ) { //analogWrite( test1P, i ); pwmWrite( test1P, i*257 ); delay( 20 ); } digitalWrite( Led1P, HIGH ); delay( 1000 ); pinMode( test1P, OUTPUT ); // General IO - works fine too for ( byte i=0; i<11; i++ ) { digitalWrite(test1P, i&1 ); delay( 5 ); } pinMode( test1P, INPUT ); delay(1000); mySPI.begin(); // SPI output - works fine mySPI.beginTransaction(SPISettings(550000, MSBFIRST, SPI_MODE0, DATA_SIZE_16BIT)); for ( byte i=0; i<11; i++ ) { mySPI.write(0x5555); delay( 5 ); } mySPI.endTransaction(); mySPI.end(); delay(1000); pinMode( test1P, OUTPUT ); // general OUTPUT - it works digitalWrite( test1P, LOW ); delay(500); digitalWrite( test1P, HIGH ); delay(1000); digitalWrite( Led1P, LOW ); pinMode( test1P, PWM ); // The following PWM sequence doesn't work for ( int i=220; i>0; i-- ) { // pin test1P seems to be in high impedance //analogWrite( test1P, i ); // state pwmWrite( test1P, i*257 ); delay( 20 ); } digitalWrite( Led1P, HIGH ); delay(1000); mySPI.begin(); // This again works mySPI.beginTransaction(SPISettings(550000, MSBFIRST, SPI_MODE0, DATA_SIZE_16BIT)); for ( int i=0; i<11; i++ ) { mySPI.write(0x5555); delay( 5 ); } mySPI.endTransaction(); mySPI.end(); /* Serial1.begin( 1200 ); delay( 1000); Serial1.println("start-dimming"); delay(1000); */ } void loop() { // put your main code here, to run repeatedly: }

RMDMOBA
Пт 19 мая 2017 г., 7:14
victor_pv написал:Таким образом, вам нужно будет снова включить устройство таймера.

victor_pv
Пт 19 мая 2017 г. 16:04
Rmdmoba написал:victor_pv написал:Таким образом, вам нужно будет снова включить устройство таймера.

RMDMOBA
Пт 19 мая 2017 г., 21:21
victor_pv написал: Я подтвердил это, не включает устройство таймера, только канал.

victor_pv
Пт 19 мая 2017 г., 21:32
Rmdmoba написал:victor_pv написал: Я подтвердил это, не включает устройство таймера, только канал.

RMDMOBA
Пт 19 мая 2017 г., 21:36
victor_pv написал: Или вы использовали обычные, то если вы переключитесь на альтернативные для SPI1, то PWM снова работает?

victor_pv
Пт 19 мая 2017 г., 21:38
Rmdmoba написал:victor_pv написал: Или вы использовали обычные, то если вы переключитесь на альтернативные для SPI1, то PWM снова работает?

RMDMOBA
Пт 19 мая 2017 г., 21:42
victor_pv написал: Вы проверяли, отключает ли метод End () для порта SPI периферийное устройство SPI?

RMDMOBA
Сб 20 мая 2017 г. 14:39
После нескольких тестов я не нашел причину, по которой PWM больше не работает после активного SPI. Единственное решение, которое я обнаружил, - это переназначить булавки SPI (или выполнить аппаратное сброс). Кажется, что SPI блокирует AF на этом PIN -коде. Даже установление всех регистров SPI обратно в «0» (состояние после сброса) не помогает. То же самое, кажется, верно на булавках, которые разделяют UART и PWM как AF.

Поскольку PWM работает после переработки SPI, это, очевидно, не проблема конфигурации канала PWM/Timer.

Изменения в PinMode () теперь не останавливают прикрепленные IRQ при настройке режимов не -PWM. Последняя версия исправления такая: if (PIN_MAP[pin].timer_device != NULL) { if ( pwm ) { // we're switching into PWM, enable timer channels timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM ); } else { // disable channel output in non pwm-Mode timer_cc_disable(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel); } }

Rogerclark
Пт 26 мая 2017 г., 7:04
Можем ли мы изменить этот шаг за раз.

Я думаю, что мы установили, что Pinmode не нужно отключать весь таймер

Можно ли сгенерировать PR только для изменения PinMode

Проблема SPI выглядит более сложной и может быть применена отдельно к изменению PinMode

Эдогальдо
Пт 26 мая 2017 г., 7:27 утра
Rogerclark написал:Можно ли сгенерировать PR только для изменения PinMode

Стивестронг
Пт 26 мая 2017 г., 7:33 утра
Эдогальдо написал: Привет, Роджер, есть PR #288, который обращается к нему, но я не понимаю, почему парень добавил второй коммит, который, на мой взгляд, снова ломает вещи..

Эдогальдо
Пт 26 мая 2017 г., 7:41
Стивестронг написал:Эдогальдо, не могли бы вы подробно описать, какие вещи точно сломаются с помощью этого пиара?

Rogerclark
Пт 26 мая 2017 г., 7:42 утра
Для меня это выглядит нормально

https: // github.com/rogerclarkmelbourne/ ... /288/файлы

RMDMOBA
Пт 26 мая 2017 12:26
Эдогальдо написал:Вопрос, так как я не такой эксперт с таймерами: разве у нас не будет какой -либо действительной комбинации (также в возможном будущем варианте), в котором 2 контакта могут отображать ту же пару {таймер, канал}?

Rogerclark
Пн 31 июля 2017 г., 4:05
У нас есть решение по этому поводу ?

victor_pv
Пн 31 июля 2017 г. 13:00
Эдогальдо написал: Пт 26 мая 2017 г., 7:41

Стивестронг
Пн 31 июля 2017 г. 13:08
Я не знаю никакого приложения, которое будет сломано этим коммитом.
Если в будущем возникнут некоторые проблемы, то мы все равно можем проанализировать ситуацию и, если это необходимо, вернуть ее.

Итак, я за этот коммит.

Rogerclark
Пн 31 июля 2017 г., 21:27
Мне нужно будет проверить, был ли PR обновлен, так как я думал, что кто -то опубликовал улучшение PR.

(Но, возможно, улучшение не сработало)

victor_pv
Пн 21 августа 2017 г., 17:03
Эта тема, кажется, сосредоточена на ядре на основе Libmaple, поэтому я переезжаю на эти форумы.

Rogerclark
Пн 21 августа 2017 г. 9:10 вечера
Нам, вероятно, нужен раздел «Libmaple Core». Я вхожу в систему как супер администратор и создаю его