From e4dbdb962706aa5c763f9b16c93bbd9d1239dbaf Mon Sep 17 00:00:00 2001 From: schodet Date: Tue, 5 Jul 2005 18:43:43 +0000 Subject: Ajout de proto. --- n/avr/modules/proto/Makefile | 5 + n/avr/modules/proto/Makefile.module | 1 + n/avr/modules/proto/README | 25 +++ n/avr/modules/proto/avrconfig.h | 38 +++++ n/avr/modules/proto/proto.c | 192 +++++++++++++++++++++ n/avr/modules/proto/proto.h | 55 ++++++ n/avr/modules/proto/proto.txt | 80 +++++++++ n/avr/modules/proto/proto_inline.c | 303 ++++++++++++++++++++++++++++++++++ n/avr/modules/proto/test/Makefile | 17 ++ n/avr/modules/proto/test/avrconfig.h | 81 +++++++++ n/avr/modules/proto/test/test_proto.c | 83 ++++++++++ n/avr/modules/proto/utils/protodec | 103 ++++++++++++ 12 files changed, 983 insertions(+) create mode 100644 n/avr/modules/proto/Makefile create mode 100644 n/avr/modules/proto/Makefile.module create mode 100644 n/avr/modules/proto/README create mode 100644 n/avr/modules/proto/avrconfig.h create mode 100644 n/avr/modules/proto/proto.c create mode 100644 n/avr/modules/proto/proto.h create mode 100644 n/avr/modules/proto/proto.txt create mode 100644 n/avr/modules/proto/proto_inline.c create mode 100644 n/avr/modules/proto/test/Makefile create mode 100644 n/avr/modules/proto/test/avrconfig.h create mode 100644 n/avr/modules/proto/test/test_proto.c create mode 100755 n/avr/modules/proto/utils/protodec (limited to 'n/avr/modules/proto') diff --git a/n/avr/modules/proto/Makefile b/n/avr/modules/proto/Makefile new file mode 100644 index 0000000..5927da2 --- /dev/null +++ b/n/avr/modules/proto/Makefile @@ -0,0 +1,5 @@ +BASE = ../.. +DOC = proto.html +EXTRACTDOC = proto.h proto_inline.h avrconfig.h + +include $(BASE)/make/Makefile.gen diff --git a/n/avr/modules/proto/Makefile.module b/n/avr/modules/proto/Makefile.module new file mode 100644 index 0000000..933c537 --- /dev/null +++ b/n/avr/modules/proto/Makefile.module @@ -0,0 +1 @@ +proto_SOURCES = proto.c diff --git a/n/avr/modules/proto/README b/n/avr/modules/proto/README new file mode 100644 index 0000000..d2ba108 --- /dev/null +++ b/n/avr/modules/proto/README @@ -0,0 +1,25 @@ +avr.proto - Protocol AVR module. + +This is a simple humman readable protocol for use over serial line for +example. See modules README for more details about AVR modules. + + +Copyright (C) 2005 Nicolas Schodet + +Robot APB Team/Efrei 2006. + Web: http://assos.efrei.fr/robot/ + Email: robot AT efrei DOT fr + +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. diff --git a/n/avr/modules/proto/avrconfig.h b/n/avr/modules/proto/avrconfig.h new file mode 100644 index 0000000..fe07533 --- /dev/null +++ b/n/avr/modules/proto/avrconfig.h @@ -0,0 +1,38 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.proto - Protocol AVR module. {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2006. + * Web: http://assos.efrei.fr/robot/ + * Email: robot AT efrei DOT fr + * + * 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. + * + * }}} */ + +/* proto - Protocol module. */ +/** Maximum argument size. */ +#define AC_PROTO_ARGS_MAX_SIZE 8 +/** 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 + +#endif /* avrconfig_h */ diff --git a/n/avr/modules/proto/proto.c b/n/avr/modules/proto/proto.c new file mode 100644 index 0000000..5d54b36 --- /dev/null +++ b/n/avr/modules/proto/proto.c @@ -0,0 +1,192 @@ +/* proto.c */ +/* avr.proto - Protocol AVR module. {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2006. + * Web: http://assos.efrei.fr/robot/ + * Email: robot AT efrei DOT fr + * + * 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 "proto.h" + +#include + +/* +AutoDec */ + +/** Accept a digit to be used for args. */ +static void +proto_accept_digit (uint8_t c); + +#if AC_PROTO_QUOTE == 1 +/** Accept a quoted char to be used for args. */ +static void +proto_accept_char (uint8_t c); +#endif + +/* Send a hex digit. */ +inline static void +proto_hex (uint8_t h); + +/* -AutoDec */ + +static uint8_t cmd; +static uint8_t size; +static uint8_t args[AC_PROTO_ARGS_MAX_SIZE]; + +/** Step of decoding: + * - 0: nothing received. + * - 1: bang received. + * - 2: command received. + * - 3: command received, and processing a number. + * - 4: quote received. */ +static uint8_t step; + +/** 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; + size = 0; + step = 2; + } + else + { + AC_PROTO_CALLBACK ('?', 0, 0); + step = 0; + } + break; + case 2: + /* Command received yet. */ + if (c == '\r') + { + AC_PROTO_CALLBACK (cmd, size, args); + step = 0; + } +#if AC_PROTO_QUOTE == 1 + else if (c == '\'') + step = 4; +#endif + else + { + step = 3; + proto_accept_digit (c); + } + break; + case 3: + step--; + proto_accept_digit (c); + break; +#if AC_PROTO_QUOTE == 1 + case 4: + step = 2; + proto_accept_char (c); + break; +#endif + } + } +} + +/** Accept a digit to be used for args. */ +static void +proto_accept_digit (uint8_t c) +{ + /* Test for argument list overflow. */ + if (size >= AC_PROTO_ARGS_MAX_SIZE) + { + AC_PROTO_CALLBACK ('?', 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 + { + AC_PROTO_CALLBACK ('?', 0, 0); + step = 0; + return; + } + /* Add digit. */ + args[size] <<= 4; + args[size] |= c; + if (step == 2) + size++; +} + +#if AC_PROTO_QUOTE == 1 +/** Accept a quoted char to be used for args. */ +static void +proto_accept_char (uint8_t c) +{ + /* Test for argument list overflow. */ + if (size >= AC_PROTO_ARGS_MAX_SIZE) + { + AC_PROTO_CALLBACK ('?', 0, 0); + step = 0; + return; + } + /* Add char. */ + args[size] = c; + size++; +} +#endif + +/* Send a hex digit. */ +inline static void +proto_hex (uint8_t h) +{ + AC_PROTO_PUTC (h >= 10 ? h - 10 + 'a' : h + '0'); +} + +/* Send a argument byte. */ +void +proto_arg (uint8_t a) +{ + proto_hex ((a >> 4) & 0xf); + proto_hex ((a >> 0) & 0xf); +} + +/** Send a command, generic function. */ +void +proto_send (uint8_t cmd, uint8_t size, uint8_t *args) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + while (size--) + proto_arg (*args++); + AC_PROTO_PUTC ('\r'); +} + diff --git a/n/avr/modules/proto/proto.h b/n/avr/modules/proto/proto.h new file mode 100644 index 0000000..0c971a9 --- /dev/null +++ b/n/avr/modules/proto/proto.h @@ -0,0 +1,55 @@ +#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: + * }}} */ + +/** Protocol callback function. Take the command and the arguments. Must be + * defined by the user. */ +void +AC_PROTO_CALLBACK (uint8_t cmd, uint8_t size, uint8_t *args); + +/** Protocol putc function. Take a char to send. Must be defined by the + * user. */ +void +AC_PROTO_PUTC (uint8_t c); + +/* +AutoDec */ + +/** Accept a new character. */ +void +proto_accept (uint8_t c); + +/* Send a argument byte. */ +void +proto_arg (uint8_t a); + +/** Send a command, generic function. */ +void +proto_send (uint8_t cmd, uint8_t size, uint8_t *args); + +/* -AutoDec */ + +#include "proto_inline.c" + +#endif /* proto_h */ diff --git a/n/avr/modules/proto/proto.txt b/n/avr/modules/proto/proto.txt new file mode 100644 index 0000000..51ded0a --- /dev/null +++ b/n/avr/modules/proto/proto.txt @@ -0,0 +1,80 @@ +*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. Les arguments sont codés en +hexadécimal. + +Par exemple : + +^<< +!z +!v03f5 +!c0094ffa8 +^>> + +On peut aussi envoyer directement un caractère ascii en paramètre en le +précédant d'une apostrophe. + +Par exemple : + +^<< +!p'sa800 +^>> + +* Vérification d'erreur + +La vérification d'erreur n'est pas forcée par l'utilisation de ce module. En +règle générale, on utilisera le fonctionnement suivant : + + * pour un message fiable, le périphérique doit retourner la commande + dès réception ; + * pour un message non-fiable, le périphérique ne retourne rien. + +Par message non-fiable, on entend un message qui arrive en permanence, et dont +l'on a pas besoin de vérifier la bonne réception. En effet, une valeur plus à +jour est préférable à une réémission. + +Seul le périphérique renvois des messages de vérification ou des messages +d'erreur. Le protocole d'échange doit être prévu en prenant cela en compte. Il +n'est par exemple pas conseillé de déclencher des messages non demandé depuis +le périphérique, en effet, il n'y a aucun moyen de vérifier s'il est arrivé +correctement. Des messages envoyés sous l'initiative du périphérique doivent +donc être des messages périodiques, pas événementiels. + +* Utilisation + +On doit définir une fonction de callback afin de traiter les messages arrivant +et une fonction d'envois de caractère utilisée dans les fonctions d'envois. Le +nom de ces deux fonctions est défini dans |avrconfig.h| + +Pour chaque caractère reçu, on appelle |proto_accept|. Pour envoyer des +commandes, on utilise les fonctions |proto_send...|. + +Regarder le programme de test pour avoir un example. + +* Doc + +*File: proto.exd +*File: proto_inline.exd diff --git a/n/avr/modules/proto/proto_inline.c b/n/avr/modules/proto/proto_inline.c new file mode 100644 index 0000000..262676f --- /dev/null +++ b/n/avr/modules/proto/proto_inline.c @@ -0,0 +1,303 @@ +/* proto_inline.c */ +/* {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2005. + * Web: http://assos.efrei.fr/robot/ + * Email: robot AT efrei DOT fr + * + * 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 "modules/utils/byte.h" + +/* Send a command with no argument. */ +extern inline void +proto_send0 (uint8_t cmd) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 1 byte argument. */ +extern inline void +proto_send1b (uint8_t cmd, uint8_t arg0) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 1 word argument. */ +extern inline void +proto_send1w (uint8_t cmd, uint16_t arg0) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 1 double word argument. */ +extern inline void +proto_send1d (uint8_t cmd, uint32_t arg0) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 2 bytes arguments. */ +extern inline void +proto_send2b (uint8_t cmd, uint8_t arg0, uint8_t arg1) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 2 words arguments. */ +extern inline void +proto_send2w (uint8_t cmd, uint16_t arg0, uint16_t arg1) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 2 double words arguments. */ +extern inline void +proto_send2d (uint8_t cmd, uint32_t arg0, uint32_t arg1) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + proto_arg (v32_to_v8 (arg1, 3)); + proto_arg (v32_to_v8 (arg1, 2)); + proto_arg (v32_to_v8 (arg1, 1)); + proto_arg (v32_to_v8 (arg1, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 3 bytes arguments. */ +extern inline void +proto_send3b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 3 words arguments. */ +extern inline void +proto_send3w (uint8_t cmd, uint16_t arg0, uint16_t arg1, uint16_t arg2) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + proto_arg (v16_to_v8 (arg2, 1)); + proto_arg (v16_to_v8 (arg2, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 3 double words arguments. */ +extern inline void +proto_send3d (uint8_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + proto_arg (v32_to_v8 (arg1, 3)); + proto_arg (v32_to_v8 (arg1, 2)); + proto_arg (v32_to_v8 (arg1, 1)); + proto_arg (v32_to_v8 (arg1, 0)); + proto_arg (v32_to_v8 (arg2, 3)); + proto_arg (v32_to_v8 (arg2, 2)); + proto_arg (v32_to_v8 (arg2, 1)); + proto_arg (v32_to_v8 (arg2, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 4 bytes arguments. */ +extern inline void +proto_send4b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t + arg3) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 4 words arguments. */ +extern inline void +proto_send4w (uint8_t cmd, uint16_t arg0, uint16_t arg1, uint16_t arg2, + uint16_t arg3) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + proto_arg (v16_to_v8 (arg2, 1)); + proto_arg (v16_to_v8 (arg2, 0)); + proto_arg (v16_to_v8 (arg3, 1)); + proto_arg (v16_to_v8 (arg3, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 4 double words arguments. */ +extern inline void +proto_send4d (uint8_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, + uint32_t arg3) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v32_to_v8 (arg0, 3)); + proto_arg (v32_to_v8 (arg0, 2)); + proto_arg (v32_to_v8 (arg0, 1)); + proto_arg (v32_to_v8 (arg0, 0)); + proto_arg (v32_to_v8 (arg1, 3)); + proto_arg (v32_to_v8 (arg1, 2)); + proto_arg (v32_to_v8 (arg1, 1)); + proto_arg (v32_to_v8 (arg1, 0)); + proto_arg (v32_to_v8 (arg2, 3)); + proto_arg (v32_to_v8 (arg2, 2)); + proto_arg (v32_to_v8 (arg2, 1)); + proto_arg (v32_to_v8 (arg2, 0)); + proto_arg (v32_to_v8 (arg3, 3)); + proto_arg (v32_to_v8 (arg3, 2)); + proto_arg (v32_to_v8 (arg3, 1)); + proto_arg (v32_to_v8 (arg3, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 5 bytes arguments. */ +extern inline void +proto_send5b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, + uint8_t arg3, uint8_t arg4) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 5 words arguments. */ +extern inline void +proto_send5w (uint8_t cmd, uint16_t arg0, uint16_t arg1, uint16_t arg2, + uint16_t arg3, uint16_t arg4) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (v16_to_v8 (arg0, 1)); + proto_arg (v16_to_v8 (arg0, 0)); + proto_arg (v16_to_v8 (arg1, 1)); + proto_arg (v16_to_v8 (arg1, 0)); + proto_arg (v16_to_v8 (arg2, 1)); + proto_arg (v16_to_v8 (arg2, 0)); + proto_arg (v16_to_v8 (arg3, 1)); + proto_arg (v16_to_v8 (arg3, 0)); + proto_arg (v16_to_v8 (arg4, 1)); + proto_arg (v16_to_v8 (arg4, 0)); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 6 bytes arguments. */ +extern inline void +proto_send6b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, + uint8_t arg3, uint8_t arg4, uint8_t arg5) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + proto_arg (arg5); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 7 bytes arguments. */ +extern inline void +proto_send7b (uint8_t cmd, uint8_t arg0, uint8_t arg1, uint8_t arg2, + uint8_t arg3, uint8_t arg4, uint8_t arg5, uint8_t arg6) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + proto_arg (arg5); + proto_arg (arg6); + AC_PROTO_PUTC ('\r'); +} + +/* Send a command with 8 bytes arguments. */ +extern inline void +proto_send8b (uint8_t cmd, + uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t arg3, + uint8_t arg4, uint8_t arg5, uint8_t arg6, uint8_t arg7) +{ + AC_PROTO_PUTC ('!'); + AC_PROTO_PUTC (cmd); + proto_arg (arg0); + proto_arg (arg1); + proto_arg (arg2); + proto_arg (arg3); + proto_arg (arg4); + proto_arg (arg5); + proto_arg (arg6); + proto_arg (arg7); + AC_PROTO_PUTC ('\r'); +} + diff --git a/n/avr/modules/proto/test/Makefile b/n/avr/modules/proto/test/Makefile new file mode 100644 index 0000000..a1506be --- /dev/null +++ b/n/avr/modules/proto/test/Makefile @@ -0,0 +1,17 @@ +BASE = ../../.. +PROGS = test_proto +test_proto_SOURCES = test_proto.c +DOC = +EXTRACTDOC = +MODULES = proto uart utils +CONFIGFILE = avrconfig.h +# atmega8, atmega8535, atmega128... +AVR_MCU = atmega8 +# -O2 : speed +# -Os : size +OPTIMIZE = -O2 + +DEFS = +LIBS = + +include $(BASE)/make/Makefile.gen diff --git a/n/avr/modules/proto/test/avrconfig.h b/n/avr/modules/proto/test/avrconfig.h new file mode 100644 index 0000000..08d7418 --- /dev/null +++ b/n/avr/modules/proto/test/avrconfig.h @@ -0,0 +1,81 @@ +#ifndef avrconfig_h +#define avrconfig_h +/* avrconfig.h */ +/* avr.proto - Protocol AVR module. {{{ + * + * Copyright (C) 2005 Nicolas Schodet + * + * Robot APB Team/Efrei 2006. + * Web: http://assos.efrei.fr/robot/ + * Email: robot AT efrei DOT fr + * + * 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 0 +/** Baudrate: 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800, + * 115200, 230400, 250000, 500000, 1000000. */ +#define AC_UART0_BAUDRATE 115200 +/** Send mode: + * - POLLING: no interrupts. + * - RING: interrupts, ring buffer. */ +#define AC_UART0_SEND_MODE RING +/** Recv mode, same as send mode. */ +#define AC_UART0_RECV_MODE RING +/** 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 +/** 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_UART0_SEND_BUFFER_FULL WAIT + +/* proto - Protocol module. */ +/** Maximum argument size. */ +#define AC_PROTO_ARGS_MAX_SIZE 8 +/** 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 + +#endif /* avrconfig_h */ diff --git a/n/avr/modules/proto/test/test_proto.c b/n/avr/modules/proto/test/test_proto.c new file mode 100644 index 0000000..3b7e535 --- /dev/null +++ b/n/avr/modules/proto/test/test_proto.c @@ -0,0 +1,83 @@ +/* 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: + * }}} */ +#include "common.h" +#include "io.h" +#include "modules/uart/uart.h" +#include "modules/proto/proto.h" +#include "modules/utils/utils.h" + +void +proto_callback (uint8_t cmd, uint8_t size, uint8_t *args) +{ +/* This macro combine command and size in one integer. */ +#define c(cmd, size) (cmd << 8 | size) + switch (c (cmd, size)) + { + case c ('z', 0): + /* This should be generaly implemented. */ + utils_reset (); + break; + case c ('a', 1): + case c ('a', 4): + case c ('b', 2): + case c ('c', 3): + case c ('d', 4): + case c ('e', 5): + case c ('f', 6): + case c ('g', 7): + case c ('h', 8): + /* Accepts some command, and test some commands. */ + proto_send1b ('e', 0xf0); + proto_send2w ('l', 0x1234, 0x5678); + proto_send1d ('o', 0x12345678); + { + volatile uint32_t i = 0x12345678; + proto_send1d ('i', i); + } + break; + default: + /* This is to handle default commands, return an error. */ + proto_send0 ('?'); + return; + } + /* When no error acknoledge. */ + proto_send (cmd, size, args); +#undef c +} + +int +main (void) +{ + sei (); + uart0_init (); + /* This command should be generaly sent on reset. */ + printf ("reset\n"); + proto_send0 ('z'); + /* This is to accept commands. */ + while (1) + { + uint8_t c = uart0_getc (); + proto_accept (c); + } +} diff --git a/n/avr/modules/proto/utils/protodec b/n/avr/modules/proto/utils/protodec new file mode 100755 index 0000000..bc4c77e --- /dev/null +++ b/n/avr/modules/proto/utils/protodec @@ -0,0 +1,103 @@ +#!/usr/bin/perl -w +use strict; + +sub syntax +{ + print <= 2 ** ($b - 1)) { + return -(2 ** $b - $h); + } else { + return $h; + } +} + +# Process one proto packet. +sub prcmd +{ + my ($cmd, $c, @v) = @_; + # Return if not wanted. + return unless exists $$cmd{$c}; + print $c; + # Print each args. + for (@{$$cmd{$c}}) + { + /^(\d+)-(\d+)(?:\.(\d+))?(u?)$/o; + my $fp = 0; + $fp = $3 if $3; + if ($4 eq 'u') { + print ' ', (cvhexu @v[$1 - 1 .. $2 - 1]) / (1 << $fp); + } else { + print ' ', (cvhex @v[$1 - 1 .. $2 - 1]) / (1 << $fp); + } + } + print "\n"; +}; + +# Read command line. +my %cmd; +my ($acmd, @acmdl); + +while ($_ = shift) +{ + # Command char. + /^[a-zA-Z]$/ and do { + $cmd{$acmd} = [ @acmdl ] if defined $acmd; + @acmdl = (); + $acmd = $_; + next; + }; + # Single arg. + /^(\d+)(\.\d+)?(u?)$/ and do { + syntax if !defined $acmd; + push @acmdl, "$1-$1$2"; + next; + }; + # Range arg. + /^(\d+)-(\d+)(\.\d+)?(u?)$/ and do { + syntax if !defined $acmd; + syntax if $2 <= $1; + push @acmdl, $_; + next; + }; + syntax; +} +$cmd{$acmd} = [ @acmdl ] if defined $acmd; + +syntax if !scalar %cmd; + +# For each line. +while (<>) +{ + chomp; + # Match a proto packet. + if (/^!([a-zA-Z])(?:[a-f0-9]{2})*$/o) + { + my $c = $1; + s/^!([a-zA-Z])//; + my @args = /[a-f0-9]{2}/og; + prcmd \%cmd, $c, @args; + } +} -- cgit v1.2.3