-
Notifications
You must be signed in to change notification settings - Fork 241
/
Copy pathmodHX711c.c
76 lines (62 loc) · 1.87 KB
/
modHX711c.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright © 2023 by Thorsten von Eicken.
#include "xsPlatform.h"
#include "xsmc.h"
#include "modGPIO.h"
#include "mc.xs.h" // for xsID_* constants
#define xsmcVar(x) xsVar(x)
typedef struct {
modGPIOConfigurationRecord clk;
modGPIOConfigurationRecord din;
int gain;
} hx711_data;
void xs_HX711_init(xsMachine *the) {
if (xsmcArgc != 3) xsUnknownError("invalid arguments");
int clk_pin = xsmcToInteger(xsArg(0));
int din_pin = xsmcToInteger(xsArg(1));
hx711_data *data = c_malloc(sizeof(hx711_data));
if (data == NULL) xsUnknownError("can't allocate data");
data->gain = xsmcToInteger(xsArg(2));
if (modGPIOInit(&data->clk, NULL, clk_pin, kModGPIOOutput))
xsUnknownError("can't init clk pin");
modGPIOWrite(&data->clk, 0);
if (modGPIOInit(&data->din, NULL, din_pin, kModGPIOInput))
xsUnknownError("can't init dat pin");
xsmcSetHostData(xsThis, data);
}
void xs_HX711_destructor(void *hostData) {
hx711_data *data = hostData;
modGPIOUninit(&data->clk);
modGPIOUninit(&data->din);
c_free(data);
}
void xs_HX711_readable(xsMachine *the) {
hx711_data *data = xsmcGetHostData(xsThis);
xsmcSetBoolean(xsResult, modGPIORead(&data->din) == 0);
}
void xs_HX711_read(xsMachine *the) {
hx711_data *data = xsmcGetHostData(xsThis);
// check data is ready
if (modGPIORead(&data->din) != 0) {
xsmcSetUndefined(xsResult);
return;
}
modCriticalSectionBegin();
// read 24 bits
int32_t value = 0;
for (int i = 0; i < 24; i++) {
modGPIOWrite(&data->clk, 1);
modDelayMicroseconds(1);
modGPIOWrite(&data->clk, 0);
value = (value<<1) | (modGPIORead(&data->din) & 1);
}
// sign-extend 24->32 bits
value = (value << 8) >> 8;
// signal gain
for (int i = 0; i < data->gain; i++) {
modGPIOWrite(&data->clk, 1);
modGPIOWrite(&data->clk, 0);
}
modCriticalSectionEnd();
// return value
xsmcSetInteger(xsResult, value);
}