DUDS
Distributed Update of Data from Something
SysPwm.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the DUDS project. It is subject to the BSD-style
3  * license terms in the LICENSE file found in the top-level directory of this
4  * distribution and at https://github.com/jjackowski/duds/blob/master/LICENSE.
5  * No part of DUDS, including this file, may be copied, modified, propagated,
6  * or distributed except according to the terms contained in the LICENSE file.
7  *
8  * Copyright (C) 2017 Jeff Jackowski
9  */
11 #include <duds/general/Errors.hpp>
12 #include <boost/exception/errinfo_file_name.hpp>
13 #include <sstream>
14 
15 // !@?!#?!#?
16 #undef linux
17 
18 namespace duds { namespace hardware { namespace interface { namespace linux {
19 
20 static const char *prefix = "/sys/class/pwm/pwmchip"; // 0/pwm0
21 // files:
22 // duty_cycle enable period polarity
23 SysPwm::SysPwm(int chip, int channel) {
24  std::ostringstream fname;
25  fname << prefix << chip << "/pwm" << channel << "/enable";
26  en.open(fname.str());
27  if (!en.is_open()) {
29  SysPwmChannel(channel) << boost::errinfo_file_name(fname.str())
30  );
31  }
32  unsigned int val;
33  en >> val;
34  if (en.fail() || (val > 1)) {
36  SysPwmChannel(channel) << boost::errinfo_file_name(fname.str())
37  );
38  }
39  running = val == 1;
40  // unwrite "enable"
41  fname.seekp(-6, std::ios_base::cur);
42  fname << "period";
43  per.open(fname.str());
44  if (!per.is_open()) {
46  SysPwmChannel(channel) << boost::errinfo_file_name(fname.str())
47  );
48  }
49  per >> val;
50  if (per.fail()) {
52  SysPwmChannel(channel) << boost::errinfo_file_name(fname.str())
53  );
54  }
55  periodNs = std::chrono::nanoseconds(val);
56  // unwrite "period"
57  fname.seekp(-6, std::ios_base::cur);
58  fname << "duty_cycle";
59  dc.open(fname.str());
60  if (!dc.is_open()) {
62  SysPwmChannel(channel) << boost::errinfo_file_name(fname.str())
63  );
64  }
65  dc >> val;
66  if (dc.fail()) {
68  SysPwmChannel(channel) << boost::errinfo_file_name(fname.str())
69  );
70  }
71  dutyNs = std::chrono::nanoseconds(val);
72 };
73 
75  disable();
76 }
77 
78 void SysPwm::enable(bool state) {
79  if (state != running) {
80  en.seekg(0);
81  char v = '0';
82  if (state) {
83  ++v;
84  }
85  en << v << std::endl;
86  if (en.fail()) {
88  }
89  running = state;
90  }
91 }
92 
93 void SysPwm::dutyPeriod(const std::chrono::nanoseconds &ns) {
94  if (dutyNs != ns) {
95  dc.seekg(0);
96  dc << ns.count() << std::endl;
97  if (dc.fail()) {
98  DUDS_THROW_EXCEPTION(PwmError() << SysPwmDutyNs(ns.count()));
99  }
100  dutyNs = ns;
101  }
102 }
103 
104 double SysPwm::dutyCycle() const {
105  return (double)dutyNs.count() / (double)periodNs.count();
106 }
107 
108 void SysPwm::period(const std::chrono::nanoseconds &ns) {
109  if (periodNs != ns) {
110  per.seekg(0);
111  per << ns.count() << std::endl;
112  if (per.fail()) {
113  DUDS_THROW_EXCEPTION(PwmError() << SysPwmPeriodNs(ns.count()));
114  }
115  periodNs = ns;
116  }
117 }
118 
119 void SysPwm::dutyCycle(double ratio) {
120  std::chrono::nanoseconds t((std::chrono::nanoseconds::rep)(
121  (double)(periodNs.count()) * ratio)
122  );
123  dutyPeriod(t);
124 }
125 
126 void SysPwm::frequency(unsigned int hz) {
127  period(
128  std::chrono::nanoseconds((std::chrono::nanoseconds::rep)(
129  (1.0 / (double)hz) * (double)(std::nano::den))
130  )
131  );
132 }
133 
134 unsigned int SysPwm::frequency() const {
135  return 1.0 / (double)periodNs.count();
136 }
137 
138 } } } }
std::chrono::nanoseconds dutyPeriod() const
Definition: SysPwm.hpp:52
boost::error_info< struct Info_SysPwmPeriodNs, long > SysPwmPeriodNs
Definition: SysPwm.hpp:25
boost::error_info< struct Info_SysPwmChannel, int > SysPwmChannel
Definition: SysPwm.hpp:23
boost::error_info< struct Info_SysPwmChip, int > SysPwmChip
Definition: SysPwm.hpp:22
boost::error_info< struct Info_SysPwmDutyNs, long > SysPwmDutyNs
Definition: SysPwm.hpp:27
std::chrono::nanoseconds dutyNs
Definition: SysPwm.hpp:39
SysPwm(int chip, int channel)
Definition: SysPwm.cpp:23
static const char * prefix
Definition: SysFsPort.cpp:17
General errors.
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
Definition: Errors.hpp:48
std::chrono::nanoseconds periodNs
Definition: SysPwm.hpp:40
std::chrono::nanoseconds period() const
Definition: SysPwm.hpp:64