Skip to content

Commit 8fe1336

Browse files
author
Matthew West
committed
Bug fixes almost to stability
1 parent 298334a commit 8fe1336

File tree

10 files changed

+236
-82
lines changed

10 files changed

+236
-82
lines changed

source/c_adc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ BBIO_err read_value(unsigned int ain, float *value)
126126
return BBIO_GEN;
127127
}
128128

129-
BBIO_err adc_setup()
129+
BBIO_err adc_setup(void)
130130
{
131131
return initialize_adc();
132132
}

source/c_adc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ SOFTWARE.
2323

2424
#ifndef BBIO_C_ADC_H
2525
#define BBIO_C_ADC_H
26+
#include "common.h"
2627

2728
extern int adc_initialized;
2829

source/c_pinmux.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,18 @@ BBIO_err set_pin_mode(const char *key, const char *mode)
1212
char pinmux_dir[20]; // "ocp:P#_##_pinmux"
1313
FILE *f = NULL;
1414

15-
build_path("/sys/devices", "ocp", ocp_dir, sizeof(ocp_dir));
15+
#ifndef BBBVERSION41
16+
BBIO_err err;
17+
err = build_path("/sys/devices", "ocp", ocp_dir, sizeof(ocp_dir));
18+
if (err != BBIO_OK) {
19+
return err;
20+
}
21+
#else
22+
strncpy(ocp_dir, "/sys/devices/platform/ocp", sizeof(ocp_dir));
23+
#endif
1624

1725
snprintf(pinmux_dir, sizeof(pinmux_dir), "ocp:%s_pinmux", key);
18-
snprintf(path, sizeof(path), "%s/%s/state", sizeof(path));
26+
snprintf(path, sizeof(path), "%s/%s/state", ocp_dir, pinmux_dir);
1927

2028
f = fopen(path, "w");
2129
if (NULL == f) {

source/c_pwm.c

Lines changed: 151 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
SOFTWARE.
2222
*/
2323

24+
#include <errno.h>
2425
#include <stdio.h>
2526
#include <stdlib.h>
2627
#include <sys/stat.h>
2728
#include <sys/types.h>
2829
#include <string.h>
2930
#include <fcntl.h>
3031
#include <unistd.h>
32+
3133
#include "c_pwm.h"
3234
#include "common.h"
3335

@@ -46,7 +48,9 @@ struct pwm_exp
4648
int period_fd;
4749
int duty_fd;
4850
int polarity_fd;
49-
unsigned long duty;
51+
int enable_fd;
52+
float duty;
53+
unsigned long duty_ns;
5054
unsigned long period_ns;
5155
struct pwm_exp *next;
5256
};
@@ -87,11 +91,11 @@ void export_pwm(struct pwm_exp *new_pwm)
8791

