/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Constructor /// </summary> /// <param name="pwmPortIn">The PWM port we use</param> /// <history> /// 01 Dec 16 Cynic - Originally written /// </history> public PWMPortFS(PWMPortEnum pwmPortIn) : base(GpioEnum.GPIO_NONE) { pwmPort = pwmPortIn; //Console.WriteLine("PWMPort Starts"); // open the port OpenPort(); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// The sysfs system requires a number to be used in order to /// specify a specific PWM device on a EHRPWM chip This function /// converts the PWMPortEnum value to that number /// </summary> /// <param name="pwmPortIn">The PWM port we use</param> /// <returns>the export number</returns> /// <history> /// 07 Mar 19 Cynic - Originally written /// 03 Mar 19 Cynic - Converted to new PWM Port Enum names /// </history> public uint ConvertPWMPortEnumToDeviceNumber(PWMPortEnum pwmPortIn) { if (pwmPortIn == PWMPortEnum.PWM0_A) { return(0); // 0 - EHRPWM0A } if (pwmPortIn == PWMPortEnum.PWM0_B) { return(1); // 1 - EHRPWM0B } if (pwmPortIn == PWMPortEnum.PWM1_A) { return(0); // 3 - EHRPWM1A } if (pwmPortIn == PWMPortEnum.PWM1_B) { return(1); // 4 - EHRPWM1B } if (pwmPortIn == PWMPortEnum.PWM2_A) { return(0); // 5 - EHRPWM2A } if (pwmPortIn == PWMPortEnum.PWM2_B) { return(1); // 6 - EHRPWM2B } throw new Exception("Unknown PWM Port: " + pwmPortIn.ToString()); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// The sysfs system requires a number to be used in order to /// export and manipulate the PWM device we wish to use. This function /// converts the PWMPortEnum value to that number /// </summary> /// <param name="pwmPortIn">The PWM port we use</param> /// <returns>the export number</returns> /// <history> /// 01 Dec 16 Cynic - Originally written /// </history> public uint ConvertPWMPortEnumToExportNumber(PWMPortEnum pwmPortIn) { if (pwmPortIn == PWMPortEnum.PWM_0) { return(0); } if (pwmPortIn == PWMPortEnum.PWM_1) { return(1); } throw new Exception("Unknown PWM Port: " + pwmPortIn.ToString()); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Gets the a fully qualified path for the FS files controlling the pwm /// </summary> /// <param name="subFileName">The name of the sub file</param> /// <param name="pwmPortIn">The PWM port we use</param> /// <history> /// 01 Dec 16 Cynic - Originally written /// </history> private string GetFullPathToPWMFile(PWMPortEnum pwmPortIn, string subFileName) { StringBuilder chipFileName = new StringBuilder(); chipFileName.Append(RPIDefinitions.PWM_CHIPFILENAME_BASE); if ((subFileName != null) && (subFileName.Length > 0)) { chipFileName.Append(@"/"); chipFileName.Append(subFileName); } chipFileName.Replace("%chip%", ConvertPWMPortEnumToChipNumber(pwmPortIn).ToString()); chipFileName.Replace("%port%", ConvertPWMPortEnumToExportNumber(pwmPortIn).ToString()); return(chipFileName.ToString()); }
/// <summary> Prepares the PWM output for use. </summary> private void Initialize() { PWMPortEnum Device = PWMBBB.PinToPWMID(this.Pins[0]); // Final path will be: /sys/devices/platform/ocp/4830_000.epwmss/4830_200.pwm/pwm/pwmchip_/pwm_ // x x y z // Where x refers to device #. dev 0 = 0, dev 1 = 2, dev 2 = 4. // y is an arbitrary number. // To me, it looks like this is assigned from 0 in steps of +2, in the order that the PWM devices were loaded into the device tree. // Operationally, it seems to have no significance, and there only ever seems to be one in each *.epwmss/*.pwm/ folder. // This is probably because at that point it is already narrowed to a single device (2 pins). // z refers to output #. out A = 0, out B = 2. // We need to write the pin number (z) into the "export" file, and a 1 into the "enable" file to prepare the pin for use. // At that point, whatever needed to be set in memory is ready for BBBCSIO's PWMPortMM to take over and work. // Why does Linux have to be so damn difficult with everything it does? :( string Path = "/sys/devices/platform/ocp"; // Append the memory addresses. byte ExportNum = 0; switch (Device) { case PWMPortEnum.PWM0_A: Path += "/48300000.epwmss/48300200.pwm/pwm/"; ExportNum = 0; break; case PWMPortEnum.PWM0_B: Path += "/48300000.epwmss/48300200.pwm/pwm/"; ExportNum = 1; break; case PWMPortEnum.PWM1_A: Path += "/48302000.epwmss/48302200.pwm/pwm/"; ExportNum = 0; break; case PWMPortEnum.PWM1_B: Path += "/48302000.epwmss/48302200.pwm/pwm/"; ExportNum = 1; break; case PWMPortEnum.PWM2_A: Path += "/48304000.epwmss/48304200.pwm/pwm/"; ExportNum = 0; break; case PWMPortEnum.PWM2_B: Path += "/48304000.epwmss/48304200.pwm/pwm/"; ExportNum = 1; break; default: throw new Exception("Invalid PWM pin given."); } // Append the (arbitrary) pwmchip #, by using the first one we find. string[] PWMChips = Directory.GetDirectories(Path); Log.Output(Log.Severity.DEBUG, Log.Source.HARDWAREIO, "Attempting to find correct pwmchip number..."); bool FoundPWMChip = false; foreach (string SubdirPath in PWMChips) { string Subdir = new DirectoryInfo(SubdirPath).Name; if (Subdir.StartsWith("pwmchip")) { Path += Subdir; FoundPWMChip = true; Log.Output(Log.Severity.DEBUG, Log.Source.HARDWAREIO, "Found \"" + Subdir + "\", using."); } else { Log.Output(Log.Severity.DEBUG, Log.Source.HARDWAREIO, "Found \"" + Subdir + "\", no good."); } } if (!FoundPWMChip) { throw new Exception("Could not find PWM chip number. Is your device tree set correctly?"); } // Export and enable the pin. if (!Directory.Exists(Path + "/pwm" + ExportNum)) { StreamWriter Exporter = File.AppendText(Path + "/export"); Exporter.Write(ExportNum); Exporter.Flush(); Exporter.Close(); } Path += ("/pwm" + ExportNum); StreamWriter Enabler = File.AppendText(Path + "/enable"); Enabler.Write("1"); Enabler.Flush(); Enabler.Close(); this.Port = new PWMPortMM(Device); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// The sysfs system requires a number to be used in order to /// locate the appropriate pwmchip? file placed there by the /// device driver /// </summary> /// <param name="pwmPortIn">The PWM port we use</param> /// <returns>the chip number</returns> /// <history> /// 01 Dec 16 Cynic - Originally written /// </history> public uint ConvertPWMPortEnumToChipNumber(PWMPortEnum pwmPortIn) { // the drivers on the RPi2 only seem to support pwmchip0 // so we always return 0 here. return(0); }