/* main.c */ /* es - Input/Output general purpose board. {{{ * * Copyright (C) 2006 Dufour Jérémy * * Robot APB Team/Efrei 2004. * 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 "io.h" #include "modules/uart/uart.h" #include "modules/proto/proto.h" #include "modules/utils/utils.h" #include "modules/utils/byte.h" #include "timer_main.h" /* main timer */ #include "sensor_rvb.h" /* RVB sensors management */ #include "sniff_rvb.h" /* RVB sensors analysis */ #include "timer_1.h" /* timer/counter 1 */ #include "others.h" /* define game color mode + jack + frontal sensor */ #include "servo_motor.h"/* Servo motor module */ #include "sharp.h" /* SHarps module */ #include "lcd.h" /* Communication with the LCD card */ #include "ack.h" /* Ack module */ #include "barillet.h" /* Statistics for RVB sensors */ uint8_t sensor_rvb_stat_enable[RVB_MAX_SENSOR], sensor_rvb_stats[RVB_MAX_SENSOR]; /* Statistics for RVB analysis. */ uint8_t sniff_rvb_stat_enable[RVB_MAX_SENSOR], sniff_rvb_stats[RVB_MAX_SENSOR]; /* Statistics for RVB ball sensors. */ uint8_t sniff_ball_stat_enable, sniff_ball_stats; /* Config and statistics for SHarps */ uint8_t sharp_stat_enable[SHARP_NUMBER], sharp_stat_freq[SHARP_NUMBER]; uint8_t sharp_enable[SHARP_NUMBER], sharp_enable_freq[SHARP_NUMBER]; /* Stats for colour selection and jack */ uint8_t others_jackcolor_stat_enable, others_jackcolor_stats; /* Stat for RVB front sensors */ uint8_t sniff_rvb_front_enable, sniff_rvb_front_stats; /* Stat for RVB hole sensor */ uint8_t sniff_rvb_hole_enable, sniff_rvb_hole_stats; /* XXX Debug stats */ uint8_t main_stats[4]; uint8_t main_stats_freq, main_stats_enable; /* Twi */ uint8_t twi_buffer_read; /* Keyboard LCD update frequency */ uint8_t lcd_key_enable, lcd_key_freq; /* Enable stat for ack */ uint8_t main_ack_freq, main_ack_enable; /* For the ack system, look at ack.h */ uint8_t ack_value; /** Call when we receive some data from proto (uart) */ 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) uint8_t compt; uint16_t temp_16b; switch (c (cmd, size)) { /* Reset */ case c ('z', 0): utils_reset (); break; /* Main stats / Debug */ case c ('Z', 1): main_stats_freq = main_stats_enable = args[0]; break; case c ('f', 0): /* Shut up ! */ ack_reset (); /* Tell us quickly next time please */ main_ack_freq = 1; break; case c ('F', 1): /* Change the frequency of ack */ main_ack_enable = args[0]; /* Tell us quickly next time please */ main_ack_freq = 1; break; /*** RVB ***/ /* RVB sensors configuration */ case c ('p', 2): sensor_rvb_config (args[0], args[1]); break; /* RVB sniff configuration */ case c ('x', 5): sniff_rvb_config (args[0], v8_to_v16 (args[1], args[2]), v8_to_v16 (args[3], args[4])); break; /* RVB sensors stats */ case c ('S', 3): temp_16b = v8_to_v16 (args[0], args[1]); for (compt = 0; compt < RVB_MAX_SENSOR; compt++) if (temp_16b & _BV(compt)) sensor_rvb_stat_enable[compt] = sensor_rvb_stats[compt] = args[2]; break; /* Set current color as reference */ case c ('r', 3): temp_16b = v8_to_v16 (args[0], args[1]); for (compt = 0; compt < RVB_MAX_SENSOR; compt++) if (temp_16b & _BV(compt)) sniff_rvb_set_ref_color (compt, args[2]); break; /* Print stats of the colour seen by the sensor */ case c ('A', 3): temp_16b = v8_to_v16 (args[0], args[1]); for (compt = 0; compt < RVB_MAX_SENSOR; compt++) if (temp_16b & _BV(compt)) sniff_rvb_stat_enable[compt] = sniff_rvb_stats[compt] = args[2]; break; /* Print stats for ball */ case c ('B', 1): sniff_ball_stats = sniff_ball_stat_enable = args[0]; break; /* Print stats for front RVB Sniff */ case c ('C', 1): sniff_rvb_front_enable = sniff_rvb_front_stats = args[0]; break; /* RVB Hole sensor */ case c ('D', 1): sniff_rvb_hole_enable = sniff_rvb_hole_stats = args[0]; break; /* Enable all sensors */ case c ('u', 1): sensor_rvb_upper_sensors (args[0]); break; /* Selection color & jack */ case c ('O', 1): others_jackcolor_stat_enable = others_jackcolor_stats = args[0]; break; /* Communication with the servo motor */ case c ('m', 2): servo_motor_set_pos (args[0], args[1]); break; /* SHarps */ /* Update frequency */ case c ('h', 2): for (compt = 0; compt < SHARP_NUMBER; compt++) if (args[0] & _BV(compt)) sharp_enable[compt] = sharp_enable_freq[compt] = args[1]; break; /* Stats frequency */ case c ('H', 2): for (compt = 0; compt < SHARP_NUMBER; compt++) if (args[0] & _BV(compt)) sharp_stat_enable[compt] = sharp_stat_freq[compt] = args[1]; break; case c ('o', 5): sharp_config_threshold (args[0], v8_to_v16 (args[1], args[2]), v8_to_v16 (args[3], args[4])); break; /* LCD */ case c ('l', 32): lcd_print (args, 32); break; case c ('L', 1): lcd_key_freq = lcd_key_enable = args[0]; break; /* Grub ! */ case c ('G', 0): lcd_grub_booting (); break; /* tests primaires pour le barillet */ case c ('v',3): temp_16b = v8_to_v16 (args[1], args[2]); vitesse_turbine( args[0], temp_16b); break; case c('w',1): sens(args[0]); break; /* tests plus complexes de la gestion du barillet */ /* Initialise la position du barillet. */ case c ('i', 0): barillet_init_zero (); break; /* bon on commence - le jack est parti */ case c ('g', 0): barillet_debut_lancement(); break; /* on passe en vitesse turbine rapide */ case c ('h',0): barillet_lancement(); break; /* Coucouche panier. */ case c ('s', 0): barillet_sleep (); break; /* deposer une balle du barillet */ case c ('d', 0): depot_balle(); break; /* extraire une balle */ case c ('e', 0): extraction(); break; /* rotation du barillet */ case c ('t', 1): rotation(args[0]); break; /* vidange du barillet */ case c ('n', 0): vidange_barillet(); break; /* Unknown commands */ default: proto_send0 ('?'); return; } /* When no error acknoledge. */ proto_send (cmd, size, args); #undef c } int main (void) { uint8_t compt; /* Serial port */ uart0_init (); /* Main timer init */ timer_main_init (); /* Init timer/counter 1 for RVB & PWM * /!\ Must be called before RVB/PWM init /!\ */ timer1_init (); /* Init RVB sensors system */ sensor_rvb_init (); /* Init Color button init */ others_init(); /* barillet init */ barillet_init(); /* Servo motor init */ servo_motor_init (); /* Sharp init */ sharp_init (); /* LCD init */ lcd_init (); /* Enable interrupts */ sei (); /* We are ready ! */ proto_send0 ('z'); while (1) { /* Wait 4.44 ms */ // FIXME Try to put this down and make some test before if it // possible. timer_main_wait (); if (main_stats_enable && !--main_stats_freq) { main_stats_freq = main_stats_enable; proto_send4b ('Z', main_stats[0], main_stats[1], main_stats[2], main_stats[3]); } main_stats[0] = TCNT0; /* Ack management */ compt = ack_get (); if (compt) if (main_ack_enable && !--main_ack_freq) { main_ack_freq = main_ack_enable; proto_send1b ('F', compt); } /* Front contact */ others_contact_update (); /* RVB Sensors stats */ for (compt = 0; compt < RVB_MAX_SENSOR; compt++) { if (sensor_rvb_stat_enable[compt] && !--sensor_rvb_stats[compt]) { /* Re init stats system for this sensor */ sensor_rvb_stats[compt] = sensor_rvb_stat_enable[compt]; // FIXME useless 16 bit value. proto_send5w ('S', compt, sensor_rvb_values[compt][0], sensor_rvb_values[compt][1], sensor_rvb_values[compt][2], sensor_rvb_values[compt][3]); } /* RVB Sensors analysis stats */ if (sniff_rvb_stat_enable[compt] && !--sniff_rvb_stats[compt]) { /* Re init stats system for this sensor */ sniff_rvb_stats[compt] = sniff_rvb_stat_enable[compt]; proto_send2b ('A', compt, sniff_rvb_analysis_color (compt, RVB_SNIFF_ALL_COLORS)); } } /* Print stats for ball */ if (sniff_ball_stat_enable && !--sniff_ball_stats) { /* Re init stats system for this sensor */ sniff_ball_stats = sniff_ball_stat_enable; proto_send2b ('B', sniff_rvb_analysis_ball (7), sniff_rvb_analysis_ball (8)); } /* Print stats for front sensors */ if (sniff_rvb_front_enable && !--sniff_rvb_front_stats) { if (sensor_rvb_state_sleeeping ()) { /* Re init stats system for this sensor */ sniff_rvb_front_stats = sniff_rvb_front_enable; proto_send2b ('C', sniff_rvb_analysis_color (4, RVB_SNIFF_ALL_COLORS), sniff_rvb_analysis_color (6, RVB_SNIFF_ALL_COLORS)); } else sniff_rvb_front_stats = 1; } /* RVB Hole */ if (sniff_rvb_hole_enable && !--sniff_rvb_hole_stats) { if (sensor_rvb_state_sleeeping ()) { /* Re init stats system for this sensor */ sniff_rvb_hole_stats = sniff_rvb_hole_enable; proto_send1b ('D', sniff_rvb_analysis_ball (5)); } else sniff_rvb_hole_stats = 1; } main_stats[1] = TCNT0; /* Update all the asserv pin comunication */ sensor_rvb_update_asserv_pins (); if (others_jackcolor_stat_enable && !--others_jackcolor_stats) { others_jackcolor_stats = others_jackcolor_stat_enable; proto_send1b ('O', other_jack_color ()); } /* LCD */ if (lcd_key_enable && !--lcd_key_freq) { lcd_key_freq = lcd_key_enable; if ((twi_buffer_read = lcd_key ())) proto_send1b ('L', twi_buffer_read); } /* gestion du barilet */ sequenceur_barillet (); /* Sharps */ for (compt = 0; compt < SHARP_NUMBER; compt++) { /* Update */ if (sharp_enable[compt] && !--sharp_enable_freq[compt]) { /* Re init update system for this sharp */ sharp_enable_freq[compt] = sharp_enable[compt]; sharp_update_values (compt); } /* Stats */ if (sharp_stat_enable[compt] && !--sharp_stat_freq[compt]) { /* Re init stats system for this sharp */ sharp_stat_freq[compt] = sharp_stat_enable[compt]; /* XXX 16 bits sucks */ proto_send2w ('H', compt, sharp_values[compt]); } } main_stats[2] = TCNT0; /* Get data for serial port */ while (uart0_poll ()) proto_accept (uart0_getc ()); /* Update RVB sensors data. * I want this to be done as later as possible, and espceically after * commands has been parsed ! */ sensor_rvb_start_capture (); main_stats[3] = TCNT0; } }