8892
BBIO_err initialize_pwm(void)
8993
{
90-
BBIO_err err;
9194
#ifdef BBBVERSION41 // don't load overlay in 4.1+
9295
if (!pwm_initialized) {
9396
strncpy(ocp_dir, "/sys/devices/platform/ocp", sizeof(ocp_dir));
9497
#else
98+
BBIO_err err;
9599
if (!pwm_initialized && load_device_tree("am33xx_pwm")) {
96100
err = build_path("/sys/devices", "ocp", ocp_dir, sizeof(ocp_dir));
97101
if (err != BBIO_OK)
@@ -126,16 +130,29 @@ BBIO_err pwm_set_frequency(const char *key, float freq) {
126130
if (period_ns != pwm->period_ns) {
127131
pwm->period_ns = period_ns;
128132

133+
// Update period ns
129134
len = snprintf(buffer, sizeof(buffer), "%lu", period_ns);
130-
write(pwm->period_fd, buffer, len);
135+
lseek(pwm->period_fd, 0, SEEK_SET); // Seek to beginning of file
136+
if (write(pwm->period_fd, buffer, len) < 0) {
137+
return BBIO_SYSFS;
138+
}
139+
140+
// Update duty ns
141+
pwm->duty_ns = (unsigned long)(pwm->period_ns * (pwm->duty / 100.0));
142+
len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty_ns);
143+
lseek(pwm->duty_fd, 0, SEEK_SET); // Seek to beginning of file
144+
if (write(pwm->duty_fd, buffer, len) < 0) {
145+
return BBIO_SYSFS;
146+
}
131147
}
132148

133149
return BBIO_OK;
134150
}
135151

152+
// Only works before chip is enabled
136153
BBIO_err pwm_set_polarity(const char *key, int polarity) {
137154
int len;
138-
char buffer[7]; /* allow room for trailing NUL byte */
155+
char buffer[9]; /* allow room for trailing NUL byte */
139156
struct pwm_exp *pwm;
140157

141158
pwm = lookup_exported_pwm(key);
@@ -144,8 +161,45 @@ BBIO_err pwm_set_polarity(const char *key, int polarity) {
144161
return BBIO_GEN;
145162
}
146163

164+
// polarity can't be changed with enabled.
165+
#ifdef BBBVERSION41
166+
// Read the current enabled status
167+
len = 1;
168+
memset(buffer, 0, 9); // Initialize buffer
169+
lseek(pwm->enable_fd, 0, SEEK_SET);
170+
if (read(pwm->enable_fd, buffer, len) < 0) {
171+
return BBIO_SYSFS;
172+
}
173+
174+
// If the PWM is enabled, disable it
175+
// Can't set the polarity with device enabled
176+
// It will be reenabled after the parameters are set
177+
if (buffer[0] == '1') {
178+
lseek(pwm->enable_fd, 0, SEEK_SET);
179+
len = snprintf(buffer, sizeof(buffer), "0");
180+
if (write(pwm->enable_fd, buffer, len) < 0) {
181+
return BBIO_SYSFS;
182+
}
183+
}
184+
185+
// Treating 0 as normal, 1 as inversed
186+
// See documentation of sysfs interface at
187+
// https://www.kernel.org/doc/Documentation/pwm.txt
188+
if (polarity == 0) {
189+
len = snprintf(buffer, sizeof(buffer), "normal");
190+
} else if (polarity == 1) {
191+
len = snprintf(buffer, sizeof(buffer), "inversed");
192+
} else {
193+
return BBIO_INVARG;
194+
}
195+
#else
147196
len = snprintf(buffer, sizeof(buffer), "%d", polarity);
148-
write(pwm->polarity_fd, buffer, len);
197+
#endif
198+
199+
lseek(pwm->polarity_fd, 0, SEEK_SET); // Seek to beginning of file
200+
if (write(pwm->polarity_fd, buffer, len) < 0) {
201+
return BBIO_SYSFS;
202+
}
149203

150204
return BBIO_OK;
151205
}
@@ -164,17 +218,22 @@ BBIO_err pwm_set_duty_cycle(const char *key, float duty) {
164218
return BBIO_GEN;
165219
}
166220

167-
pwm->duty = (unsigned long)(pwm->period_ns * (duty / 100.0));
221+
pwm->duty = duty;
222+
pwm->duty_ns = (unsigned long)(pwm->period_ns * (duty / 100.0));
168223

169-
len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty);
170-
write(pwm->duty_fd, buffer, len);
224+
len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty_ns);
225+
lseek(pwm->duty_fd, 0, SEEK_SET); // Seek to beginning of file
226+
if (write(pwm->duty_fd, buffer, len) < 0) {
227+
return BBIO_SYSFS;
228+
}
171229

172230
return BBIO_OK;
173231
}
174232

