diff --git a/conf/airframes/AGGIEAIR/aggieair_conf.xml b/conf/airframes/AGGIEAIR/aggieair_conf.xml index f1b8423087..4a470aeaa0 100644 --- a/conf/airframes/AGGIEAIR/aggieair_conf.xml +++ b/conf/airframes/AGGIEAIR/aggieair_conf.xml @@ -29,7 +29,7 @@ telemetry="telemetry/AGGIEAIR/aggieair_fixedwing.xml" flight_plan="flight_plans/basic.xml" settings="settings/fixedwing_basic.xml" - settings_modules="modules/nav_basic_fw.xml modules/guidance_basic_fw.xml modules/stabilization_attitude_fw.xml modules/ahrs_float_mlkf.xml modules/imu_common.xml modules/gps.xml" + settings_modules="modules/vms_ecu_demo.xml modules/nav_basic_fw.xml modules/guidance_basic_fw.xml modules/stabilization_attitude_fw.xml modules/ahrs_float_mlkf.xml modules/imu_common.xml modules/gps.xml" gui_color="#00009e93ffff" /> + diff --git a/conf/conf_tests.xml b/conf/conf_tests.xml index 58aa9ab32a..1624342c9d 100644 --- a/conf/conf_tests.xml +++ b/conf/conf_tests.xml @@ -67,7 +67,7 @@ /> + + + + + + A simple module for Viking Motorsports Engine Control Unit demonstration, + showing it usability for Formula SAE student competition. + More info at https://wiki.paparazziuav.org/wiki/VMS_ECU + + +
+ +
+
+ + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+ diff --git a/sw/airborne/boards/vms_ecu/chibios/v1.0/board.h b/sw/airborne/boards/vms_ecu/chibios/v1.0/board.h index 72110cdeb7..4eb265091f 100644 --- a/sw/airborne/boards/vms_ecu/chibios/v1.0/board.h +++ b/sw/airborne/boards/vms_ecu/chibios/v1.0/board.h @@ -1074,50 +1074,7 @@ /* * LEDs */ -/* 1 red, on PA8 */ -#ifndef USE_LED_1 -#define USE_LED_1 1 -#endif -#define LED_1_GPIO GPIOA -#define LED_1_GPIO_PIN 8 -#define LED_1_GPIO_ON gpio_clear -#define LED_1_GPIO_OFF gpio_set - -/* 2 green, shared with JTAG_TRST */ -#ifndef USE_LED_2 -#define USE_LED_2 1 -#endif -#define LED_2_GPIO GPIOB -#define LED_2_GPIO_PIN 4 -#define LED_2_GPIO_ON gpio_clear -#define LED_2_GPIO_OFF gpio_set - -/* 3 green, shared with ADC12 (ADC_6 on connector ANALOG2) */ -#ifndef USE_LED_3 -#define USE_LED_3 1 -#endif -#define LED_3_GPIO GPIOC -#define LED_3_GPIO_PIN 2 -#define LED_3_GPIO_ON gpio_clear -#define LED_3_GPIO_OFF gpio_set - -/* 4 red, shared with ADC15 (ADC_4 on connector ANALOG2) */ -#ifndef USE_LED_4 -#define USE_LED_4 1 -#endif -#define LED_4_GPIO GPIOC -#define LED_4_GPIO_PIN 5 -#define LED_4_GPIO_ON gpio_clear -#define LED_4_GPIO_OFF gpio_set - -/* 5 green, on PC15 */ -#ifndef USE_LED_5 -#define USE_LED_5 0 -#endif -#define LED_5_GPIO GPIOC -#define LED_5_GPIO_PIN 15 -#define LED_5_GPIO_ON gpio_set -#define LED_5_GPIO_OFF gpio_clear +// no LEDS here /* * ADCs @@ -1199,6 +1156,7 @@ /* * PWM defines + * no PWM outputs used */ #ifndef USE_PWM0 #define USE_PWM0 1 @@ -1263,6 +1221,7 @@ /** * PPM radio defines + * no ppm inputs used */ #define RC_PPM_TICKS_PER_USEC 6 #define PPM_TIMER_FREQUENCY 6000000 @@ -1271,6 +1230,7 @@ /** * I2C defines + * No I2C devices used */ #define I2C1_CLOCK_SPEED 400000 #define I2C1_CFG_DEF { \ @@ -1289,29 +1249,26 @@ /** * SPI Config */ -#define SPI1_GPIO_AF GPIO_AF5 -#define SPI1_GPIO_PORT_MISO GPIOA -#define SPI1_GPIO_MISO GPIO6 -#define SPI1_GPIO_PORT_MOSI GPIOA -#define SPI1_GPIO_MOSI GPIO7 -#define SPI1_GPIO_PORT_SCK GPIOA -#define SPI1_GPIO_SCK GPIO5 - -// SLAVE0 on SPI connector +// SLAVE0 - unconnected #define SPI_SELECT_SLAVE0_PORT GPIOB #define SPI_SELECT_SLAVE0_PIN 9 -// SLAVE1 on AUX1 +// SLAVE1 - unconnected #define SPI_SELECT_SLAVE1_PORT GPIOB #define SPI_SELECT_SLAVE1_PIN 1 -// SLAVE2 on AUX2 -#define SPI_SELECT_SLAVE2_PORT GPIOC -#define SPI_SELECT_SLAVE2_PIN 5 -// SLAVE3 on AUX3 -#define SPI_SELECT_SLAVE3_PORT GPIOC -#define SPI_SELECT_SLAVE3_PIN 4 -// SLAVE4 on AUX4 +// SLAVE2 is ASPIRIN MPU600 CS +#define SPI_SELECT_SLAVE2_PORT GPIOB +#define SPI_SELECT_SLAVE2_PIN 12 +// SLAVE3 is BARO_CS +#define SPI_SELECT_SLAVE3_PORT GPIOE +#define SPI_SELECT_SLAVE3_PIN 3 +// SLAVE4 - unconnected #define SPI_SELECT_SLAVE4_PORT GPIOB -#define SPI_SELECT_SLAVE4_PIN 5 +#define SPI_SELECT_SLAVE4_PIN 2 + +/** + * SD card + * TODO: add defines for SD log + */ /** * Baro diff --git a/sw/airborne/modules/fsae_electric/vms_ecu_demo.c b/sw/airborne/modules/fsae_electric/vms_ecu_demo.c new file mode 100644 index 0000000000..73bb4e3c16 --- /dev/null +++ b/sw/airborne/modules/fsae_electric/vms_ecu_demo.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2017 Michal Podhradsky + * + * This file is part of paparazzi. + * + * paparazzi 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, or (at your option) + * any later version. + * + * paparazzi 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 paparazzi; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +/** \file modules/fsae_electric/vms_ecu_demo.c + * + * Viking Motorsports Engine Control Unit demo module + * see https://wiki.paparazziuav.org/wiki/VMS_ECU + * for more details + */ +#include "modules/fsae_electric/vms_ecu_demo.h" +#include "mcu_periph/gpio.h" +#include "ch.h" // for DAC +#include "hal.h" // for DAC + +#include "generated/airframe.h" +#include BOARD_CONFIG + +/* + * ADC + */ +// define bit resolution +#ifndef ADC_BIT_RES +#define ADC_BIT_RES 12 +#endif + +// default reference (3.3 Volts) +#define ADC_VREF 3300.0 //mV + +// reading multiplier +#define ADC_VREF_MULT ADC_VREF/(1<3.3V) + +#define DAC_BUFFER_SIZE 1//360 + +float ain_1; +float ain_2; +float ain_3; +float ain_4; + +struct adc_buf adc_buf_1; +struct adc_buf adc_buf_2; +struct adc_buf adc_buf_3; +struct adc_buf adc_buf_4; + + + +/* + * DAC + */ +uint16_t dac_1; +uint16_t dac_2; + +static const DACConfig dac1cfg1 = { + .init = 2047U, + .datamode = DAC_DHRM_12BIT_RIGHT +}; + +static const DACConfig dac1cfg2 = { + .init = 0U, + .datamode = DAC_DHRM_12BIT_RIGHT +}; + + +dacsample_t dac_ref1; +dacsample_t dac_ref2; + + +/* + * DIGITAL IO + */ +bool ams_status; +bool pwr_ready; +bool pwr_stdby; +bool rtds; + +uint8_t stg_in; +uint8_t stb_in; + + + +/* + * CAN + */ +struct can_instance { + CANDriver *canp; + uint32_t led; +}; + +static const struct can_instance can1 = {&CAND1, 11}; +static const struct can_instance can2 = {&CAND2, 12}; + + +/* + * Internal loopback mode, 500KBaud, automatic wakeup, automatic recover + * from abort mode. + * See section 22.7.7 on the STM32 reference manual. + */ +static const CANConfig cancfg_lb = { + CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP, + CAN_BTR_LBKM | CAN_BTR_SJW(0) | CAN_BTR_TS2(1) | + CAN_BTR_TS1(8) | CAN_BTR_BRP(6) +}; + +/* + * Normal mode, see if we can ping each other + */ +static const CANConfig cancfg = { + CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP, + CAN_BTR_SJW(0) | CAN_BTR_TS2(1) | + CAN_BTR_TS1(8) | CAN_BTR_BRP(6) +}; + +/* + * Receiver thread. + */ +static THD_WORKING_AREA(can_rx1_wa, 256); +static THD_WORKING_AREA(can_rx2_wa, 256); +static THD_FUNCTION(can_rx, p) { + struct can_instance *cip = p; + event_listener_t el; + CANRxFrame rxmsg; + + (void)p; + chRegSetThreadName("receiver"); + chEvtRegister(&cip->canp->rxfull_event, &el, 0); + while(!chThdShouldTerminateX()) { + if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0) + continue; + while (canReceive(cip->canp, CAN_ANY_MAILBOX, + &rxmsg, TIME_IMMEDIATE) == MSG_OK) { + // Process message. + palTogglePad(GPIOD, cip->led); + } + } + //chEvtUnregister(&CAND1.rxfull_event, &el); + chEvtUnregister(&cip->canp->rxfull_event, &el); +} + + +/* + * Transmitter thread. + */ +static THD_WORKING_AREA(can_tx_wa, 256); +static THD_FUNCTION(can_tx, p) { + CANTxFrame txmsg; + + (void)p; + chRegSetThreadName("transmitter"); + txmsg.IDE = CAN_IDE_EXT; + txmsg.EID = 0x01234567; + txmsg.RTR = CAN_RTR_DATA; + txmsg.DLC = 8; + txmsg.data32[0] = 0x55AA55AA; + txmsg.data32[1] = 0x00FF00FF; + + while (!chThdShouldTerminateX()) { + //canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100)); + canTransmit(&CAND2, CAN_ANY_MAILBOX, &txmsg, MS2ST(100)); + chThdSleepMilliseconds(500); + } +} + + +#if PERIODIC_TELEMETRY +#include "subsystems/datalink/telemetry.h" +static void send_ecu(struct transport_tx *trans, struct link_device *dev) +{ + pprz_msg_send_ECU(trans, dev, AC_ID, + &stg_in, + &stb_in, + &ain_1, + &ain_2, + &ain_3, + &ain_4); +} +#endif + +void vms_ecu_demo_init(void) +{ + // Digital + ams_status = false; + pwr_ready = false; + pwr_stdby = false; + rtds = false; + stg_in = 0; + stb_in = 0; + + // Analog + ain_1 = 0.0; + ain_2 = 0.0; + ain_3 = 0.0; + ain_4 = 0.0; + + adc_buf_channel(ADC_1, &adc_buf_1, DEFAULT_AV_NB_SAMPLE); + adc_buf_channel(ADC_2, &adc_buf_2, DEFAULT_AV_NB_SAMPLE); + adc_buf_channel(ADC_3, &adc_buf_3, DEFAULT_AV_NB_SAMPLE); + adc_buf_channel(ADC_4, &adc_buf_4, DEFAULT_AV_NB_SAMPLE); + + dac_1 = 0; + dac_2 = 0; + + /* + * Activates the CAN drivers 1 and 2. + */ + canStart(&CAND1, &cancfg); + canStart(&CAND2, &cancfg); + + + + /* + * Starting the transmitter and receiver threads. + */ + chThdCreateStatic(can_rx1_wa, sizeof(can_rx1_wa), NORMALPRIO + 7, + can_rx, (void *)&can1); + chThdCreateStatic(can_rx2_wa, sizeof(can_rx2_wa), NORMALPRIO + 7, + can_rx, (void *)&can2); + chThdCreateStatic(can_tx_wa, sizeof(can_tx_wa), NORMALPRIO + 7, + can_tx, NULL); + +#if PERIODIC_TELEMETRY + register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_ECU, send_ecu); +#endif + + //DAC + /* + * Starting DAC1 driver, setting up the output pin as analog as suggested + * by the Reference Manual. + */ + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD1, &dac1cfg1); + dacStart(&DACD2, &dac1cfg2); + dac_ref1 = 0; + dac_ref2 = 0; + + dacPutChannelX(&DACD1,0,dac_ref1); + dacPutChannelX(&DACD2,1,dac_ref2); +} + +void vms_ecu_demo_periodic(void) +{ + // * PD10 - Digital output. (DOUT_LS1) + if (ams_status) { + gpio_set(GPIOD, 10); + } + else { + gpio_clear(GPIOD, 10); + } + + // *PD11 - Digital output. (DOUT_LS2). + if (pwr_ready) { + gpio_set(GPIOD, 11); + } + else { + gpio_clear(GPIOD, 11); + } + + // *PD12 - Digital output. (DOUT_LS3). + if (pwr_stdby) { + gpio_set(GPIOD, 12); + } + else { + gpio_clear(GPIOD, 12); + } + + // *PD13 - Digital output. (DOUT_LS4). + if (rtds) { + gpio_set(GPIOD, 13); + } + else { + gpio_clear(GPIOD, 13); + } + + static bool flag = false; + // read inputs + if (flag) { + stg_in = palReadPad(GPIOE, 7); // PE7 - Digital input. (DIN1:DIN_STG1). + flag = false; + } + else { + stb_in = palReadPad(GPIOE, 9); // PE9 - Digital input. (DIN3:DIN_STB1). + flag = true; + } + + // Analog + ain_1 = ((float)(adc_buf_1.sum/adc_buf_1.av_nb_sample))*ADC_VREF_MULT*ADC_VGAIN/1000.0; + ain_2 = ((float)(adc_buf_2.sum/adc_buf_2.av_nb_sample))*ADC_VREF_MULT*ADC_VGAIN/1000.0; + ain_3 = ((float)(adc_buf_3.sum/adc_buf_3.av_nb_sample))*ADC_VREF_MULT*ADC_VGAIN/1000.0; + ain_4 = ((float)(adc_buf_4.sum/adc_buf_4.av_nb_sample))*ADC_VREF_MULT*ADC_VGAIN/1000.0; +} + + +void vms_ecu_demo_UpdateDac1(uint16_t val) { + dac_1 = val; + dac_ref1 = dac_1; + dacPutChannelX(&DACD1,0,dac_ref1); +} + +void vms_ecu_demo_UpdateDac2(uint16_t val) { + dac_2 = val; + dac_ref2 = dac_2; + dacPutChannelX(&DACD2,1,dac_ref2); +} diff --git a/sw/airborne/modules/fsae_electric/vms_ecu_demo.h b/sw/airborne/modules/fsae_electric/vms_ecu_demo.h new file mode 100644 index 0000000000..8e5e008390 --- /dev/null +++ b/sw/airborne/modules/fsae_electric/vms_ecu_demo.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 Michal Podhradsky + * + * This file is part of paparazzi. + * + * paparazzi 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, or (at your option) + * any later version. + * + * paparazzi 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 paparazzi; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +/** \file modules/fsae_electric/vms_ecu_demo.h + * + * Viking Motorsports Engine Control Unit demo module + * see https://wiki.paparazziuav.org/wiki/VMS_ECU + * for more details + */ +#ifndef DRIVERS_TEST_H +#define DRIVERS_TEST_H + +#include "std.h" +#include "mcu_periph/adc.h" + +#if !USE_CHIBIOS_RTOS +#error Only Chibios is supported +#endif + +// Definitions of pins + +extern bool ams_status; +extern bool pwr_ready; +extern bool pwr_stdby; +extern bool rtds; + +void vms_ecu_demo_init(void); +void vms_ecu_demo_periodic(void); +/** Reset sweep number */ +extern void vms_ecu_demo_UpdateDac1(uint16_t val); +extern void vms_ecu_demo_UpdateDac2(uint16_t val); +extern uint16_t dac_1; +extern uint16_t dac_2; + +#endif /* DRIVERS_TEST */