/// <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); }
/// <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); }