From ea695ca13b725b6f2037986ef26fa1fea06b8faf Mon Sep 17 00:00:00 2001 From: schodet Date: Tue, 30 Sep 2003 22:17:01 +0000 Subject: Initial revision --- 2004/n/asserv/src/README | 3 + 2004/n/asserv/src/main.c | 115 +++++++++++++ 2004/n/asserv/src/motor.c | 402 +++++++++++++++++++++++++++++++++++++++++++++ 2004/n/asserv/src/motor.h | 91 ++++++++++ 2004/n/asserv/src/serial.c | 149 +++++++++++++++++ 2004/n/asserv/src/serial.h | 86 ++++++++++ 6 files changed, 846 insertions(+) create mode 100644 2004/n/asserv/src/README create mode 100644 2004/n/asserv/src/main.c create mode 100644 2004/n/asserv/src/motor.c create mode 100644 2004/n/asserv/src/motor.h create mode 100644 2004/n/asserv/src/serial.c create mode 100644 2004/n/asserv/src/serial.h (limited to '2004/n/asserv') diff --git a/2004/n/asserv/src/README b/2004/n/asserv/src/README new file mode 100644 index 0000000..6b8b31d --- /dev/null +++ b/2004/n/asserv/src/README @@ -0,0 +1,3 @@ +APBTasserv - asservissement Robot 2004 + +Merci à l'ANCR et Fribotte pour la doc et les exemples. diff --git a/2004/n/asserv/src/main.c b/2004/n/asserv/src/main.c new file mode 100644 index 0000000..1dd817e --- /dev/null +++ b/2004/n/asserv/src/main.c @@ -0,0 +1,115 @@ +/* main.c */ +/* APBTasserv - asservissement Robot 2004 {{{ + * + * Copyright (C) 2003 Nicolas Schodet + * + * Robot APB Team/Efrei 2004. + * Web: http://assos.efrei.fr/robot/ + * Mail: 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 <18f442.h> // Définition des registres du PIC18 +#include // Définition de la librairie standard + +// Pattes libres. +/* +40 rb7 (coupee) +39 rb6 : D3 +38 rb5 : D2 +37 rb4 : D1 +36 rb3 : D0 +35 rb2 : Clk busp +30 rd7 +29 rd6 : Capteur sharp +28 rd5 : Capteur doigts +27 rd4 : Capteur couleur +24 rc5 +23 rc4 +22 rd3 : Jack +21 rd2 +18 rc3 +10 re2 +9 re1 +8 re0 +7 ra5 +5 ra3 +4 ra2 +3 ra1 + +A1-5 B2-7 C4-5 D2-6 E0-2 +*/ + +// General configuration +#fuses HS,WDT,WDT128,PUT,NOBROWNOUT,NOLVP +#use delay(clock=20000000) +#use rs232(baud=115200,xmit=PIN_C6,parity=N,rcv=PIN_C7,bits=8) +#priority EXT,EXT1,RDA,TIMER2 + +#include "motor.c" +#include "serial.c" + +/* Initialise le PIC. */ +void +main_init (void) +{ + /* Configuration de la liaison série. */ + setup_psp (PSP_DISABLED); + /* Configuration de l'interface SPI : non utilisée. */ + setup_spi (FALSE); + // Configuration du chien de garde + //setup_wdt (WDT_OFF); + // Configuration du TIMER 0 pour lire le nombre de pas faits en reculant + setup_timer_0 (RTCC_EXT_L_TO_H | RTCC_8_BIT | RTCC_DIV_1); + // Confguration du TIMER 1 pour lire le nombre de pas faits en avançant + setup_timer_1 (T1_DISABLED); + // Configuration du TIMER 2. + // Tpwm = (PR2 + 1) * 4 * Tosc * TMR2_prescale + // Fpwm = 20kHz + // Tint2 = TMR2_postscale * Tpwm + // Tint2 = 0,5ms + setup_timer_2 (T2_DIV_BY_1, 249, 10); + // Configuration du TIMER 3 : non utilisé + setup_timer_3 (T3_EXTERNAL | T3_DIV_BY_1); + // Configuration de l'ADC + setup_adc_ports (NO_ANALOGS); + setup_adc (ADC_CLOCK_DIV_2); + // Configuration des registres pour un fonctionnement en PWM + setup_ccp1 (CCP_PWM); + setup_ccp2 (CCP_PWM); + set_pwm1_duty (0); + set_pwm2_duty (0); + // Configuration pour l'autorisation des interruptions. + enable_interrupts (INT_EXT); + enable_interrupts (INT_EXT1); + enable_interrupts (INT_TIMER2); + enable_interrupts (INT_RDA); + enable_interrupts (GLOBAL); + // Heu, on s'en servait pour le bus... + //output_low (PIN_B2); +} + +void +main (void) +{ + delay_ms (20); + motor_init (); + serial_init (); + main_init (); + while (1) + { + } +} diff --git a/2004/n/asserv/src/motor.c b/2004/n/asserv/src/motor.c new file mode 100644 index 0000000..94954f2 --- /dev/null +++ b/2004/n/asserv/src/motor.c @@ -0,0 +1,402 @@ +/* motor.c */ +/* APBTasserv - asservissement Robot 2004 {{{ + * + * Copyright (C) 2003 Nicolas Schodet + * + * Robot APB Team/Efrei 2004. + * Web: http://assos.efrei.fr/robot/ + * Mail: 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 "motor.h" +#include "serial.h" + +/* Variables globales. */ +signed long motor_ttl; /* Time to live : arrète le robot au bout de + ce nombre de pas. */ +short motor_asservi; /* Asservissement activé ? */ +unsigned int motor_kp, motor_ki, motor_kd; /* Coefficients du PID. */ +unsigned int motor_a; /* Acceleration. */ +signed long motor_int_max; /* Terme intégral maximum. */ +unsigned int motor_pid_int; /* Compteur d'interruptions 2 entre deux + calculs de PID. */ + +/* Statistiques, etc... */ +short motor_stat; /* Report motor stats. */ +unsigned int motor_stat_delay; /* Delay between stats. */ +unsigned int motor_stat_delay_cpt; /* Delay counter. */ + +/* Moteurs. */ +signed int motor_g_vdes, motor_g_vacc; /* Vitesse désirée, actuelle. */ +signed int motor_d_vdes, motor_d_vacc; +unsigned int motor_g_cpt_av, motor_g_cpt_ar; /* Compteur pour les interruptions. */ +unsigned int motor_d_cpt_av, motor_d_cpt_ar; +signed long motor_g_cpt, motor_d_cpt; /* Compteurs. */ +signed long motor_g_e_old, motor_d_e_old; /* Dernière erreur, pour le + calcul de la dérivée. */ +signed long motor_g_int, motor_d_int; /* Valeur integrale. */ + +/* Initialise le modue moteur. */ +void +motor_init (void) +{ + motor_ttl = 2000; + motor_asservi = 0; + motor_kp = 10; motor_ki = 5; motor_kd = 0; + motor_a = 2; + motor_int_max = 1000; + motor_pid_int = 0; + motor_stat = 0; + motor_stat_delay = 101; + motor_stat_delay_cpt = 0; + motor_g_vdes = 0; motor_g_vacc = 0; + motor_d_vdes = 0; motor_d_vacc = 0; + motor_g_cpt_av = 0; motor_g_cpt_ar = 0; + motor_d_cpt_av = 0; motor_d_cpt_ar = 0; + motor_g_cpt = 0; motor_d_cpt = 0; + motor_g_e_old = 0; motor_d_e_old = 0; + motor_g_int = 0; motor_d_int = 0; +} + +/* Addition limitée à 32000. */ +signed long +safe_add_long (signed long &a, signed long &b) +{ + signed long ret; + /* Additionne. */ + ret = a + b; + /* Vérifie les débordements par cohérence des signes. */ + if (a > 0 && b > 0 && ret <= 0) + return 32000; + else if (a < 0 && b < 0 && ret >= 0) + return -32000; + else + return ret; +} + +/* Limite un entier entre -MAX et MAX. */ +signed long +boundary (signed long &n, signed long &max) +{ + if (n > max) + return max; + if (n < -max) + return -max; + return n; +} + +/* Multiplication par les coef. */ +signed long +safe_mul_long (signed long &a, unsigned int &k) +{ + unsigned long ua; + short sa; + signed long temp; + /* Sépare le signe de la valeur absolue. */ + if (a >= 0) + { + sa = 1; + ua = a; + } + else + { + sa = 0; + ua = -a; + } + /* Multiplie le poid fort. */ + temp = make8 (ua, 1) * k; + /* Test un futur débordement. */ + if (temp > 255) + { + if (sa) return 32760; + else return -32760; + } + else + { + temp = make8 (temp, 1); + temp += ((long) make8 (ua, 0)) * k ; + if (sa) return temp; + else return -temp; + } +} + +/* Met à jour la vitesse du moteur gauche. */ +void +motor_update_left_speed (void) +{ + if (motor_g_vacc != motor_g_vdes) + { + if (motor_g_vacc < motor_g_vdes) + { + /* Accélère. */ + motor_g_vacc += motor_a; + if (motor_g_vacc > motor_g_vdes) + motor_g_vacc = motor_g_vdes; + } + else + { + /* Freine. */ + motor_g_vacc -= motor_a; + if (motor_g_vacc < motor_g_vdes) + motor_g_vacc = motor_g_vdes; + } + } +} + +/* Met à jour la vitesse du moteur droit. */ +void +motor_update_right_speed (void) +{ + if (motor_d_vacc != motor_d_vdes) + { + if (motor_d_vacc < motor_d_vdes) + { + /* Accélère. */ + motor_d_vacc += motor_a; + if (motor_d_vacc > motor_d_vdes) + motor_d_vacc = motor_d_vdes; + } + else + { + /* Freine. */ + motor_d_vacc -= motor_a; + if (motor_d_vacc < motor_d_vdes) + motor_d_vacc = motor_d_vdes; + } + } +} + +/* Calcule le PID associé au moteur gauche. */ +void +motor_compute_left_pid (void) +{ + signed long e; + signed long diff; + signed long pwm; + signed long temp; + unsigned char av, ar; + /* Récupère les compteurs. */ + disable_interrupts (INT_EXT); + av = motor_g_cpt_av; + motor_g_cpt_av = 0; + enable_interrupts (INT_EXT); + disable_interrupts (INT_EXT1); + ar = motor_g_cpt_ar; + motor_g_cpt_ar = 0; + enable_interrupts (INT_EXT1); + /* Calcule l'erreur. */ + diff = av; + diff -= ar; + motor_g_cpt += diff; + e = motor_g_vacc - diff; + /* Calcul de l'integrale. */ + motor_g_int = safe_add_long (motor_g_int, e); + motor_g_int = boundary (motor_g_int, motor_int_max); + /* Calcul du PID. */ + pwm = safe_mul_long (e, motor_kp); + temp = safe_mul_long (motor_g_int, motor_ki); + pwm = safe_add_long (pwm, temp); + temp = 1000; + pwm = boundary (pwm, temp); + /* Envois la sauce. */ + motor_g_pwm (pwm); + /* Information de PWM. */ + if (motor_stat) + { + if (!motor_stat_delay_cpt--) + { + serial_send_motor_stat ('l', motor_g_vacc, e, pwm); + motor_stat_delay_cpt = motor_stat_delay; + } + } + /* Conserve l'ancienne erreur pour le terme dérivé. */ + //motor_g_old_e = e; +} + +/* Calcule le PID associé au moteur droit. */ +void +motor_compute_right_pid (void) +{ + signed long e; + signed long diff; + signed long pwm; + signed long temp; + unsigned char av, ar; + /* Récupère les compteurs. */ + av = get_timer0 (); + ar = get_timer3 (); + /* Calcule l'erreur. */ + diff = av; + diff -= motor_d_cpt_av; + if (av < motor_d_cpt_av) diff += 256; + diff -= ar; + diff += motor_d_cpt_ar; + if (ar < motor_d_cpt_ar) diff -= 256; + motor_d_cpt += diff; + e = motor_d_vacc - diff; + /* Sauvegarde les compteurs. */ + motor_d_cpt_av = av; + motor_d_cpt_ar = ar; + /* Calcul de l'integrale. */ + motor_d_int = safe_add_long (motor_d_int, e); + motor_d_int = boundary (motor_d_int, motor_int_max); + /* Calcul du PID. */ + pwm = safe_mul_long (e, motor_kp); + temp = safe_mul_long (motor_d_int, motor_ki); + pwm = safe_add_long (pwm, temp); + temp = 1000; + pwm = boundary (pwm, temp); + /* Envois la sauce. */ + motor_d_pwm (pwm); + /* Information de PWM. */ + if (motor_stat) + { + if (!motor_stat_delay_cpt--) + { + serial_send_motor_stat ('r', motor_d_vacc, e, pwm); + motor_stat_delay_cpt = motor_stat_delay; + } + } + /* Conserve l'ancienne erreur pour le terme dérivé. */ + //motor_d_old_e = e; +} + +/* Paramètre la PWM pour le moteur gauche. */ +void +motor_g_pwm (signed long &pwm) +{ + if (!motor_asservi) pwm = 0; + if (pwm >= 0) + { + output_high (PIN_D1); + set_pwm2_duty(pwm); + } + else + { + output_low (PIN_D1); + set_pwm2_duty (-pwm); + } +} + +/* Paramètre la PWM pour le moteur droit. */ +void +motor_d_pwm (signed long &pwm) +{ + if (!motor_asservi) pwm = 0; + if (pwm >= 0) + { + output_high (PIN_D0); + set_pwm1_duty(pwm); + } + else + { + output_low (PIN_D0); + set_pwm1_duty (-pwm); + } +} + +/* Interruptions de comptage moteur. */ +#int_EXT +EXT_isr() +{ + motor_g_cpt_av++; +} + +#int_EXT1 +EXT1_isr() +{ + motor_g_cpt_ar++; +} + +/* Interruption de PID. */ +#int_TIMER2 +TIMER2_isr () +{ + if ((motor_pid_int & 7) == 0) + { + motor_compute_left_pid (); + motor_compute_right_pid (); + } + if ((motor_pid_int & 63) == 0) + { + motor_update_left_speed (); + motor_update_right_speed (); + serial_parse (); + } + motor_pid_int++; +} + +/* Traite une entrée série. */ +short +motor_parse (void) +{ + switch (serial_recv_com ()) + { + case 'v': + serial_recv_int (motor_g_vdes); + serial_recv_int1 (motor_d_vdes); + serial_send_ok ('v'); + return 1; + case 's': + motor_g_vdes = 0; + motor_d_vdes = 0; + serial_send_ok ('s'); + return 1; + case 'a': + serial_recv_int (motor_a); + serial_send_ok ('a'); + return 1; + case 'p': + serial_recv_int (motor_kp); + serial_send_ok ('p'); + return 1; + case 'i': + serial_recv_int (motor_ki); + serial_send_ok ('i'); + return 1; + case 'm': + serial_recv_bool (motor_stat); + serial_send_ok ('m'); + return 1; + case 'g': + serial_recv_bool (motor_asservi); + motor_toggle_asservi (); + serial_send_ok ('g'); + return 1; + default: + return 0; + } +} + +/* Démarre l'asservissement. */ +void +motor_toggle_asservi (void) +{ + if (motor_asservi) + { + motor_g_cpt_av = 0; + motor_g_cpt_ar = 0; + motor_d_cpt_av = get_timer0 (); + motor_d_cpt_ar = get_timer3 (); + motor_g_vacc = 0; + motor_d_vdes = 0; + motor_g_vdes = 0; + motor_d_vdes = 0; + motor_g_int = 0; + motor_d_int = 0; + } +} diff --git a/2004/n/asserv/src/motor.h b/2004/n/asserv/src/motor.h new file mode 100644 index 0000000..92b1680 --- /dev/null +++ b/2004/n/asserv/src/motor.h @@ -0,0 +1,91 @@ +#ifndef motor_h +#define motor_h +/* motor.h */ +/* APBTasserv - asservissement Robot 2004 {{{ + * + * Copyright (C) 2003 Nicolas Schodet + * + * Robot APB Team/Efrei 2004. + * Web: http://assos.efrei.fr/robot/ + * Mail: 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. + * + * }}} */ + +/* +AutoDec */ + +/* Initialise le modue moteur. */ +void +motor_init (void); + +/* Addition limitée à 32000. */ +signed long +safe_add_long (signed long &a, signed long &b); + +/* Limite un entier entre -MAX et MAX. */ +signed long +boundary (signed long &n, signed long &max); + +/* Multiplication par les coef. */ +signed long +safe_mul_long (signed long &a, unsigned int &k); + +/* Met à jour la vitesse du moteur gauche. */ +void +motor_update_left_speed (void); + +/* Met à jour la vitesse du moteur droit. */ +void +motor_update_right_speed (void); + +/* Calcule le PID associé au moteur gauche. */ +void +motor_compute_left_pid (void); + +/* Calcule le PID associé au moteur droit. */ +void +motor_compute_right_pid (void); + +/* Paramètre la PWM pour le moteur gauche. */ +void +motor_g_pwm (signed long &pwm); + +/* Paramètre la PWM pour le moteur droit. */ +void +motor_d_pwm (signed long &pwm); + +/* Interruptions de comptage moteur. */ +#int_EXT +EXT_isr(); + +#int_EXT1 +EXT1_isr(); + +/* Interruption de PID. */ +#int_TIMER2 +TIMER2_isr (); + +/* Traite une entrée série. */ +short +motor_parse (void); + +/* Démarre l'asservissement. */ +void +motor_toggle_asservi (short fl); + +/* -AutoDec */ + +#endif /* motor_h */ diff --git a/2004/n/asserv/src/serial.c b/2004/n/asserv/src/serial.c new file mode 100644 index 0000000..a72f7db --- /dev/null +++ b/2004/n/asserv/src/serial.c @@ -0,0 +1,149 @@ +/* serial.c */ +/* APBTasserv - asservissement Robot 2004 {{{ + * + * Copyright (C) 2003 Nicolas Schodet + * + * Robot APB Team/Efrei 2004. + * Web: http://assos.efrei.fr/robot/ + * Mail: 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 "serial.h" +#include "motor.h" + +/* Macros de lecture du tampon. */ +#define HEXDIGIT(a) ((a) <= 9 ? (a) + '0' : (a) + ('a' - 10)) +#define SERIAL2INT(a, b) (HEX (a) << 4 | HEX (b)) + +#define CRLF "\r" + +/* Tampon de reception. */ +char serial_recv_buf[SERIAL_RECV_BUF_LEN]; +int serial_recv_buf_n; +short serial_recv_full, serial_recv_working; + +/* Tampon d'emmission. */ +#define SERIAL_SEND_BUF_LEN 20 +char serial_send_buf[SERIAL_SEND_BUF_LEN]; +int serial_send_buf_n; +short serial_send_full, serial_send_working; + +/* Initialise la reception serie. */ +void +serial_init (void) +{ + serial_recv_buf_n = 0; + serial_recv_full = 0; + serial_recv_working = 0; + serial_send_buf_n = 0; + serial_send_full = 0; + serial_send_working = 0; + printf ("!z" CRLF); +} + +/* Recois des caractères. */ +#int_RDA +serial_recv () +{ + char c; + if (serial_recv_full) return; + c = getc (); + if (c == '\n' || c == '\r') + { + if (serial_recv_buf_n) + serial_recv_full = 1; + } + else if (c == '!' || serial_recv_buf_n >= SERIAL_RECV_BUF_LEN) + serial_recv_buf_n = 0; + else + serial_recv_buf[serial_recv_buf_n++] = c; +} + +/* Traite la commande recue. */ +void +serial_parse (void) +{ + restart_wdt (); + /* Si le tampon n'est pas plein, bye, bye. */ + if (!serial_recv_full || serial_recv_working) return; + serial_recv_working = 1; + /* Vérifie la taille du tampon. */ + if (serial_recv_buf_n) + { + /* Est-ce une commande moteur. */ + if (!motor_parse ()) + { + switch (serial_recv_com ()) + { + case 'z': + reset_cpu (); + break; + default: + serial_send_error ('?'); + break; + } + } + } + serial_recv_buf_n = 0; + serial_recv_working = 0; + serial_recv_full = 0; +} + +/* Envoie un code d'erreur. */ +void +serial_send_error (char c) +{ + printf ("!e%c" CRLF, c); +} + +/* Envoie un code ok. */ +void +serial_send_ok (char c) +{ + printf ("!o%c" CRLF, c); +} + +/* Envoie un rapport d'un moteur. */ +void +serial_send_motor_stat (char side, unsigned int vacc, unsigned long &e, unsigned long &pwm) +{ + printf ("!m%c", side); + serial_send_int (vacc); + putc (','); + serial_send_long (e); + putc (','); + serial_send_long (pwm); + puts (CRLF); +} + +/* Envoie un long. */ +void +serial_send_long (unsigned long &value) +{ + putc (HEXDIGIT ((make8 (value, 1) >> 4) & 0xf)); + putc (HEXDIGIT (make8 (value, 1) & 0xf)); + putc (HEXDIGIT ((make8 (value, 0) >> 4) & 0xf)); + putc (HEXDIGIT (make8 (value, 0) & 0xf)); +} + +/* Envoie un int. */ +void +serial_send_int (unsigned int &value) +{ + putc (HEXDIGIT ((value >> 4) & 0xf)); + putc (HEXDIGIT (value & 0xf)); +} diff --git a/2004/n/asserv/src/serial.h b/2004/n/asserv/src/serial.h new file mode 100644 index 0000000..e06c1f0 --- /dev/null +++ b/2004/n/asserv/src/serial.h @@ -0,0 +1,86 @@ +#ifndef serial_h +#define serial_h +/* serial.h */ +/* APBTasserv - asservissement Robot 2004 {{{ + * + * Copyright (C) 2003 Nicolas Schodet + * + * Robot APB Team/Efrei 2004. + * Web: http://assos.efrei.fr/robot/ + * Mail: 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. + * + * }}} */ + +/* Tampon de reception. */ +#define SERIAL_RECV_BUF_LEN 20 +extern char serial_recv_buf[SERIAL_RECV_BUF_LEN]; +extern int serial_recv_buf_n; + +/* Macros de récupération de la commande recu. */ +#define HEXBIN(a) (((a) >= '0' && (a) <= '9') ? (a) - '0' : (a) - ('a' + 10)) +#define serial_recv_com() \ + (serial_recv_buf[0]) +#define serial_recv_int(v) \ + ((v) = HEXBIN (serial_recv_buf[1]) << 4 | HEXBIN (serial_recv_buf[2])) +#define serial_recv_int1(v) \ + ((v) = HEXBIN (serial_recv_buf[3]) << 4 | HEXBIN (serial_recv_buf[4])) +#define serial_recv_long(v) \ + ((v) = make16 (HEXBIN (serial_recv_buf[0]) << 4 | HEXBIN \ + (serial_recv_buf[1]), \ + HEXBIN (serial_recv_buf[2]) << 4 | HEXBIN \ + (serial_recv_buf[3]))) +#define serial_recv_bool(v) \ + ((v) = serial_recv_buf[1] == '1') + + +/* +AutoDec */ + +/* Initialise la reception serie. */ +void +serial_init (void); + +/* Recois des caractères. */ +#int_RDA +serial_recv (); + +/* Traite la commande recue. */ +void +serial_parse (void); + +/* Envoie un code d'erreur. */ +void +serial_send_error (char c); + +/* Envoie un code ok. */ +void +serial_send_ok (char c); + +/* Envoie un rapport d'un moteur. */ +void +serial_send_motor_stat (char side, unsigned int vacc, unsigned long &e, unsigned long &pwm); + +/* Envoie un long. */ +void +serial_send_long (unsigned long &value); + +/* Envoie un int. */ +void +serial_send_int (unsigned int &value); + +/* -AutoDec */ + +#endif /* serial_h */ -- cgit v1.2.3