aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2016-06-08 19:32:06 -0400
committerKevin O'Connor <kevin@koconnor.net>2016-06-13 23:18:59 -0400
commit71947d6beafe118259ca2805dbb21fac5ab3b165 (patch)
tree27e5aece7a81832d6512f0eefe6925dccf5e0ed4
parent220a1e419760e4854f5b4ad9565f1c42e75f7bc2 (diff)
downloadkutter-71947d6beafe118259ca2805dbb21fac5ab3b165.tar.gz
kutter-71947d6beafe118259ca2805dbb21fac5ab3b165.tar.xz
kutter-71947d6beafe118259ca2805dbb21fac5ab3b165.zip
gpiocmds: Add Kconfig option to allow boards to disable ADC commands
Some boards may not support the ADC hardware. Update the build so that those commands do not need to be compiled if they are not available. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--Makefile5
-rw-r--r--src/Kconfig6
-rw-r--r--src/Makefile4
-rw-r--r--src/adccmds.c117
-rw-r--r--src/avr/Kconfig5
-rw-r--r--src/gpiocmds.c111
6 files changed, 135 insertions, 113 deletions
diff --git a/Makefile b/Makefile
index 1ca95481..170ce9fb 100644
--- a/Makefile
+++ b/Makefile
@@ -25,8 +25,8 @@ CPP=cpp
PYTHON=python
# Source files
-src-y=sched.c command.c stepper.c basecmd.c gpiocmds.c spicmds.c endstop.c
-dirs-y=src
+src-y =
+dirs-y = src
# Default compiler flags
cc-option=$(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`" \
@@ -58,6 +58,7 @@ MAKEFLAGS += --no-print-directory
endif
# Include board specific makefile
+include src/Makefile
-include src/$(patsubst "%",%,$(CONFIG_BOARD_DIRECTORY))/Makefile
################ Common build rules
diff --git a/src/Kconfig b/src/Kconfig
index e7460cce..ac9322ee 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -13,6 +13,12 @@ endchoice
source "src/avr/Kconfig"
source "src/simulator/Kconfig"
+# The HAVE_GPIO_x options allow boards to disable support for some
+# commands if the hardware does not support the feature.
+config HAVE_GPIO_ADC
+ bool
+ default n
+
config INLINE_STEPPER_HACK
# Enables gcc to inline stepper_event() into the main timer irq handler
bool
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 00000000..5a640863
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,4 @@
+# Main code build rules
+
+src-y += sched.c command.c stepper.c basecmd.c gpiocmds.c spicmds.c endstop.c
+src-$(CONFIG_HAVE_GPIO_ADC) += adccmds.c
diff --git a/src/adccmds.c b/src/adccmds.c
new file mode 100644
index 00000000..2ae7f43c
--- /dev/null
+++ b/src/adccmds.c
@@ -0,0 +1,117 @@
+// Commands for controlling GPIO analog-to-digital input pins
+//
+// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "basecmd.h" // alloc_oid
+#include "board/gpio.h" // struct gpio_adc
+#include "board/irq.h" // irq_save
+#include "command.h" // DECL_COMMAND
+#include "sched.h" // DECL_TASK
+
+struct analog_in {
+ struct timer timer;
+ uint32_t rest_time, sample_time, next_begin_time;
+ uint16_t value, min_value, max_value;
+ struct gpio_adc pin;
+ uint8_t state, sample_count;
+};
+
+static uint8_t
+analog_in_event(struct timer *timer)
+{
+ struct analog_in *a = container_of(timer, struct analog_in, timer);
+ if (gpio_adc_sample(a->pin)) {
+ a->timer.waketime += gpio_adc_sample_time();
+ return SF_RESCHEDULE;
+ }
+ uint16_t value = gpio_adc_read(a->pin);
+ uint8_t state = a->state;
+ if (state >= a->sample_count) {
+ state = 0;
+ } else {
+ value += a->value;
+ }
+ a->value = value;
+ a->state = state+1;
+ if (a->state < a->sample_count) {
+ a->timer.waketime += a->sample_time;
+ return SF_RESCHEDULE;
+ }
+ if (a->value < a->min_value || a->value > a->max_value)
+ shutdown("adc out of range");
+ a->next_begin_time += a->rest_time;
+ a->timer.waketime = a->next_begin_time;
+ return SF_RESCHEDULE;
+}
+
+void
+command_config_analog_in(uint32_t *args)
+{
+ struct analog_in *a = alloc_oid(
+ args[0], command_config_analog_in, sizeof(*a));
+ a->timer.func = analog_in_event;
+ a->pin = gpio_adc_setup(args[1]);
+ a->state = 1;
+}
+DECL_COMMAND(command_config_analog_in, "config_analog_in oid=%c pin=%u");
+
+void
+command_query_analog_in(uint32_t *args)
+{
+ struct analog_in *a = lookup_oid(args[0], command_config_analog_in);
+ sched_del_timer(&a->timer);
+ gpio_adc_clear_sample(a->pin);
+ a->next_begin_time = args[1];
+ a->timer.waketime = a->next_begin_time;
+ a->sample_time = args[2];
+ a->sample_count = args[3];
+ a->state = a->sample_count + 1;
+ a->rest_time = args[4];
+ a->min_value = args[5];
+ a->max_value = args[6];
+ if (! a->sample_count)
+ return;
+ sched_timer(&a->timer);
+}
+DECL_COMMAND(command_query_analog_in,
+ "query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c"
+ " rest_ticks=%u min_value=%hu max_value=%hu");
+
+static void
+analog_in_task(void)
+{
+ static uint16_t next;
+ if (!sched_check_periodic(3, &next))
+ return;
+ uint8_t oid;
+ struct analog_in *a;
+ foreach_oid(oid, a, command_config_analog_in) {
+ if (a->state != a->sample_count)
+ continue;
+ uint8_t flag = irq_save();
+ if (a->state != a->sample_count) {
+ irq_restore(flag);
+ continue;
+ }
+ uint16_t value = a->value;
+ uint32_t next_begin_time = a->next_begin_time;
+ a->state++;
+ irq_restore(flag);
+ sendf("analog_in_state oid=%c next_clock=%u value=%hu"
+ , oid, next_begin_time, value);
+ }
+}
+DECL_TASK(analog_in_task);
+
+static void
+analog_in_shutdown(void)
+{
+ uint8_t i;
+ struct analog_in *a;
+ foreach_oid(i, a, command_config_analog_in) {
+ gpio_adc_clear_sample(a->pin);
+ }
+}
+DECL_SHUTDOWN(analog_in_shutdown);
diff --git a/src/avr/Kconfig b/src/avr/Kconfig
index 24e33812..9cfbec07 100644
--- a/src/avr/Kconfig
+++ b/src/avr/Kconfig
@@ -2,6 +2,11 @@
if MACH_AVR
+config AVR_SELECT
+ bool
+ default y
+ select HAVE_GPIO_ADC
+
config BOARD_DIRECTORY
string
default "avr"
diff --git a/src/gpiocmds.c b/src/gpiocmds.c
index ff03dfd1..283d3d2e 100644
--- a/src/gpiocmds.c
+++ b/src/gpiocmds.c
@@ -288,114 +288,3 @@ soft_pwm_shutdown(void)
}
}
DECL_SHUTDOWN(soft_pwm_shutdown);
-
-
-/****************************************************************
- * Analog input pins
- ****************************************************************/
-
-struct analog_in {
- struct timer timer;
- uint32_t rest_time, sample_time, next_begin_time;
- uint16_t value, min_value, max_value;
- struct gpio_adc pin;
- uint8_t state, sample_count;
-};
-
-static uint8_t
-analog_in_event(struct timer *timer)
-{
- struct analog_in *a = container_of(timer, struct analog_in, timer);
- if (gpio_adc_sample(a->pin)) {
- a->timer.waketime += gpio_adc_sample_time();
- return SF_RESCHEDULE;
- }
- uint16_t value = gpio_adc_read(a->pin);
- uint8_t state = a->state;
- if (state >= a->sample_count) {
- state = 0;
- } else {
- value += a->value;
- }
- a->value = value;
- a->state = state+1;
- if (a->state < a->sample_count) {
- a->timer.waketime += a->sample_time;
- return SF_RESCHEDULE;
- }
- if (a->value < a->min_value || a->value > a->max_value)
- shutdown("adc out of range");
- a->next_begin_time += a->rest_time;
- a->timer.waketime = a->next_begin_time;
- return SF_RESCHEDULE;
-}
-
-void
-command_config_analog_in(uint32_t *args)
-{
- struct analog_in *a = alloc_oid(
- args[0], command_config_analog_in, sizeof(*a));
- a->timer.func = analog_in_event;
- a->pin = gpio_adc_setup(args[1]);
- a->state = 1;
-}
-DECL_COMMAND(command_config_analog_in, "config_analog_in oid=%c pin=%u");
-
-void
-command_query_analog_in(uint32_t *args)
-{
- struct analog_in *a = lookup_oid(args[0], command_config_analog_in);
- sched_del_timer(&a->timer);
- gpio_adc_clear_sample(a->pin);
- a->next_begin_time = args[1];
- a->timer.waketime = a->next_begin_time;
- a->sample_time = args[2];
- a->sample_count = args[3];
- a->state = a->sample_count + 1;
- a->rest_time = args[4];
- a->min_value = args[5];
- a->max_value = args[6];
- if (! a->sample_count)
- return;
- sched_timer(&a->timer);
-}
-DECL_COMMAND(command_query_analog_in,
- "query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c"
- " rest_ticks=%u min_value=%hu max_value=%hu");
-
-static void
-analog_in_task(void)
-{
- static uint16_t next;
- if (!sched_check_periodic(3, &next))
- return;
- uint8_t oid;
- struct analog_in *a;
- foreach_oid(oid, a, command_config_analog_in) {
- if (a->state != a->sample_count)
- continue;
- uint8_t flag = irq_save();
- if (a->state != a->sample_count) {
- irq_restore(flag);
- continue;
- }
- uint16_t value = a->value;
- uint32_t next_begin_time = a->next_begin_time;
- a->state++;
- irq_restore(flag);
- sendf("analog_in_state oid=%c next_clock=%u value=%hu"
- , oid, next_begin_time, value);
- }
-}
-DECL_TASK(analog_in_task);
-
-static void
-analog_in_shutdown(void)
-{
- uint8_t i;
- struct analog_in *a;
- foreach_oid(i, a, command_config_analog_in) {
- gpio_adc_clear_sample(a->pin);
- }
-}
-DECL_SHUTDOWN(analog_in_shutdown);