From 3087da4bf912c6b2aa168b230e1004a1d6713d0c Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Fri, 22 Jul 2011 16:42:38 +0200 Subject: [PATCH 01/16] Rename internal functions and defines to be able to run SHT and SHT_I2C in parallel for comparsion. --- conf/messages.xml | 10 ++- sw/airborne/modules/meteo/humid_sht.h | 6 ++ sw/airborne/modules/meteo/humid_sht_i2c.c | 88 +++++++++++------------ sw/airborne/modules/meteo/humid_sht_i2c.h | 50 ++++++------- 4 files changed, 83 insertions(+), 71 deletions(-) diff --git a/conf/messages.xml b/conf/messages.xml index f5977aeff4..5fee9d9122 100644 --- a/conf/messages.xml +++ b/conf/messages.xml @@ -652,7 +652,7 @@ - + @@ -839,7 +839,13 @@ - + + + + + + + diff --git a/sw/airborne/modules/meteo/humid_sht.h b/sw/airborne/modules/meteo/humid_sht.h index cdfbe421d0..7419aca52f 100644 --- a/sw/airborne/modules/meteo/humid_sht.h +++ b/sw/airborne/modules/meteo/humid_sht.h @@ -9,11 +9,17 @@ /* GPIO P0.x defaults */ #ifndef DAT_PIN +/* ADC1 Port, ADC_4, P0.30 */ #define DAT_PIN 30 +/* IRH Port, IRH_2, P0.25 */ +// #define DAT_PIN 25 #endif #ifndef SCK_PIN +/* ADC1 Port, ADC_3, P0.4 */ #define SCK_PIN 4 +/* IRH Port, IRH_1, P0.22 */ +// #define SCK_PIN 22 #endif #define noACK 0 diff --git a/sw/airborne/modules/meteo/humid_sht_i2c.c b/sw/airborne/modules/meteo/humid_sht_i2c.c index 3360eaa1a2..94b4e7d06e 100644 --- a/sw/airborne/modules/meteo/humid_sht_i2c.c +++ b/sw/airborne/modules/meteo/humid_sht_i2c.c @@ -49,8 +49,8 @@ struct i2c_transaction sht_trans; uint8_t sht_status; uint8_t sht_serial[8] = {0}; uint32_t sht_serial1=0, sht_serial2=0; -uint16_t humidsht, tempsht; -float fhumidsht, ftempsht; +uint16_t humidsht_i2c, tempsht_i2c; +float fhumidsht_i2c, ftempsht_i2c; int8_t humid_sht_crc(volatile uint8_t* data) { uint8_t i, bit, crc = 0; @@ -70,126 +70,126 @@ int8_t humid_sht_crc(volatile uint8_t* data) { return 0; } -void humid_sht_init(void) { - sht_status = SHT_UNINIT; +void humid_sht_init_i2c(void) { + sht_status = SHT2_UNINIT; } -void humid_sht_periodic( void ) { +void humid_sht_periodic_i2c( void ) { switch (sht_status) { - case SHT_UNINIT: + case SHT2_UNINIT: /* do soft reset, then wait at least 15ms */ - sht_status = SHT_RESET; - sht_trans.buf[0] = SHT_SOFT_RESET; + sht_status = SHT2_RESET; + sht_trans.buf[0] = SHT2_SOFT_RESET; I2CTransmit(SHT_I2C_DEV, sht_trans, SHT_SLAVE_ADDR, 1); break; - case SHT_SERIAL: + case SHT2_SERIAL: /* get serial number part 1 */ - sht_status = SHT_SERIAL1; + sht_status = SHT2_SERIAL1; sht_trans.buf[0] = 0xFA; sht_trans.buf[1] = 0x0F; I2CTransceive(SHT_I2C_DEV, sht_trans, SHT_SLAVE_ADDR, 2, 8); break; - case SHT_SERIAL1: - case SHT_SERIAL2: + case SHT2_SERIAL1: + case SHT2_SERIAL2: break; default: /* trigger temp measurement, no master hold */ - sht_trans.buf[0] = SHT_TRIGGER_TEMP; - sht_status = SHT_TRIG_TEMP; + sht_trans.buf[0] = SHT2_TRIGGER_TEMP; + sht_status = SHT2_TRIG_TEMP; I2CTransmit(SHT_I2C_DEV, sht_trans, SHT_SLAVE_ADDR, 1); /* send serial number every 30 seconds */ - RunOnceEvery((4*30), DOWNLINK_SEND_SHT_SERIAL(DefaultChannel, &sht_serial1, &sht_serial2)); + RunOnceEvery((4*30), DOWNLINK_SEND_SHT_I2C_SERIAL(DefaultChannel, &sht_serial1, &sht_serial2)); break; } } /* needs 85ms delay from temp trigger measurement */ void humid_sht_p_temp( void ) { - if (sht_status == SHT_GET_TEMP) { + if (sht_status == SHT2_GET_TEMP) { /* get temp */ - sht_status = SHT_READ_TEMP; + sht_status = SHT2_READ_TEMP; I2CReceive(SHT_I2C_DEV, sht_trans, SHT_SLAVE_ADDR, 3); } } /* needs 29ms delay from humid trigger measurement */ void humid_sht_p_humid( void ) { - if (sht_status == SHT_GET_HUMID) { + if (sht_status == SHT2_GET_HUMID) { /* read humid */ - sht_status = SHT_READ_HUMID; + sht_status = SHT2_READ_HUMID; I2CReceive(SHT_I2C_DEV, sht_trans, SHT_SLAVE_ADDR, 3); } } -void humid_sht_event( void ) { +void humid_sht_event_i2c( void ) { if (sht_trans.status == I2CTransSuccess) { switch (sht_status) { - case SHT_TRIG_TEMP: - sht_status = SHT_GET_TEMP; + case SHT2_TRIG_TEMP: + sht_status = SHT2_GET_TEMP; sht_trans.status = I2CTransDone; break; - case SHT_READ_TEMP: + case SHT2_READ_TEMP: /* read temperature */ - tempsht = (sht_trans.buf[0] << 8) | sht_trans.buf[1]; - tempsht &= 0xFFFC; + tempsht_i2c = (sht_trans.buf[0] << 8) | sht_trans.buf[1]; + tempsht_i2c &= 0xFFFC; if (humid_sht_crc(sht_trans.buf) == 0) { /* trigger humid measurement, no master hold */ - sht_trans.buf[0] = SHT_TRIGGER_HUMID; - sht_status = SHT_TRIG_HUMID; + sht_trans.buf[0] = SHT2_TRIGGER_HUMID; + sht_status = SHT2_TRIG_HUMID; I2CTransmit(SHT_I2C_DEV, sht_trans, SHT_SLAVE_ADDR, 1); } else { /* checksum error, restart */ - sht_status = SHT_IDLE; + sht_status = SHT2_IDLE; sht_trans.status == I2CTransDone; } break; - case SHT_TRIG_HUMID: - sht_status = SHT_GET_HUMID; + case SHT2_TRIG_HUMID: + sht_status = SHT2_GET_HUMID; sht_trans.status = I2CTransDone; break; - case SHT_READ_HUMID: + case SHT2_READ_HUMID: /* read humidity */ - humidsht = (sht_trans.buf[0] << 8) | sht_trans.buf[1]; - humidsht &= 0xFFFC; - fhumidsht = -6. + 125. / 65536. * humidsht; - ftempsht = -46.85 + 175.72 / 65536. * tempsht; + humidsht_i2c = (sht_trans.buf[0] << 8) | sht_trans.buf[1]; + humidsht_i2c &= 0xFFFC; + fhumidsht_i2c = -6. + 125. / 65536. * humidsht_i2c; + ftempsht_i2c = -46.85 + 175.72 / 65536. * tempsht_i2c; - sht_status = SHT_IDLE; + sht_status = SHT2_IDLE; sht_trans.status = I2CTransDone; if (humid_sht_crc(sht_trans.buf) == 0) { - DOWNLINK_SEND_SHT_STATUS(DefaultChannel, &humidsht, &tempsht, &fhumidsht, &ftempsht); + DOWNLINK_SEND_SHT_I2C_STATUS(DefaultChannel, &humidsht_i2c, &tempsht_i2c, &fhumidsht_i2c, &ftempsht_i2c); } break; - case SHT_RESET: - sht_status = SHT_SERIAL; + case SHT2_RESET: + sht_status = SHT2_SERIAL; sht_trans.status = I2CTransDone; break; - case SHT_SERIAL1: + case SHT2_SERIAL1: /* read serial number part 1 */ sht_serial[5] = sht_trans.buf[0]; sht_serial[4] = sht_trans.buf[2]; sht_serial[3] = sht_trans.buf[4]; sht_serial[2] = sht_trans.buf[6]; /* get serial number part 2 */ - sht_status = SHT_SERIAL2; + sht_status = SHT2_SERIAL2; sht_trans.buf[0] = 0xFC; sht_trans.buf[1] = 0xC9; I2CTransceive(SHT_I2C_DEV, sht_trans, SHT_SLAVE_ADDR, 2, 6); break; - case SHT_SERIAL2: + case SHT2_SERIAL2: /* read serial number part 2 */ sht_serial[1] = sht_trans.buf[0]; sht_serial[0] = sht_trans.buf[1]; @@ -197,8 +197,8 @@ void humid_sht_event( void ) { sht_serial[6] = sht_trans.buf[4]; sht_serial1=sht_serial[7]<<24|sht_serial[6]<<16|sht_serial[5]<<8|sht_serial[4]; sht_serial2=sht_serial[3]<<24|sht_serial[2]<<16|sht_serial[1]<<8|sht_serial[0]; - DOWNLINK_SEND_SHT_SERIAL(DefaultChannel, &sht_serial1, &sht_serial2); - sht_status = SHT_IDLE; + DOWNLINK_SEND_SHT_I2C_SERIAL(DefaultChannel, &sht_serial1, &sht_serial2); + sht_status = SHT2_IDLE; sht_trans.status = I2CTransDone; break; diff --git a/sw/airborne/modules/meteo/humid_sht_i2c.h b/sw/airborne/modules/meteo/humid_sht_i2c.h index 746717a607..1c26fe5f8d 100644 --- a/sw/airborne/modules/meteo/humid_sht_i2c.h +++ b/sw/airborne/modules/meteo/humid_sht_i2c.h @@ -3,37 +3,37 @@ #include "std.h" -#define SHT_WRITE_USER 0xE6 -#define SHT_READ_USER 0xE7 -#define SHT_TRIGGER_TEMP 0xF3 -#define SHT_TRIGGER_HUMID 0xF5 -#define SHT_SOFT_RESET 0xFE +#define SHT2_WRITE_USER 0xE6 +#define SHT2_READ_USER 0xE7 +#define SHT2_TRIGGER_TEMP 0xF3 +#define SHT2_TRIGGER_HUMID 0xF5 +#define SHT2_SOFT_RESET 0xFE -enum sht_stat{ - SHT_UNINIT, - SHT_IDLE, - SHT_RESET, - SHT_SERIAL, - SHT_SERIAL1, - SHT_SERIAL2, - SHT_SET_CONFIG, - SHT_READ_SERIAL, - SHT_TRIG_TEMP, - SHT_GET_TEMP, - SHT_READ_TEMP, - SHT_TRIG_HUMID, - SHT_GET_HUMID, - SHT_READ_HUMID +enum sht_stat_i2c{ + SHT2_UNINIT, + SHT2_IDLE, + SHT2_RESET, + SHT2_SERIAL, + SHT2_SERIAL1, + SHT2_SERIAL2, + SHT2_SET_CONFIG, + SHT2_READ_SERIAL, + SHT2_TRIG_TEMP, + SHT2_GET_TEMP, + SHT2_READ_TEMP, + SHT2_TRIG_HUMID, + SHT2_GET_HUMID, + SHT2_READ_HUMID }; int8_t humid_sht_crc(volatile uint8_t* data); -void humid_sht_init(void); -void humid_sht_periodic(void); +void humid_sht_init_i2c(void); +void humid_sht_periodic_i2c(void); void humid_sht_p_temp(void); void humid_sht_p_humid(void); -void humid_sht_event(void); +void humid_sht_event_i2c(void); -extern uint16_t humidsht, tempsht; -extern float fhumidsht, ftempsht; +extern uint16_t humidsht_i2c, tempsht_i2c; +extern float fhumidsht_i2c, ftempsht_i2c; #endif From df54ababd77bd3cc925f176e9c615fe97f96ce09 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Fri, 22 Jul 2011 17:13:15 +0200 Subject: [PATCH 02/16] Add University of Reading solar radiation sensor. --- conf/messages.xml | 23 ++++++- conf/modules/light_solar.xml | 17 ++++++ sw/airborne/modules/meteo/light_solar.c | 80 +++++++++++++++++++++++++ sw/airborne/modules/meteo/light_solar.h | 14 +++++ 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 conf/modules/light_solar.xml create mode 100644 sw/airborne/modules/meteo/light_solar.c create mode 100644 sw/airborne/modules/meteo/light_solar.h diff --git a/conf/messages.xml b/conf/messages.xml index 5fee9d9122..d09933be9f 100644 --- a/conf/messages.xml +++ b/conf/messages.xml @@ -800,7 +800,28 @@ - + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/modules/light_solar.xml b/conf/modules/light_solar.xml new file mode 100644 index 0000000000..7cf08e80b9 --- /dev/null +++ b/conf/modules/light_solar.xml @@ -0,0 +1,17 @@ + + + +
+ +
+ + + + + + + + + +
+ diff --git a/sw/airborne/modules/meteo/light_solar.c b/sw/airborne/modules/meteo/light_solar.c new file mode 100644 index 0000000000..38b20450a0 --- /dev/null +++ b/sw/airborne/modules/meteo/light_solar.c @@ -0,0 +1,80 @@ +/* + * $Id: light_solar.c $ + * + * Copyright (C) 2011 Martin Mueller + * + * 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 light_solar.c + * \brief University of Reading solar radiation sensor interface + * + * This reads the values for intensity from the University of Reading solar sensor. + */ + + +#include "mcu_periph/adc.h" +#include "mcu_periph/uart.h" +#include "messages.h" +#include "downlink.h" +#include "modules/meteo/light_solar.h" + +#ifndef ADC_CHANNEL_LIGHT_SOLAR_UP +#define ADC_CHANNEL_LIGHT_SOLAR_UP ADC_1 +#endif +#ifndef ADC_CHANNEL_LIGHT_SOLAR_DN +#define ADC_CHANNEL_LIGHT_SOLAR_DN ADC_2 +#endif + +#ifndef ADC_CHANNEL_LIGHT_NB_SAMPLES +#define ADC_CHANNEL_LIGHT_NB_SAMPLES 16 +#endif + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif + +uint16_t up[LIGHT_NB], dn[LIGHT_NB]; +int32_t light_cnt; + +static struct adc_buf buf_light_sol_up; +static struct adc_buf buf_light_sol_dn; + +void light_solar_init( void ) { + adc_buf_channel(ADC_CHANNEL_LIGHT_SOLAR_UP, &buf_light_sol_up, ADC_CHANNEL_LIGHT_NB_SAMPLES); + adc_buf_channel(ADC_CHANNEL_LIGHT_SOLAR_DN, &buf_light_sol_dn, ADC_CHANNEL_LIGHT_NB_SAMPLES); + + light_cnt = 0; +} + +void light_solar_periodic( void ) { + up[light_cnt] = buf_light_sol_up.sum / buf_light_sol_up.av_nb_sample; + dn[light_cnt] = buf_light_sol_dn.sum / buf_light_sol_dn.av_nb_sample; + + /* 10k/10k voltage divider, 10 bits adc, 3.3V max */ + + if (++light_cnt >= LIGHT_NB) { + DOWNLINK_SEND_SOLAR_RADIATION(DefaultChannel, + &up[0], &dn[0], &up[1], &dn[1], &up[2], &dn[2], &up[3], &dn[3], + &up[4], &dn[4], &up[5], &dn[5], &up[6], &dn[6], &up[7], &dn[7], + &up[8], &dn[8], &up[9], &dn[9]); + light_cnt = 0; + } +} + diff --git a/sw/airborne/modules/meteo/light_solar.h b/sw/airborne/modules/meteo/light_solar.h new file mode 100644 index 0000000000..7fbcb1bd01 --- /dev/null +++ b/sw/airborne/modules/meteo/light_solar.h @@ -0,0 +1,14 @@ +#ifndef TEMP_SOLAR_H +#define TEMP_SOLAR_H + +#include "std.h" + +#define LIGHT_NB 10 + +extern uint16_t up[LIGHT_NB], dn[LIGHT_NB]; +extern int32_t light_cnt; + +void light_solar_init(void); +void light_solar_periodic(void); + +#endif From 813eee7a8e2c28d410eab0b87d9d269a2800bece Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Fri, 22 Jul 2011 17:31:19 +0200 Subject: [PATCH 03/16] Add University of Reading Geiger-Mueller counter. --- conf/messages.xml | 7 +- conf/modules/geiger_counter.xml | 14 ++ .../non_ap/geiger_counter/geiger_counter.c | 171 ++++++++++++++++++ sw/airborne/modules/meteo/geiger_counter.c | 77 ++++++++ sw/airborne/modules/meteo/geiger_counter.h | 11 ++ 5 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 conf/modules/geiger_counter.xml create mode 100644 sw/airborne/firmwares/non_ap/geiger_counter/geiger_counter.c create mode 100644 sw/airborne/modules/meteo/geiger_counter.c create mode 100644 sw/airborne/modules/meteo/geiger_counter.h diff --git a/conf/messages.xml b/conf/messages.xml index d09933be9f..0542da3beb 100644 --- a/conf/messages.xml +++ b/conf/messages.xml @@ -1165,7 +1165,12 @@
- + + + + + + diff --git a/conf/modules/geiger_counter.xml b/conf/modules/geiger_counter.xml new file mode 100644 index 0000000000..a09ec1c90a --- /dev/null +++ b/conf/modules/geiger_counter.xml @@ -0,0 +1,14 @@ + + + +
+ +
+ + + + + + +
+ diff --git a/sw/airborne/firmwares/non_ap/geiger_counter/geiger_counter.c b/sw/airborne/firmwares/non_ap/geiger_counter/geiger_counter.c new file mode 100644 index 0000000000..76c22094b4 --- /dev/null +++ b/sw/airborne/firmwares/non_ap/geiger_counter/geiger_counter.c @@ -0,0 +1,171 @@ +/* + * $Id$ + * + * Copyright (C) 2011 Martin Mueller + * + * 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. + * + */ + +/* I2C interface for University of Reading Geiger-Mueller counter */ + +#include + +#define END_MSG 0x13 + +/* green LED pin PB5 (on arduino pro mini) */ +#define LED_GR_PIN 13 + +#define GEIGER_CNT_I2C_ADDR 0x76 + +enum stats { + INIT, + FOUND_SYNC, + FOUND_1, + FOUND_2, + FOUND_3, + FOUND_4, + FOUND_5 }; + +int received data = 0; +int stat = 0, received data = 0; +unsigned long count_geiger_1 = 0; +unsigned long count_geiger_2 = 0; +unsigned short volt_geiger = 0; + +void read_i2c() { + unsigned char dat[10]; + digitalWrite(LED_GR_PIN, LOW); + received_data = 0; + memcpy(dat, count_geiger_1, 4); + memcpy(dat+4, count_geiger_2, 4); + memcpy(dat+8, volt_geiger, 2); + Wire.send(dat, 2); +} + +void setup() { + /* serial port */ + Serial.begin(2400); + pinMode(2,OUTPUT); + digitalWrite(2,HIGH); +#ifdef DEBUG + Serial.println("geiger counter init"); +#endif + + /* I2C init */ + Wire.begin(GEIGER_CNT_I2C_ADDR >> 1); + Wire.onRequest(read_i2c); + + /* green LED init */ + digitalWrite(LED_GR_PIN, LOW); + pinMode(LED_GR_PIN, OUTPUT); + + stat = INIT; +} + +void loop() { + unsigned char ser; + int i; + + /* wait for data */ + if (Serial.available() > 0) { + ser = Serial.read(); + switch (stat) { + case INIT: + /* sync on the last byte of the prev message */ + if (b == END_MSG) { + count_geiger_1 = 0; + count_geiger_2 = 0; + volt_geiger = 0; + i = 0; + stat = FOUND_SYNC; + } + break; + case FOUND_SYNC: + if ((b <= '9') && (b >= '0')) { + count_geiger_1 = count_geiger_1 * 10 + (b-'0'); + if (++i > 7) state = IDLE; + } else if (b == ',')) { + i = 0; + stat = FOUND_1; + } else stat = INIT; + break; + case FOUND_1: + /* read counter 1 */ + if ((b <= '9') && (b >= '0')) { + count_geiger_2 = count_geiger_2 * 10 + (b-'0'); + if (++i > 7) state = IDLE; + } else if (b == ',')) { +#ifdef DEBUG + Serial.println(count_geiger_1, DEC); +#endif + i = 0; + stat = FOUND_2; + } else stat = INIT; + break; + case FOUND_2: + /* read counter 2 */ + if ((b <= '9') && (b >= '0')) { + count_geiger_2 = count_geiger_2 * 10 + (b-'0'); + if (++i > 7) state = IDLE; + } else if (b == ',')) { +#ifdef DEBUG + Serial.println(count_geiger_2, DEC); +#endif + i = 0; + stat = FOUND_3; + } else stat = INIT; + break; + case FOUND_3: + /* ignore 3 */ + if ((b <= '9') && (b >= '0')) { + if (++i > 7) state = IDLE; + } else if (b == ',')) { + i = 0; + stat = FOUND_4; + } else stat = INIT; + break; + case FOUND_4: + /* ignore 4 */ + if ((b <= '9') && (b >= '0')) { + if (++i > 7) state = IDLE; + } else if (b == ',')) { + i = 0; + stat = FOUND_5; + } else stat = INIT; + break; + case FOUND_5: + /* read voltage */ + if ((b <= '9') && (b >= '0')) { + volt_geiger = volt_geiger * 10 + (b-'0'); + if (++i > 7) state = IDLE; + } else if (b == 'V')) { + digitalWrite(LED_GR_PIN, HIGH); +#ifdef DEBUG + Serial.println(volt_geiger, DEC); +#endif + received_data = 0; + stat = INIT; + } else stat = INIT; + break; + default: + stat = INIT; + } + } +} + diff --git a/sw/airborne/modules/meteo/geiger_counter.c b/sw/airborne/modules/meteo/geiger_counter.c new file mode 100644 index 0000000000..3c98c238a7 --- /dev/null +++ b/sw/airborne/modules/meteo/geiger_counter.c @@ -0,0 +1,77 @@ +/* + * $Id$ + * + * Copyright (C) 2011 Martin Mueller + * + * 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 geiger_counter.c + * \brief I2C interface for University of Reading Geiger counter + * + */ + +#include "modules/meteo/geiger_counter.h" +#include "mcu_periph/i2c.h" +#include "mcu_periph/uart.h" +#include "messages.h" +#include "downlink.h" + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif + +#ifndef GEIGER_CNT_DEV +#define GEIGER_CNT_DEV i2c0 +#endif + +#define GEIGER_CNT_I2C_ADDR 0x76 + +struct i2c_transaction geiger_trans; +uint32_t count_geiger_1, count_geiger_2; +uint16_t volt_geiger; + +void geiger_counter_init( void ) { +} + +void geiger_counter_periodic( void ) { + I2CReceive(GEIGER_CNT_DEV, geiger_trans, GEIGER_CNT_I2C_ADDR, 10); +} + +void geiger_counter_event( void ) { + if (geiger_trans.status == I2CTransSuccess) { + count_geiger_1 = (geiger_trans.buf[3] << 24) | + (geiger_trans.buf[2] << 16) | + (geiger_trans.buf[1] << 8) | + (geiger_trans.buf[0]); + count_geiger_2 = (geiger_trans.buf[7] << 24) | + (geiger_trans.buf[6] << 16) | + (geiger_trans.buf[5] << 8) | + (geiger_trans.buf[4]); + volt_geiger = (geiger_trans.buf[9] << 8) | + (geiger_trans.buf[8]); + geiger_trans.status = I2CTransDone; + + if (volt_geiger & 0x8000) { + volt_geiger &= 0x7FFF; + DOWNLINK_SEND_GEIGER_COUNTER(DefaultChannel, + &count_geiger_1, &count_geiger_2, &volt_geiger); + } + } +} diff --git a/sw/airborne/modules/meteo/geiger_counter.h b/sw/airborne/modules/meteo/geiger_counter.h new file mode 100644 index 0000000000..cbc900708d --- /dev/null +++ b/sw/airborne/modules/meteo/geiger_counter.h @@ -0,0 +1,11 @@ +#ifndef GEIGER_COUNTER_H +#define GEIGER_COUNTER_H + +#include "std.h" + +void geiger_counter_init(void); +void geiger_counter_periodic(void); +void geiger_counter_event(void); + +#endif + From e8249cda13fbd45a6844cb53b211e8e30c89ed15 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Fri, 22 Jul 2011 18:04:28 +0200 Subject: [PATCH 04/16] Add Universitaet Tuebingen thermocouple sensor. --- conf/messages.xml | 19 +++- conf/modules/temp_tcouple_adc.xml | 17 ++++ sw/airborne/modules/meteo/temp_tcouple_adc.c | 91 ++++++++++++++++++++ sw/airborne/modules/meteo/temp_tcouple_adc.h | 14 +++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 conf/modules/temp_tcouple_adc.xml create mode 100644 sw/airborne/modules/meteo/temp_tcouple_adc.c create mode 100644 sw/airborne/modules/meteo/temp_tcouple_adc.h diff --git a/conf/messages.xml b/conf/messages.xml index 0542da3beb..ed2349cd76 100644 --- a/conf/messages.xml +++ b/conf/messages.xml @@ -859,7 +859,24 @@
- + + + + + + + + + + + + + + + + + + diff --git a/conf/modules/temp_tcouple_adc.xml b/conf/modules/temp_tcouple_adc.xml new file mode 100644 index 0000000000..0b44301318 --- /dev/null +++ b/conf/modules/temp_tcouple_adc.xml @@ -0,0 +1,17 @@ + + + +
+ +
+ + + + + + + + + +
+ diff --git a/sw/airborne/modules/meteo/temp_tcouple_adc.c b/sw/airborne/modules/meteo/temp_tcouple_adc.c new file mode 100644 index 0000000000..048f8ea826 --- /dev/null +++ b/sw/airborne/modules/meteo/temp_tcouple_adc.c @@ -0,0 +1,91 @@ +/* + * $Id: temp_tcouple_adc.c $ + * + * Copyright (C) 2011 Martin Mueller + * + * 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 temp_tcouple_adc.c + * \brief Universitaet Tuebingen thermocouple interface + * + * This reads the values for reference and measurement temperature + * from the Universitaet Tuebingen thermocouple sensor. + */ + + +#include "mcu_periph/adc.h" +#include "mcu_periph/uart.h" +#include "messages.h" +#include "downlink.h" +#include "modules/meteo/temp_tcouple_adc.h" + +#ifndef ADC_CHANNEL_TEMP_REF +#define ADC_CHANNEL_TEMP_REF ADC_4 +#endif +#ifndef ADC_CHANNEL_TEMP_VAL +#define ADC_CHANNEL_TEMP_VAL ADC_3 +#endif + +#ifndef ADC_CHANNEL_TEMP_TCOUPLE_NB_SAMPLES +#define ADC_CHANNEL_TEMP_TCOUPLE_NB_SAMPLES 16 +#endif + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif + +uint16_t ref[TCOUPLE_NB], val[TCOUPLE_NB]; +float fref[TCOUPLE_NB], fval[TCOUPLE_NB]; +int32_t temp_cnt; + +static struct adc_buf buf_temp_tcouple_ref; +static struct adc_buf buf_temp_tcouple_val; + +void temp_tcouple_adc_init( void ) { + adc_buf_channel(ADC_CHANNEL_TEMP_REF, + &buf_temp_tcouple_ref, + ADC_CHANNEL_TEMP_TCOUPLE_NB_SAMPLES); + adc_buf_channel(ADC_CHANNEL_TEMP_VAL, + &buf_temp_tcouple_val, + ADC_CHANNEL_TEMP_TCOUPLE_NB_SAMPLES); + temp_cnt = 0; +} + +void temp_tcouple_adc_periodic( void ) { + val[temp_cnt] = buf_temp_tcouple_val.sum / buf_temp_tcouple_val.av_nb_sample; + ref[temp_cnt] = buf_temp_tcouple_ref.sum / buf_temp_tcouple_ref.av_nb_sample; + + /* no voltage divider, 10 bits adc, 3.3V max */ + /* T = U * 52.288899706 - 7.977784737996595 */ + fval[temp_cnt] = ((float)(val[temp_cnt] * 3.3) / 1023.) + * 52.288899706 - 7.977784737996595; + fref[temp_cnt] = ((float)(ref[temp_cnt] * 3.3) / 1023.) + * 100. - 13.; + + if (++temp_cnt >= TCOUPLE_NB) { + DOWNLINK_SEND_TEMP_TCOUPLE(DefaultChannel, + &fval[0], &fval[1], &fval[2], &fval[3], + &fref[0], &fref[1], &fref[2], &fref[3], + &val[0], &val[1], &val[2], &val[3], + &ref[0], &ref[1], &ref[2], &ref[3]); + temp_cnt = 0; + } +} + diff --git a/sw/airborne/modules/meteo/temp_tcouple_adc.h b/sw/airborne/modules/meteo/temp_tcouple_adc.h new file mode 100644 index 0000000000..b3636542e4 --- /dev/null +++ b/sw/airborne/modules/meteo/temp_tcouple_adc.h @@ -0,0 +1,14 @@ +#ifndef TEMP_TCOUPLE_ADC_H +#define TEMP_TCOUPLE_ADC_H + +#include "std.h" + +#define TCOUPLE_NB 4 + +extern uint16_t up[TCOUPLE_NB], dn[TCOUPLE_NB]; +extern int32_t tcouple_cnt; + +void temp_tcouple_adc_init(void); +void temp_tcouple_adc_periodic(void); + +#endif From 88ff740f9ef03366d144b56eeba3d4da4d87bdcd Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Fri, 22 Jul 2011 18:32:24 +0200 Subject: [PATCH 05/16] Allow other sensors to be used for HIH humidity sensor temperature compensation. --- sw/airborne/modules/meteo/humid_dpicco.h | 2 ++ sw/airborne/modules/meteo/humid_hih.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/sw/airborne/modules/meteo/humid_dpicco.h b/sw/airborne/modules/meteo/humid_dpicco.h index 7272e5763e..1b95a76d0a 100644 --- a/sw/airborne/modules/meteo/humid_dpicco.h +++ b/sw/airborne/modules/meteo/humid_dpicco.h @@ -10,6 +10,8 @@ #define DPICCO_TEMP_RANGE 165.0 #define DPICCO_TEMP_OFFS -40.0 +extern float dpicco_temp; + extern void dpicco_init( void ); extern void dpicco_periodic( void ); extern void dpicco_event( void ); diff --git a/sw/airborne/modules/meteo/humid_hih.c b/sw/airborne/modules/meteo/humid_hih.c index 2e61b5ca45..6904c54d80 100644 --- a/sw/airborne/modules/meteo/humid_hih.c +++ b/sw/airborne/modules/meteo/humid_hih.c @@ -31,6 +31,8 @@ #include #include "modules/meteo/humid_hih.h" #include "modules/meteo/temp_tmp102.h" +#include "modules/meteo/humid_dpicco.h" +#include "modules/meteo/humid_sht.h" #include "mcu_periph/adc.h" #include "mcu_periph/uart.h" #include "messages.h" @@ -58,8 +60,12 @@ void humid_hih_init( void ) { } void humid_hih_periodic( void ) { - float fvout; + float fvout, fhih_temp; + /* get temperature from external source */ + fhih_temp = ftempsht; + /****************************************/ + adc_humid_hih = buf_humid_hih.sum / buf_humid_hih.av_nb_sample; /* 36k/68k voltage divider, 3.3V full sweep, 10 bits adc */ @@ -69,8 +75,8 @@ void humid_hih_periodic( void ) { fhih_humid = ((fvout / 5.0)-0.16)/0.0062; /* temperature compensation */ - fhih_humid = fhih_humid/(1.0546 - (0.00216 * ftmp_temperature)); + fhih_humid = fhih_humid/(1.0546 - (0.00216 * fhih_temp)); - DOWNLINK_SEND_HIH_STATUS(DefaultChannel, &adc_humid_hih, &fhih_humid, &ftmp_temperature); + DOWNLINK_SEND_HIH_STATUS(DefaultChannel, &adc_humid_hih, &fhih_humid, &fhih_temp); } From 8b3eb0e7146a88ad02dd0c0656b962fe44b86ad3 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Fri, 22 Jul 2011 18:50:31 +0200 Subject: [PATCH 06/16] ACAM Picocap Single-chip solution for Capacitance (humidity) Measurement --- conf/messages.xml | 7 +- conf/modules/humid_pcap01.xml | 13 ++ sw/airborne/modules/meteo/humid_pcap01.c | 263 +++++++++++++++++++++++ sw/airborne/modules/meteo/humid_pcap01.h | 120 +++++++++++ 4 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 conf/modules/humid_pcap01.xml create mode 100644 sw/airborne/modules/meteo/humid_pcap01.c create mode 100644 sw/airborne/modules/meteo/humid_pcap01.h diff --git a/conf/messages.xml b/conf/messages.xml index ed2349cd76..e9fb2a741a 100644 --- a/conf/messages.xml +++ b/conf/messages.xml @@ -1181,7 +1181,12 @@
- + + + + + + diff --git a/conf/modules/humid_pcap01.xml b/conf/modules/humid_pcap01.xml new file mode 100644 index 0000000000..2e792e2c2c --- /dev/null +++ b/conf/modules/humid_pcap01.xml @@ -0,0 +1,13 @@ + + + +
+ +
+ + + + + + +
\ No newline at end of file diff --git a/sw/airborne/modules/meteo/humid_pcap01.c b/sw/airborne/modules/meteo/humid_pcap01.c new file mode 100644 index 0000000000..345095bc3c --- /dev/null +++ b/sw/airborne/modules/meteo/humid_pcap01.c @@ -0,0 +1,263 @@ +/* + * $Id: humid_pcap01.c $ + * + * Copyright (C) 2011 Norman Wildmann, Martin Mueller + * + * 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 humid_pcap01.c + * \brief ACAM Picocap Single-chip Solution for Capacitance Measurement + * + * This reads the values for temperature and humidity from the ACAM capacitance and resistance + * measurement unit through I2C. + */ + +#include "led.h" +#include "sys_time.h" +#include "mcu_periph/i2c.h" +#include "mcu_periph/uart.h" +#include "messages.h" +#include "downlink.h" +#include "modules/meteo/humid_pcap01.h" +#ifdef PCAP01_LOAD_FIRMWARE +#include "modules/meteo/humid_pcap01_firmware.h" +#endif + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif + +uint8_t pcap01_meas_started; +struct i2c_transaction pcap01_trans; +PCAP01VALUE pcap01Value; + +#ifndef PCAP01_I2C_DEV +#define PCAP01_I2C_DEV i2c0 +#endif + +void writePCAP01_SRAM(uint8_t data, uint16_t s_add) +{ + while (pcap01_trans.status == I2CTransPending); + + pcap01_trans.buf[0] = 0x90+(unsigned char)(s_add>>8); + pcap01_trans.buf[1] = (unsigned char)(s_add); + pcap01_trans.buf[2] = data; + I2CTransmit(PCAP01_I2C_DEV, pcap01_trans, PCAP01_ADDR, 3); +} + +uint8_t readPCAP01_SRAM(uint16_t s_add) +{ + while (pcap01_trans.status == I2CTransPending); + + pcap01_trans.buf[0] = 0x10+(unsigned char)(s_add>>8); + pcap01_trans.buf[1] = (unsigned char)(s_add); + I2CTransceive(PCAP01_I2C_DEV, pcap01_trans, PCAP01_ADDR, 2, 1); + while (pcap01_trans.status == I2CTransPending); + + return pcap01_trans.buf[0]; +} +/** +* \brief PCAP01_Control +* +* Function to send control commands to the PCAP01 +* +* \param control Control command +* possible commands: +* PCAP01_PU_RESET : Hard reset of the device +* PCAP01_IN_RESET : Software reset +* PCAP01_START : Start measurement +* PCAP01_START : Start measurement +* PCAP01_TERM : Stop measurement +*/ + void PCAP01_Control(uint8_t control) +{ + while (pcap01_trans.status == I2CTransPending); + + pcap01_trans.buf[0] = control; + pcap01_trans.buf[1] = 0; + pcap01_trans.buf[2] = 0; + pcap01_trans.buf[3] = 0; + I2CTransmit(PCAP01_I2C_DEV, pcap01_trans, PCAP01_ADDR, 4); +} + + void pcap01writeRegister(uint8_t reg,uint32_t value) + { + while (pcap01_trans.status == I2CTransPending); + + pcap01_trans.buf[0] = PCAP01_WRITE_REG + reg; + pcap01_trans.buf[1] = (unsigned char) (value>>16); + pcap01_trans.buf[2] = (unsigned char) (value>>8); + pcap01_trans.buf[3] = (unsigned char) (value); + I2CTransmit(PCAP01_I2C_DEV, pcap01_trans, PCAP01_ADDR, 4); + } + +#ifdef PCAP01_LOAD_FIRMWARE +void writePCAP01_firmware(void) +{ + int i = 0; + char testbyte = 44; + uint16_t testaddress = 71; + // Hard reset + PCAP01_Control(PCAP01_PU_RESET); + sys_time_usleep(50000); + //write testbyte + writePCAP01_SRAM(testbyte, testaddress); + + //check testbyte + if (readPCAP01_SRAM(testaddress) != testbyte) + return; + else + { +LED_ON(3); + //Hard reset + PCAP01_Control(PCAP01_PU_RESET); + //write firmware + for (i = 0;i< sizeof(firmware); i++) + { + writePCAP01_SRAM(firmware[i],i); + } + //fill with ffs + for (;i< 4029; i++) + { + writePCAP01_SRAM(0xff,i); + } + i++; +#ifdef PCAP01_200HZ + //write end bytes of sram + writePCAP01_SRAM(0x04,i++); + writePCAP01_SRAM(0x01,i++); + writePCAP01_SRAM(0x01,i++); +#endif +#ifdef PCAP01_STANDARD + //write end bytes of sram + writePCAP01_SRAM(0x02,i++); + writePCAP01_SRAM(0x01,i++); + writePCAP01_SRAM(0x03,i++); +#endif + } +} +#endif // PCAP01_LOAD_FIRMWARE + +void pcap01_init(void) { + pcap01_trans.status = I2CTransDone; + pcap01Value.status = PCAP01_IDLE; +#ifdef PCAP01_LOAD_FIRMWARE + writePCAP01_firmware(); +#endif + pcap01writeRegister(PCAP01_REG0, PCAP01_REG0_VALUE); + pcap01writeRegister(PCAP01_REG1, PCAP01_REG1_VALUE); + pcap01writeRegister(PCAP01_REG2, PCAP01_REG2_VALUE); + pcap01writeRegister(PCAP01_REG3, PCAP01_REG3_VALUE); + pcap01writeRegister(PCAP01_REG4, PCAP01_REG4_VALUE); + pcap01writeRegister(PCAP01_REG5, PCAP01_REG5_VALUE); + pcap01writeRegister(PCAP01_REG6, PCAP01_REG6_VALUE); + pcap01writeRegister(PCAP01_REG7, PCAP01_REG7_VALUE); + pcap01writeRegister(PCAP01_REG8, PCAP01_REG8_VALUE); + pcap01writeRegister(PCAP01_REG9, PCAP01_REG9_VALUE); + pcap01writeRegister(PCAP01_REG10, PCAP01_REG10_VALUE); + pcap01writeRegister(PCAP01_REG11, PCAP01_REG11_VALUE); + pcap01writeRegister(PCAP01_REG12, PCAP01_REG12_VALUE); + pcap01writeRegister(PCAP01_REG13, PCAP01_REG13_VALUE); + pcap01writeRegister(PCAP01_REG14, PCAP01_REG14_VALUE); + pcap01writeRegister(PCAP01_REG15, PCAP01_REG15_VALUE); + pcap01writeRegister(PCAP01_REG16, PCAP01_REG16_VALUE); + pcap01writeRegister(PCAP01_REG17, PCAP01_REG17_VALUE); + pcap01writeRegister(PCAP01_REG18, PCAP01_REG18_VALUE); + pcap01writeRegister(PCAP01_REG19, PCAP01_REG19_VALUE); + pcap01writeRegister(PCAP01_REG20, PCAP01_REG20_VALUE); + PCAP01_Control(PCAP01_IN_RESET); + sys_time_usleep(500000); + PCAP01_Control(PCAP01_START); +} + +void pcap01readRegister(uint8_t reg) + { + uint16_t byte1 = 0x40 | reg; + pcap01_trans.buf[0] = byte1; + I2CTransceive(PCAP01_I2C_DEV, pcap01_trans, PCAP01_ADDR, 1, 3); + } + +/** +* \brief pcap01_readData +* +* function where current measurement data from pcap01 is read into +* global sensor variable +* +* \param control Control command +* possible commands: +* PCAP01_PU_RESET : Hard reset of the device +* PCAP01_IN_RESET : Software reset +* PCAP01_START : Start measurement +* PCAP01_START : Start measurement +* PCAP01_TERM : Stop measurement +*/ +void pcap01_periodic(void) +{ + pcap01Value.status = PCAP01_GET_HUMID; +#ifdef PCAP01_STANDARD + pcap01readRegister(PCAP01_REG1); +#endif +#ifdef PCAP01_200HZ + pcap01readRegister(PCAP01_REG2); +#endif +} + +void pcap01_event(void) +{ + float humidity; + float temperature; + + if (pcap01_trans.status == I2CTransSuccess) { + switch (pcap01Value.status) { + + case PCAP01_GET_HUMID: + pcap01Value.C_ratio = pcap01_trans.buf[0] << 16; + pcap01Value.C_ratio |= (pcap01_trans.buf[1] << 8); + pcap01Value.C_ratio |= pcap01_trans.buf[2]; + pcap01Value.status = PCAP01_GET_TEMP; +#ifdef PCAP01_STANDARD + pcap01readRegister(PCAP01_REG13); +#endif +#ifdef PCAP01_200HZ + pcap01readRegister(PCAP01_REG3); +#endif + break; + + case PCAP01_GET_TEMP: + pcap01Value.R_ratio = pcap01_trans.buf[0] << 16; + pcap01Value.R_ratio |= (pcap01_trans.buf[1] << 8); + pcap01Value.R_ratio |= pcap01_trans.buf[2]; + humidity = pcap01Value.C_ratio * (-0.0023959245437) + 516.4124438673063; + temperature = pcap01Value.R_ratio * 61.927 - 259.74; + DOWNLINK_SEND_PCAP01_STATUS(DefaultChannel, + &pcap01Value.C_ratio, + &pcap01Value.R_ratio, + &humidity, + &temperature); + pcap01_trans.status = I2CTransDone; + pcap01Value.status = PCAP01_IDLE; + break; + + default: + pcap01_trans.status = I2CTransDone; + break; + } + } +} diff --git a/sw/airborne/modules/meteo/humid_pcap01.h b/sw/airborne/modules/meteo/humid_pcap01.h new file mode 100644 index 0000000000..0ebac83cad --- /dev/null +++ b/sw/airborne/modules/meteo/humid_pcap01.h @@ -0,0 +1,120 @@ +#ifndef PCAP01_H +#define PCAP01_H + +#include "std.h" + +//#define PCAP01_STANDARD +#define PCAP01_200HZ + +typedef struct { + uint32_t temp; + uint32_t hum_t; + uint32_t hum; + uint32_t R_ratio; + uint32_t C_ratio; + uint32_t NV_temp; + uint32_t V_rh; + uint32_t status; +}PCAP01VALUE; + +#define PCAP01_ADDR 0xA0 + +#define PCAP01_IDLE 0 +#define PCAP01_GET_HUMID 1 +#define PCAP01_GET_TEMP 2 + +//OpCodes für PCap Programmierung +#define PCAP01_PU_RESET 0x88 +#define PCAP01_IN_RESET 0x8a +#define PCAP01_START 0x8c +#define PCAP01_TERM 0x84 + +#define PCAP01_WRITE_REG 0xC0 +#define PCAP01_READ_REG 0x40 +#define PCAP01_READ_STAT 0x48 +#define PCAP01_WRITE_SRAM 0x90 +#define PCAP01_WRITE_OTP 0xA0 + +// Configuration Registers +#define PCAP01_REG0 0x00 +#define PCAP01_REG1 0x01 +#define PCAP01_REG2 0x02 +#define PCAP01_REG3 0x03 +#define PCAP01_REG4 0x04 +#define PCAP01_REG5 0x05 +#define PCAP01_REG6 0x06 +#define PCAP01_REG7 0x07 +#define PCAP01_REG8 0x08 +#define PCAP01_REG9 0x09 +#define PCAP01_REG10 0x0A +#define PCAP01_REG11 0x0B +#define PCAP01_REG12 0x0C +#define PCAP01_REG13 0x0D +#define PCAP01_REG14 0x0E +#define PCAP01_REG15 0x0F +#define PCAP01_REG16 0x10 +#define PCAP01_REG17 0x11 +#define PCAP01_REG18 0x12 +#define PCAP01_REG19 0x13 +#define PCAP01_REG20 0x14 + +#ifdef PCAP01_200HZ +// Register configuration values +#define PCAP01_REG0_VALUE 0x420F0F +#define PCAP01_REG1_VALUE 0x201004 +#define PCAP01_REG2_VALUE 0x1F460A +#define PCAP01_REG3_VALUE 0x090004 +#define PCAP01_REG4_VALUE 0x08040D +#define PCAP01_REG5_VALUE 0xC0001E +#define PCAP01_REG6_VALUE 0x000C40 +#define PCAP01_REG7_VALUE 0x1F0000 +#define PCAP01_REG8_VALUE 0x800053 +#define PCAP01_REG9_VALUE 0x00A88F +#define PCAP01_REG10_VALUE 0x18004B +#define PCAP01_REG11_VALUE 0x000000 +#define PCAP01_REG12_VALUE 0x000000 +#define PCAP01_REG13_VALUE 0x000000 +#define PCAP01_REG14_VALUE 0x000000 +#define PCAP01_REG15_VALUE 0x000000 +#define PCAP01_REG16_VALUE 0x000000 +#define PCAP01_REG17_VALUE 0x000006 +#define PCAP01_REG18_VALUE 0x0000A6 +#define PCAP01_REG19_VALUE 0x000001 +#define PCAP01_REG20_VALUE 0x000001 +#endif +#ifdef PCAP01_STANDARD +// Register configuration values +#define PCAP01_REG0_VALUE 0x4200FF +#define PCAP01_REG1_VALUE 0x201022 +#define PCAP01_REG2_VALUE 0x0F460B +#define PCAP01_REG3_VALUE 0x070010 +#define PCAP01_REG4_VALUE 0x080000 +#define PCAP01_REG5_VALUE 0x000000 +#define PCAP01_REG6_VALUE 0x000040 +#define PCAP01_REG7_VALUE 0x1F0000 +#define PCAP01_REG8_VALUE 0xA00010 +#define PCAP01_REG9_VALUE 0xFF000F +#define PCAP01_REG10_VALUE 0x180047 +#define PCAP01_REG11_VALUE 0x000000 +#define PCAP01_REG12_VALUE 0x000000 +#define PCAP01_REG13_VALUE 0x000000 +#define PCAP01_REG14_VALUE 0x000000 +#define PCAP01_REG15_VALUE 0x000000 +#define PCAP01_REG16_VALUE 0x000000 +#define PCAP01_REG17_VALUE 0x000000 +#define PCAP01_REG18_VALUE 0x000000 +#define PCAP01_REG19_VALUE 0x200000 +#define PCAP01_REG20_VALUE 0x000001 +#endif + +void writePCAP01_SRAM(uint8_t data, uint16_t s_add); +uint8_t readPCAP01_SRAM(uint16_t s_add); +void PCAP01_Control(uint8_t control); +void pcap01readRegister(uint8_t reg); +void pcap01writeRegister(uint8_t reg,uint32_t value); +void writePCAP01_firmware(void); +void pcap01_init(void); +void pcap01_periodic(void); +void pcap01_event(void); + +#endif From 035eb8300a23edf1ca3b78fc89af23a64cab4575 Mon Sep 17 00:00:00 2001 From: Felix Ruess Date: Sun, 24 Jul 2011 16:59:51 +0200 Subject: [PATCH 07/16] Add Meteo Plot Profile through gnuplot. --- .gitignore | 2 + sw/logalizer/Makefile | 5 +- sw/logalizer/plotprofile.c | 138 +++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 sw/logalizer/plotprofile.c diff --git a/.gitignore b/.gitignore index 22b80c9dc3..b40917524e 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ /conf/%gconf.xml /conf/srtm_data/* /conf/maps_data/* +/conf/gps/ublox_conf # /doc/pprz_algebra/ /doc/pprz_algebra/headfile.log @@ -99,6 +100,7 @@ /sw/logalizer/plotter /sw/logalizer/gtk_export.ml /sw/logalizer/sd2log +/sw/logalizer/plotprofile # /sw/simulator/ /sw/simulator/gaia diff --git a/sw/logalizer/Makefile b/sw/logalizer/Makefile index 4768fac813..01dd11580b 100644 --- a/sw/logalizer/Makefile +++ b/sw/logalizer/Makefile @@ -27,7 +27,7 @@ OCAMLC = ocamlc OCAMLOPT = ocamlopt INCLUDES= $(shell ocamlfind query -r -i-format xml-light) $(shell ocamlfind query -r -i-format lablgtk2) -I ../lib/ocaml -all: play plotter plot sd2log +all: play plotter plot sd2log plotprofile play : log_file.cmo play_core.cmo play.cmo @echo OL $@ @@ -105,6 +105,9 @@ MORE_CFLAGS = -DHAVE_DLFCN_H=1 -DSTDC_HEADERS=1 -I. -I. -I.. -g -O2 -I/usr/ disp3d: disp3d.c $(CC) $(MORE_CFLAGS) -g -o $@ $^ $(MORE_FLAGS) +plotprofile: plotprofile.c + gcc -g -O2 -Wall `pkg-config glib-2.0 --cflags` -o $@ $^ `pkg-config glib-2.0 --libs` `pcre-config --libs` -lglibivy + test1: test1.c $(CC) $(MORE_CFLAGS) -g -o $@ $^ $(MORE_FLAGS) -lglut diff --git a/sw/logalizer/plotprofile.c b/sw/logalizer/plotprofile.c new file mode 100644 index 0000000000..39f0cdcf2a --- /dev/null +++ b/sw/logalizer/plotprofile.c @@ -0,0 +1,138 @@ + +/* + +http://users.softlab.ntua.gr/~ttsiod/gnuplotStreaming.html + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HEIGHT_SPAN 20000 + +FILE *Gplt, *Gplh; +int32_t alt = 0; +int32_t temp[HEIGHT_SPAN] = {0}; +int32_t humid[HEIGHT_SPAN] = {0}; + +void on_GPS(IvyClientPtr app, void *user_data, int argc, char *argv[]){ +/* + + + + + + + + + + + + + + +7.73 11 GPS 0 55577549 665183336 0 -4310 0 0 1642 345957748 31 0 +*/ + + int32_t _alt; + + _alt = atoi(argv[5]); + alt = _alt / 100; +// if ((_alt/100) < HEIGHT_SPAN) alt = _alt; + +// printf("alt %f\n", (float) _alt/100.); +} + +void on_TMP_STATUS(IvyClientPtr app, void *user_data, int argc, char *argv[]){ +/* + + + + +*/ + + float _temp; + int i; + + _temp = atof(argv[2]); + if (alt < HEIGHT_SPAN) temp[alt] = _temp * 100; + +// printf("temp %f\n", _temp); + fprintf(Gplt, "plot '-' w points pt 0 title \"Temp\"\n"); + for (i = 0; i < HEIGHT_SPAN; i++){ + if (temp[i] != 0) fprintf(Gplt, "%f %d\n", temp[i]/100., i); + } + fprintf(Gplt,"e\n"); +} + +void on_SHT_STATUS(IvyClientPtr app, void *user_data, int argc, char *argv[]){ +/* + + + + + + +*/ + + float _humid; + int i; + + _humid = atof(argv[3]); + if (alt < HEIGHT_SPAN) humid[alt] = _humid * 100; + +// printf("humid %f\n", _humid); + fprintf(Gplh, "plot '-' w points pt 0 title \"Humid\"\n"); + for (i = 0; i < HEIGHT_SPAN; i++){ + if (humid[i] != 0) fprintf(Gplh, "%f %d\n", humid[i]/100., i); + } + fprintf(Gplh,"e\n"); +} + +int main( int argc, char* argv[] ) +{ + double xmint, xmaxt, xminh, xmaxh, ymin, ymax; + GMainLoop *ml; + + ml = g_main_loop_new(NULL, FALSE); + + IvyInit ("IvyPlotProfile", "IvyPlotProfile READY", NULL, NULL, NULL, NULL); + IvyBindMsg(on_GPS, NULL, "^(\\S*) GPS (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*) (\\S*)"); + IvyBindMsg(on_TMP_STATUS, NULL, "^(\\S*) TMP_STATUS (\\S*) (\\S*)"); + IvyBindMsg(on_SHT_STATUS, NULL, "^(\\S*) SHT_STATUS (\\S*) (\\S*) (\\S*) (\\S*)"); +// IvyBindMsg(on_SHT_STATUS, NULL, "^(\\S*) DPICCO_STATUS (\\S*) (\\S*) (\\S*) (\\S*)"); + IvyStart("127.255.255.255"); + + xmint = 5; + xmaxt = 35; + xminh = 0; + xmaxh = 100; + ymin = 500; + ymax = 2300; + + Gplt = popen("gnuplot -geometry 300x300 -noraise","w"); + setlinebuf(Gplt); + fprintf(Gplt, "set xrange[%f:%f]\n", xmint, xmaxt); + fprintf(Gplt, "set yrange[%f:%f]\n", ymin, ymax); + + Gplh = popen("gnuplot -geometry 300x300 -noraise","w"); + setlinebuf(Gplh); + fprintf(Gplh, "set xrange[%f:%f]\n", xminh, xmaxh); + fprintf(Gplh, "set yrange[%f:%f]\n", ymin, ymax); + + g_main_loop_run(ml); + + fclose(Gplt); + fclose(Gplh); + return 0; +} From bf46afca9cf10afa9a429f4230c075809634803b Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Sun, 24 Jul 2011 11:25:21 +0200 Subject: [PATCH 08/16] oops, should be conf/control_panel.xml.example instead --- conf/control_panel.xml.example | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/control_panel.xml.example b/conf/control_panel.xml.example index b54fddac02..88bb2185d3 100644 --- a/conf/control_panel.xml.example +++ b/conf/control_panel.xml.example @@ -68,6 +68,8 @@ + + From 6b669d111d9bb8f17be9b81f65615a4e51895d1b Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Sun, 24 Jul 2011 10:27:12 +0200 Subject: [PATCH 09/16] SHT I2c and thermocouple fixes --- conf/modules/humid_sht_i2c.xml | 6 +++--- sw/airborne/modules/meteo/temp_tcouple_adc.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/conf/modules/humid_sht_i2c.xml b/conf/modules/humid_sht_i2c.xml index a9587748e3..82eb88d942 100644 --- a/conf/modules/humid_sht_i2c.xml +++ b/conf/modules/humid_sht_i2c.xml @@ -9,11 +9,11 @@
- - + + - + diff --git a/sw/airborne/modules/meteo/temp_tcouple_adc.h b/sw/airborne/modules/meteo/temp_tcouple_adc.h index b3636542e4..95f8a1b23f 100644 --- a/sw/airborne/modules/meteo/temp_tcouple_adc.h +++ b/sw/airborne/modules/meteo/temp_tcouple_adc.h @@ -5,7 +5,6 @@ #define TCOUPLE_NB 4 -extern uint16_t up[TCOUPLE_NB], dn[TCOUPLE_NB]; extern int32_t tcouple_cnt; void temp_tcouple_adc_init(void); From 7dd9d96df301b39617a3ef48422c1a3709a25cc8 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Sun, 26 Jun 2011 13:10:43 +0200 Subject: [PATCH 10/16] add Mediatek MT3329 DIYDrones 1.4/1.6 GPS receiver support, needs testing --- Makefile | 11 +- Makefile.install | 1 + conf/airframes/mm/fixed-wing/funjetmm.xml | 2 +- conf/autopilot/fixedwing.xml | 2 +- .../fixedwing/gps_mediatek_diy.makefile | 23 + conf/mtk.dtd | 26 ++ conf/mtk.xml | 34 ++ sw/airborne/subsystems/gps.h | 1 + sw/airborne/subsystems/gps/gps_mtk.c | 401 ++++++++++++++++++ sw/airborne/subsystems/gps/gps_mtk.h | 136 ++++++ sw/tools/Makefile | 2 +- sw/tools/gen_mtk.ml | 176 ++++++++ 12 files changed, 810 insertions(+), 5 deletions(-) create mode 100644 conf/autopilot/subsystems/fixedwing/gps_mediatek_diy.makefile create mode 100644 conf/mtk.dtd create mode 100644 conf/mtk.xml create mode 100644 sw/airborne/subsystems/gps/gps_mtk.c create mode 100644 sw/airborne/subsystems/gps/gps_mtk.h create mode 100644 sw/tools/gen_mtk.ml diff --git a/Makefile b/Makefile index cb9eec3f45..239dec6985 100644 --- a/Makefile +++ b/Makefile @@ -52,11 +52,13 @@ STATICINCLUDE =$(PAPARAZZI_HOME)/var/include MESSAGES_H=$(STATICINCLUDE)/messages.h MESSAGES2_H=$(STATICINCLUDE)/messages2.h UBX_PROTOCOL_H=$(STATICINCLUDE)/ubx_protocol.h +MTK_PROTOCOL_H=$(STATICINCLUDE)/mtk_protocol.h XSENS_PROTOCOL_H=$(STATICINCLUDE)/xsens_protocol.h DL_PROTOCOL_H=$(STATICINCLUDE)/dl_protocol.h DL_PROTOCOL2_H=$(STATICINCLUDE)/dl_protocol2.h MESSAGES_XML = $(CONF)/messages.xml UBX_XML = $(CONF)/ubx.xml +MTK_XML = $(CONF)/mtk.xml XSENS_XML = $(CONF)/xsens_MTi-G.xml TOOLS=$(PAPARAZZI_SRC)/sw/tools HAVE_ARM_NONE_EABI_GCC := $(shell which arm-none-eabi-gcc) @@ -108,7 +110,7 @@ misc: multimon: cd $(MULTIMON); $(MAKE) -static_h: $(MESSAGES_H) $(MESSAGES2_H) $(UBX_PROTOCOL_H) $(XSENS_PROTOCOL_H) $(DL_PROTOCOL_H) $(DL_PROTOCOL2_H) +static_h: $(MESSAGES_H) $(MESSAGES2_H) $(UBX_PROTOCOL_H) $(MTK_PROTOCOL_H) $(XSENS_PROTOCOL_H) $(DL_PROTOCOL_H) $(DL_PROTOCOL2_H) usb_lib: @[ -d sw/airborne/arch/lpc21/lpcusb ] && ((test -x "$(ARMGCC)" && (cd sw/airborne/arch/lpc21/lpcusb; $(MAKE))) || echo "Not building usb_lib: ARMGCC=$(ARMGCC) not found") || echo "Not building usb_lib: sw/airborne/arch/lpc21/lpcusb directory missing" @@ -132,6 +134,11 @@ $(UBX_PROTOCOL_H) : $(UBX_XML) tools $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) $(TOOLS)/gen_ubx.out $< > /tmp/ubx.h $(Q)mv /tmp/ubx.h $@ +$(MTK_PROTOCOL_H) : $(MTK_XML) tools + @echo BUILD $@ + $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) $(TOOLS)/gen_mtk.out $< > /tmp/mtk.h + $(Q)mv /tmp/mtk.h $@ + $(XSENS_PROTOCOL_H) : $(XSENS_XML) tools @echo BUILD $@ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) $(TOOLS)/gen_xsens.out $< > /tmp/xsens.h @@ -215,7 +222,7 @@ fast_deb: clean: rm -fr dox build-stamp configure-stamp conf/%gconf.xml debian/files debian/paparazzi-arm7 debian/paparazzi-avr debian/paparazzi-base debian/paparazzi-bin debian/paparazzi-dev - rm -f $(MESSAGES_H) $(MESSAGES2_H) $(UBX_PROTOCOL_H) $(DL_PROTOCOL_H) + rm -f $(MESSAGES_H) $(MESSAGES2_H) $(UBX_PROTOCOL_H) $(MTK_PROTOCOL_H) $(DL_PROTOCOL_H) find . -mindepth 2 -name Makefile -exec sh -c '$(MAKE) -C `dirname {}` $@' \; find . -name '*~' -exec rm -f {} \; rm -f paparazzi sw/simulator/launchsitl diff --git a/Makefile.install b/Makefile.install index 1acf59704f..fd2aa46350 100644 --- a/Makefile.install +++ b/Makefile.install @@ -134,6 +134,7 @@ install_tools: $(INSTALLDATA) sw/tools/gen_settings.ml $(DESTDIR)/sw/tools/ $(INSTALLDATA) sw/tools/gen_tuning.ml $(DESTDIR)/sw/tools/ $(INSTALLDATA) sw/tools/gen_ubx.ml $(DESTDIR)/sw/tools/ + $(INSTALLDATA) sw/tools/gen_mtk.ml $(DESTDIR)/sw/tools/ $(INSTALLDATA) sw/tools/gen_xsens.ml $(DESTDIR)/sw/tools/ $(INSTALLDATA) sw/tools/gen_modules.ml $(DESTDIR)/sw/tools/ $(INSTALLDATA) sw/tools/gen_common.cmo $(DESTDIR)/sw/tools/ diff --git a/conf/airframes/mm/fixed-wing/funjetmm.xml b/conf/airframes/mm/fixed-wing/funjetmm.xml index 7dee6dd558..17fd3c558a 100644 --- a/conf/airframes/mm/fixed-wing/funjetmm.xml +++ b/conf/airframes/mm/fixed-wing/funjetmm.xml @@ -37,7 +37,7 @@ - + diff --git a/conf/autopilot/fixedwing.xml b/conf/autopilot/fixedwing.xml index f65f6282b1..ad2527f967 100644 --- a/conf/autopilot/fixedwing.xml +++ b/conf/autopilot/fixedwing.xml @@ -34,7 +34,7 @@ - + diff --git a/conf/autopilot/subsystems/fixedwing/gps_mediatek_diy.makefile b/conf/autopilot/subsystems/fixedwing/gps_mediatek_diy.makefile new file mode 100644 index 0000000000..5b11c32b8d --- /dev/null +++ b/conf/autopilot/subsystems/fixedwing/gps_mediatek_diy.makefile @@ -0,0 +1,23 @@ +# Mediatek MT3329, DIYDrones V1.4/1.6 protocol + + +ap.CFLAGS += -DUSE_GPS -DGPS_CONFIGURE -DGPS_USE_LATLONG +ap.CFLAGS += -DGPS_LINK=$(GPS_PORT) +ap.CFLAGS += -DUSE_$(GPS_PORT) +ap.CFLAGS += -D$(GPS_PORT)_BAUD=$(GPS_BAUD) + +ifneq ($(GPS_LED),none) + ap.CFLAGS += -DGPS_LED=$(GPS_LED) +endif + +ap.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_mtk.h\" +ap.srcs += $(SRC_SUBSYSTEMS)/gps/gps_mtk.c + +$(TARGET).srcs += $(SRC_SUBSYSTEMS)/gps.c + +sim.CFLAGS += -DUSE_GPS -DGPS_USE_LATLONG +sim.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_sim.h\" +sim.srcs += $(SRC_SUBSYSTEMS)/gps/gps_sim.c + +jsbsim.CFLAGS += -DUSE_GPS -DGPS_TYPE_H=\"subsystems/gps/gps_sim.h\" +jsbsim.srcs += $(SRC_SUBSYSTEMS)/gps/gps_sim.c diff --git a/conf/mtk.dtd b/conf/mtk.dtd new file mode 100644 index 0000000000..73fe522085 --- /dev/null +++ b/conf/mtk.dtd @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/conf/mtk.xml b/conf/mtk.xml new file mode 100644 index 0000000000..201ba3b60a --- /dev/null +++ b/conf/mtk.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sw/airborne/subsystems/gps.h b/sw/airborne/subsystems/gps.h index 21a30c6bb1..c8121322b8 100644 --- a/sw/airborne/subsystems/gps.h +++ b/sw/airborne/subsystems/gps.h @@ -38,6 +38,7 @@ #endif #define GPS_FIX_NONE 0x00 +#define GPS_FIX_2D 0x02 #define GPS_FIX_3D 0x03 #define GpsFixValid() (gps.fix == GPS_FIX_3D) diff --git a/sw/airborne/subsystems/gps/gps_mtk.c b/sw/airborne/subsystems/gps/gps_mtk.c new file mode 100644 index 0000000000..812521670c --- /dev/null +++ b/sw/airborne/subsystems/gps/gps_mtk.c @@ -0,0 +1,401 @@ +/* + * Copyright (C) 2011 The Paparazzi Team + * + * 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 gps_mtk.h + * @brief Mediatek MT3329 specific code + * + * supports: + * DIYDrones V1.4 protocol (AXN1.30_2278) + * DIYDrones V1.6 protocol (AXN1.30_2389) + * + * documentation is partly incorrect, see mtk.xml for what seems + * to be "real" + * + */ + +#include "subsystems/gps.h" + +#include "led.h" + +#include "subsystems/nav.h" +#include "math/pprz_geodetic_float.h" +#include "sys_time.h" + +#define MTK_DIY_OUTPUT_RATE MTK_DIY_OUTPUT_4HZ +#define OUTPUT_RATE 4 + +/* parser status */ +#define UNINIT 0 +#define GOT_SYNC1_14 1 +#define GOT_SYNC2_14 2 +#define GOT_CLASS_14 3 +#define GOT_SYNC1_16 4 +#define GOT_SYNC2_16 5 +#define GOT_ID 6 +#define GOT_PAYLOAD 7 +#define GOT_CHECKSUM1 8 + +/* last error type */ +#define GPS_MTK_ERR_NONE 0 +#define GPS_MTK_ERR_OVERRUN 1 +#define GPS_MTK_ERR_MSG_TOO_LONG 2 +#define GPS_MTK_ERR_CHECKSUM 3 +#define GPS_MTK_ERR_UNEXPECTED 4 +#define GPS_MTK_ERR_OUT_OF_SYNC 5 + +/* defines for UTC-GPS time conversion */ +#define SECS_MINUTE (60) +#define SECS_HOUR (60*60) +#define SECS_DAY (60*60*24) +#define SECS_WEEK (60*60*24*7) + +#define isleap(x) ((((x)%400)==0) || (!(((x)%100)==0) && (((x)%4)==0))) + +const int8_t DAYS_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +struct GpsMtk gps_mtk; + +#ifdef GPS_CONFIGURE +bool_t gps_configuring; +static uint8_t gps_status_config; +#endif + +void gps_impl_init(void) { + gps_mtk.status = UNINIT; + gps_mtk.msg_available = FALSE; + gps_mtk.error_cnt = 0; + gps_mtk.error_last = GPS_MTK_ERR_NONE; +#ifdef GPS_CONFIGURE + gps_status_config = 0; + gps_configuring = TRUE; +#endif +} + +static void gps_mtk_time2itow(uint32_t gps_date, uint32_t gps_time, + int16_t* gps_week, uint32_t* gps_itow) { + /* convert UTC date/time to GPS week/itow, we have no idea about GPS + leap seconds for now */ + uint16_t gps_msecond = gps_time % 1000; + uint8_t gps_second = (gps_time / 1000) % 100; + uint8_t gps_minute = (gps_time / 100000) % 100; + uint8_t gps_hour = (gps_time / 10000000) % 100; + uint16_t gps_year = 2000 + (gps_date % 100); + uint8_t gps_month = (gps_date / 100) % 100; + uint8_t gps_day = (gps_date / 10000) % 100; + int32_t i, days; + + *gps_week = 0; + *gps_itow = 0; + + /* sanity checks */ + if (gps_month > 12) return; + if (gps_day > (DAYS_MONTH[gps_month] + + ((gps_month == 1) ? isleap(gps_year):0))) return; + if (gps_hour > 23) return; + if (gps_minute > 59) return; + if (gps_second > 59) return; + + /* days since 6-JAN-1980 */ + days = -6; + for (i = 1980; i < gps_year; i++) days += (365 + isleap(i)); + + /* add days in gps_year */ + for (i = 0; i < gps_month-1; i++) { + days += DAYS_MONTH[i] + ((i == 1) ? isleap(gps_year):0); + } + days += gps_day; + + /* convert */ + *gps_week = (uint16_t) (days / 7); + *gps_itow = ((days % 7) * SECS_DAY + + gps_hour * SECS_HOUR + + gps_minute * SECS_MINUTE + + gps_second) * 1000 + + gps_msecond; +} + +void gps_mtk_read_message(void) { + if (gps_mtk.msg_class == MTK_DIY14_ID) { + if (gps_mtk.msg_id == MTK_DIY14_NAV_ID) { +#ifdef GPS_TIMESTAMP + /* get hardware clock ticks */ + SysTimeTimerStart(gps.t0); + gps.t0_tow = MTK_DIY14_NAV_ITOW(gps_mtk.msg_buf); + gps.t0_tow_frac = 0; +#endif + gps.lla_pos.lat = RadOfDeg(MTK_DIY14_NAV_LAT(gps_mtk.msg_buf))*10; + gps.lla_pos.lon = RadOfDeg(MTK_DIY14_NAV_LON(gps_mtk.msg_buf))*10; + // FIXME: with MTK you do not receive vertical speed + if (cpu_time_sec - gps.last_fix_time < 2) { + gps.ned_vel.z = ((gps.hmsl - + MTK_DIY14_NAV_HEIGHT(gps_mtk.msg_buf)*10)*OUTPUT_RATE)/10; + } else gps.ned_vel.z = 0; + gps.hmsl = MTK_DIY14_NAV_HEIGHT(gps_mtk.msg_buf)*10; + // FIXME: with MTK you do not receive ellipsoid altitude + gps.lla_pos.alt = gps.hmsl; + gps.gspeed = MTK_DIY14_NAV_GSpeed(gps_mtk.msg_buf); + // FIXME: with MTK you do not receive speed 3D + gps.speed_3d = gps.gspeed; + gps.course = (RadOfDeg(MTK_DIY14_NAV_Heading(gps_mtk.msg_buf)))*10; + gps.num_sv = MTK_DIY14_NAV_numSV(gps_mtk.msg_buf); + switch (MTK_DIY14_NAV_GPSfix(gps_mtk.msg_buf)) { + case MTK_DIY_FIX_3D: + gps.fix = GPS_FIX_3D; + break; + case MTK_DIY_FIX_2D: + gps.fix = GPS_FIX_2D; + break; + default: + gps.fix = GPS_FIX_NONE; + } + gps.tow = MTK_DIY14_NAV_ITOW(gps_mtk.msg_buf);; + // FIXME: with MTK DIY 1.4 you do not receive GPS week + gps.week = 0; + /* Computes from (lat, long) in the referenced UTM zone */ + struct LlaCoor_f lla_f; + lla_f.lat = ((float) gps.lla_pos.lat) / 1e7; + lla_f.lon = ((float) gps.lla_pos.lon) / 1e7; + struct UtmCoor_f utm_f; + utm_f.zone = nav_utm_zone0; + /* convert to utm */ + utm_of_lla_f(&utm_f, &lla_f); + /* copy results of utm conversion */ + gps.utm_pos.east = utm_f.east*100; + gps.utm_pos.north = utm_f.north*100; + gps.utm_pos.alt = utm_f.alt*1000; + gps.utm_pos.zone = nav_utm_zone0; +#ifdef GPS_LED + if (gps.fix == GPS_FIX_3D) { + LED_ON(GPS_LED); + } + else { + LED_TOGGLE(GPS_LED); + } +#endif + } + } + + if (gps_mtk.msg_class == MTK_DIY16_ID) { + if (gps_mtk.msg_id == MTK_DIY16_NAV_ID) { + uint32_t gps_date, gps_time; + gps_date = MTK_DIY16_NAV_UTC_DATE(gps_mtk.msg_buf); + gps_time = MTK_DIY16_NAV_UTC_TIME(gps_mtk.msg_buf); + gps_mtk_time2itow(gps_date, gps_time, &gps.week, &gps.tow); +#ifdef GPS_TIMESTAMP + /* get hardware clock ticks */ + SysTimeTimerStart(gps.t0); + gps.t0_tow = gps.tow; + gps.t0_tow_frac = 0; +#endif + gps.lla_pos.lat = RadOfDeg(MTK_DIY16_NAV_LAT(gps_mtk.msg_buf))*10; + gps.lla_pos.lon = RadOfDeg(MTK_DIY16_NAV_LON(gps_mtk.msg_buf))*10; + // FIXME: with MTK you do not receive vertical speed + if (cpu_time_sec - gps.last_fix_time < 2) { + gps.ned_vel.z = ((gps.hmsl - + MTK_DIY16_NAV_HEIGHT(gps_mtk.msg_buf)*10)*OUTPUT_RATE)/10; + } else gps.ned_vel.z = 0; + gps.hmsl = MTK_DIY16_NAV_HEIGHT(gps_mtk.msg_buf)*10; + // FIXME: with MTK you do not receive ellipsoid altitude + gps.lla_pos.alt = gps.hmsl; + gps.gspeed = MTK_DIY16_NAV_GSpeed(gps_mtk.msg_buf); + // FIXME: with MTK you do not receive speed 3D + gps.speed_3d = gps.gspeed; + gps.course = (RadOfDeg(MTK_DIY16_NAV_Heading(gps_mtk.msg_buf)*10000)) * 10; + gps.num_sv = MTK_DIY16_NAV_numSV(gps_mtk.msg_buf); + switch (MTK_DIY16_NAV_GPSfix(gps_mtk.msg_buf)) { + case MTK_DIY_FIX_3D: + gps.fix = GPS_FIX_3D; + break; + case MTK_DIY_FIX_2D: + gps.fix = GPS_FIX_2D; + break; + default: + gps.fix = GPS_FIX_NONE; + } + /* HDOP? */ + /* Computes from (lat, long) in the referenced UTM zone */ + struct LlaCoor_f lla_f; + lla_f.lat = ((float) gps.lla_pos.lat) / 1e7; + lla_f.lon = ((float) gps.lla_pos.lon) / 1e7; + struct UtmCoor_f utm_f; + utm_f.zone = nav_utm_zone0; + /* convert to utm */ + utm_of_lla_f(&utm_f, &lla_f); + /* copy results of utm conversion */ + gps.utm_pos.east = utm_f.east*100; + gps.utm_pos.north = utm_f.north*100; + gps.utm_pos.alt = utm_f.alt*1000; + gps.utm_pos.zone = nav_utm_zone0; +#ifdef GPS_LED + if (gps.fix == GPS_FIX_3D) { + LED_ON(GPS_LED); + } + else { + LED_TOGGLE(GPS_LED); + } +#endif + } + } +} + +/* byte parsing */ +void gps_mtk_parse( uint8_t c ) { + if (gps_mtk.status < GOT_PAYLOAD) { + gps_mtk.ck_a += c; + gps_mtk.ck_b += gps_mtk.ck_a; + } + switch (gps_mtk.status) { + case UNINIT: + if (c == MTK_DIY14_SYNC1) + gps_mtk.status = GOT_SYNC1_14; + if (c == MTK_DIY16_ID) + gps_mtk.msg_class = c; + gps_mtk.status = GOT_SYNC1_16; + break; + /* MTK_DIY_VER_14 */ + case GOT_SYNC1_14: + if (c != MTK_DIY14_SYNC2) { + gps_mtk.error_last = GPS_MTK_ERR_OUT_OF_SYNC; + goto error; + } + if (gps_mtk.msg_available) { + /* Previous message has not yet been parsed: discard this one */ + gps_mtk.error_last = GPS_MTK_ERR_OVERRUN; + goto error; + } + gps_mtk.ck_a = 0; + gps_mtk.ck_b = 0; + gps_mtk.status++; + gps_mtk.len = MTK_DIY14_NAV_LENGTH; + break; + case GOT_SYNC2_14: + if (c != MTK_DIY14_ID) { + gps_mtk.error_last = GPS_MTK_ERR_OUT_OF_SYNC; + goto error; + } + gps_mtk.msg_class = c; + gps_mtk.msg_idx = 0; + gps_mtk.status++; + break; + case GOT_CLASS_14: + if (c != MTK_DIY14_NAV_ID) { + gps_mtk.error_last = GPS_MTK_ERR_OUT_OF_SYNC; + goto error; + } + gps_mtk.msg_id = c; + gps_mtk.status = GOT_ID; + break; + /* MTK_DIY_VER_16 */ + case GOT_SYNC1_16: + if (c != MTK_DIY16_NAV_ID) { + gps_mtk.error_last = GPS_MTK_ERR_OUT_OF_SYNC; + goto error; + } + if (gps_mtk.msg_available) { + /* Previous message has not yet been parsed: discard this one */ + gps_mtk.error_last = GPS_MTK_ERR_OVERRUN; + goto error; + } + gps_mtk.msg_id = c; + gps_mtk.ck_a = 0; + gps_mtk.ck_b = 0; + gps_mtk.status++; + break; + case GOT_SYNC2_16: + gps_mtk.len = c; + gps_mtk.msg_idx = 0; + gps_mtk.status = GOT_ID; + break; + case GOT_ID: + gps_mtk.msg_buf[gps_mtk.msg_idx] = c; + gps_mtk.msg_idx++; + if (gps_mtk.msg_idx >= gps_mtk.len) { + gps_mtk.status++; + } + break; + case GOT_PAYLOAD: + if (c != gps_mtk.ck_a) { + gps_mtk.error_last = GPS_MTK_ERR_CHECKSUM; + goto error; + } + gps_mtk.status++; + break; + case GOT_CHECKSUM1: + if (c != gps_mtk.ck_b) { + gps_mtk.error_last = GPS_MTK_ERR_CHECKSUM; + goto error; + } + gps_mtk.msg_available = TRUE; + goto restart; + break; + default: + gps_mtk.error_last = GPS_MTK_ERR_UNEXPECTED; + goto error; + } + return; + error: + gps_mtk.error_cnt++; + restart: + gps_mtk.status = UNINIT; + return; +} + + +/* + * + * + * GPS dynamic configuration + * + * + */ +#ifdef GPS_CONFIGURE + +static void MtkSend_CFG(char* dat) { + while (*dat != 0) GpsLink(Transmit(*dat++)); +} + +void gps_configure_uart(void) { +} + +#ifdef USER_GPS_CONFIGURE +#include USER_GPS_CONFIGURE +#else +static bool_t user_gps_configure(bool_t cpt) { + switch (cpt) { + case 0: + MtkSend_CFG(MTK_DIY_SET_BINARY); + break; + case 1: + MtkSend_CFG(MTK_DIY_OUTPUT_RATE); + return FALSE; + } + return TRUE; /* Continue, except for the last case */ +} +#endif // ! USER_GPS_CONFIGURE + +void gps_configure( void ) { + static uint32_t count=0; + /* start configuring after having received 50 bytes */ + if (count++ > 50) + gps_configuring = user_gps_configure(gps_status_config++); +} + +#endif /* GPS_CONFIGURE */ diff --git a/sw/airborne/subsystems/gps/gps_mtk.h b/sw/airborne/subsystems/gps/gps_mtk.h new file mode 100644 index 0000000000..eeffd03afd --- /dev/null +++ b/sw/airborne/subsystems/gps/gps_mtk.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2011 The Paparazzi Team + * + * 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. + */ + + +#ifndef MTK_H +#define MTK_H + +#include "mcu_periph/uart.h" + +/** Includes macros generated from mtk.xml */ +#include "mtk_protocol.h" + +#define GPS_MTK_MAX_PAYLOAD 255 + +struct GpsMtk { + bool_t msg_available; + uint8_t msg_buf[GPS_MTK_MAX_PAYLOAD] __attribute__ ((aligned)); + uint8_t msg_id; + uint8_t msg_class; + + uint8_t status; + uint16_t len; + uint8_t msg_idx; + uint8_t ck_a, ck_b; + uint8_t send_ck_a, send_ck_b; + uint8_t error_cnt; + uint8_t error_last; + + uint8_t status_flags; + uint8_t sol_flags; +}; + +extern struct GpsMtk gps_mtk; + + +/* + * This part is used by the autopilot to read data from a uart + */ +#define __GpsLink(dev, _x) dev##_x +#define _GpsLink(dev, _x) __GpsLink(dev, _x) +#define GpsLink(_x) _GpsLink(GPS_LINK, _x) + +#define GpsBuffer() GpsLink(ChAvailable()) + +#ifdef GPS_CONFIGURE +extern bool_t gps_configuring; +#define GpsConfigure() { \ + if (gps_configuring) \ + gps_configure(); \ + } +#else +#define GpsConfigure() {} +#endif + +#define GpsEvent(_sol_available_callback) { \ + if (GpsBuffer()) { \ + ReadGpsBuffer(); \ + GpsConfigure(); \ + } \ + if (gps_mtk.msg_available) { \ + gps_mtk_read_message(); \ + if (gps_mtk.msg_class == MTK_DIY14_ID && \ + gps_mtk.msg_id == MTK_DIY14_NAV_ID) { \ + if (gps.fix == GPS_FIX_3D) { \ + gps.last_fix_time = cpu_time_sec; \ + } \ + _sol_available_callback(); \ + } \ + if (gps_mtk.msg_class == MTK_DIY16_ID && \ + gps_mtk.msg_id == MTK_DIY16_NAV_ID) { \ + if (gps.fix == GPS_FIX_3D) { \ + gps.last_fix_time = cpu_time_sec; \ + } \ + _sol_available_callback(); \ + } \ + gps_mtk.msg_available = FALSE; \ + } \ + } + +#define ReadGpsBuffer() { \ + while (GpsLink(ChAvailable())&&!gps_mtk.msg_available) \ + gps_mtk_parse(GpsLink(Getch())); \ + } + + +extern void gps_mtk_read_message(void); +extern void gps_mtk_parse(uint8_t c); + +#define MTK_DIY_FIX_3D 3 +#define MTK_DIY_FIX_2D 2 +#define MTK_DIY_FIX_NONE 1 + +/* + * dynamic GPS configuration + */ +#ifdef GPS_CONFIGURE +#define MTK_DIY_SET_BINARY "$PGCMD,16,0,0,0,0,0*6A\r\n" +#define MTK_DIY_SET_NMEA "$PGCMD,16,1,1,1,1,1*6B\r\n" + +#define MTK_DIY_OUTPUT_1HZ "$PMTK220,1000*1F\r\n" +#define MTK_DIY_OUTPUT_2HZ "$PMTK220,500*2B\r\n" +#define MTK_DIY_OUTPUT_4HZ "$PMTK220,250*29\r\n" +#define MTK_DIY_OTUPUT_5HZ "$PMTK220,200*2C\r\n" +#define MTK_DIY_OUTPUT_10HZ "$PMTK220,100*2F\r\n" + +#define MTK_BAUD_RATE_38400 "$PMTK251,38400*27\r\n" + +#define MTK_DIY_SBAS_ON "$PMTK313,1*2E\r\n" +#define MTK_DIY_SBAS_OFF "$PMTK313,0*2F\r\n" + +#define MTK_DIY_WAAS_ON "$PSRF151,1*3F\r\n" +#define MTK_DIY_WAAS_OFF "$PSRF151,0*3E\r\n" + +extern void gps_configure(void); +extern void gps_configure_uart(void); +#endif + +#endif /* MTK_H */ diff --git a/sw/tools/Makefile b/sw/tools/Makefile index e0f0b33ccf..fe5f2a91fd 100644 --- a/sw/tools/Makefile +++ b/sw/tools/Makefile @@ -30,7 +30,7 @@ OCAMLNETCMA=$(shell ocamlfind query -r -a-format -predicates byte netstring) OCAMLLEX=ocamllex OCAMLYACC=ocamlyacc -all: gen_common.cmo gen_aircraft.out gen_airframe.out gen_messages2.out gen_messages.out gen_ubx.out gen_flight_plan.out gen_radio.out gen_periodic.out gen_settings.out gen_tuning.out gen_xsens.out gen_modules.out find_free_msg_id.out +all: gen_common.cmo gen_aircraft.out gen_airframe.out gen_messages2.out gen_messages.out gen_ubx.out gen_mtk.out gen_flight_plan.out gen_radio.out gen_periodic.out gen_settings.out gen_tuning.out gen_xsens.out gen_modules.out find_free_msg_id.out FP_CMO = fp_proc.cmo gen_flight_plan.cmo ABS_FP = $(FP_CMO:%=$$PAPARAZZI_SRC/sw/tools/%) diff --git a/sw/tools/gen_mtk.ml b/sw/tools/gen_mtk.ml new file mode 100644 index 0000000000..692745152d --- /dev/null +++ b/sw/tools/gen_mtk.ml @@ -0,0 +1,176 @@ +(* + * $Id$ + * + * XML preprocessing for Mediatek (DIYDrones 1.4/1.6) protocol + * + * Copyright (C) 2003 Pascal Brisset, Antoine Drouin + * + * 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. + * + *) + +open Printf + +let out = stdout + +let sizeof = function + "U4" | "I4" -> 4 + | "U2" | "I2" -> 2 + | "U1" | "I1" -> 1 + | "U4BE" | "I4BE" -> 4 + | "U2BE" | "I2BE" -> 2 + | x -> failwith (sprintf "sizeof: unknown format '%s'" x) + +let (+=) = fun r x -> r := !r + x + +let c_type = fun format -> + match format with + "I2" -> "int16_t" + | "I4" -> "int32_t" + | "U2" -> "uint16_t" + | "U4" -> "uint32_t" + | "U1" -> "uint8_t" + | "I1" -> "int8_t" + | "I2BE" -> "int16_t" + | "I4BE" -> "int32_t" + | "U2BE" -> "uint16_t" + | "U4BE" -> "uint32_t" + | _ -> failwith (sprintf "Gen_mtk.c_type: unknown format '%s'" format) + +let get_at = fun offset format block_size -> + let t = c_type format in + let block_offset = + if block_size = 0 then "" else sprintf "+%d*_mtk_block" block_size in + match format with + "U4" | "I4" -> sprintf "(%s)(*((uint8_t*)_mtk_payload+%d%s)|*((uint8_t*)_mtk_payload+1+%d%s)<<8|((%s)*((uint8_t*)_mtk_payload+2+%d%s))<<16|((%s)*((uint8_t*)_mtk_payload+3+%d%s))<<24)" t offset block_offset offset block_offset t offset block_offset t offset block_offset + | "U2" | "I2" -> sprintf "(%s)(*((uint8_t*)_mtk_payload+%d%s)|*((uint8_t*)_mtk_payload+1+%d%s)<<8)" t offset block_offset offset block_offset + | "U1" | "I1" -> sprintf "(%s)(*((uint8_t*)_mtk_payload+%d%s))" t offset block_offset + | "U4BE" | "I4BE" -> sprintf "(%s)(*((uint8_t*)_mtk_payload+3+%d%s)|*((uint8_t*)_mtk_payload+2+%d%s)<<8|((%s)*((uint8_t*)_mtk_payload+1+%d%s))<<16|((%s)*((uint8_t*)_mtk_payload+%d%s))<<24)" t offset block_offset offset block_offset t offset block_offset t offset block_offset + | "U2BE" | "I2BE" -> sprintf "(%s)(*((uint8_t*)_mtk_payload+1+%d%s)|*((uint8_t*)_mtk_payload+%d%s)<<8)" t offset block_offset offset block_offset + | _ -> failwith (sprintf "Gen_mtk.c_type: unknown format '%s'" format) + +let define = fun x y -> + fprintf out "#define %s %s\n" x y + +exception Length_error of Xml.xml*int*int + + + + +let parse_message = fun class_name m -> + let msg_name = Xml.attrib m "name" in + + fprintf out "\n"; + let msg_id = sprintf "MTK_%s_%s_ID" class_name msg_name in + define msg_id (Xml.attrib m "ID"); + + let field_name = fun f -> ExtXml.attrib f "name" in + let format = fun f -> Xml.attrib f "format" in + + let offset = ref 0 in + let rec gen_access_macro = fun block_size f -> + match Xml.tag f with + "field" -> + let fn = field_name f + and fmt = format f in + let block_no = if block_size = 0 then "" else ",_mtk_block" in + define (sprintf "MTK_%s_%s_%s(_mtk_payload%s)" class_name msg_name fn block_no) (get_at !offset fmt block_size); + offset += sizeof fmt + | "block" -> + let s = int_of_string (Xml.attrib f "length") in + let o = !offset in + List.iter (gen_access_macro s) (Xml.children f); + let s' = !offset - o in + if s <> s' then raise (Length_error (f, s, s')) + | x -> failwith ("Unexpected field: " ^ x) + in + + List.iter (gen_access_macro 0) (Xml.children m); + begin + try + let l = int_of_string (Xml.attrib m "length") in + if l <> !offset then raise (Length_error (m, l, !offset)) + with + Xml.No_attribute("length") -> () (** Undefined length authorized *) + end; + + (** Generating send function *) + let param_name = fun f -> String.lowercase (field_name f) in + let rec param_names = fun f r -> + if Xml.tag f = "field" then + param_name f :: r + else + List.fold_right param_names (Xml.children f) r in + let param_type = fun f -> c_type (format f) in + fprintf out "\n#define MtkSend_%s_%s(" class_name msg_name; + fprintf out "%s" (String.concat "," (param_names m [])); + fprintf out ") { \\\n"; + fprintf out " MtkHeader(MTK_%s_ID, %s, %d);\\\n" class_name msg_id !offset; + let rec send_one_field = fun f -> + match Xml.tag f with + "field" -> + let s = sizeof (format f) in + let p = param_name f in + let t = param_type f in + fprintf out " %s _%s = %s; MtkSend%dByAddr((uint8_t*)&_%s);\\\n" t p p s p + | "block" -> + List.iter send_one_field (Xml.children f) + | _ -> assert (false) in + List.iter send_one_field (Xml.children m); + fprintf out " MtkTrailer();\\\n"; + fprintf out "}\n\n#define MTK_%s_%s_LENGTH %d\n" class_name msg_name !offset + + +let parse_class = fun c -> + let _class_id = int_of_string (Xml.attrib c "id") + and class_name = Xml.attrib c "name" in + + fprintf out "\n"; + define (sprintf "MTK_%s_ID" class_name) (Xml.attrib c "ID"); + + List.iter (parse_message class_name) (Xml.children c) + + +let _ = + if Array.length Sys.argv <> 2 then begin + failwith (sprintf "Usage: %s <.xml mtk protocol file>" Sys.argv.(0)) + end; + let xml_file = Sys.argv.(1) in + try + let xml = Xml.parse_file xml_file in + fprintf out "/* Generated from %s */\n" xml_file; + fprintf out "/* Please DO NOT EDIT */\n\n"; + + define "MTK_DIY14_SYNC1" "0xB5"; + define "MTK_DIY14_SYNC2" "0x62"; + + List.iter parse_class (Xml.children xml) + with + Xml.Error (em, ep) -> + let l = Xml.line ep + and c1, c2 = Xml.range ep in + fprintf stderr "File \"%s\", line %d, characters %d-%d:\n" xml_file l c1 c2; + fprintf stderr "%s\n" (Xml.error_msg em); + exit 1 + | Length_error (m, l1, l2) -> + fprintf stderr "File \"%s\", inconsistent length: %d expected, %d found from fields in message:\n %s\n" xml_file l1 l2 (Xml.to_string_fmt m); + exit 1 + | Dtd.Check_error e -> + fprintf stderr "File \"%s\", DTD check error: %s\n" xml_file (Dtd.check_error e) + | Dtd.Prove_error e -> + fprintf stderr "\nFile \"%s\", DTD check error: %s\n\n" xml_file (Dtd.prove_error e) From eb24667ab623c2c38303e01f3c3888bd8df797d8 Mon Sep 17 00:00:00 2001 From: Stephen Dwyer Date: Sun, 24 Jul 2011 20:44:44 -0600 Subject: [PATCH 11/16] added conditional compile for ivy bus address in jsbsim fixedwing sim, darwin or linux --- sw/simulator/sim_ac_jsbsim.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sw/simulator/sim_ac_jsbsim.c b/sw/simulator/sim_ac_jsbsim.c index 55f66a17a8..a72840fd36 100644 --- a/sw/simulator/sim_ac_jsbsim.c +++ b/sw/simulator/sim_ac_jsbsim.c @@ -57,7 +57,11 @@ static void sim_parse_options(int argc, char** argv); static void sim_init(void); static gboolean sim_periodic(gpointer data); +#ifdef __APPLE__ +string ivyBus = "224.255.255.255"; +#else string ivyBus = "127.255.255.255"; +#endif string fgAddress = "127.0.0.1"; static void ivy_transport_init(void); From ce86defece1ac45576348794fb6a3a078f55e852 Mon Sep 17 00:00:00 2001 From: Felix Ruess Date: Tue, 26 Jul 2011 22:59:06 +0200 Subject: [PATCH 12/16] updated settings and added raw and scaled telemetry modes for default_fixedwing_imu --- conf/settings/basic.xml | 8 ++--- conf/settings/basic_ins.xml | 33 +++++++++++++++++++++ conf/settings/ins_basic.xml | 1 + conf/settings/tuning.xml | 4 +-- conf/settings/tuning_basic_ins.xml | 4 +-- conf/settings/tuning_ins.xml | 4 +-- conf/telemetry/default_fixedwing_imu.xml | 37 +++++++++++++++++------- 7 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 conf/settings/basic_ins.xml diff --git a/conf/settings/basic.xml b/conf/settings/basic.xml index 767f0659f7..bb455f1b11 100644 --- a/conf/settings/basic.xml +++ b/conf/settings/basic.xml @@ -10,10 +10,10 @@ - + - - + + @@ -21,7 +21,7 @@ - + diff --git a/conf/settings/basic_ins.xml b/conf/settings/basic_ins.xml new file mode 100644 index 0000000000..f11281ab82 --- /dev/null +++ b/conf/settings/basic_ins.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/settings/ins_basic.xml b/conf/settings/ins_basic.xml index 386a15c7db..fee795e317 100644 --- a/conf/settings/ins_basic.xml +++ b/conf/settings/ins_basic.xml @@ -1,5 +1,6 @@ +use other file diff --git a/conf/settings/tuning.xml b/conf/settings/tuning.xml index 22ac1e1d7c..cea85bacb2 100644 --- a/conf/settings/tuning.xml +++ b/conf/settings/tuning.xml @@ -17,8 +17,8 @@ - - + + diff --git a/conf/settings/tuning_basic_ins.xml b/conf/settings/tuning_basic_ins.xml index 0d84278f26..1f092a4a56 100644 --- a/conf/settings/tuning_basic_ins.xml +++ b/conf/settings/tuning_basic_ins.xml @@ -17,8 +17,8 @@ - - + + diff --git a/conf/settings/tuning_ins.xml b/conf/settings/tuning_ins.xml index 2cf8fe880b..4ba4f43d96 100644 --- a/conf/settings/tuning_ins.xml +++ b/conf/settings/tuning_ins.xml @@ -17,8 +17,8 @@ - - + + diff --git a/conf/telemetry/default_fixedwing_imu.xml b/conf/telemetry/default_fixedwing_imu.xml index 256cb30917..7aa765f25b 100644 --- a/conf/telemetry/default_fixedwing_imu.xml +++ b/conf/telemetry/default_fixedwing_imu.xml @@ -53,6 +53,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -71,17 +97,6 @@ - - - - - - - - - - - From e43182449344dfa57d8e82c906c6308c7747f8ec Mon Sep 17 00:00:00 2001 From: Felix Ruess Date: Tue, 26 Jul 2011 23:21:03 +0200 Subject: [PATCH 13/16] ups, removed accidental text again --- conf/settings/ins_basic.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/settings/ins_basic.xml b/conf/settings/ins_basic.xml index fee795e317..386a15c7db 100644 --- a/conf/settings/ins_basic.xml +++ b/conf/settings/ins_basic.xml @@ -1,6 +1,5 @@ -use other file From 1bf2335fe21d9df55b888990aa61c364f8dc9e10 Mon Sep 17 00:00:00 2001 From: Felix Ruess Date: Tue, 26 Jul 2011 23:31:17 +0200 Subject: [PATCH 14/16] fix imu messages in default_fixedwing_imu.xml --- conf/telemetry/default_fixedwing_imu.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/conf/telemetry/default_fixedwing_imu.xml b/conf/telemetry/default_fixedwing_imu.xml index 7aa765f25b..28e3f604b0 100644 --- a/conf/telemetry/default_fixedwing_imu.xml +++ b/conf/telemetry/default_fixedwing_imu.xml @@ -70,14 +70,13 @@ - - - - + + + From f79dd3de5653c95fd7eef2e990a28e9fc024376d Mon Sep 17 00:00:00 2001 From: Felix Ruess Date: Wed, 27 Jul 2011 00:44:00 +0200 Subject: [PATCH 15/16] renamed tuning_ins settings files, now tuning_ins.xml should be standard one for everyone, tuning_ins_dcm.xml for debugging ahrs_dcm as well --- conf/settings/tuning_ins.xml | 5 +---- conf/settings/{tuning_basic_ins.xml => tuning_ins_dcm.xml} | 5 ++++- 2 files changed, 5 insertions(+), 5 deletions(-) rename conf/settings/{tuning_basic_ins.xml => tuning_ins_dcm.xml} (94%) diff --git a/conf/settings/tuning_ins.xml b/conf/settings/tuning_ins.xml index 4ba4f43d96..1f092a4a56 100644 --- a/conf/settings/tuning_ins.xml +++ b/conf/settings/tuning_ins.xml @@ -18,7 +18,7 @@ - + @@ -32,9 +32,6 @@ - - - diff --git a/conf/settings/tuning_basic_ins.xml b/conf/settings/tuning_ins_dcm.xml similarity index 94% rename from conf/settings/tuning_basic_ins.xml rename to conf/settings/tuning_ins_dcm.xml index 1f092a4a56..4ba4f43d96 100644 --- a/conf/settings/tuning_basic_ins.xml +++ b/conf/settings/tuning_ins_dcm.xml @@ -18,7 +18,7 @@ - + @@ -32,6 +32,9 @@ + + + From 4746fe38d8f83cb693465eaacf40d89ab0ad7258 Mon Sep 17 00:00:00 2001 From: Felix Ruess Date: Wed, 27 Jul 2011 00:45:47 +0200 Subject: [PATCH 16/16] renamed flag NPS to USE_NPS, ifdef USE_NPS around nps specific funtions in imu_b2 sim file --- conf/autopilot/subsystems/rotorcraft/fdm_nps.makefile | 2 +- sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.c | 2 ++ sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.h | 3 ++- sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.c | 6 +++--- sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.h | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/conf/autopilot/subsystems/rotorcraft/fdm_nps.makefile b/conf/autopilot/subsystems/rotorcraft/fdm_nps.makefile index 51e0e4c1ce..fec5b73817 100644 --- a/conf/autopilot/subsystems/rotorcraft/fdm_nps.makefile +++ b/conf/autopilot/subsystems/rotorcraft/fdm_nps.makefile @@ -17,7 +17,7 @@ NPSDIR = $(SIMDIR)/nps sim.ARCHDIR = $(ARCH) -sim.CFLAGS += -DSITL -DNPS +sim.CFLAGS += -DSITL -DUSE_NPS sim.CFLAGS += `pkg-config glib-2.0 --cflags` -I /usr/include/meschach sim.LDFLAGS += `pkg-config glib-2.0 --libs` -lm -lpcre -lglibivy -lgsl -lgslcblas sim.CFLAGS += -I$(NPSDIR) -I$(SRC_FIRMWARE) -I$(SRC_BOARD) -I../simulator -I$(PAPARAZZI_HOME)/conf/simulator/nps diff --git a/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.c b/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.c index e486ebbc38..e680ebc675 100644 --- a/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.c +++ b/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.c @@ -35,6 +35,7 @@ void imu_periodic(void) { } +#ifdef USE_NPS #include "nps_sensors.h" void imu_feed_gyro_accel(void) { @@ -61,3 +62,4 @@ void imu_feed_mag(void) { ami601_status = AMI601_DATA_AVAILABLE; #endif } +#endif //USE_NPS diff --git a/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.h b/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.h index 8ef38139af..025acd33bf 100644 --- a/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.h +++ b/sw/airborne/arch/sim/subsystems/imu/imu_b2_arch.h @@ -31,8 +31,9 @@ extern int imu_overrun; +#ifdef USE_NPS extern void imu_feed_gyro_accel(void); extern void imu_feed_mag(void); - +#endif #endif /* IMU_B2_HW_H */ diff --git a/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.c b/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.c index de1a37d3d7..be462fc82b 100644 --- a/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.c +++ b/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.c @@ -28,7 +28,7 @@ #include #include -#ifdef NPS +#ifdef USE_NPS #include "nps_radio_control.h" #endif @@ -55,7 +55,7 @@ value send_ppm(value unit) { return unit; } -#ifdef NPS +#ifdef USE_NPS #define PPM_OF_NPS(_nps, _neutral, _min, _max) \ ((_nps) >= 0 ? (_neutral) + (_nps) * ((_max)-(_neutral)) : (_neutral) + (_nps) * ((_neutral)- (_min))) @@ -94,7 +94,7 @@ value send_ppm(value unit) { return unit; } -#ifdef NPS +#ifdef USE_NPS void radio_control_feed(void) {} #endif diff --git a/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.h b/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.h index 5f9bfd681d..c0f27a3b5e 100644 --- a/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.h +++ b/sw/airborne/arch/sim/subsystems/radio_control/ppm_arch.h @@ -36,7 +36,7 @@ #define PPM_NB_CHANNEL RADIO_CONTROL_NB_CHANNEL -#ifdef NPS +#ifdef USE_NPS extern void radio_control_feed(void); #endif