25const char *pc_gpio_dir_name(pc_gpio_dir dir)
29 case pc_gpio_dir::PC_GPIO_IN:
31 case pc_gpio_dir::PC_GPIO_IN_PULLUP:
33 case pc_gpio_dir::PC_GPIO_IN_PULLDOWN:
35 case pc_gpio_dir::PC_GPIO_OUT:
60int32_t pc_gpio_json(
const pc_gpio_pin *pins, uint8_t count,
char *out, uint32_t cap)
75 for (uint8_t i = 0; i < count; i++)
77 const pc_gpio_pin *p = &pins[i];
78 if (
pc_frame_append(out, cap, GPIO_PIN, i ?
"," :
"", (uint32_t)p->pin, p->label ? p->label :
"",
79 pc_gpio_dir_name(p->dir), p->level ? 1u : 0u) == 0)
89static bool form_field_uint(
const char *body,
size_t len,
const char *name,
unsigned *out)
91 size_t nlen = strnlen(name, len + 1);
92 for (
size_t i = 0; i + nlen + 1 <= len; i++)
94 bool at_field = (i == 0) || body[i - 1] ==
'&';
95 if (!at_field || memcmp(body + i, name, nlen) != 0 || body[i + nlen] !=
'=')
99 size_t j = i + nlen + 1;
100 if (j >= len || body[j] <
'0' || body[j] >
'9')
105 for (; j < len && body[j] >=
'0' && body[j] <=
'9'; j++)
107 v = v * 10 + (unsigned)(body[j] -
'0');
115bool pc_gpio_parse_set(
const char *body,
size_t len, uint8_t *pin, uint8_t *level)
117 if (!body || !pin || !level)
123 if (!form_field_uint(body, len,
"pin", &p) || !form_field_uint(body, len,
"level", &l))
132bool pc_gpio_is_output(
const pc_gpio_pin *pins, uint8_t count, uint8_t pin)
138 for (uint8_t i = 0; i < count; i++)
140 if (pins[i].pin == pin && pins[i].dir == pc_gpio_dir::PC_GPIO_OUT)
150void pc_gpio_begin_pins(
const pc_gpio_pin *pins, uint8_t count)
156 for (uint8_t i = 0; i < count; i++)
160 case pc_gpio_dir::PC_GPIO_OUT:
161 pinMode(pins[i].pin, OUTPUT);
163 case pc_gpio_dir::PC_GPIO_IN_PULLUP:
164 pinMode(pins[i].pin, INPUT_PULLUP);
166 case pc_gpio_dir::PC_GPIO_IN_PULLDOWN:
167 pinMode(pins[i].pin, INPUT_PULLDOWN);
170 pinMode(pins[i].pin, INPUT);
176void pc_gpio_read(pc_gpio_pin *pins, uint8_t count)
182 for (uint8_t i = 0; i < count; i++)
184 pins[i].level = (uint8_t)(digitalRead(pins[i].pin) ? 1 : 0);
188void pc_gpio_write(uint8_t pin, uint8_t level)
190 digitalWrite(pin, level ? HIGH : LOW);
195void pc_gpio_begin_pins(
const pc_gpio_pin *, uint8_t)
199void pc_gpio_read(pc_gpio_pin *, uint8_t)
203void pc_gpio_write(uint8_t, uint8_t)
size_t pc_frame_append(char *out, size_t cap, const pc_field *spec,...)
Append spec to the NUL-terminated contents already in out.
Declarative frame builder: a frame is a static table of typed fields, built by one engine.
@ PC_FK_LIT
literal text from lit; takes no argument
Browser GPIO pin-mapper / diagnostics (PC_ENABLE_GPIO_MAP).
One field of a frame. Frames are static const pc_field[], so they live in rodata.