FEZ Hydra - 4 PWM's - Where is the 4th?

Hi All,

It says here: https://www.ghielectronics.com/catalog/product/328 - PWM Pulse-Width Modulation = 4

I have a need to look for the 4th PWM PIN on the Hydra.

Schematic: http://www.ghielectronics.com/downloads/schematic/FEZ_Hydra_Mainboard_SCH.pdf

PWM0, 1 and 2 are on X7, Header 7. Pin 7 (PWM_0), Pin 8 (PWM_1) and Pin 9(PWM_2)

Can someone please advise where the 4th PWM is?

Is it the LCD PWM Pin?

If so, can it be used for other means? and which Ref address does it sit on?.

EG: Cpu.PWMChannel.PWM_0 ā†’ Cpu.PWMChannel.PWM_7

Thanks again

ChrisO

PB8 and PB9 are also PWM pins (Socket3, pins 3 and 4 - although thatā€™s not a P socket).
http://gadgeteer.codeplex.com/SourceControl/latest#Main/Mainboards/GHIElectronics/FEZHydra/Software/FEZHydra/FEZHydra_42/FEZHydra_42.cs is where I saw thatā€¦ But I donā€™t have a mapping to the PWM Channelsā€¦

1 Like

Hi Brett, As always you come through with good stuff thanks!. Will run some tests and let you know how I go.

+1 Thx.

ChrisO

Well Brett,

A big fail!! This is the Line that fails:



Error:
 #### Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (1) ####
 #### Message: 
 #### Microsoft.SPOT.Hardware.PWM::Commit [IP: 0000] ####
 #### Microsoft.SPOT.Hardware.PWM::.ctor [IP: 0045] ####
 #### Hydra_PWM_Pin_Test.Program::ProgramStarted [IP: 0093] ####
A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.SPOT.Hardware.PWM.dll


