summaryrefslogtreecommitdiffhomepage
path: root/digital/io
diff options
context:
space:
mode:
authorJérémy Dufour2008-03-09 19:54:27 +0100
committerJérémy Dufour2008-03-09 19:54:27 +0100
commit67755c5e9684d0d70ac4947f1a150b75593ba105 (patch)
treee17df648b4bb14cae221464679cb1313ff182ad5 /digital/io
parentc52789c26ef48cb8776a1d74887b40c38cc83de4 (diff)
* digital/io
- add asserv communication implementation (not fully completed); - correct a few English errors in asserv module (header and documentation); - add main timer to repeat the main loop every 4.444 ms; - add build system.
Diffstat (limited to 'digital/io')
-rw-r--r--digital/io/doc/proto_asserv.txt2
-rw-r--r--digital/io/src/Makefile12
-rw-r--r--digital/io/src/asserv.c255
-rw-r--r--digital/io/src/asserv.h2
-rw-r--r--digital/io/src/avrconfig.h98
-rw-r--r--digital/io/src/main.c131
-rw-r--r--digital/io/src/main_timer.avr.h62
7 files changed, 560 insertions, 2 deletions
diff --git a/digital/io/doc/proto_asserv.txt b/digital/io/doc/proto_asserv.txt
index 2c5473a3..d0e1ebc2 100644
--- a/digital/io/doc/proto_asserv.txt
+++ b/digital/io/doc/proto_asserv.txt
@@ -62,7 +62,7 @@ This table describe the list of supported commands by the *asserv* card:
+=========+=======+=================+=====================================+
| 'z' | Other | None | Reset |
+---------+-------+-----------------+-------------------------------------+
-| 'w' | Other | None | Stop motor (useful for end match) |
+| 'w' | Other | None | Free motor (useful for end match) |
+---------+-------+-----------------+-------------------------------------+
| 's' | Other | None | Stop |
+---------+-------+-----------------+-------------------------------------+
diff --git a/digital/io/src/Makefile b/digital/io/src/Makefile
new file mode 100644
index 00000000..70dc62c7
--- /dev/null
+++ b/digital/io/src/Makefile
@@ -0,0 +1,12 @@
+BASE = ../../avr
+AVR_PROGS = io
+io_SOURCES = main.c asserv.c
+MODULES = proto uart twi
+CONFIGFILE = avrconfig.h
+# atmega8, atmega8535, atmega128...
+AVR_MCU = atmega128
+# -O2 : speed
+# -Os : size
+OPTIMIZE = -O2
+
+include $(BASE)/make/Makefile.gen
diff --git a/digital/io/src/asserv.c b/digital/io/src/asserv.c
new file mode 100644
index 00000000..d36deb91
--- /dev/null
+++ b/digital/io/src/asserv.c
@@ -0,0 +1,255 @@
+/* asserv.c */
+/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{
+ *
+ * Copyright (C) 2008 Dufour Jrmy
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "asserv.h"
+
+#include "modules/twi/twi.h" /* twi_* */
+#include "modules/utils/byte.h" /* v*_to_v* */
+
+/**
+ * Sequence number.
+ * It is used for the acknowledge of the command send to the asserv.
+ */
+static uint8_t asserv_twi_seq;
+
+/**
+ * Flag to know if last command has been proceed by the asserv board.
+ */
+static uint8_t asserv_twi_seq_ack;
+
+/**
+ * Shared buffer used to send commands to the asserv.
+ */
+static uint8_t asserv_twi_buffer[7];
+
+/**
+ * Pointer to access the buffer to put the parameters list.
+ */
+static uint8_t *asserv_twi_buffer_param = &asserv_twi_buffer[2];
+
+/**
+ * Update TWI module until request (send or receive) is finished.
+ * This functions is blocking.
+ */
+static inline void
+asserv_twi_update (void);
+
+/**
+ * Send a command to the asserv board using the TWI module.
+ * If the command you want to send have some parameters, you need to fill
+ * asserv_twi_buffer_param buffer.
+ * @param command the command to send.
+ * @param length the length of the parameters list (in byte).
+ * @return
+ * - 0 when there is no error
+ * - 1 if there is already a command running on the asserv (not acknowledged
+ * or not finished yet).
+ */
+static inline uint8_t
+asserv_twi_send_command (uint8_t command, uint8_t length);
+
+
+/**
+ * Settings list of the asserv program.
+ */
+enum asserv_setting_e
+{
+ POSITION_X,
+ POSITION_Y,
+ POSITION_ANGULAR,
+ SPEED
+};
+
+/* Initialize the asserv control module. */
+void
+asserv_init (void)
+{
+ /* Initialize TWI with my (io) address */
+ twi_init (AC_IO_TWI_ADDRESS);
+ /* We are at first command */
+ asserv_twi_seq = asserv_twi_seq_ack = 0;
+}
+
+/* Update TWI module until request (send or receive) is finished. */
+static inline void
+asserv_twi_update (void)
+{
+ while (!twi_ms_is_finished ())
+ ;
+}
+
+/* Send a command to the asserv board using the TWI module. */
+static inline uint8_t
+asserv_twi_send_command (uint8_t command, uint8_t length)
+{
+ /* Check we are not doing a command ? */
+ if (asserv_twi_seq != asserv_twi_seq_ack)
+ return 1;
+
+ /* Put the command into the buffer */
+ asserv_twi_buffer[0] = command;
+ /* Put the sequence number */
+ asserv_twi_buffer[1] = ++asserv_twi_seq;
+
+ /* Send command to the asserv */
+ if (twi_ms_send (AC_ASSERV_TWI_ADDRESS, asserv_twi_buffer, length + 2) != 0)
+ return -1;
+
+ /* Update until the command is sent */
+ asserv_twi_update ();
+ return 0;
+}
+
+/* Reset the asserv board. */
+void
+asserv_reset (void)
+{
+ /* Send the reset command to the asserv board */
+ asserv_twi_send_command ('z', 0);
+}
+
+/* Free the motors (stop controlling them). */
+void
+asserv_free_motor (void)
+{
+ /* Send the free motor command to the asserv board */
+ asserv_twi_send_command ('w', 0);
+}
+
+/* Stop the motor (and the bot). */
+void
+asserv_stop_motor (void)
+{
+ /* Send the stop motor command to the asserv board */
+ asserv_twi_send_command ('s', 0);
+}
+
+/* Move linearly. */
+void
+asserv_move_linearly (int32_t distance)
+{
+ /* Put distance as parameter */
+ asserv_twi_buffer_param[0] = v32_to_v8 (distance, 3);
+ asserv_twi_buffer_param[1] = v32_to_v8 (distance, 2);
+ asserv_twi_buffer_param[2] = v32_to_v8 (distance, 1);
+ /* Send the linear move command to the asserv board */
+ asserv_twi_send_command ('l', 3);
+}
+
+ /* Move angularly (turn). */
+void
+asserv_move_angularly (int16_t angle)
+{
+ /* Put angle as parameter */
+ asserv_twi_buffer_param[0] = v16_to_v8 (angle, 1);
+ asserv_twi_buffer_param[1] = v16_to_v8 (angle, 0);
+ /* Send the angular move command to the asserv board */
+ asserv_twi_send_command ('a', 2);
+}
+
+/* Go to the wall (moving backward). */
+void
+asserv_go_to_the_wall (void)
+{
+ /* Send the go the wall command to the asserv board */
+ asserv_twi_send_command ('f', 0);
+}
+
+/* Move forward to approach a gutter. */
+void
+asserv_go_to_gutter (void)
+{
+ /* Send the go the gutter command to the asserv board */
+ asserv_twi_send_command ('F', 0);
+}
+
+/* Move the arm. */
+void
+asserv_move_arm (uint16_t position, uint8_t speed)
+{
+ /* Put position and speed as parameters */
+ asserv_twi_buffer_param[0] = v16_to_v8 (position, 1);
+ asserv_twi_buffer_param[1] = v16_to_v8 (position, 0);
+ asserv_twi_buffer_param[2] = speed;
+ /* Send the move the arm command to the asserv board */
+ asserv_twi_send_command ('b', 3);
+}
+
+/* Set current X position. */
+void
+asserv_set_x_position (int32_t x)
+{
+ /* 'X' subcommand */
+ asserv_twi_buffer_param[0] = 'X';
+ /* Put x position as parameter */
+ asserv_twi_buffer_param[1] = v32_to_v8 (x, 3);
+ asserv_twi_buffer_param[2] = v32_to_v8 (x, 2);
+ asserv_twi_buffer_param[3] = v32_to_v8 (x, 1);
+ /* Send the set X position command to the asserv board */
+ asserv_twi_send_command ('p', 4);
+}
+
+/* Set current Y position. */
+void
+asserv_set_y_position (int32_t y)
+{
+ /* 'Y' subcommand */
+ asserv_twi_buffer_param[0] = 'Y';
+ /* Put y position as parameter */
+ asserv_twi_buffer_param[1] = v32_to_v8 (y, 3);
+ asserv_twi_buffer_param[2] = v32_to_v8 (y, 2);
+ asserv_twi_buffer_param[3] = v32_to_v8 (y, 1);
+ /* Send the set Y position command to the asserv board */
+ asserv_twi_send_command ('p', 4);
+}
+
+/* Set current angular position. */
+void
+asserv_set_angle_position (int16_t angle)
+{
+ /* 'A' subcommand */
+ asserv_twi_buffer_param[0] = 'A';
+ /* Put angle position as parameter */
+ asserv_twi_buffer_param[1] = v32_to_v8 (angle, 1);
+ asserv_twi_buffer_param[2] = v32_to_v8 (angle, 0);
+ /* Send the set angular position command to the asserv board */
+ asserv_twi_send_command ('p', 3);
+}
+
+/* Set speeds of movements. */
+void
+asserv_set_speed (uint8_t linear_high, uint8_t angular_high,
+ uint8_t linear_low, uint8_t angular_low)
+{
+ /* 's' subcommand */
+ asserv_twi_buffer_param[0] = 's';
+ /* Put speeds as parameters */
+ asserv_twi_buffer_param[1] = linear_high;
+ asserv_twi_buffer_param[2] = angular_high;
+ asserv_twi_buffer_param[3] = linear_low;
+ asserv_twi_buffer_param[4] = angular_low;
+ /* Send the set speed of movements command to the asserv board */
+ asserv_twi_send_command ('p', 5);
+}
diff --git a/digital/io/src/asserv.h b/digital/io/src/asserv.h
index 138fb6f3..a4c680af 100644
--- a/digital/io/src/asserv.h
+++ b/digital/io/src/asserv.h
@@ -100,7 +100,7 @@ asserv_go_to_gutter (void);
/**
* Move the arm.
- * A complete rotation correspond to 5000 step.
+ * A complete rotation correspond to 5000 steps.
* Arm class command.
* @param position desired goal position (in step).
* @param speed speed of the movement.
diff --git a/digital/io/src/avrconfig.h b/digital/io/src/avrconfig.h
new file mode 100644
index 00000000..4d72b213
--- /dev/null
+++ b/digital/io/src/avrconfig.h
@@ -0,0 +1,98 @@
+#ifndef avrconfig_h
+#define avrconfig_h
+/* avrconfig.h */
+/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{
+ *
+ * Copyright (C) 2008 Dufour Jrmy
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * }}} */
+
+/* global */
+/** AVR Frequency : 1000000, 1843200, 2000000, 3686400, 4000000, 7372800,
+ * 8000000, 11059200, 14745600, 16000000, 18432000, 20000000. */
+#define AC_FREQ 14745600
+
+/* uart - UART module. */
+/** Select hardware uart for primary uart: 0, 1 or -1 to disable. */
+#define AC_UART0_PORT 1
+/** Baudrate: 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800,
+ * 115200, 230400, 250000, 500000, 1000000. */
+#define AC_UART0_BAUDRATE 38400
+/** Send mode:
+ * - POLLING: no interrupts.
+ * - RING: interrupts, ring buffer. */
+#define AC_UART0_SEND_MODE POLLING
+/** Recv mode, same as send mode. */
+#define AC_UART0_RECV_MODE POLLING
+/** Character size: 5, 6, 7, 8, 9 (only 8 implemented). */
+#define AC_UART0_CHAR_SIZE 8
+/** Parity : ODD, EVEN, NONE. */
+#define AC_UART0_PARITY EVEN
+/** Stop bits : 1, 2. */
+#define AC_UART0_STOP_BITS 1
+/** Send buffer size, should be power of 2 for RING mode. */
+#define AC_UART0_SEND_BUFFER_SIZE 32
+/** Recv buffer size, should be power of 2 for RING mode. */
+#define AC_UART0_RECV_BUFFER_SIZE 32
+/** If the send buffer is full when putc:
+ * - DROP: drop the new byte.
+ * - WAIT: wait until there is room in the send buffer. */
+#define AC_UART0_SEND_BUFFER_FULL WAIT
+/** In HOST compilation:
+ * - STDIO: use stdin/out.
+ * - PTS: use pseudo terminal. */
+#define AC_UART0_HOST_DRIVER PTS
+/** Same thing for secondary port. */
+#define AC_UART1_PORT -1
+#define AC_UART1_BAUDRATE 115200
+#define AC_UART1_SEND_MODE RING
+#define AC_UART1_RECV_MODE RING
+#define AC_UART1_CHAR_SIZE 8
+#define AC_UART1_PARITY EVEN
+#define AC_UART1_STOP_BITS 1
+#define AC_UART1_SEND_BUFFER_SIZE 32
+#define AC_UART1_RECV_BUFFER_SIZE 32
+#define AC_UART1_SEND_BUFFER_FULL WAIT
+#define AC_UART1_HOST_DRIVER PTS
+
+/* proto - Protocol module. */
+/** Maximum argument size. */
+#define AC_PROTO_ARGS_MAX_SIZE 12
+/** Callback function name. */
+#define AC_PROTO_CALLBACK proto_callback
+/** Putchar function name. */
+#define AC_PROTO_PUTC uart0_putc
+/** Support for quote parameter. */
+#define AC_PROTO_QUOTE 1
+
+/* twi - TWI module. */
+/** Activate master part. */
+#define AC_TWI_MASTER_ENABLE 1
+/** Activate slave part. */
+#define AC_TWI_SLAVE_ENABLE 0
+
+/* io - io/ai board. */
+/** TWI address of the io board. */
+#define AC_IO_TWI_ADDRESS 2
+/** TWI address of the asserv board. */
+#define AC_ASSERV_TWI_ADDRESS 4
+
+#endif /* avrconfig_h */
diff --git a/digital/io/src/main.c b/digital/io/src/main.c
new file mode 100644
index 00000000..602688ef
--- /dev/null
+++ b/digital/io/src/main.c
@@ -0,0 +1,131 @@
+/* main.c */
+/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{
+ *
+ * Copyright (C) 2008 Dufour Jrmy
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "common.h"
+#include "io.h"
+#include "modules/uart/uart.h"
+#include "modules/proto/proto.h"
+#include "modules/utils/utils.h"
+
+/* AVR include, non HOST */
+#ifndef HOST
+# include "main_timer.avr.h"
+#endif /* HOST */
+
+#include "asserv.h" /* Functions to control the asserv board */
+
+/**
+ * Initialize the main and all its subsystems.
+ */
+static void main_init (void);
+
+/**
+ * Main (and infinite) loop of the io program.
+ */
+static void main_loop (void);
+
+/**
+ * Initialize the main and all its subsystems.
+ */
+static void
+main_init (void)
+{
+ /* Serial port */
+ uart0_init ();
+ /* Main timer */
+ main_timer_init ();
+ /* Asserv communication */
+ asserv_init ();
+
+ /* Enable interrupts */
+ sei ();
+
+ /* io initialization done */
+ proto_send0 ('z');
+}
+
+/**
+ * Main (and infinite) loop of the io program.
+ */
+static void
+main_loop (void)
+{
+ /* Infinite loop */
+ while (1)
+ {
+ /* Wait for an overflow of the main timer (4.444ms) */
+ main_timer_wait ();
+
+ /* Get the data from the UART */
+ while (uart0_poll ())
+ /* Manage UART protocol */
+ proto_accept (uart0_getc ());
+
+ /* Update TWI module to get new data */
+ // TODO
+ }
+}
+
+/**
+ * Manage received UART commands.
+ * @param cmd commands received.
+ * @param size the length of arguments.
+ * @param args the argument of the command.
+ */
+void
+proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
+{
+#define c(cmd, size) (cmd << 8 | size)
+ switch (c (cmd, size))
+ {
+ case c ('z', 0):
+ /* Reset */
+ utils_reset ();
+ break;
+
+ default:
+ /* Unknown commands */
+ proto_send0 ('?');
+ return;
+ }
+ /* When no error, acknowledge commands */
+ proto_send (cmd, size, args);
+#undef c
+}
+
+/**
+ * Main function.
+ */
+int
+main (int argc, char **argv)
+{
+ /* Initialize the main and its subsystems */
+ main_init ();
+
+ /* Start the main loop */
+ main_loop ();
+
+ return 0;
+}
diff --git a/digital/io/src/main_timer.avr.h b/digital/io/src/main_timer.avr.h
new file mode 100644
index 00000000..528c8e4d
--- /dev/null
+++ b/digital/io/src/main_timer.avr.h
@@ -0,0 +1,62 @@
+#ifndef main_timer_avr_h
+#define main_timer_avr_h
+/* main_timer.avr.h */
+/* io - Input & Output with Artificial Intelligence (ai) support on AVR. {{{
+ *
+ * Copyright (C) 2008 Dufour Jrmy
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * }}} */
+
+/**
+ * @file Main timer module.
+ * Main timer module is used for the main loop of the io board to ensure it is
+ * executed only to the defined loop time (at the maximum). It uses the
+ * timer/counter 0 of the AVR.
+ */
+
+/**
+ * Initialize the main timer to 4.444 ms.
+ */
+static inline void
+main_timer_init (void)
+{
+ /* Fov = F_io / (prescaler * (TOP + 1))
+ * TOP = 0xff
+ * prescaler = 256
+ * Tov = 1 / Fov = 4.444 ms */
+ TCCR0 = regv (FOC0, WGM00, COM01, COM0, WGM01, CS02, CS01, CS00,
+ 0, 0, 0, 0, 0, 1, 1, 0);
+}
+
+/**
+ * Wait until the main timer overflows.
+ */
+static inline void
+main_timer_wait (void)
+{
+ /* Loop until an overflow of the timer occurs */
+ while (!(TIFR & _BV (TOV0)))
+ ;
+ /* Write 1 to clear */
+ TIFR = _BV (TOV0);
+}
+
+#endif /* main_timer_avr_h */