/* chenil.c */ /* Chenillard. {{{ * * 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 "n/avr/utils/utils.h" #include #include /* * Brochage : * * leds sur D1 D2 D3 D4 C0 C1 C2 C3. */ /* +AutoDec */ /* -AutoDec */ /* Allume les leds indiquées dans LED. */ static inline void allume (uint8_t leds) { PORTD = (leds << 1) & 0x1e; PORTC = (leds >> 4) & 0x0f; } /* Allume les N leds indiquées dans le tableau LEDT pendant T * 10ms. */ static void go_chenil (uint8_t t, uint8_t n, uint8_t ledt[]) { uint8_t i; int8_t l; uint8_t leds; while (t--) { /* 255 itération afin de varier le rapport cyclique. */ for (i = 255; i; i--) { leds = 0; /* Construit le mot pour allume(). */ for (l = n - 1; l >= 0; l--) { leds <<= 1; if (ledt[l] >= i) leds |= 1; } allume (leds); delay_ns (10000000 / 255); } } } /* Codes de programmation du chenillard, voir plus bas le switch. */ static const uint8_t modes[] = { 101, 10, 1, 7, 2, 7, 1, 7, 2, 7, 1, 7, 2, 7, 3, 16, 101, 5, 1, 7, 2, 7, 1, 7, 2, 7, 1, 7, 2, 7, 3, 16, 4, 8, 103, 0, 1, 15, 2, 7, 0, 1 }; int main (void) { uint8_t step = 0; uint8_t mode = 0, repeat = 0, index = 0, speed = 7, decay = 64, on = 255; uint8_t ons = 0; uint8_t n1 = 8 - 1, leds[8]; int8_t l; DDRD = 0x1e; DDRC = 0x0f; for (l = n1; l >= 0; l--) leds[l] = 0; while (1) { if (!repeat) { /* Change de mode. */ mode = modes[index++]; repeat = modes[index++]; } switch (mode) { case 0: /* Fin de liste. */ index = 0; goto noled; case 1: /* Vers la droite. */ leds[step++] = on; step &= n1; break; case 2: /* Vers la gauche. */ leds[step--] = on; step &= n1; break; case 3: /* Les deux. */ leds[step] = on; leds[n1 - step] = on; step++; step &= n1; break; case 4: /* Colision. */ if (step < 4) { leds[step] = on; leds[n1 - step] = on; } step++; step &= n1; break; case 101: speed = repeat; repeat = 1; goto noled; case 102: speed = repeat; repeat = 1; goto noled; case 103: step = repeat; repeat = 1; goto noled; case 104: on = repeat; repeat = 1; goto noled; case 105: ons = repeat; repeat = 1; goto noled; case 106: decay = repeat; repeat = 1; goto noled; } go_chenil (speed, n1 + 1, leds); /* Faibli les leds. */ for (l = n1; l >= 0; l--) { if (leds[l] > decay) leds[l] -= decay; else leds[l] = 0; } on += ons; noled: repeat--; } }