X-Git-Url: http://git.droids-corp.org/?p=aversive.git;a=blobdiff_plain;f=projects%2Fmicrob2010%2Fmainboard%2Fmain.c;fp=projects%2Fmicrob2010%2Fmainboard%2Fmain.c;h=1b4d4b04c66bb21d633969fe5c33243219805009;hp=0000000000000000000000000000000000000000;hb=5918edd6f4f713ef3c8b0b0020dd30a4fb8222ae;hpb=9d2d9100592e18fed985730298215884127fc568 diff --git a/projects/microb2010/mainboard/main.c b/projects/microb2010/mainboard/main.c new file mode 100755 index 0000000..1b4d4b0 --- /dev/null +++ b/projects/microb2010/mainboard/main.c @@ -0,0 +1,295 @@ +/* + * Copyright Droids Corporation + * Olivier Matz + * + * 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 + * + * Revision : $Id: main.c,v 1.10 2009-11-08 17:24:33 zer0 Exp $ + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/eeprom_mapping.h" +#include "../common/i2c_commands.h" + +#include "main.h" +#include "ax12_user.h" +#include "strat.h" +#include "cmdline.h" +#include "sensor.h" +#include "actuator.h" +#include "cs.h" +#include "i2c_protocol.h" + +#if __AVR_LIBC_VERSION__ == 10602UL +#error "won't work with this version" +#endif + +/* 0 means "programmed" + * ---- with 16 Mhz quartz + * CKSEL 3-0 : 0111 + * SUT 1-0 : 10 + * CKDIV8 : 1 + * ---- bootloader + * BOOTZ 1-0 : 01 (4K bootloader) + * BOOTRST : 0 (reset on bootloader) + * ---- jtag + * jtagen : 0 + */ + +struct genboard gen; +struct mainboard mainboard; +struct mechboard mechboard; +struct sensorboard sensorboard; + +/***********************/ + +void bootloader(void) +{ +#define BOOTLOADER_ADDR 0x3f000 + if (pgm_read_byte_far(BOOTLOADER_ADDR) == 0xff) { + printf_P(PSTR("Bootloader is not present\r\n")); + return; + } + cli(); + BRAKE_ON(); + /* ... very specific :( */ + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK2 = 0; + TIMSK3 = 0; + TIMSK4 = 0; + TIMSK5 = 0; + EIMSK = 0; + UCSR0B = 0; + UCSR1B = 0; + UCSR2B = 0; + UCSR3B = 0; + SPCR = 0; + TWCR = 0; + ACSR = 0; + ADCSRA = 0; + + EIND = 1; + __asm__ __volatile__ ("ldi r31,0xf8\n"); + __asm__ __volatile__ ("ldi r30,0x00\n"); + __asm__ __volatile__ ("eijmp\n"); + + /* never returns */ +} + +void do_time_monitor(void *dummy) +{ + uint16_t seconds; + seconds = eeprom_read_word(EEPROM_TIME_ADDRESS); + seconds ++; + eeprom_write_word(EEPROM_TIME_ADDRESS, seconds); +} + +void do_led_blink(void *dummy) +{ +#if 1 /* simple blink */ + LED1_TOGGLE(); +#endif +} + +static void main_timer_interrupt(void) +{ + static uint8_t cpt = 0; + cpt++; + sei(); + if ((cpt & 0x3) == 0) + scheduler_interrupt(); +} + +int main(void) +{ + uint16_t seconds; + + /* brake */ + BRAKE_DDR(); + BRAKE_OFF(); + + /* CPLD reset on PG3 */ + DDRG |= 1<<3; + PORTG &= ~(1<<3); /* implicit */ + + /* LEDS */ + DDRJ |= 0x0c; + DDRL = 0xc0; + LED1_OFF(); + LED2_OFF(); + LED3_OFF(); + LED4_OFF(); + + memset(&gen, 0, sizeof(gen)); + memset(&mainboard, 0, sizeof(mainboard)); + mainboard.flags = DO_ENCODERS | DO_RS | + DO_POS | DO_POWER | DO_BD; + sensorboard.opponent_x = I2C_OPPONENT_NOT_THERE; + + /* UART */ + uart_init(); +#if CMDLINE_UART == 3 + fdevopen(uart3_dev_send, uart3_dev_recv); + uart_register_rx_event(3, emergency); +#elif CMDLINE_UART == 1 + fdevopen(uart1_dev_send, uart1_dev_recv); + uart_register_rx_event(1, emergency); +#else +# error not supported +#endif + + //eeprom_write_byte(EEPROM_MAGIC_ADDRESS, EEPROM_MAGIC_MAINBOARD); + /* check eeprom to avoid to run the bad program */ + if (eeprom_read_byte(EEPROM_MAGIC_ADDRESS) != + EEPROM_MAGIC_MAINBOARD) { + sei(); + printf_P(PSTR("Bad eeprom value\r\n")); + while(1); + } + + /* LOGS */ + error_register_emerg(mylog); + error_register_error(mylog); + error_register_warning(mylog); + error_register_notice(mylog); + error_register_debug(mylog); + + /* SPI + ENCODERS */ + encoders_spi_init(); /* this will also init spi hardware */ + + /* I2C */ + i2c_init(I2C_MODE_MASTER, I2C_MAINBOARD_ADDR); + i2c_protocol_init(); + i2c_register_recv_event(i2c_recvevent); + i2c_register_send_event(i2c_sendevent); + + /* TIMER */ + timer_init(); + timer0_register_OV_intr(main_timer_interrupt); + + /* PWM */ + PWM_NG_TIMER_16BITS_INIT(1, TIMER_16_MODE_PWM_10, + TIMER1_PRESCALER_DIV_1); + PWM_NG_TIMER_16BITS_INIT(4, TIMER_16_MODE_PWM_10, + TIMER4_PRESCALER_DIV_1); + + PWM_NG_INIT16(&gen.pwm1_4A, 4, A, 10, PWM_NG_MODE_SIGNED | + PWM_NG_MODE_SIGN_INVERTED, &PORTD, 4); + PWM_NG_INIT16(&gen.pwm2_4B, 4, B, 10, PWM_NG_MODE_SIGNED | + PWM_NG_MODE_SIGN_INVERTED, &PORTD, 5); + PWM_NG_INIT16(&gen.pwm3_1A, 1, A, 10, PWM_NG_MODE_SIGNED, + &PORTD, 6); + PWM_NG_INIT16(&gen.pwm4_1B, 1, B, 10, PWM_NG_MODE_SIGNED, + &PORTD, 7); + + + /* servos */ + PWM_NG_TIMER_16BITS_INIT(3, TIMER_16_MODE_PWM_10, + TIMER1_PRESCALER_DIV_256); + PWM_NG_INIT16(&gen.servo1, 3, C, 10, PWM_NG_MODE_NORMAL, + NULL, 0); + PWM_NG_TIMER_16BITS_INIT(5, TIMER_16_MODE_PWM_10, + TIMER1_PRESCALER_DIV_256); + PWM_NG_INIT16(&gen.servo2, 5, A, 10, PWM_NG_MODE_NORMAL, + NULL, 0); + PWM_NG_INIT16(&gen.servo3, 5, B, 10, PWM_NG_MODE_NORMAL, + NULL, 0); + PWM_NG_INIT16(&gen.servo4, 5, C, 10, PWM_NG_MODE_NORMAL, + NULL, 0); + pwm_ng_set(&gen.servo2, 290); /* right */ + pwm_ng_set(&gen.servo3, 400); /* left */ + /* 2 lintels 180, 485 */ + /* 1 lintel 155, 520 */ + + /* SCHEDULER */ + scheduler_init(); + + scheduler_add_periodical_event_priority(do_led_blink, NULL, + 100000L / SCHEDULER_UNIT, + LED_PRIO); + /* all cs management */ + microb_cs_init(); + + /* sensors, will also init hardware adc */ + sensor_init(); + + /* TIME */ + time_init(TIME_PRIO); + + /* start i2c slave polling */ + scheduler_add_periodical_event_priority(i2c_poll_slaves, NULL, + 8000L / SCHEDULER_UNIT, I2C_POLL_PRIO); + + /* strat */ + gen.logs[0] = E_USER_STRAT; + gen.log_level = 5; + strat_reset_infos(); + + /* strat-related event */ + scheduler_add_periodical_event_priority(strat_event, NULL, + 25000L / SCHEDULER_UNIT, + STRAT_PRIO); + + /* eeprom time monitor */ + scheduler_add_periodical_event_priority(do_time_monitor, NULL, + 1000000L / SCHEDULER_UNIT, + EEPROM_TIME_PRIO); + + sei(); + + printf_P(PSTR("\r\n")); + printf_P(PSTR("Respect et robustesse.\r\n")); + seconds = eeprom_read_word(EEPROM_TIME_ADDRESS); + printf_P(PSTR("Running since %d mn %d\r\n"), seconds/60, seconds%60); + cmdline_interact(); + + return 0; +}