13
13
#define PLUGIN_VALUENAME1_022 " PWM"
14
14
15
15
#define PLUGIN_022_PCA9685_MODE1 0x00 // location for Mode1 register address
16
- #define PCA9685_MODE2 0x01 // location for Mode2 register address
17
- #define PCA9685_MODE2_VALUES 0x20
18
- #define PCA9685_LED0 0x06 // location for start of LED0 registers
19
- #define PCA9685_ADDRESS 0x40 // I2C address
20
- #define PCA9685_MAX_ADDRESS 0x7F
21
- #define PCA9685_NUMS_ADDRESS PCA9685_MAX_ADDRESS - PCA9685_ADDRESS
22
- #define PCA9685_MAX_PINS 15
23
- #define PCA9685_MAX_PWM 4095
24
- #define PCA9685_MIN_FREQUENCY 23.0 // Min possible PWM cycle frequency
25
- #define PCA9685_MAX_FREQUENCY 1500.0 // Max possible PWM cycle frequency
26
- #define PCA9685_ALLLED_REG (byte)0xFA
27
-
28
- /*
29
- is bit flag any bit rapresent the initialization state of PCA9685
30
- es: bit 3 is set 1 PCA9685 with address 0X40 + 0x03 is intin
31
- */
32
- #define IS_INIT (state, bit ) ((bit >= 0 ) && (bit < 32 ) && ((state & (1 << bit)) != 0 ))
33
- #define SET_INIT (state, bit ) (state |= (1 << bit))
34
- long long initializeState; //
16
+ #define PCA9685_MODE2 0x01 // location for Mode2 register address
17
+ #define PCA9685_MODE2_VALUES 0x20
18
+ #define PCA9685_LED0 0x06 // location for start of LED0 registers
19
+ #define PCA9685_ADDRESS 0x40 // I2C address
20
+ #define PCA9685_MAX_ADDRESS 0x7F
21
+ #define PCA9685_NUMS_ADDRESS (PCA9685_MAX_ADDRESS - PCA9685_ADDRESS)
22
+ #define PCA9685_MAX_PINS 15
23
+ #define PCA9685_MAX_PWM 4095
24
+ #define PCA9685_MIN_FREQUENCY 23.0 // Min possible PWM cycle frequency
25
+ #define PCA9685_MAX_FREQUENCY 1500.0 // Max possible PWM cycle frequency
26
+ #define PCA9685_ALLLED_REG (byte)0xFA
27
+
28
+
29
+ // Bit mask to keep track of addresses initialized.
30
+ static uint32_t initializeState_lo = 0 ;
31
+ static uint32_t initializeState_hi = 0 ;
32
+
33
+ bool p022_is_init (uint8_t address) {
34
+ if ((address < PCA9685_ADDRESS) || (address > PCA9685_MAX_ADDRESS)) { return false ; }
35
+ uint32_t address_offset = address - PCA9685_ADDRESS;
36
+
37
+ if (address_offset < 32 ) {
38
+ return initializeState_lo & (1 << address_offset);
39
+ } else {
40
+ return initializeState_hi & (1 << (address_offset - 32 ));
41
+ }
42
+ }
43
+
44
+ bool p022_set_init (uint8_t address) {
45
+ if ((address < PCA9685_ADDRESS) || (address > PCA9685_MAX_ADDRESS)) { return false ; }
46
+ uint32_t address_offset = address - PCA9685_ADDRESS;
47
+
48
+ if (address_offset < 32 ) {
49
+ initializeState_lo |= (1 << address_offset);
50
+ } else {
51
+ initializeState_hi |= (1 << (address_offset - 32 ));
52
+ }
53
+ return true ;
54
+ }
55
+
56
+ bool p022_clear_init (uint8_t address) {
57
+ if ((address < PCA9685_ADDRESS) || (address > PCA9685_MAX_ADDRESS)) { return false ; }
58
+ uint32_t address_offset = address - PCA9685_ADDRESS;
59
+
60
+ if (address_offset < 32 ) {
61
+ initializeState_lo &= ~(1 << address_offset);
62
+ } else {
63
+ initializeState_hi &= ~(1 << (address_offset - 32 ));
64
+ }
65
+ return true ;
66
+ }
67
+
35
68
36
69
boolean Plugin_022 (byte function, struct EventStruct *event, String& string)
37
70
{
@@ -49,6 +82,10 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
49
82
range = PCONFIG (2 );
50
83
}
51
84
85
+ if ((address < PCA9685_ADDRESS) || (address > PCA9685_MAX_ADDRESS)) {
86
+ address = PCA9685_ADDRESS;
87
+ }
88
+
52
89
if (freq == 0 ) {
53
90
freq = PCA9685_MAX_FREQUENCY;
54
91
}
@@ -88,56 +125,66 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
88
125
89
126
case PLUGIN_WEBFORM_LOAD:
90
127
{
91
- int optionValues[PCA9685_NUMS_ADDRESS];
92
-
93
- for (int i = 0 ; i < PCA9685_NUMS_ADDRESS; i++)
128
+ // The options lists are quite long.
129
+ // To prevent stack overflow issues, each selection has its own scope.
94
130
{
95
- optionValues[i] = PCA9685_ADDRESS + i;
96
- }
97
- addFormSelectorI2C (F (" i2c_addr" ), PCA9685_NUMS_ADDRESS, optionValues, address);
131
+ int optionValues[PCA9685_NUMS_ADDRESS];
98
132
99
- String m2Options[PCA9685_MODE2_VALUES];
100
- int m2Values[PCA9685_MODE2_VALUES];
101
-
102
- for (int i = 0 ; i < PCA9685_MODE2_VALUES; i++)
133
+ for (int i = 0 ; i < PCA9685_NUMS_ADDRESS; i++)
134
+ {
135
+ optionValues[i] = PCA9685_ADDRESS + i;
136
+ }
137
+ addFormSelectorI2C (F (" i2c_addr" ), PCA9685_NUMS_ADDRESS, optionValues, address);
138
+ }
103
139
{
104
- m2Values[i] = i ;
105
- m2Options[i] = formatToHex_decimal (i) ;
140
+ String m2Options[PCA9685_MODE2_VALUES] ;
141
+ int m2Values[PCA9685_MODE2_VALUES] ;
106
142
107
- if (i == 0x10 ) {
108
- m2Options[i] += F (" - (default)" );
143
+ for (int i = 0 ; i < PCA9685_MODE2_VALUES; i++)
144
+ {
145
+ m2Values[i] = i;
146
+ m2Options[i] = formatToHex_decimal (i);
147
+
148
+ if (i == 0x10 ) {
149
+ m2Options[i] += F (" - (default)" );
150
+ }
109
151
}
152
+ addFormSelector (F (" MODE2" ), F (" p022_mode2" ), PCA9685_MODE2_VALUES, m2Options, m2Values, mode2);
153
+ }
154
+ {
155
+ String freqString = F (" Frequency (" );
156
+ freqString += PCA9685_MIN_FREQUENCY;
157
+ freqString += ' -' ;
158
+ freqString += PCA9685_MAX_FREQUENCY;
159
+ freqString += ' )' ;
160
+ addFormNumericBox (freqString, F (" p022_freq" ), freq, PCA9685_MIN_FREQUENCY, PCA9685_MAX_FREQUENCY);
161
+ }
162
+ {
163
+ String funitString = F (" default " );
164
+ funitString += PCA9685_MAX_FREQUENCY;
165
+ addUnit (funitString);
166
+ }
167
+ {
168
+ addFormNumericBox (F (" Range (1-10000)" ), F (" p022_range" ), range, 1 , 10000 );
169
+ String runitString = F (" default " );
170
+ runitString += PCA9685_MAX_PWM;
171
+ addUnit (runitString);
110
172
}
111
- addFormSelector (F (" MODE2" ), F (" p022_mode2" ), PCA9685_MODE2_VALUES, m2Options, m2Values, mode2);
112
-
113
- String freqString = F (" Frequency (" );
114
- freqString += PCA9685_MIN_FREQUENCY;
115
- freqString += ' -' ;
116
- freqString += PCA9685_MAX_FREQUENCY;
117
- freqString += ' )' ;
118
- addFormNumericBox (freqString, F (" p022_freq" ), freq, PCA9685_MIN_FREQUENCY, PCA9685_MAX_FREQUENCY);
119
- String funitString = F (" default " );
120
- funitString += PCA9685_MAX_FREQUENCY;
121
- addUnit (funitString);
122
-
123
- addFormNumericBox (F (" Range (1-10000)" ), F (" p022_range" ), range, 1 , 10000 );
124
- String runitString = F (" default " );
125
- runitString += PCA9685_MAX_PWM;
126
- addUnit (runitString);
127
-
128
173
success = true ;
129
174
break ;
130
175
}
131
176
132
177
case PLUGIN_WEBFORM_SAVE:
133
178
{
179
+ p022_clear_init (CONFIG_PORT);
134
180
CONFIG_PORT = getFormItemInt (F (" i2c_addr" ));
135
181
PCONFIG (0 ) = getFormItemInt (F (" p022_mode2" ));
136
182
PCONFIG (1 ) = getFormItemInt (F (" p022_freq" ));
137
183
PCONFIG (2 ) = getFormItemInt (F (" p022_range" ));
138
184
139
- if (!IS_INIT (initializeState, ( CONFIG_PORT - PCA9685_ADDRESS) ))
185
+ if (!p022_is_init ( CONFIG_PORT))
140
186
{
187
+ Plugin_022_initialize (address);
141
188
if (PCONFIG (0 ) != mode2) {
142
189
Plugin_022_writeRegister (address, PCA9685_MODE2, PCONFIG (0 ));
143
190
}
@@ -186,7 +233,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
186
233
{
187
234
if ((event->Par2 >= 0 ) && (event->Par2 <= range))
188
235
{
189
- if (!IS_INIT (initializeState, ( address - PCA9685_ADDRESS) ))
236
+ if (!p022_is_init ( address))
190
237
{
191
238
Plugin_022_initialize (address);
192
239
Plugin_022_writeRegister (address, PCA9685_MODE2, mode2);
@@ -225,7 +272,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
225
272
226
273
if ((event->Par1 >= PCA9685_MIN_FREQUENCY) && (event->Par1 <= PCA9685_MAX_FREQUENCY))
227
274
{
228
- if (!IS_INIT (initializeState, ( address - PCA9685_ADDRESS) ))
275
+ if (!p022_is_init ( address))
229
276
{
230
277
Plugin_022_initialize (address);
231
278
Plugin_022_writeRegister (address, PCA9685_MODE2, mode2);
@@ -262,7 +309,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
262
309
263
310
if ((event->Par1 >= 0 ) && (event->Par1 < PCA9685_MODE2_VALUES))
264
311
{
265
- if (!IS_INIT (initializeState, ( address - PCA9685_ADDRESS) ))
312
+ if (!p022_is_init ( address))
266
313
{
267
314
Plugin_022_initialize (address);
268
315
Plugin_022_Frequency (address, freq);
@@ -282,7 +329,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
282
329
{
283
330
if (parseString (line, 2 ) == F (" pca" ))
284
331
{
285
- if (!IS_INIT (initializeState, ( address - PCA9685_ADDRESS) ))
332
+ if (!p022_is_init ( address))
286
333
{
287
334
Plugin_022_initialize (address);
288
335
Plugin_022_writeRegister (address, PCA9685_MODE2, mode2);
@@ -302,7 +349,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
302
349
303
350
if ((event->Par1 >= 0 ) && (event->Par1 <= PCA9685_MAX_PINS))
304
351
{
305
- if (!IS_INIT (initializeState, ( address - PCA9685_ADDRESS) ))
352
+ if (!p022_is_init ( address))
306
353
{
307
354
Plugin_022_initialize (address);
308
355
Plugin_022_writeRegister (address, PCA9685_MODE2, mode2);
@@ -358,7 +405,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
358
405
359
406
if ((event->Par1 >= 0 ) && (event->Par1 <= PCA9685_MAX_PINS))
360
407
{
361
- if (!IS_INIT (initializeState, ( address - PCA9685_ADDRESS) ))
408
+ if (!p022_is_init ( address))
362
409
{
363
410
Plugin_022_initialize (address);
364
411
Plugin_022_writeRegister (address, PCA9685_MODE2, mode2);
@@ -561,7 +608,7 @@ void Plugin_022_initialize(int address)
561
608
delay (1 );
562
609
Plugin_022_writeRegister (i2cAddress, PLUGIN_022_PCA9685_MODE1, (byte)B10100000); // set up for auto increment
563
610
// Plugin_022_writeRegister(i2cAddress, PCA9685_MODE2, (byte)0x10); // set to output
564
- SET_INIT (initializeState, ( address - PCA9685_ADDRESS) );
611
+ p022_set_init ( address);
565
612
}
566
613
567
614
#endif // USES_P022
0 commit comments