Skip to content

Commit caf1ad6

Browse files
committed
pico digital monitor based on esp8266
1 parent 10737fb commit caf1ad6

File tree

2 files changed

+222
-1
lines changed

2 files changed

+222
-1
lines changed

modules/pins/digital/monitor/manifest.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,18 @@
2020
"*": "$(MODULES)/pins/digital/monitor/gecko/*"
2121
}
2222
},
23+
"pico": {
24+
"modules": {
25+
"*": "$(MODULES)/pins/digital/monitor/pico/*"
26+
}
27+
},
2328
"qca4020": {
2429
"modules": {
2530
"*": "$(MODULES)/pins/digital/monitor/qca4020/*"
2631
}
2732
},
2833
"...": {
29-
"error": "pins/digital module unsupported"
34+
"error": "pins/digital/monitor module unsupported"
3035
}
3136
}
3237
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* Copyright (c) 2018-2021 Moddable Tech, Inc.
3+
*
4+
* This file is part of the Moddable SDK Runtime.
5+
*
6+
* The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* The Moddable SDK Runtime is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with the Moddable SDK Runtime. If not, see <http://www.gnu.org/licenses/>.
18+
*
19+
*/
20+
21+
#include "xsmc.h"
22+
#include "xsHost.h"
23+
#include "modGPIO.h"
24+
#include "mc.xs.h" // for xsID_ values
25+
#include "hardware/gpio.h"
26+
27+
struct modDigitalMonitorRecord {
28+
struct modDigitalMonitorRecord *next;
29+
xsMachine *the;
30+
xsSlot obj;
31+
uint8_t pin;
32+
uint8_t edge;
33+
uint8_t triggered;
34+
uint32_t rises;
35+
uint32_t falls;
36+
};
37+
typedef struct modDigitalMonitorRecord modDigitalMonitorRecord;
38+
typedef struct modDigitalMonitorRecord *modDigitalMonitor;
39+
40+
static void gpioISR(uint gpio, uint32_t events);
41+
static void digitalMonitorDeliver(void *the, void *refcon, uint8_t *message, uint16_t messageLength);
42+
43+
static modDigitalMonitor gMonitors;
44+
45+
void xs_digital_monitor_destructor(void *data)
46+
{
47+
modDigitalMonitor monitor = data;
48+
if (NULL == monitor)
49+
return;
50+
51+
modCriticalSectionBegin();
52+
53+
if (gMonitors == monitor)
54+
gMonitors = monitor->next;
55+
else {
56+
modDigitalMonitor walker;
57+
for (walker = gMonitors; walker; walker = walker->next) {
58+
if (walker->next == monitor) {
59+
walker->next = monitor->next;
60+
break;
61+
}
62+
}
63+
}
64+
65+
// disable interrupt for this pin
66+
gpio_set_irq_enabled(monitor->pin, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, false);
67+
gpio_init(monitor->pin);
68+
69+
// remove ISR
70+
// if (NULL == gMonitors)
71+
// ETS_GPIO_INTR_DISABLE();
72+
73+
modCriticalSectionEnd();
74+
75+
c_free(monitor);
76+
}
77+
78+
void xs_digital_monitor(xsMachine *the)
79+
{
80+
modDigitalMonitor monitor;
81+
int pin, edge, mode = kModGPIOInput;
82+
modGPIOConfigurationRecord config;
83+
84+
xsmcVars(1);
85+
86+
if (!xsmcHas(xsArg(0), xsID_pin))
87+
xsUnknownError("pin missing");
88+
89+
if (!xsmcHas(xsArg(0), xsID_edge))
90+
xsUnknownError("edge missing");
91+
92+
xsmcGet(xsVar(0), xsArg(0), xsID_pin);
93+
pin = xsmcToInteger(xsVar(0));
94+
if ((pin < 0) || (pin > 29))
95+
xsUnknownError("invalid pin");
96+
97+
xsmcGet(xsVar(0), xsArg(0), xsID_edge);
98+
edge = xsmcToInteger(xsVar(0));
99+
if ((edge < 1) || (edge > 3))
100+
xsUnknownError("invalid edge");
101+
102+
if (xsmcHas(xsArg(0), xsID_mode)) {
103+
xsmcGet(xsVar(0), xsArg(0), xsID_mode);
104+
mode = xsmcToInteger(xsVar(0));
105+
}
106+
107+
monitor = c_malloc(sizeof(modDigitalMonitorRecord));
108+
if (!monitor)
109+
xsUnknownError("no memory");
110+
111+
monitor->the = the;
112+
monitor->obj = xsThis;
113+
monitor->pin = pin;
114+
monitor->edge = edge;
115+
monitor->triggered = false;
116+
monitor->rises = 0;
117+
monitor->falls = 0;
118+
119+
xsRemember(monitor->obj);
120+
121+
xsmcSetHostData(xsThis, monitor);
122+
123+
config.pin = (uint8_t)pin;
124+
modGPIOSetMode(&config, mode);
125+
126+
// install ISR
127+
if (NULL == gMonitors)
128+
gpio_set_irq_enabled_with_callback(pin, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, false, gpioISR);
129+
130+
modCriticalSectionBegin();
131+
monitor->next = gMonitors;
132+
gMonitors = monitor;
133+
modCriticalSectionEnd();
134+
135+
// enable interrupt for this pin
136+
gpio_set_irq_enabled(monitor->pin, edge << 2, true); // shift to GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE
137+
138+
}
139+
140+
void xs_digital_monitor_close(xsMachine *the)
141+
{
142+
modDigitalMonitor monitor = xsmcGetHostData(xsThis);
143+
xsForget(monitor->obj);
144+
xs_digital_monitor_destructor(monitor);
145+
xsmcSetHostData(xsThis, NULL);
146+
}
147+
148+
void xs_digital_monitor_read(xsMachine *the)
149+
{
150+
modDigitalMonitor monitor = xsmcGetHostData(xsThis);
151+
152+
xsmcSetInteger(xsResult, gpio_get(monitor->pin));
153+
}
154+
155+
void xs_digital_monitor_get_rises(xsMachine *the)
156+
{
157+
modDigitalMonitor monitor = xsmcGetHostData(xsThis);
158+
159+
if (!(monitor->edge & 1))
160+
xsUnknownError("not configured");
161+
162+
xsmcSetInteger(xsResult, monitor->rises);
163+
}
164+
165+
void xs_digital_monitor_get_falls(xsMachine *the)
166+
{
167+
modDigitalMonitor monitor = xsmcGetHostData(xsThis);
168+
169+
if (!(monitor->edge & 2))
170+
xsUnknownError("not configured");
171+
172+
xsmcSetInteger(xsResult, monitor->falls);
173+
}
174+
175+
void gpioISR(uint gpio, uint32_t events)
176+
{
177+
modDigitalMonitor walker;
178+
uint8_t doUpdate = 0;
179+
180+
for (walker = gMonitors; walker; walker = walker->next) {
181+
if (walker->pin != gpio)
182+
continue;
183+
184+
if (gpio_get(gpio)) {
185+
if (1 & walker->edge) {
186+
walker->rises += 1;
187+
doUpdate = !walker->triggered;
188+
walker->triggered = true;
189+
}
190+
}
191+
else if (2 & walker->edge) {
192+
walker->falls += 1;
193+
doUpdate = !walker->triggered;
194+
walker->triggered = true;
195+
}
196+
break;
197+
}
198+
199+
if (doUpdate)
200+
modMessagePostToMachineFromISR(walker->the, digitalMonitorDeliver, walker);
201+
}
202+
203+
void digitalMonitorDeliver(void *the, void *refcon, uint8_t *message, uint16_t messageLength)
204+
{
205+
modDigitalMonitor walker = refcon;
206+
207+
walker->triggered = false;
208+
209+
xsBeginHost(walker->the);
210+
xsCall0(walker->obj, xsID_onChanged);
211+
xsEndHost(walker->the);
212+
}
213+
214+
void xs_digital_monitor_get_pwm_duty(xsMachine *the) {}
215+
void xs_digital_monitor_get_pwm_freq(xsMachine *the) {}
216+

0 commit comments

Comments
 (0)