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.
I think the custom firmware is a bit beyond me at the moment :’(
Is the current GHI Firmware Source Code available for viewing? 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.
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…
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.
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.
@ 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 .