175-
BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
233+
BBIO_err pwm_setup(const char *key, float duty, float freq, int polarity)
176234
{
177-
int err;
235+
int e;
236+
BBIO_err err;
178237

179238
#ifdef BBBVERSION41
180239
char pwm_dev_path[45]; // "/sys/devices/platform/ocp/48300000.epwmss"
@@ -187,14 +246,14 @@ BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
187246
char polarity_path[90];
188247
char enable_path[90];
189248

190-
int period_fd, duty_fd, polarity_fd;
191-
struct pwm_exp *new_pwm, *pwm;
249+
int period_fd, duty_fd, polarity_fd, enable_fd;
250+
struct pwm_exp *new_pwm;
192251
struct stat s;
193252
FILE *f = NULL;
194253
pwm_t *p;
195254

196255
if (!pwm_initialized) {
197-
err = initialize_pwm()
256+
err = initialize_pwm();
198257
if (err != BBIO_OK) {
199258
return err;
200259
}
@@ -225,22 +284,25 @@ BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
225284
}
226285

227286
err = build_path(ocp_dir, p->chip, pwm_dev_path, sizeof(pwm_dev_path));
228-
if (err != BBIO_OK)
287+
if (err != BBIO_OK) {
229288
return err;
289+
}
230290

231291
err = build_path(pwm_dev_path, p->addr, pwm_addr_path, sizeof(pwm_addr_path));
232-
if (err != BBIO_OK)
292+
if (err != BBIO_OK) {
233293
return err;
294+
}
234295

235296
err = build_path(pwm_addr_path, "pwm/pwmchip", pwm_chip_path, sizeof(pwm_chip_path));
236-
if (err != BBIO_OK)
297+
if (err != BBIO_OK) {
237298
return err;
299+
}
238300

239301
snprintf(pwm_path, sizeof(pwm_path), "%s/pwm%d", pwm_chip_path, p->index);
240302

241303
// Export PWM if hasn't already been
242-
err = stat(pwm_path, &s);
243-
if (-1 == err) {
304+
e = stat(pwm_path, &s);
305+
if (-1 == e) {
244306
if (ENOENT == errno) { // directory does not exist
245307
snprintf(pwm_export_path, sizeof(pwm_export_path), "%s/export", pwm_chip_path);
246308
f = fopen(pwm_export_path, "w");
@@ -252,30 +314,31 @@ BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
252314
} else {
253315
perror("stat");
254316
return BBIO_GEN;
317+
}
318+
} else {
319+
if (S_ISDIR(s.st_mode)) {
320+
/* It is a directory. Already exported */
255321
} else {
256-
if (S_ISDIR(s.st_mode)) {
257-
/* It is a directory. Already exported */
258-
} else {
259-
/* It's a file. Shouldn't ever happen */
260-
return BBIO_GEN;
261-
}
322+
/* It's a file. Shouldn't ever happen */
323+
return BBIO_GEN;
262324
}
263325
}
264326

265-
err = stat(pwm_path, &s);
266-
if (-1 == err) {
327+
e = stat(pwm_path, &s);
328+
if (-1 == e) {
267329
if (ENOENT == errno) {
268330
// Directory still doesn't exist, exit with error
269331
return BBIO_GEN;
270332
}
271333
}
272334

273335
snprintf(duty_path, sizeof(duty_path), "%s/duty_cycle", pwm_path);
336+
snprintf(enable_path, sizeof(enable_path), "%s/enable", pwm_path);
274337
#else
275338
char fragment[18];
276339
char pwm_fragment[20];
277340
char pwm_path[45];
278-
char duty_path[56]
341+
char duty_path[56];
279342
char period_path[50];
280343
char polarity_path[55];
281344
int period_fd, duty_fd, polarity_fd;
@@ -317,10 +380,10 @@ BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
317380
if ((period_fd = open(period_path, O_RDWR)) < 0)
318381
return BBIO_SYSFS;
319382

320-
321383
if ((duty_fd = open(duty_path, O_RDWR)) < 0) {
322384
//error, close already opened period_fd.
323385
close(period_fd);
386+
324387
return BBIO_SYSFS;
325388
}
326389

@@ -329,11 +392,24 @@ BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
329392
close(period_fd);
330393
close(duty_fd);
331394
return BBIO_SYSFS;
332-
}
395+
}
396+
397+
#ifdef BBBVERSION41
398+
if ((enable_fd = open(enable_path, O_RDWR)) < 0) {
399+
// error, close already opened files
400+
close(period_fd);
401+
close(duty_fd);
402+
close(polarity_fd);
403+
return BBIO_SYSFS;
404+
}
405+
#endif
333406

334407
// add to list
335408
new_pwm = malloc(sizeof(struct pwm_exp));
336-
if (new_pwm == 0) {
409+
if (new_pwm == NULL) {
410+
close(period_fd);
411+
close(duty_fd);
412+
close(polarity_fd);
337413
return BBIO_MEM; // out of memory
338414
}
339415

@@ -342,32 +418,67 @@ BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
342418
new_pwm->period_fd = period_fd;
343419
new_pwm->duty_fd = duty_fd;
344420
new_pwm->polarity_fd = polarity_fd;
421+
new_pwm->enable_fd = enable_fd;
345422
new_pwm->next = NULL;
346423

347424
export_pwm(new_pwm);
348425

349-
pwm_set_frequency(key, freq);
350-
pwm_set_polarity(key, polarity);
351-
pwm_set_duty_cycle(key, duty);
426+
return BBIO_OK;
427+
}
428+
429+
BBIO_err pwm_start(const char *key, float duty, float freq, int polarity)
430+
{
431+
BBIO_err err;
432+
char buffer[20];
433+
size_t len;
434+
435+
struct pwm_exp *pwm = lookup_exported_pwm(key);
436+
if (pwm == NULL) {
437+
err = pwm_setup(key, duty, freq, polarity);
438+
if (err != BBIO_OK) {
439+
return err;
440+
}
352441

353-
#ifdef BBBVERSION41 // Enable the PWM
354-
f = fopen(enable_path);
355-
if (f == NULL)
442+
pwm = lookup_exported_pwm(key);
443+
}
444+
445+
err = pwm_set_polarity(key, polarity);
446+
if (err != BBIO_OK) {
447+
return err;
448+
}
449+
450+
err = pwm_set_frequency(key, freq);
451+
if (err != BBIO_OK) {
452+
return err;
453+
}
454+
455+
err = pwm_set_duty_cycle(key, duty);
456+
if (err != BBIO_OK) {
457+
return err;
458+
}
459+
460+
#ifdef BBBVERSION41 // Enable the PWM (don't think it's necessary before 4.1+)
461+
if (pwm == NULL) {
462+
return BBIO_GEN;
463+
}
464+
len = snprintf(buffer, sizeof(buffer), "1");
465+
lseek(pwm->enable_fd, 0, SEEK_SET);
466+
if (write(pwm->enable_fd, buffer, len) < 0) {
356467
return BBIO_SYSFS;
357-
fprintf(f, "1");
358-
fclose(f);
468+
}
359469
#endif
360470

361471
return BBIO_OK;
362472
}
363473

474+
364475
BBIO_err pwm_disable(const char *key)
365476
{
366477
struct pwm_exp *pwm, *temp, *prev_pwm = NULL;
367-
char fragment[18];
368-
int err;
369478

370479
#ifndef BBBVERSION41
480+
BBIO_err err;
481+
char fragment[18];
371482
snprintf(fragment, sizeof(fragment), "bone_pwm_%s", key);
372483
err = unload_device_tree(fragment);
373484
if (err != BBIO_OK)

0 commit comments

Comments
 (0)