```cs

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

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

// PWM References...
using Microsoft.SPOT.Hardware;

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

// Get the Pins Library...
using GHI.Hardware.FEZHydra;

namespace Hydra_PWM_Pin_Test
{
    public partial class Program
    {
        // Config the PWM...
        // These are the Known Pins and can be referenced by: "Cpu.PWMChannel.PWM_0 --> 2"... (Pins 7, 8 and 9 on X7)
        private PWM MyPWM1; // (Cpu.Pin)FEZHydra_Pins.PD14; //PWM0
        private PWM MyPWM2; // (Cpu.Pin)FEZHydra_Pins.PD15; //PWM1
        private PWM MyPWM3; // (Cpu.Pin)FEZHydra_Pins.PD16; //PWM2

        // GHI have HYDRA down as having four (4) avaliable PWM Pins in the Specs...
        // See: https://www.ghielectronics.com/catalog/product/328
        // The Schematic and other Documentation show the Pins Below as the only other PWM Pins...
        // See: http://www.ghielectronics.com/downloads/schematic/FEZ_Hydra_Mainboard_SCH.pdf
        // and: http://gadgeteer.codeplex.com/SourceControl/latest#Main/Mainboards/GHIElectronics/FEZHydra/Software/FEZHydra/FEZHydra_42/FEZHydra_42.cs
        // Thanks to Brett!

        // These are the Known Pins and can be referenced by: "Cpu.PWMChannel.PWM_0 --> 2"...
        // socket.CpuPins[7] = (Cpu.Pin)FEZHydra_Pins.PD14; //PWM0
        // socket.CpuPins[8] = (Cpu.Pin)FEZHydra_Pins.PD15; //PWM1
        // socket.CpuPins[9] = (Cpu.Pin)FEZHydra_Pins.PD16; //PWM2

        // The below PWM Pin's are Pin 3 and 4 on X3...
        // socket.CpuPins[3] = (Cpu.Pin)FEZHydra_Pins.PB8; //PWM0
	     // socket.CpuPins[4] = (Cpu.Pin)FEZHydra_Pins.PB9; //PWM1


        // The below PWM Pin is Pin 9 on X11...
        // socket.CpuPins[9] = (Cpu.Pin)FEZHydra_Pins.PC3;  //LCD_PWM

        // This is the mystery 4th PWM Channel...
        private PWM MyPWM4;

        // This is the mystery 4th PWM Channel... 
        // Cpu.PWMChannel.PWM_3 - FAILED!!!...
        // Cpu.PWMChannel.PWM_4 - FAILED!!!...
        // Cpu.PWMChannel.PWM_5 - FAILED!!!...
        // Cpu.PWMChannel.PWM_6 - FAILED!!!...
        // Cpu.PWMChannel.PWM_7 - FAILED!!!...
        // Cpu.PWMChannel all Channels outside the known Cpu.PWMChannels have failed...
        // (Cpu.PWMChannel)(Cpu.Pin)GHI.Hardware.FEZHydra.Pin.PB8; - FAILED!!!...
        // (Cpu.PWMChannel)(Cpu.Pin)GHI.Hardware.FEZHydra.Pin.PB9; - FAILED!!!...
        // (Cpu.PWMChannel)(Cpu.Pin)GHI.Hardware.FEZHydra.Pin.PC3; - FAILED!!!...
        Cpu.PWMChannel MysteryChannel = (Cpu.PWMChannel)(Cpu.Pin)GHI.Hardware.FEZHydra.Pin.PB9;

        // WARNING messing around here can cause issues!!!!
        // See: https://www.ghielectronics.com/docs/125/loader-tinybooter-update-fez-hydra
        // You may need to go through the process: "Method 2: Ground MISO and Power-cycle/Reset" to recover your Hydra...
        // Following the above process, you will need to reapply the latest firmware...
        // This is not for the faint hearted!!!


        // Program Entry...
        void ProgramStarted()
        {
            // Notify Progress...
            Debug.Print("Running Application.");

            // Button Event Handler...
            button.ButtonPressed += new GTM.GHIElectronics.Button.ButtonEventHandler(button_ButtonPressed);

            // Notify Progress...
            Debug.Print("Button Event Handler Attached.");

            // Init PWM...
            MyPWM1 = new PWM(Cpu.PWMChannel.PWM_0, 100, 0.5, false);
            MyPWM2 = new PWM(Cpu.PWMChannel.PWM_1, 100, 0.5, false);
            MyPWM3 = new PWM(Cpu.PWMChannel.PWM_2, 100, 0.5, false);

            // Notify Progress...
            Debug.Print("PWM 0 - 2 Configured Successfully.");

            try
            {
                // This is the mystery 4th PWM Channel...
                MyPWM4 = new PWM(MysteryChannel, 100, 0.5, false);
            }
            catch
            {
                // Notify Progress...
                Debug.Print("Configuring PWM 4 Failed.");
            }

            // Notify Progress...
            Debug.Print("PWM 4 Configured Successfully.");

        }

        // Configured as a safety for NON Looped code...
        void button_ButtonPressed(GTM.GHIElectronics.Button sender, GTM.GHIElectronics.Button.ButtonState state)
        {
            // Turn the LED on...
            button.TurnLEDOn();

            // Sleep for a split second...
            Thread.Sleep(200);

            // Start the PWM...
            MyPWM1.Start();
            MyPWM2.Start();
            MyPWM3.Start();
            MyPWM4.Start();

            // Notify Progress...
            Debug.Print("PWM Started Successfully.");

            // Turn off the LED on the Button...
            button.TurnLEDOff();
        }
    }
}

@ ChrisO - Unfortunately, the fourth PWM channel is not exposed in the Hydra firmware.

The pin is however connected to the LED in the corner that is near socket 5. As it was connected to this debug LED, it was probably decided that it was not necessary to include it as a usable PWM.

There are two ways that you can use this pin as PWM, either by modifying the firmware for a custom firmware that exposes the pin to the NetMF driver or to use the Register Class and manually set this channel.

It was in error that we listed four usable PWM channels on the product page. We may add this to a future firmware release as this was an oversight.

1 Like

Hey Aron,

Thank You for the prompt and accurate answer!!!

I think the custom firmware is a bit beyond me at the moment :ā€™(

Is the current GHI Firmware Source Code available for viewing? :open_mouth: If I stare at it long enough maybe I can do somethingā€¦

Maybe my frequency range might be enough to make use of the Output Compare. I will try that first.

As a future request for all FEZ Mainboards, can we please have as many PWM available to the user as possible? PWM would have to be the most important overall function on all my projects and no doubt many others also.

Thanks again Aron!!! :smiley:

http://ghiopensource.codeplex.com is the repository. I looked aroiund for about 30 minutes and decided Iā€™d never be doing any porting work, because I couldnā€™t figure out where the PWM channels were definedā€¦

1 Like

Thanks Brett - Will have a read now and see if I can make any sense of it. +1 Guys thanks for your help!!!

Downloaded the Source. I can see some definitions in:

ghiopensource-31757\DeviceCode\GHI\Libraries\GHI.Hardware Assemblies\GHI.Hardware.FEZHydra\FEZHydra.cs

Maybe this is a place to start looking?

Aron, any suggestions on where to start?

Thanks!

steps taken:

LED / PD18 / PWM3 <-- Our PWM!!! Thanks Aron!!

PD14 / DSR0 / PWM0
PD15 / DSR0 / PWM1
PD16 / DSR0 / PWM2


/// <summary>Digital I/O.</summary>
        public const Cpu.Pin PD14 = (Cpu.Pin)(14 + 32 + 32 + 32);

        /// <summary>Digital I/O.</summary>
        public const Cpu.Pin PD15 = (Cpu.Pin)(15 + 32 + 32 + 32);

        /// <summary>Digital I/O.</summary>
        public const Cpu.Pin PD16 = (Cpu.Pin)(16 + 32 + 32 + 32);

        // This is the On Board LED - PWM_3...
        /// <summary>Digital I/O.</summary>
        public const Cpu.Pin PD18 = (Cpu.Pin)(18 + 32 + 32 + 32);

So is it possible to move the PWM to:


/// <summary>Digital I/O.</summary>
        public const Cpu.Pin PD20 = (Cpu.Pin)(20 + 32 + 32 + 32);

Ideally a re-order of the PWM Pins would be best:
PWM_0 = PD20
PWM_1 = PD14
PWM_2 = PD15
PWM_3 = PD16

This would be suitable for my purposes.

Then I guess the next step is how to rebuild and repackage the Firmware? Anyone have any good tutorials on this?

Thanks and all the Best

Chris

Ok, I was thinking this cant be the right place to look (Above) C Sharp does not seem to be the right Language to do this hardcore work.

See: ghiopensource-31757\DeviceCode\Targets\Native\AT91\DeviceCode\AT91_PWM

from: http://ghiopensource.codeplex.com/SourceControl/latest#DeviceCode/

This is more like what we want!!! More to come soon!!!

P.S: PWM is PIN Based isnā€™t it? So unless I MOD the LED and solder an extermal pin for access, this will still not work?

I mean, I cant programmatically change the PWM Pin allocations can I?

changing pin mapping to features will have to be a function of the processor. If it allows you to ā€œremapā€ the PWM pin to something other than the pin used for LED, then youā€™ll need to find in the source code the part that does this hardware mapping - but if it canā€™t remap the pin then youā€™re right, youā€™re going to need to remove the LED / hijack itā€™s signal

Looks like this can be done, currently for me its a huge task however.

The On board LED is configured in the GHIElectronics.Gadgeteer.FEZHydra.dll from what I can see and this is not part of the open source Code that has been shared.

EDIT: http://gadgeteer.codeplex.com/SourceControl/latest#Main/Mainboards/GHIElectronics/FEZHydra/Software/FEZHydra/FEZHydra_42/FEZHydra_42.cs

It is shared.

I mean, its an awe full waste to use highly needed real-estate (PWM_3) just to flash a LED!!

Maybe Aron can help out with some Code or some suggestions?


unsigned int PMW_PinTable[MAX_PWM_PINS] = {
	AT91_GPIO_Driver::PD14, 
	AT91_GPIO_Driver::PD15, 
	AT91_GPIO_Driver::PD16}; 

volatile unsigned long *PWM_ChannelModeRegister[MAX_PWM_PINS] = {
	(volatile unsigned long *)0xFFFC8200,	// PWM_CPRD0
	(volatile unsigned long *)0xFFFC8220,	// PWM_CPRD1
	(volatile unsigned long *)0xFFFC8240};	// PWM_CPRD2


volatile unsigned long *PWM_DutyRegister[MAX_PWM_PINS] = {
	(volatile unsigned long *)0xFFFC8204,	// PWM_CDTY0
	(volatile unsigned long *)0xFFFC8224,	// PWM_CDTY1
	(volatile unsigned long *)0xFFFC8244};	// PWM_CDTY2

volatile unsigned long *PWM_PeriodRegister[MAX_PWM_PINS] = {
	(volatile unsigned long *)0xFFFC8208,	// PWM_CPRD0
	(volatile unsigned long *)0xFFFC8228,	// PWM_CPRD1
	(volatile unsigned long *)0xFFFC8248};	// PWM_CPRD2

It does look like we can add the PWM_3 to the code, but I wonder if the On Board Debug LED code on boot will cause issues. I am not able to find this code yet.

I would very much like to be able to use this PWM Pin!!!

This code that you are looking at are the registers that control the PWM controller of the chip that Hydra uses: AT91SAM9RL64 You can find the datasheet by going to Atmels website or search for it online.

If you use the Register class, you can map the final PWM Channel to the proper registers and access it the same way that the raw C++ code is doing except you will do it for the final channel only (although, you could control all of the channels in the same manner if you so choose).

If you download the datasheet, you will see that the PWM functions can only be mapped to particular pins. For the final PWM Channel, there are only two physical pins on the processor that can handle it and unfortunately, the other pin is not exposed at all. Beginning at page 37 of this Atmel document (Hydra processor manual) 6289D-ATARM-3-Oct-11, it will define the multiplexing of the processorā€™s functions.

I hope that this information will lead you to your fourth PWM channel.

1 Like

Hey Aron, Thanks again for your help!!!

OK got the Datasheet.

Pins being:
[ul]
PD18 PWM3 ā† Already Exposed (On board Debug LED)
PD8 NPCS2 PWM3 ā† configures as Peripheral B - H14 PD8/NPCS2/PWM3 - Not Exposed[/ul]

According to the ā€œAT91SAM9RL64 Multiplexing on PIO Controller Dā€ Table on page 40, as Aron points out this table starts on page 37.

You donā€™t sound very confident that this can be done?

I see GHI have changed the Specs section to reflect 3 PWM Channels now also. Good Idea! Stop people expecting to use the 4th PWM!

Gotta Say Aron, you know your stuff!!! A true asset!!! Thanks for sharing your knowledge
:wink:

Time issues made a decision for me. FEZ Raptor Upgrade fixes my problem.

A bit frustrated about having to spend another $99 US to get the job done however.

@ ChrisO - What do you mean by needing to spend another $99 to get the job done? If you are going to use two boards in your project, one to be the master control and the other to control the PWM, you could go with a Cerberus as it has a lot more than 3 PWM to service your project and it is a bit less expensive . :wink: