PWM on the FEZ Cerberus Mainboard

Using:


// Using System...
using System;
using System.Threading;
using System.Collections;

// Using Microsoft...
using Microsoft.SPOT;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Presentation.Controls;

// Using Gadgeteer...
using GT = Gadgeteer;
using Gadgeteer.Networking;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace PWMTest
{
    public partial class Program
    {
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            PWM PWM_0 = new PWM(Cpu.PWMChannel.PWM_0, 100, 0.5, false); //   <--Pin 7 on X3 - Schematic says Pin 7 on X 5? 
            PWM PWM_1 = new PWM(Cpu.PWMChannel.PWM_1, 110, 0.5, false); //   <--Pin 8 on X3 - Schematic says Pin 8 on X 5? 
            PWM PWM_2 = new PWM(Cpu.PWMChannel.PWM_2, 120, 0.5, false); //   <--Pin 9 on X3 - Schematic says Pin 9 on X 5? 
            PWM PWM_3 = new PWM(Cpu.PWMChannel.PWM_3, 130, 0.5, false); //   <--Pin 7 on X4 - Schematic says Pin 7 on X 6? 
            PWM PWM_4 = new PWM(Cpu.PWMChannel.PWM_4, 140, 0.5, false); //   <--Pin 8 on X4 - Schematic says Pin 8 on X 6? 
            PWM PWM_5 = new PWM(Cpu.PWMChannel.PWM_5, 150, 0.5, false); //   <--Pin 9 on X4 - Schematic says Pin 9 on X 6? 

            PWM_0.Start();
            PWM_1.Start();
            PWM_2.Start();
            PWM_3.Start();
            PWM_4.Start();
            PWM_5.Start();
        }
    }
}

URL: https://www.ghielectronics.com/catalog/product/349
See: http://www.ghielectronics.com/downloads/schematic/FEZ_Cerberus_Mainboard_SCH.PDF

Problem 1:
Pin Outs are wrong. Whats going on here? See Code.

Promlen 2:
PWM’s dont work as expected.
–>Pin 7 on X3 - I get: 120Hz 0.60DC Should be: 100Hz 0.5DC → WRONG!
–>Pin 8 on X3 - I get: 110Hz 0.5DC Should be: 110Hz 0.5DC → Correct!
–>Pin 9 on X3 - I get: 120Hz 0.5DC Should be: 120Hz 0.5DC → Correct!
–>Pin 7 on X4 - I get: 130Hz 0.5DC Should be: 130Hz 0.5DC → Correct!
–>Pin 8 on X4 - I get: 150Hz 0.53DC Should be: 140Hz 0.5DC → WRONG!
–>Pin 9 on X4 - I get: 150Hz 0.5DC Should be: 150Hz 0.5DC → Correct!

Whats going on here?

GHI I am really frustrated guys, this is the second board that I have purchased that does not do what you are telling us that it does in the specs!

This means that there are only 4 PWM’s that work properly, and according to the schematic they are on the wrong Gadgeteer connectors.

What the??? :wall: :wall:

D*** the time I have lost in the last few weeks because of these stupid problems is rediculous.

Pins share the same clock. Set them all to the same frequency and change the duty cycle

Hi Gus,

Setting the Frequency the same for all PWM’s doesn’t make sense. Why do the other pins work?

Yes the clock is hard wired, 168MHz for the Cerrberus. But the divisor for the Frequency is working as an individual Clock Divisor on each PWM and it works on all PWM’s except the previous two mentioned.

Duty Cycle the same. All other PWMs are working as expected.

EG: I can sweep one PWM either Duty Cycle or Frequency or both without affecting the other channel. I can do this on all My FEZ Boards, Raptor, Hydra and on the Cerberus, except for the two channels that dont work.

So why just two PWM’s not working as the rest?

Thanks

Chris

Hi Chris,

It is the nature on how PWM works on this STM processor.

To illustrate, let me describe the different PWM types:

Hydra and G400 have an independent PWM processor via being an Atmel brand processor.

Cerberus is an STM brand processor and does not have an independent PWM processor. Cerberus, like a lot of processors, generate thier PWM through the use of timers on the processor. Cerberus has many timers with four channels each. When the processor uses its timers as the PWM source, the timer frequency needs to be the same between channels but the period (duty cycle) can be different.

Here is a complete list of the timer to channel pins for the Cerbware:

//                         C6,A7,C7,A8,B0,B1,B5,B4,B3,B11,B10,A10,A9,A15, B8, B9
 #define STM32F4_PWM_TIMER { 8,14, 8, 1, 3, 3, 3, 3, 2,  2,  2,  1, 1,  2,  4,  4}
 #define STM32F4_PWM_CHNL  { 0, 0, 1, 0, 2, 3, 1, 0, 1,  3,  2,  2, 1,  0,  2,  3}
 #define STM32F4_PWM_PINS  {38, 7,39, 8,16,17,21,20,19, 27, 26, 10, 9, 15, 24, 25}

As you can see PWM_0 and PWM_2 share the same timer (TIM8) and therefore cannot be different frequencies, only different duty cycles. As you can also see, PWM_4 and PWM_5 are also on the same timer (TIM3) and therefore cannot have different frequencies, only different duty cycles.

We will be adding a chart to the developer page to better allow proper usage of the PWM in situations like these.

2 Likes

Wow, that makes it really clear. I had wondered about the “PWM needs the same clock frequency on all channels” several times as it comes up in the forums. That explanation puts the topic to bed and tucks it in nice and neat. Thanks.

1 Like

Aron, EXCELLENT explanation thank you! It clarify s what I said above.

This is how it should have been explained and yes it needs to be in the Developers Guide, this is essential information for many when planning projects.

For many, PWM is useless unless the frequency can be changed!

Realistically, any situation where a Timer is shared, it should not be classed as PWM, instead maybe as Shared PWM because this is not true PWM as there is no ‘Modulation’ component to fixed frequency DC Pulses as Duty Cycle is proportional to Frequency.

Ref: Pulse-width modulation - Wikipedia

This means that the Cerberus Specs should read:

PWM = 4 (Pin 8 on X3, Pin 9 on X3, Pin 7 on X4, Pin 9 on X4)
Shared PWM = 2 ((Pin 7 on X3 shared with Pin 8 on X3) (Pin 8 on X4 shared with Pin 9 on X4))

Thanks again Aron.

All the Best

Chris

Hi Blue Hair Bob,

This is only true for PWM Channels that “Share a Timer” and not true for PWM Channels that have their own dedicated Timer.

All the Best

Chris