Skip to content

Commit 6d2c8c4

Browse files
committed
Add support for debounced inputs
1 parent 979b3e1 commit 6d2c8c4

3 files changed

Lines changed: 100 additions & 1 deletion

File tree

devGpioGenericApp/Db/pin.template

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,12 @@ record(bo, "$(P)GPIO$(N)_RESET")
9292
field(OUT, "@$(CHIP),$(N),reset")
9393
field(VAL, "0")
9494
}
95+
96+
record(longout, "$(P)GPIO$(N)_DEBOUNCE")
97+
{
98+
field(DTYP, "devGpioCfgLo")
99+
field(DESC, "Debounce period (us)")
100+
field(OUT, "@$(CHIP),$(N),debounce")
101+
field(VAL, "0")
102+
field(PINI, "YES")
103+
}

devGpioGenericApp/src/devGpio.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <epicsAtomic.h>
3131
#include <iocInit.h>
3232
#include <initHooks.h>
33+
#include <longoutRecord.h>
3334

3435
#include <linux/gpio.h>
3536
#include <fcntl.h>
@@ -92,6 +93,7 @@ struct gpio_pin {
9293
enum gpio_edge edge = GPIO_EDGE_RISING;
9394
enum gpio_bias bias = GPIO_BIAS_NONE;
9495
enum gpio_drive drive = GPIO_DRIVE_PUSH_PULL;
96+
uint32_t debounce_us = 0; /* debounce period, us */
9597
uint64_t ts; /* hardware/kernel timestamp */
9698
};
9799

@@ -133,6 +135,16 @@ struct gpio_bo_cfg_dpvt {
133135
gpio_bo_cfg_param param;
134136
};
135137

138+
enum gpio_lo_cfg_param {
139+
GPIO_LO_CFG_DEBOUNCE,
140+
};
141+
142+
struct gpio_lo_cfg_dpvt {
143+
struct gpio_chip* chip;
144+
int pin;
145+
gpio_lo_cfg_param param;
146+
};
147+
136148
static std::map<std::string, gpio_chip*> s_chips;
137149

138150
static void gpio_thread_proc(void* param);
@@ -370,6 +382,12 @@ gpio_reconfig_pin(gpio_chip* chip, int pin)
370382

371383
config.num_attrs = 0;
372384

385+
if (p.type == GPIO_TYPE_INPUT) {
386+
config.num_attrs = 1;
387+
config.attrs[0].attr.debounce_period_us = p.debounce_us;
388+
config.attrs[0].mask = 1<<p.num;
389+
}
390+
373391
if (ioctl(p.fd, GPIO_V2_LINE_SET_CONFIG_IOCTL, &config) < 0) {
374392
perror("ioctl(GPIO_V2_LINE_SET_CONFIG_IOCTL)");
375393
return false;
@@ -716,6 +734,77 @@ devGpioCfgMbbo_WriteRecord(mbboRecord* precord)
716734
return 0;
717735
}
718736

737+
/**************************** devGpioCfgLo *****************************/
738+
739+
static long devGpioCfgLo_InitRecord(dbCommon* precord);
740+
static long devGpioCfgLo_WriteRecord(longoutRecord* precord);
741+
742+
longoutdset devGpioCfgLo = {
743+
.common = {
744+
.number = 5,
745+
.init_record = devGpioCfgLo_InitRecord,
746+
},
747+
.write_longout = devGpioCfgLo_WriteRecord
748+
};
749+
750+
static bool
751+
devGpioCfgLo_ParseInstio(gpio_lo_cfg_dpvt* dpvt, char* rem)
752+
{
753+
char* param = strtok(rem, ",");
754+
if (!param) {
755+
printf("%s: Bad param type\n", __func__);
756+
return false;
757+
}
758+
759+
if (!strcmp(param, "debounce"))
760+
dpvt->param = GPIO_LO_CFG_DEBOUNCE;
761+
else {
762+
printf("%s: Bad cfg param\n", __func__);
763+
return false;
764+
}
765+
return true;
766+
}
767+
768+
static long
769+
devGpioCfgLo_InitRecord(dbCommon* precord)
770+
{
771+
auto* plo = reinterpret_cast<longoutRecord*>(precord);
772+
auto* dpvt = dpvt_create<gpio_lo_cfg_dpvt>(plo->out.value.instio.string, devGpioCfgLo_ParseInstio);
773+
774+
if (!dpvt)
775+
return S_dev_badOutType;
776+
777+
plo->dpvt = dpvt;
778+
return 0;
779+
}
780+
781+
static long
782+
devGpioCfgLo_WriteRecord(longoutRecord* precord)
783+
{
784+
auto* dpvt = dpvt_get<gpio_lo_cfg_dpvt>(precord);
785+
if (!dpvt)
786+
return 1;
787+
788+
auto& p = dpvt->chip->pins[dpvt->pin];
789+
790+
switch (dpvt->param) {
791+
case GPIO_LO_CFG_DEBOUNCE:
792+
p.debounce_us = precord->val;
793+
break;
794+
default:
795+
assert(0);
796+
}
797+
798+
if (!gpio_reconfig_pin(dpvt->chip, dpvt->pin)) {
799+
recGblSetSevr(precord, COMM_ALARM, MAJOR_ALARM);
800+
return 1;
801+
}
802+
803+
return 0;
804+
}
805+
806+
epicsExportAddress(dset, devGpioCfgLo);
807+
719808
/**************************** Input Event Thread *****************************/
720809

721810
/* NOTE: This code assumes that we have one fd per pin. */

devGpioGenericApp/src/devGpioGeneric.dbd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
device(bi, INST_IO, devGpioBi, "devGpio")
33
device(bo, INST_IO, devGpioBo, "devGpio")
44
device(mbbo, INST_IO, devGpioCfgMbbo, "devGpioCfg")
5-
device(bo, INST_IO, devGpioCfgBo, "devGpioCfgBo")
5+
device(bo, INST_IO, devGpioCfgBo, "devGpioCfgBo")
6+
device(longout, INST_IO, devGpioCfgLo, "devGpioCfgLo")

0 commit comments

Comments
 (0)