From 8955d8da9476fa8fa37b0a5a88fa7be10c511b35 Mon Sep 17 00:00:00 2001 From: schodet Date: Sun, 18 Jul 2004 22:03:16 +0000 Subject: Initial revision --- n/avr/proto/Makefile | 16 +++ n/avr/proto/Makefile.avr | 100 ++++++++++++++++++ n/avr/proto/Makefile.module | 1 + n/avr/proto/Module | 1 + n/avr/proto/avrconfig.h | 33 ++++++ n/avr/proto/proto.c | 248 ++++++++++++++++++++++++++++++++++++++++++++ n/avr/proto/proto.h | 74 +++++++++++++ n/avr/proto/proto.txt | 50 +++++++++ n/avr/proto/test_proto.c | 49 +++++++++ n/avr/proto/testconfig.h | 61 +++++++++++ 10 files changed, 633 insertions(+) create mode 100644 n/avr/proto/Makefile create mode 100644 n/avr/proto/Makefile.avr create mode 100644 n/avr/proto/Makefile.module create mode 100644 n/avr/proto/Module create mode 100644 n/avr/proto/avrconfig.h create mode 100644 n/avr/proto/proto.c create mode 100644 n/avr/proto/proto.h create mode 100644 n/avr/proto/proto.txt create mode 100644 n/avr/proto/test_proto.c create mode 100644 n/avr/proto/testconfig.h (limited to 'n/avr') 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: + * }}} */ + +/* 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: + * }}} */ +#include "proto.h" + +#include + +/* +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: + * }}} */ + +#include + +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: + * }}} */ +#include "proto.h" +#include + +/* +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: +// }}} + +#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 -- cgit v1.2.3