summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-04-13 06:16:01 -0700
committerKeith Packard <keithp@keithp.com>2016-04-13 06:20:34 -0700
commitb8a19e83b7b1b8e2a1fcbdd58e41f9f974ae28ff (patch)
tree258a7c88d6ceaa3c8b06849f44d729a3b33d0f65
parentcfb91ec7ef6ef485d813af96a0f206bb7a2204dd (diff)
altos/detherm: Add servo driver
This just provides commands to test the servo with. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--src/detherm/Makefile1
-rw-r--r--src/detherm/ao_detherm.c2
-rw-r--r--src/detherm/ao_pins.h16
-rw-r--r--src/drivers/ao_servo.c118
-rw-r--r--src/drivers/ao_servo.h41
5 files changed, 174 insertions, 4 deletions
diff --git a/src/detherm/Makefile b/src/detherm/Makefile
index 35df6c96..6b0e0bf8 100644
--- a/src/detherm/Makefile
+++ b/src/detherm/Makefile
@@ -42,6 +42,7 @@ ALTOS_SRC = \
ao_ms5607.c \
ao_convert_pa.c \
ao_pwm.c \
+ ao_servo.c \
ao_task.c \
ao_config.c \
ao_cmd.c \
diff --git a/src/detherm/ao_detherm.c b/src/detherm/ao_detherm.c
index 64dee586..fba9195e 100644
--- a/src/detherm/ao_detherm.c
+++ b/src/detherm/ao_detherm.c
@@ -18,6 +18,7 @@
#include <ao.h>
#include <ao_exti.h>
#include <ao_pwm.h>
+#include <ao_servo.h>
void main(void)
{
@@ -38,6 +39,7 @@ void main(void)
ao_ms5607_init();
// ao_flight_init();
ao_pwm_init();
+ ao_servo_init();
ao_log_init();
ao_report_init();
ao_config_init();
diff --git a/src/detherm/ao_pins.h b/src/detherm/ao_pins.h
index 8cd4a9c4..1c577b6e 100644
--- a/src/detherm/ao_pins.h
+++ b/src/detherm/ao_pins.h
@@ -98,10 +98,18 @@
#define AO_PWM_TIMER_ENABLE STM_RCC_APB1ENR_TIM3EN
#define AO_PWM_TIMER_SCALE 32
-/* Motor */
+/* Servo */
-#define AO_MOTOR_DIR_GPIO (&stm_gpiob)
-#define AO_MOTOR_DIR_PIN 0
-#define AO_MOTOR_SPEED_PWM 0
+#define AO_SERVO_DIR_PORT (&stm_gpiob)
+#define AO_SERVO_DIR_BIT 0
+#define AO_SERVO_SPEED_PWM 0
+
+/* limit 2 */
+#define AO_SERVO_LIMIT_FORE_PORT (&stm_gpiob)
+#define AO_SERVO_LIMIT_FORE_BIT 6
+
+/* limit 1 */
+#define AO_SERVO_LIMIT_BACK_PORT (&stm_gpiob)
+#define AO_SERVO_LIMIT_BACK_BIT 7
#endif /* _AO_PINS_H_ */
diff --git a/src/drivers/ao_servo.c b/src/drivers/ao_servo.c
new file mode 100644
index 00000000..b48a4112
--- /dev/null
+++ b/src/drivers/ao_servo.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2016 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+#include "ao_servo.h"
+#include "ao_pwm.h"
+#include "ao_exti.h"
+
+static uint8_t limit_wakeup;
+
+static void
+ao_limit_isr(void)
+{
+ ao_wakeup(&limit_wakeup);
+}
+
+static void
+ao_limit_enable(uint8_t dir)
+{
+ if (dir == AO_SERVO_FORE)
+ ao_exti_enable(AO_SERVO_LIMIT_FORE_PORT, AO_SERVO_LIMIT_FORE_BIT);
+ else
+ ao_exti_enable(AO_SERVO_LIMIT_BACK_PORT, AO_SERVO_LIMIT_BACK_BIT);
+}
+
+static void
+ao_limit_disable(uint8_t dir)
+{
+ if (dir == AO_SERVO_FORE)
+ ao_exti_disable(AO_SERVO_LIMIT_FORE_PORT, AO_SERVO_LIMIT_FORE_BIT);
+ else
+ ao_exti_disable(AO_SERVO_LIMIT_BACK_PORT, AO_SERVO_LIMIT_BACK_BIT);
+}
+
+static uint8_t
+ao_limit_get(uint8_t dir)
+{
+ if (dir == AO_SERVO_FORE)
+ return !ao_gpio_get(AO_SERVO_LIMIT_FORE_PORT, AO_SERVO_LIMIT_FORE_BIT, PIN);
+ else
+ return !ao_gpio_get(AO_SERVO_LIMIT_BACK_PORT, AO_SERVO_LIMIT_BACK_BIT, PIN);
+}
+
+void
+ao_servo_run(uint16_t speed, uint8_t dir, uint16_t timeout)
+{
+ printf ("speed %d dir %d\n", speed, dir);
+
+ /* Turn on the motor */
+ ao_gpio_set(AO_SERVO_DIR_PORT, AO_SERVO_DIR_BIT, AO_SERVO_DIR_PIN, dir);
+ ao_pwm_set(AO_SERVO_SPEED_PWM, speed);
+
+ /* Wait until the limit sensor is triggered */
+ ao_arch_block_interrupts();
+ ao_limit_enable(dir);
+ while (!ao_limit_get(dir))
+ if (ao_sleep_for(&limit_wakeup, timeout))
+ break;
+ ao_limit_disable(dir);
+ ao_arch_release_interrupts();
+
+ /* Turn off the motor */
+ ao_pwm_set(AO_SERVO_SPEED_PWM, 0);
+}
+
+#define init_limit(p,b) do { \
+ ao_enable_port(p); \
+ ao_exti_setup(p, b, \
+ AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_MED, \
+ ao_limit_isr); \
+ } while (0)
+
+
+static void
+ao_servo_cmd(void)
+{
+ uint8_t dir;
+ uint16_t speed;
+
+ ao_cmd_decimal();
+ dir = ao_cmd_lex_u32;
+ ao_cmd_decimal();
+ speed = ao_cmd_lex_u32;
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+
+ printf("Run servo %d\n", dir);
+ ao_servo_run(speed, dir, AO_MS_TO_TICKS(200));
+}
+
+static const struct ao_cmds ao_servo_cmds[] = {
+ { ao_servo_cmd, "S <dir> <speed>\0Run servo in indicated direction" },
+ { 0, NULL },
+};
+
+
+void
+ao_servo_init(void)
+{
+ init_limit(AO_SERVO_LIMIT_FORE_PORT, AO_SERVO_LIMIT_FORE_BIT);
+ init_limit(AO_SERVO_LIMIT_BACK_PORT, AO_SERVO_LIMIT_BACK_BIT);
+ ao_enable_output(AO_SERVO_DIR_PORT, AO_SERVO_DIR_BIT, AO_SERVO_DIR_PIN, 0);
+ ao_cmd_register(&ao_servo_cmds[0]);
+}
diff --git a/src/drivers/ao_servo.h b/src/drivers/ao_servo.h
new file mode 100644
index 00000000..e1df347a
--- /dev/null
+++ b/src/drivers/ao_servo.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2016 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_SERVO_H_
+#define _AO_SERVO_H_
+
+void
+ao_servo_run(uint16_t speed, uint8_t dir, uint16_t timeout);
+
+void
+ao_servo_init(void);
+
+#define AO_SERVO_FORE 0
+#define AO_SERVO_BACK 1
+
+/* To configure the servo:
+ *
+ * #define AO_SERVO_PWM <pwm index>
+ * #define AO_SERVO_DIR_PORT <gpio>
+ * #define AO_SERVO_DIR_PIN <pin>
+ * #define AO_SERVO_LIMIT_FORE_PORT <gpio>
+ * #define AO_SERVO_LIMIT_FORE_PIN <pin>
+ * #define AO_SERVO_LIMIT_BACK_PORT <gpio>
+ * #define AO_SERVO_LIMIT_BACK_PIN <pin>
+ */
+
+#endif /* _AO_SERVO_H_ */