Main Site Documentation

PWM Conversion from NETMF to TinyCLR OS


#1

I am totally confused and tired (it’s very late here). I have an existing NETMF STM32F405 project that I am trying to convert to TinyCLR OS. So far I have been able to convert everything (Registers, CAN, Watchdog, Serial IO) but not LEDs. My LEDs are PWM (so I can pulse them) and I can’t figure out how to convert NETMF PWM to TinyCLR OS PWM. I have 3 LEDS as outlined below as they are in NETMF:

  1. Red - PWM_1, PA7, Pin 23, TIM14_CH1
  2. Blue - PWM_4, PB0, Pin 26, TIM3_CH3,
  3. Green - PWM_5, PB1, Pin 27, TIM3_CH4

I have tried everything I can think of using the TinyCLR OS Pwm class and can’t get anything to work. There doesn’t seem to be any corresponding mapping between the two OS’s. I have flashed my processor with the FEZCerberus.0.5.0 firmware.

Any help will be most appreciated. - Thanks.


#2

http://docs.ghielectronics.com/tinyclr/tutorials/pwm.html


#3

@ B5 Fan - PWM for the FEZ Cerberus are defined in https://github.com/ghi-electronics/TinyCLR-Ports/blob/master/Devices/FEZCerberus/DeviceSelector.h#L85


#4

I know how to program a PWM pin in TinyCLR OS. I just don’t know how to reference my existing pins (PA7, PB0, PB1). I was all over the docs and existing mapping but just very unclear as to whether I was missing something or the port was missing something.

Here is my confusion. In NETMF the PWM mappig is the following:

PWM_0 = PC6
PWM_1 = PA7
PWM_2 = PC7
PWM_3 = PA8
PWM_4 = PB0
PWM_5 = PB1
PWM_6 = PB5
PWM_7 = PB4
PWM_8 = PB3
PWM_9 = PB11
PWM_10 = PB10
PWM_11 = PA10
PWM_12 = PA9
PWM_13 = PA15
PWM_14 = PB8
PWM_15 = PB9

And you used the following code to create a PWM pin:


PWM TestLed = new PWM(Cpu.PWMChannel.PWM_1, 60, 1, false);
TestLed.Start();

Now in TinyCLR OS the code would be:


PwmController TestController = PwmController.FromId(FEZ.PwmPin.Controller1.Id); // which controller to use?
TestController.SetDesiredFrequency(60);
PwmPin TestLed = TestController.OpenPin(FEZ.PwmPin.Controller1.D0); // which pin to use?
TestLed.SetActiveDutyCyclePercentage(1);
TestLed.Start();

What I spent half the night doing was trying to figure out which controller and pin to use for my NETMF PWM_1 (PA7) pin. I tried OpenPin with the actual STM pin (23) but that threw an exception. I looked at the metadata from the Pwm class and that confused me more. I just don’t see any relationship between the old NETMF and the new TinyCLR OS.

Is it just that what I need is missing from the current port? If so, can you please let me know what I need to add to create another port for my PA7, PB0, and PB1 Pwm pins?

Thanks.


#5

Im newbie and correct if i’m wrong. For blue and green led in DeviceSelctor.h pwm must be:


 #define MAX_PWM_PER_CONTROLLER 4
 #define TOTAL_PWM_CONTROLLER 1
 #define STM32F4_PWM {{TIM3 , 0x22, { _P_NONE_ , _P_NONE_ , _P(B, 0) , _P(B, 1)} , { false, false, false, false }, 0.0, 0.0, {0.0, 0.0, 0.0, 0.0}, 0, 0}}

and after in program:


PwmController pwm = PwmController.FromId("GHIElectronics.TinyCLR.NativeApis.STM32F4.PwmProvider\\0");
PwmPin blueLed = pwm.OpenPin(2);


#6

@ B5 Fan - This is explained the the document I linked to.

NETMF was wrong grouping all PWM channels together as some use the same timer (controller) and some don’t. There is not PWM1, PWM2…etc in the STM32 datasheet. TinyCLR OS fixes this. For example TIM2_CH1 is controller 2 channel 1. You can see the actual code under PWM https://github.com/ghi-electronics/TinyCLR-Ports/blob/master/Targets/STM32F4/STM32F4_PWM.cpp

The most important thing is to forget how NETMF did PWM :slight_smile:


#7

@ dox - welcome to the community. I see the need to add a generic PWM example to our documentation, like we do for GPIO. We will get on that.


#8

Ok, it looks like PA7 is also TIM3_CH2 so my LEDs are all on Controller 3, Pin 2 (Red), Pin 3 (Blue), and Pin 4 (Green). Does this mean I need to change DeviceSelctor.h to the following?


 #define STM32F4_PWM  ...
{TIM3, 0x22, { _P_NONE_ ,_P(A, 7) , _P(B, 0) , _P(B, 1)} , { false, false, false, false }, 0.0, 0.0, {0.0, 0.0, 0.0, 0.0}, 0, }

And if so, do I need to build a new port or is there somewhere I can insert/change the existing port to reflect this?

Also, just curious, why does TIM1 and TIM2 use 0x12 while TIM3 and TIM4 use 0x22?

BTW, I’m not a C++ guy so reading the port code is a little challenging.

Thanks for the help.


#9

@ B5 Fan - The team is telling me that this is going to completely change, probably be generic so it will work on any port without changes, or significant changes. Give a few days to look into this.


#10

@ B5 Fan - BTW correct code:


 #define MAX_PWM_PER_CONTROLLER 4
 #define TOTAL_PWM_CONTROLLER  3
 #define STM32F4_PWM {{ TIM1  ,  0x00,     { _P_NONE_ , _P_NONE_ , _P_NONE_ , _P_NONE_} ,  { false, false, false, false }, 0.0, 0.0, {0.0, 0.0, 0.0, 0.0}, 0, 0 },\
                     { TIM2  ,  0x00,     { _P_NONE_ , _P_NONE_ , _P_NONE_ , _P_NONE_} ,  { false, false, false, false }, 0.0, 0.0, {0.0, 0.0, 0.0, 0.0}, 0, 0 },\
                     { TIM3  ,  0x22,     { _P(B, 4) , _P(B, 5) , _P(B, 0) , _P(B, 1)} ,  { false, false, false, false }, 0.0, 0.0, {0.0, 0.0, 0.0, 0.0}, 0, 0 }}

PwmController pwm = PwmController.FromId("GHIElectronics.TinyCLR.NativeApis.STM32F4.PwmProvider\\2");
PwmPin blueLed = pwm.OpenPin(2);

0x12 and 0x22 is GPIO alternate mode + function value. 0x12 == AF1 and 0x22 == AF2. Check alternate function mapping table in MCU datasheet.


#11

Ok will do. Thanks Gus.