[Libmaple] pinMode() disables timer even if no PWM mode involved
Re: pinMode() disables timer even if no PWM mode involved
Just an idea: reinvoking pinMode() doesn't solve the issue?
Re: pinMode() disables timer even if no PWM mode involved
I supposed this too, and changed the end method of SPI tentatively. I set all the control registers to '0' ( the reset state ), but it changed nothing.victor_pv wrote:I suspect the case may be that when SPI or Serial end, the pins are not configured completely back to default and something extra may need to be done.
That's the way how I tried to switch back to PWM: seting pinMode to PWM and then pwmWrite() - but it didn't work.edogaldo wrote:Just an idea: reinvoking pinMode() doesn't solve the issue?
Last edited by rmdMoba on Thu May 18, 2017 8:46 pm, edited 1 time in total.
- RogerClark
- Posts: 8416
- Joined: Mon Apr 27, 2015 10:36 am
- Location: Melbourne, Australia
- Contact:
Re: pinMode() disables timer even if no PWM mode involved
can you post your test code
Re: pinMode() disables timer even if no PWM mode involved
By the way, I just noticed this thread is in "STM core: Bugs and enhancements" section.
If we are referring to the Maple core I'd suggest to move it elsewhere..
Too many cores these days...

If we are referring to the Maple core I'd suggest to move it elsewhere..
Too many cores these days...


Re: pinMode() disables timer even if no PWM mode involved
I checked the output on PA7 with a scope:
Edit: I used the 'rogerclarkmelbourne/Arduino_STM32' repository from Github
Code: Select all
// 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:
}
Re: pinMode() disables timer even if no PWM mode involved
Not sure if you already address that, but the SPI library disables the Timer device mapped to the pins it uses:rmdMoba wrote:I checked the output on PA7 with a scope:Edit: I used the 'rogerclarkmelbourne/Arduino_STM32' repository from GithubCode: Select all
// 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: }
Code: Select all
disable_pwm(nssi);
disable_pwm(scki);
disable_pwm(misoi);
disable_pwm(mosii);
Re: pinMode() disables timer even if no PWM mode involved
Yes, sure. But that is whatvictor_pv wrote:So you will need to enable the timer device again.
Code: Select all
pinMode( test1P, PWM ); // The following PWM sequence doesn't work
After a reset the timer is disabled too, and pinMode() sets it accordingly to create PWM pulses. Why does this not work when SPI disabled the timer?
Re: pinMode() disables timer even if no PWM mode involved
Not sure if pinMode really enables the Timer device, or just enables the channel output. If you have confirmed it in the code already then that's it, but if you haven't, confirm it to be sure.rmdMoba wrote:Yes, sure. But that is whatvictor_pv wrote:So you will need to enable the timer device again.should do.Code: Select all
pinMode( test1P, PWM ); // The following PWM sequence doesn't work
After a reset the timer is disabled too, and pinMode() sets it accordingly to create PWM pulses. Why does this not work when SPI disabled the timer?
EDIT:
I confirmed it, does not enable the timer device, only the channel.
Re: pinMode() disables timer even if no PWM mode involved
That's true, but it's not the problem. Activating SPI also disables only the channel. The timer itself is still running. This is essential, because there are other channels where pwm may be active on non SPI pins.victor_pv wrote: I confirmed it, does not enable the timer device, only the channel.
The problem is obviously, that SPI blocks the PWM output even after an SPI.end().
If I remap the SPI output ( AFIO Register MAPR ) to the alternate pins after executing SPI.end(), then PWM works again.
Code: Select all
// Test PWM on libmaple 4 ( general Output / SPI and PWM )
#include
// const byte test1P = 7; //Generic = port A7 ( SPI1-MOSI or TIM3 Ch2 )
const byte test1P = 4; // MapleMini = port A7 ( SPI1-MOSI or TIM3 Ch2 )
SPIClass mySPI(1);
void setup() {
delay( 1000 );
pinMode( test1P, PWM ); // This PWM Sequence works fine
for ( byte i=0; i<220; i++ ) {
//analogWrite( test1P, i );
pwmWrite( test1P, i*257 );
delay( 20 );
}
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);
AFIO_BASE->MAPR = 1; // remap SPI1
pinMode( test1P, PWM ); // The following PWM sequence only works if SPI is remapped
for ( int i=220; i>0; i-- ) {
//analogWrite( test1P, i );
pwmWrite( test1P, i*257 );
delay( 20 );
}
delay(1000);
AFIO_BASE->MAPR = 0; // remap SPI1 back to standard pins
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();
}
void loop() {
// put your main code here, to run repeatedly:
}
Re: pinMode() disables timer even if no PWM mode involved
I am a bit confused by this sentence " If I remap the SPI output ( AFIO Register MAPR ) to the alternate pins after executing SPI.end(), then PWM works again.". Does that mean you were not using the default SPI pins, but alternate ones instead? or you were using the normal ones, then if you switch to the alternate ones for SPI1 then PWM works again?rmdMoba wrote:That's true, but it's not the problem. Activating SPI also disables only the channel. The timer itself is still running. This is essential, because there are other channels where pwm may be active on non SPI pins.victor_pv wrote: I confirmed it, does not enable the timer device, only the channel.
The problem is obviously, that SPI blocks the PWM output even after an SPI.end().
If I remap the SPI output ( AFIO Register MAPR ) to the alternate pins after executing SPI.end(), then PWM works again.
Code: Select all
// Test PWM on libmaple 4 ( general Output / SPI and PWM ) #include
// const byte test1P = 7; //Generic = port A7 ( SPI1-MOSI or TIM3 Ch2 ) const byte test1P = 4; // MapleMini = port A7 ( SPI1-MOSI or TIM3 Ch2 ) SPIClass mySPI(1); void setup() { delay( 1000 ); pinMode( test1P, PWM ); // This PWM Sequence works fine for ( byte i=0; i<220; i++ ) { //analogWrite( test1P, i ); pwmWrite( test1P, i*257 ); delay( 20 ); } 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); AFIO_BASE->MAPR = 1; // remap SPI1 pinMode( test1P, PWM ); // The following PWM sequence only works if SPI is remapped for ( int i=220; i>0; i-- ) { //analogWrite( test1P, i ); pwmWrite( test1P, i*257 ); delay( 20 ); } delay(1000); AFIO_BASE->MAPR = 0; // remap SPI1 back to standard pins 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(); } void loop() { // put your main code here, to run repeatedly: }