Beispiel #1
0
        /// <summary>
        /// Calculates the prescale value from the frequency (according to <see cref="ClockSpeed"/>)
        /// then writes that register, then calls <see cref="ReadFrequency"/> to update properties.
        /// Note the actual frequency may differ to the requested frequency due to clock scale (rounding).
        /// </summary>
        /// <remarks>
        /// The prescale can only be set during sleep mode. This method enters <see cref="Sleep"/> if necessary,
        /// then only if the device was awake before, calls <see cref="Wake"/> afterwards. It's important not to
        /// start output unexpectedly to avoid damage, i.e. if the device was sleeping before, the frequency is
        /// changed without starting the oscillator.
        /// </remarks>
        /// <param name="frequency">Desired frequency to set in Hz.</param>
        /// <returns>
        /// Effective frequency in Hz, read-back and recalculated after setting the desired frequency.
        /// Frequency in Hz. Related properties are also updated.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown when <paramref name="frequency"/> is less than <see cref="FrequencyMinimum"/> or greater than
        /// <see cref="FrequencyMaximum"/>.
        /// </exception>
        public int WriteFrequency(int frequency)
        {
            // Validate
            if (frequency < FrequencyMinimum || frequency > FrequencyMaximum)
            {
                throw new ArgumentOutOfRangeException(nameof(frequency));
            }

            // Calculate prescale
            var prescale = CalculatePrescale(frequency, ClockSpeed);

            // Enter sleep mode and record wake status
            var wasAwake = Sleep();

            // Write prescale
            I2cExtensions.WriteJoinByte(_hardware, (byte)Pca9685Register.Prescale, prescale);

            // Read result
            var actual = ReadFrequency();

            // Wake-up if previously running
            if (wasAwake)
            {
                Wake();
            }

            // Update related properties
            PwmMsMinimum = Pca9685ChannelValue.CalculateWidthMs(frequency, 0);
            PwmMsMaximum = Pca9685ChannelValue.CalculateWidthMs(frequency, Pca9685ChannelValue.Maximum);

            // Return actual frequency
            return(actual);
        }
Beispiel #2
0
        /// <summary>
        /// Reads the prescale register and calculates the <see cref="Frequency"/> (and related properties)
        /// based on <see cref="ClockSpeed"/>.
        /// </summary>
        /// <returns>
        /// Frequency in Hz. Related properties are also updated.
        /// </returns>
        public int ReadFrequency()
        {
            // Read prescale register
            var prescale = I2cExtensions.WriteReadByte(_hardware, (byte)Pca9685Register.Prescale);

            // Calculate frequency
            var frequency = CalculateFrequency(prescale, ClockSpeed);

            // Update related properties
            Frequency    = frequency;
            PwmMsMinimum = Pca9685ChannelValue.CalculateWidthMs(frequency, 0);
            PwmMsMaximum = Pca9685ChannelValue.CalculateWidthMs(frequency, Pca9685ChannelValue.Maximum);

            // Return result
            return(frequency);
        }