RSeries astromech firmware
AnalogWrite.h
Go to the documentation of this file.
1 #ifndef AnalogWrite_h
2 #define AnalogWrite_h
3 
4 #include "ReelTwo.h"
5 
6 #ifdef ESP32
7 struct analog_write_channel
8 {
9  int8_t pin;
10  uint32_t frequency;
11  uint8_t resolution;
12 };
13 
14 #define ANALOG_WRITE_DEFAULT_FREQUENCY 1000
15 #define ANALOG_WRITE_DEFAULT_RESOLUTION 8
16 
17 analog_write_channel _analog_write_channels[LEDC_CHANNELS];
18 // {-1, 5000, 13},
19 // {-1, 5000, 13},
20 // {-1, 5000, 13},
21 // {-1, 5000, 13},
22 // {-1, 5000, 13},
23 // {-1, 5000, 13},
24 // {-1, 5000, 13},
25 // {-1, 5000, 13},
26 // {-1, 5000, 13},
27 // {-1, 5000, 13},
28 // {-1, 5000, 13},
29 // {-1, 5000, 13},
30 // {-1, 5000, 13},
31 // {-1, 5000, 13},
32 // {-1, 5000, 13},
33 // {-1, 5000, 13}
34 // };
35 
36 int analogWriteChannel(uint8_t pin)
37 {
38  int channelNum = -1;
39 
40  // Check if pin already attached to a channel
41  for (uint8_t i = 0; i < SizeOfArray(_analog_write_channels); i++)
42  {
43  if (_analog_write_channels[i].pin == pin)
44  {
45  channelNum = i;
46  break;
47  }
48  }
49 
50  // If not, attach it to a free channel
51  if (channelNum == -1)
52  {
53  for (int i = SizeOfArray(_analog_write_channels)-1; i >= 0; i--)
54  {
55  analog_write_channel& channel = _analog_write_channels[i];
56  if (channel.pin == 0)
57  {
58  channel.pin = pin;
59  channelNum = i;
60  // Setup default values
61  if (channel.frequency == 0 && channel.resolution == 0)
62  {
63  channel.frequency = ANALOG_WRITE_DEFAULT_FREQUENCY;
64  channel.resolution = ANALOG_WRITE_DEFAULT_RESOLUTION;
65  }
66  // printf("ATTACH PIN=%d to CHANNEL=%d frequency=%u bits=%d\n", pin, channelNum, channel.frequency, channel.resolution);
67  ledcAttachPin(pin, channelNum);
68  ledcSetup(channelNum, ANALOG_WRITE_DEFAULT_FREQUENCY, ANALOG_WRITE_DEFAULT_RESOLUTION);
69  if (ledcChangeFrequency(i, channel.frequency, channel.resolution) != channel.frequency)
70  {
71  // Failed to change frequency revert to known defaults
72  channel.frequency = ANALOG_WRITE_DEFAULT_FREQUENCY;
73  channel.resolution = ANALOG_WRITE_DEFAULT_RESOLUTION;
74  }
75  break;
76  }
77  }
78  }
79  return channelNum;
80 }
81 
82 void analogWriteFrequencyResolution(uint32_t frequency, uint8_t resolution = 8)
83 {
84  for (uint8_t i = 0; i < SizeOfArray(_analog_write_channels); i++)
85  {
86  bool updateChannel = true;
87  analog_write_channel& channel = _analog_write_channels[i];
88  if (channel.pin != 0)
89  updateChannel = (ledcChangeFrequency(i, frequency, resolution) == frequency);
90  if (updateChannel)
91  {
92  channel.frequency = frequency;
93  channel.resolution = resolution;
94  }
95  }
96 }
97 
98 bool analogWriteFrequencyResolution(uint8_t pin, uint32_t frequency, uint8_t resolution = 8)
99 {
100  unsigned channelNum = analogWriteChannel(pin);
101 
102  // Make sure the pin was attached to a channel, if not do nothing
103  if (channelNum < SizeOfArray(_analog_write_channels))
104  {
105  bool updateChannel = true;
106  analog_write_channel& channel = _analog_write_channels[channelNum];
107  if (channel.pin != 0)
108  {
109  // uint32_t freq = ledcChangeFrequency(channelNum, frequency, resolution);
110  // printf("freq: %u\n", freq);
111  updateChannel = (ledcChangeFrequency(channelNum, frequency, resolution) == frequency);
112  }
113  if (updateChannel)
114  {
115  channel.frequency = frequency;
116  channel.resolution = resolution;
117  return true;
118  }
119  }
120  return false;
121 }
122 
123 void analogWriteFrequency(uint32_t frequency)
124 {
125  for (uint8_t i = 0; i < SizeOfArray(_analog_write_channels); i++)
126  {
127  bool updateChannel = true;
128  analog_write_channel& channel = _analog_write_channels[i];
129  if (channel.pin != 0)
130  updateChannel = (ledcChangeFrequency(i, frequency, channel.resolution) == frequency);
131  if (updateChannel)
132  channel.frequency = frequency;
133  }
134 }
135 
136 void analogWriteFrequency(uint8_t pin, uint32_t frequency)
137 {
138  unsigned channelNum = analogWriteChannel(pin);
139 
140  // Make sure the pin was attached to a channel, if not do nothing
141  if (channelNum < SizeOfArray(_analog_write_channels))
142  {
143  bool updateChannel = true;
144  analog_write_channel& channel = _analog_write_channels[channelNum];
145  if (channel.pin != 0)
146  updateChannel = (ledcChangeFrequency(channelNum, frequency, channel.resolution) == frequency);
147  if (updateChannel)
148  channel.frequency = frequency;
149  }
150 }
151 
152 void analogWriteResolution(uint8_t resolution)
153 {
154  for (uint8_t i = 0; i < SizeOfArray(_analog_write_channels); i++)
155  {
156  bool updateChannel = true;
157  analog_write_channel& channel = _analog_write_channels[i];
158  if (channel.pin != 0)
159  updateChannel = (ledcChangeFrequency(i, channel.frequency, resolution) == channel.frequency);
160  if (updateChannel)
161  channel.resolution = resolution;
162  }
163 }
164 
165 void analogWriteResolution(uint8_t pin, uint8_t resolution)
166 {
167  unsigned channelNum = analogWriteChannel(pin);
168 
169  // Make sure the pin was attached to a channel, if not do nothing
170  if (channelNum < SizeOfArray(_analog_write_channels))
171  {
172  bool updateChannel = true;
173  analog_write_channel& channel = _analog_write_channels[channelNum];
174  if (channel.pin != 0)
175  updateChannel = (ledcChangeFrequency(channelNum, channel.frequency, resolution) == channel.frequency);
176  if (updateChannel)
177  channel.resolution = resolution;
178  }
179 }
180 
181 void analogWrite(uint8_t pin, uint32_t value, uint32_t valueMax)
182 {
183  int channel = analogWriteChannel(pin);
184 
185  // Make sure the pin was attached to a channel, if not do nothing
186  if (channel != -1 && channel < SizeOfArray(_analog_write_channels))
187  {
188  uint8_t resolution = _analog_write_channels[channel].resolution;
189  uint32_t levels = pow(2, resolution);
190  uint32_t duty = ((levels - 1) / valueMax) * min(value, valueMax);
191 
192  // write duty to LEDC
193  // printf("ledcWrite pin=%d duty=%u levels=%u\n", pin, duty, levels);
194  ledcWrite(channel, duty);
195  }
196 }
197 
198 void analogWrite(uint8_t pin, float value)
199 {
200  value = min(max(0.0f, value), 1.0f);
201  int channel = analogWriteChannel(pin);
202 
203  // Make sure the pin was attached to a channel, if not do nothing
204  if (channel != -1 && channel < SizeOfArray(_analog_write_channels))
205  {
206  uint8_t resolution = _analog_write_channels[channel].resolution;
207  uint32_t levels = pow(2, resolution);
208  uint32_t duty = (levels - 1) * value;
209 
210  // write duty to LEDC
211  // printf("ledcWrite pin=%d duty=%u levels=%u\n", pin, duty, levels);
212  ledcWrite(channel, duty);
213  }
214 }
215 #endif
216 
217 #endif
ReelTwo.h
SizeOfArray
#define SizeOfArray(arr)
Definition: ReelTwo.h:213