/// <summary>
 /// Create a new <see cref="SignalGenerator"/> generating a signal at the specified frequency with the specified duty cycle.
 /// <para>The signal is stopped when the returned object is disposed. You must store a reference to the returned object to keep the signal generating.</para>
 /// <para>Note that PWM is far more powerful as a simple frequency generator with no repeat count.</para>
 /// </summary>
 /// <param name="pin">Output pin</param>
 /// <param name="frequency">Signal frequency (Hz) (1 to 50000)</param>
 ///<param name="repeatCount">The repeat count, 0 for never ending</param>
 /// <param name="dutyCycle">Duty cycle in range 0.0 to 1.0 (excluded)</param>
 /// <returns></returns>
 /// <exception cref="ArgumentOutOfRangeException">frequency is greater than 50kHz or dutyCycle lead to a level time less than 5µs</exception>
 static public SignalGenerator StartNew(Cpu.Pin pin, double frequency, int repeatCount, double dutyCycle = 0.5) {
     if (frequency <= 0)
         throw new ArgumentOutOfRangeException("frequency", "frequency must be greater than 0");
     if (frequency > 50000)
         throw new ArgumentOutOfRangeException("frequency", "frequency must be lower than 50kHz");
     uint onTime = (uint)(dutyCycle * 1000000 / frequency);
     uint offTime = (uint)((1 - dutyCycle) * 1000000 / frequency);
     if (onTime < 5 || offTime < 5)
         throw new ArgumentOutOfRangeException("dutyCycle", "Level times less than 5µs");
     SignalGenerator sg = new SignalGenerator(pin, false);
     sg.LevelTimes = new uint[] { onTime, offTime };
     sg.Start(repeatCount);
     return sg;
     }
        /// <summary>
        /// Create a new <see cref="SignalGenerator"/> repeating the specified number of pulses. This is designed to show a numerical information with a simple led. 
        /// <para>Note that the signal is stopped when the returned object is disposed. You must store a reference to the returned object to keep the signal generating.</para>
        /// </summary>
        /// <param name="pin"></param>
        /// <param name="pulseCount">The number of pulses</param>
        /// <param name="burstInterval">Number of pulse period to separate the pulse bursts</param>
        /// <param name="pulsePeriod">Pulse period in seconds</param>
        /// <returns></returns>
        static public SignalGenerator StartNewLedPulse(Cpu.Pin pin, int pulseCount, int burstInterval = 3, double pulsePeriod = 0.25) {
            if (pulseCount <= 1)
                throw new ArgumentOutOfRangeException("pulseCount", "pulseCount must be greater than 1");
            SignalGenerator sg = new SignalGenerator(pin, false);
            sg.LevelTimes = new uint[2 * pulseCount];
            for (int i = 0; i < pulseCount; i++) {
                sg.LevelTimes[2 * i] = (uint)(pulsePeriod * 0.2 * 1000000);
                sg.LevelTimes[2 * i + 1] = (uint)(pulsePeriod * 0.8 * 1000000);
                }
            //add the burst interval to the last low level
            sg.LevelTimes[2 * pulseCount - 1] += (uint)(pulsePeriod * burstInterval * 1000000);
            sg.Start();
            return sg;

            }
        /// <summary>
        /// Create a new <see cref="SignalGenerator"/> repeating the specified number of pulses. This is designed to show a numerical information with a simple led.
        /// <para>Note that the signal is stopped when the returned object is disposed. You must store a reference to the returned object to keep the signal generating.</para>
        /// </summary>
        /// <param name="pin"></param>
        /// <param name="pulseCount">The number of pulses</param>
        /// <param name="burstInterval">Number of pulse period to separate the pulse bursts</param>
        /// <param name="pulsePeriod">Pulse period in seconds</param>
        /// <returns></returns>
        static public SignalGenerator StartNewLedPulse(Cpu.Pin pin, int pulseCount, int burstInterval = 3, double pulsePeriod = 0.25)
        {
            if (pulseCount <= 1)
            {
                throw new ArgumentOutOfRangeException("pulseCount", "pulseCount must be greater than 1");
            }
            SignalGenerator sg = new SignalGenerator(pin, false);

            sg.LevelTimes = new uint[2 * pulseCount];
            for (int i = 0; i < pulseCount; i++)
            {
                sg.LevelTimes[2 * i]     = (uint)(pulsePeriod * 0.2 * 1000000);
                sg.LevelTimes[2 * i + 1] = (uint)(pulsePeriod * 0.8 * 1000000);
            }
            //add the burst interval to the last low level
            sg.LevelTimes[2 * pulseCount - 1] += (uint)(pulsePeriod * burstInterval * 1000000);
            sg.Start();
            return(sg);
        }
        /// <summary>
        /// Create a new <see cref="SignalGenerator"/> generating a signal at the specified frequency with the specified duty cycle.
        /// <para>The signal is stopped when the returned object is disposed. You must store a reference to the returned object to keep the signal generating.</para>
        /// <para>Note that PWM is far more powerful as a simple frequency generator with no repeat count.</para>
        /// </summary>
        /// <param name="pin">Output pin</param>
        /// <param name="frequency">Signal frequency (Hz) (1 to 50000)</param>
        ///<param name="repeatCount">The repeat count, 0 for never ending</param>
        /// <param name="dutyCycle">Duty cycle in range 0.0 to 1.0 (excluded)</param>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException">frequency is greater than 50kHz or dutyCycle lead to a level time less than 5µs</exception>
        static public SignalGenerator StartNew(Cpu.Pin pin, double frequency, int repeatCount, double dutyCycle = 0.5)
        {
            if (frequency <= 0)
            {
                throw new ArgumentOutOfRangeException("frequency", "frequency must be greater than 0");
            }
            if (frequency > 50000)
            {
                throw new ArgumentOutOfRangeException("frequency", "frequency must be lower than 50kHz");
            }
            uint onTime  = (uint)(dutyCycle * 1000000 / frequency);
            uint offTime = (uint)((1 - dutyCycle) * 1000000 / frequency);

            if (onTime < 5 || offTime < 5)
            {
                throw new ArgumentOutOfRangeException("dutyCycle", "Level times less than 5µs");
            }
            SignalGenerator sg = new SignalGenerator(pin, false);

            sg.LevelTimes = new uint[] { onTime, offTime };
            sg.Start(repeatCount);
            return(sg);
        }