summaryrefslogtreecommitdiff
path: root/n/avr/proto
diff options
context:
space:
mode:
authorschodet2004-07-18 22:03:16 +0000
committerschodet2004-07-18 22:03:16 +0000
commit8955d8da9476fa8fa37b0a5a88fa7be10c511b35 (patch)
treea3fea08698b56b9c8195ad0bba79d88a79307f06 /n/avr/proto
parente7233cb43576b7759ffa47867ef4e7ed6dd8bc20 (diff)
Initial revision
Diffstat (limited to 'n/avr/proto')
-rw-r--r--n/avr/proto/Makefile16
-rw-r--r--n/avr/proto/Makefile.avr100
-rw-r--r--n/avr/proto/Makefile.module1
-rw-r--r--n/avr/proto/Module1
-rw-r--r--n/avr/proto/avrconfig.h33
-rw-r--r--n/avr/proto/proto.c248
-rw-r--r--n/avr/proto/proto.h74
-rw-r--r--n/avr/proto/proto.txt50
-rw-r--r--n/avr/proto/test_proto.c49
-rw-r--r--n/avr/proto/testconfig.h61
10 files changed, 633 insertions, 0 deletions
diff --git a/n/avr/proto/Makefile b/n/avr/proto/Makefile
new file mode 100644
index 0000000..9855cda
--- /dev/null
+++ b/n/avr/proto/Makefile
@@ -0,0 +1,16 @@
+PROGS = test_proto
+SOURCES = test_proto.c proto.c
+DOC = proto.html
+EXTRACTDOC = avrconfig.h proto.h
+MODULES = n/avr/rs232
+CONFIGFILE = testconfig.h
+# atmega8, atmega8535, atmega128...
+MCU_TARGET = atmega8
+# -O2 : speed
+# -Os : size
+OPTIMIZE = -O2
+
+DEFS =
+LIBS =
+
+include Makefile.avr
diff --git a/n/avr/proto/Makefile.avr b/n/avr/proto/Makefile.avr
new file mode 100644
index 0000000..01c9b7b
--- /dev/null
+++ b/n/avr/proto/Makefile.avr
@@ -0,0 +1,100 @@
+# Flags. {{{1
+
+CC = avr-gcc
+
+CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) \
+ $(if $(CONFIGFILE), $(CONFIGFILE:%=-include %))
+CPPFLAGS = $(DEFS) -Imodules
+LDFLAGS =
+
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+
+# Main rules. {{{1
+
+CSOURCES = $(filter %.c, $(SOURCES))
+SSOURCES = $(filter %.s, $(SOURCES))
+OBJECTS = $(CSOURCES:%.c=%.o) $(SSOURCES:%.s=%.o)
+ELFS = $(PROGS:%=%.elf)
+
+all: elf lst hex
+
+.PHONY: all clean elf lst doc text hex srec bin eeprom ehex esrec ebin
+
+# Rules for modules. {{{1
+
+MODULESFILES = $(MODULES:%=modules/%/Makefile.module)
+
+include $(MODULESFILES)
+
+SOURCES += $(MODULESSOURCES)
+
+$(MODULESFILES):
+ mkdir -p modules
+ cd modules && cvs co $(@:modules/%/Makefile.module=%)
+ test -f $@
+
+# General rules. {{{1
+
+elf: $(PROGS:%=%.elf)
+lst: $(PROGS:%=%.lst)
+
+$(PROGS:%=%.elf): $(OBJECTS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+%.lst: %.elf
+ $(OBJDUMP) -h -S $< > $@
+
+clean:
+ rm -f *.o $(OBJECTS) $(PROGS:%=%.elf) *.lst *.map *.bak *~
+ rm -f $(DOC) *.exd $(EXTRA_CLEAN_FILES) $(TEXTS) $(EEPROMS)
+
+# Rules for building the doc. {{{1
+
+doc: $(DOC)
+
+%.html: %.txt %.exd
+ aft $<
+
+%.exd: $(EXTRACTDOC)
+ test -n "$^" && extractdoc $^ > $@ || true
+
+# Rules for building the .text rom images. {{{1
+
+TEXTS = $(PROGS:%=%.hex) $(PROGS:%=%.bin) $(PROGS:%=%.srec)
+
+text: hex bin srec
+
+hex: $(PROGS:%=%.hex)
+bin: $(PROGS:%=%.bin)
+srec: $(PROGS:%=%.srec)
+
+%.hex: %.elf
+ $(OBJCOPY) -j .text -j .data -O ihex $< $@
+
+%.srec: %.elf
+ $(OBJCOPY) -j .text -j .data -O srec $< $@
+
+%.bin: %.elf
+ $(OBJCOPY) -j .text -j .data -O binary $< $@
+
+# Rules for building the .eeprom rom images. {{{1
+
+EEPROMS = $(PROGS:%=%_eeprom.hex) $(PROGS:%=%_eeprom.bin) \
+ $(PROGS:%=%_eeprom.srec)
+
+eeprom: ehex ebin esrec
+
+ehex: $(PROGS:%=%_eeprom.hex)
+ebin: $(PROGS:%=%_eeprom.bin)
+esrec: $(PROGS:%=%_eeprom.srec)
+
+%_eeprom.hex: %.elf
+ $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
+
+%_eeprom.srec: %.elf
+ $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@
+
+%_eeprom.bin: %.elf
+ $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@
+
diff --git a/n/avr/proto/Makefile.module b/n/avr/proto/Makefile.module
new file mode 100644
index 0000000..9f2d113
--- /dev/null
+++ b/n/avr/proto/Makefile.module
@@ -0,0 +1 @@
+MODULESSOURCES += proto.c
diff --git a/n/avr/proto/Module b/n/avr/proto/Module
new file mode 100644
index 0000000..343309d
--- /dev/null
+++ b/n/avr/proto/Module
@@ -0,0 +1 @@
+proto.c
diff --git a/n/avr/proto/avrconfig.h b/n/avr/proto/avrconfig.h
new file mode 100644
index 0000000..4bf8392
--- /dev/null
+++ b/n/avr/proto/avrconfig.h
@@ -0,0 +1,33 @@
+#ifndef avrconfig_h
+#define avrconfig_h
+/* avrconfig.h - config file for avr projects. */
+/* n.avr.proto - Protocol Module. {{{
+ *
+ * Copyright (C) 2004 Nicolas Schodet
+ *
+ * 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.
+ *
+ * Contact :
+ * Web: http://perso.efrei.fr/~schodet/
+ * Email: <contact@ni.fr.eu.org>
+ * }}} */
+
+/* proto - Protocol module. */
+/** Maximum argument number. */
+#define AC_PROTO_MAX_ARGS 3
+/** Protocol arguments type. */
+#define AC_PROTO_ARG_TYPE uint8_t
+
+#endif /* avrconfig_h */
diff --git a/n/avr/proto/proto.c b/n/avr/proto/proto.c
new file mode 100644
index 0000000..a426c41
--- /dev/null
+++ b/n/avr/proto/proto.c
@@ -0,0 +1,248 @@
+/* proto.c */
+/* {{{
+ *
+ * Copyright (C) 2004 Nicolas Schodet
+ *
+ * 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.
+ *
+ * Contact :
+ * Web: http://perso.efrei.fr/~schodet/
+ * Email: <contact@ni.fr.eu.org>
+ * }}} */
+#include "proto.h"
+
+#include <ctype.h>
+
+/* +AutoDec */
+
+/** Accept a digit to be used for args. */
+static void
+proto_accept_digit (uint8_t c);
+
+/* Send a hex digit. */
+static void
+proto_hex (uint8_t h);
+
+/* Send a arg. */
+inline static void
+proto_arg (proto_arg_t a);
+
+/* -AutoDec */
+
+static uint8_t cmd;
+static proto_arg_t argv[AC_PROTO_MAX_ARGS];
+static uint8_t argc;
+
+/** Step of decoding:
+ * - 0: nothing received.
+ * - 1: bang received.
+ * - 2: command received.
+ * - 3, 4, 5: command received, and processing a number. */
+static uint8_t step;
+
+static proto_cb_f func_cb;
+static proto_putc_f func_putc;
+
+/** Initialize and set the callback function. */
+void
+proto_init (proto_cb_f f_cb, proto_putc_f f_putc)
+{
+ func_cb = f_cb;
+ func_putc = f_putc;
+}
+
+/** Accept a new character. */
+void
+proto_accept (uint8_t c)
+{
+ if (c == '!')
+ {
+ step = 1;
+ }
+ else
+ {
+ switch (step)
+ {
+ case 0:
+ /* Nothing received yet. */
+ break;
+ case 1:
+ /* Bang received yet. */
+ if (isalpha (c))
+ {
+ cmd = c;
+ step = 2;
+ argc = 0;
+ }
+ else
+ {
+ func_cb ('?', 0, 0);
+ step = 0;
+ }
+ break;
+ case 2:
+ /* Command received yet. */
+ if (c == '\r')
+ {
+ func_cb (cmd, argc, argv);
+ step = 0;
+ }
+ else if (c == ',')
+ {
+ }
+ else
+ {
+ step += sizeof (proto_arg_t) * 2 - 1;
+ proto_accept_digit (c);
+ }
+ break;
+ case 3:
+ case 4:
+ case 5:
+ step--;
+ proto_accept_digit (c);
+ break;
+ }
+ }
+}
+
+/** Accept a digit to be used for args. */
+static void
+proto_accept_digit (uint8_t c)
+{
+ /* Test for argument list overflow. */
+ if (argc >= AC_PROTO_MAX_ARGS)
+ {
+ func_cb ('?', 0, 0);
+ step = 0;
+ return;
+ }
+ /* Convert from hexa. */
+ if ('0' <= c && c <= '9')
+ c -= '0';
+ else if ('a' <= c && c <= 'f')
+ c -= 'a' - 10;
+ else if ('A' <= c && c <= 'F')
+ c -= 'A' - 10;
+ else
+ {
+ func_cb ('?', 0, 0);
+ return;
+ }
+ /* Add digit. */
+ argv[argc] <<= 4;
+ argv[argc] |= c;
+ if (step == 2)
+ argc++;
+}
+
+/* Send a hex digit. */
+static void
+proto_hex (uint8_t h)
+{
+ func_putc (h >= 10 ? h - 10 + 'a' : h + '0');
+}
+
+/* Send a arg. */
+inline static void
+proto_arg (proto_arg_t a)
+{
+ if (sizeof (proto_arg_t) == 2)
+ {
+ proto_hex (a >> 12);
+ proto_hex ((a >> 8) & 0xf);
+ }
+ proto_hex ((a >> 4) & 0xf);
+ proto_hex ((a >> 0) & 0xf);
+}
+
+/** Send a command, generic function. */
+void
+proto_send (uint8_t cmd, uint8_t argc, proto_arg_t *argv)
+{
+ func_putc ('!');
+ func_putc (cmd);
+ while (argc-- > 1)
+ {
+ proto_arg (*argv++);
+ func_putc (',');
+ }
+ if (!argc)
+ proto_arg (*argv);
+ func_putc ('\r');
+}
+
+/** Send a command, no arg. */
+void
+proto_send0 (uint8_t cmd)
+{
+ func_putc ('!');
+ func_putc (cmd);
+ func_putc ('\r');
+}
+
+/** Send a command, one arg. */
+void
+proto_send1 (uint8_t cmd, proto_arg_t a0)
+{
+ func_putc ('!');
+ func_putc (cmd);
+ proto_arg (a0);
+ func_putc ('\r');
+}
+
+/** Send a command, two arg. */
+void
+proto_send2 (uint8_t cmd, proto_arg_t a0, proto_arg_t a1)
+{
+ func_putc ('!');
+ func_putc (cmd);
+ proto_arg (a0);
+ func_putc (',');
+ proto_arg (a1);
+ func_putc ('\r');
+}
+
+/** Send a command, three arg. */
+void
+proto_send3 (uint8_t cmd, proto_arg_t a0, proto_arg_t a1, proto_arg_t a2)
+{
+ func_putc ('!');
+ func_putc (cmd);
+ proto_arg (a0);
+ func_putc (',');
+ proto_arg (a1);
+ func_putc (',');
+ proto_arg (a2);
+ func_putc ('\r');
+}
+
+/** Send a command, four arg. */
+void
+proto_send4 (uint8_t cmd, proto_arg_t a0, proto_arg_t a1, proto_arg_t a2,
+ proto_arg_t a3)
+{
+ func_putc ('!');
+ func_putc (cmd);
+ proto_arg (a0);
+ func_putc (',');
+ proto_arg (a1);
+ func_putc (',');
+ proto_arg (a2);
+ func_putc (',');
+ proto_arg (a3);
+ func_putc ('\r');
+}
+
diff --git a/n/avr/proto/proto.h b/n/avr/proto/proto.h
new file mode 100644
index 0000000..2bfe7b8
--- /dev/null
+++ b/n/avr/proto/proto.h
@@ -0,0 +1,74 @@
+#ifndef proto_h
+#define proto_h
+/* proto.h */
+/* {{{
+ *
+ * Copyright (C) 2004 Nicolas Schodet
+ *
+ * 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.
+ *
+ * Contact :
+ * Web: http://perso.efrei.fr/~schodet/
+ * Email: <contact@ni.fr.eu.org>
+ * }}} */
+
+#include <inttypes.h>
+
+typedef AC_PROTO_ARG_TYPE proto_arg_t;
+
+/** Protocol callback type. Take the command and the arguments. */
+typedef void (*proto_cb_f) (uint8_t cmd, uint8_t argc, proto_arg_t argv[]);
+
+/** Protocol putc function type. Take a char to send. */
+typedef void (*proto_putc_f) (uint8_t c);
+
+/* +AutoDec */
+
+/** Initialize and set the callback function. */
+void
+proto_init (proto_cb_f f_cb, proto_putc_f f_putc);
+
+/** Accept a new character. */
+void
+proto_accept (uint8_t c);
+
+/** Send a command, generic function. */
+void
+proto_send (uint8_t cmd, uint8_t argc, proto_arg_t *argv);
+
+/** Send a command, no arg. */
+void
+proto_send0 (uint8_t cmd);
+
+/** Send a command, one arg. */
+void
+proto_send1 (uint8_t cmd, proto_arg_t a0);
+
+/** Send a command, two arg. */
+void
+proto_send2 (uint8_t cmd, proto_arg_t a0, proto_arg_t a1);
+
+/** Send a command, three arg. */
+void
+proto_send3 (uint8_t cmd, proto_arg_t a0, proto_arg_t a1, proto_arg_t a2);
+
+/** Send a command, four arg. */
+void
+proto_send4 (uint8_t cmd, proto_arg_t a0, proto_arg_t a1, proto_arg_t a2,
+ proto_arg_t a3);
+
+/* -AutoDec */
+
+#endif /* proto_h */
diff --git a/n/avr/proto/proto.txt b/n/avr/proto/proto.txt
new file mode 100644
index 0000000..1c8b84d
--- /dev/null
+++ b/n/avr/proto/proto.txt
@@ -0,0 +1,50 @@
+*Title: Module AVR Protocole série
+*Author: Ni
+
+* Principe
+
+Ce module s'occupe de gérer le protocole de communication sur une ligne de type
+port série. Il propose un service de décodage et un service d'encodage.
+
+Pour utiliser le décodage, il suffit d'appeler une fonctions à chaque
+caractère reçu. Si une commande a été reçu, ou en cas d'erreur, elle appelle
+une fonction définie par l'utilisateur avec pour paramètres les informations
+sur la commande reçue.
+
+Pour utiliser l'encodage, il suffit d'appeler une fonction émission avec
+les paramètres que l'on veux envoyer.
+
+* Protocole
+
+Le protocole de communication est basé sur des trames. Chaque trame commence
+par un point d'exclamation et se termine par un retour chariot. Tout ce qui
+n'est pas entouré de ces caractères est ignoré.
+
+Le point d'exclamation est directement suivi de la commande. La commande est
+un caractère alphabétique minuscule ou majuscule.
+
+Après la commande vient une liste de d'arguments séparés par des virgules
+optionnelles. Les arguments sont codés en hexadécimal, sur un ou deux octets
+en fonction du réglage à la compilation.
+
+Par exemple :
+
+^<<
+!z
+!v03,f5
+!c0094,ffa8
+^>>
+
+* Utilisation
+
+On appelle d'abord la fonction d'initialisation avec en premier paramètre la
+fonction callback (qui est appelée en cas de décodage réussi ou en cas
+d'erreur), et en second paramètre la fonction de sortie (appelé avec en
+paramètre le caractère à sortir).
+
+Pour chaque caractère reçu, on appelle |proto_accept|. Pour envoyer des
+commandes, on utilise les fonctions |proto_send...|.
+
+* Doc
+
+*File: proto.exd
diff --git a/n/avr/proto/test_proto.c b/n/avr/proto/test_proto.c
new file mode 100644
index 0000000..fa8f48a
--- /dev/null
+++ b/n/avr/proto/test_proto.c
@@ -0,0 +1,49 @@
+/* test_proto.c */
+/* {{{
+ *
+ * Copyright (C) 2004 Nicolas Schodet
+ *
+ * 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.
+ *
+ * Contact :
+ * Web: http://perso.efrei.fr/~schodet/
+ * Email: <contact@ni.fr.eu.org>
+ * }}} */
+#include "proto.h"
+#include <n/avr/rs232/rs232.h>
+
+/* +AutoDec */
+/* -AutoDec */
+
+void
+test_callback (uint8_t c, uint8_t argc, proto_arg_t argv[])
+{
+ proto_send (c, argc, argv);
+}
+
+int
+main (void)
+{
+ rs232_init ();
+ proto_init (test_callback, rs232_putc);
+ rs232_putc ('!');
+ rs232_putc ('z');
+ rs232_putc ('\r');
+ while (1)
+ {
+ uint8_t c = rs232_getc ();
+ proto_accept (c);
+ }
+}
diff --git a/n/avr/proto/testconfig.h b/n/avr/proto/testconfig.h
new file mode 100644
index 0000000..fc042d0
--- /dev/null
+++ b/n/avr/proto/testconfig.h
@@ -0,0 +1,61 @@
+#ifndef testconfig_h
+#define testconfig_h
+// testconfig.h
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// 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.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+
+#include "avrconfig.h"
+
+/* global */
+/** AVR Frequency : 1000000, 1843200, 2000000, 3686400, 4000000, 7372800,
+ * 8000000, 11059200, 14745600, 16000000, 18432000, 20000000. */
+#define AC_FREQ 14745600
+
+/* rs232 - RS232 Module. */
+/** Baudrate : 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800,
+ * 115200, 230400, 250000, 500000, 1000000. */
+#define AC_RS232_BAUDRATE 115200
+/** Send mode :
+ * - POLLING : no interrupts;
+ * - RING : interrupts, ring buffer;
+ * - PACKETS : interrupts, by packets delimited by SOP and EOP
+ * (unimplemented). */
+#define AC_RS232_SEND_MODE POLLING
+/** Recv mode, same as send mode. */
+#define AC_RS232_RECV_MODE POLLING
+/** Character size : 5, 6, 7, 8, 9 (only 8 implemented). */
+#define AC_RS232_CHAR_SIZE 8
+/** Parity : ODD, EVEN, NONE. */
+#define AC_RS232_PARITY EVEN
+/** Stop bits : 1, 2. */
+#define AC_RS232_STOP_BITS 1
+/** SOP (Start of packet) caracter. */
+#define AC_RS232_SOP(c) ((c) == '!')
+/** EOP (End of packet) caracter. */
+#define AC_RS232_EOP(c) ((c) == '\r')
+/** Send buffer size, should be power of 2 for RING mode. */
+#define AC_RS232_SEND_BUFFER_SIZE 32
+/** Recv buffer size, should be power of 2 for RING mode. */
+#define AC_RS232_RECV_BUFFER_SIZE 32
+
+#endif // testconfig_h