X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fkernel%2Fao_data.h;h=4fc9db8f16a7810ba8b54c89619bf9331f97608e;hb=HEAD;hp=6ee0965d4e732ed4ce25adec78ac11231942356e;hpb=b540f6f5b034f33b8e1d1c3b91e2403a56479caa;p=fw%2Faltos diff --git a/src/kernel/ao_data.h b/src/kernel/ao_data.h index 6ee0965d..a6ae6fa8 100644 --- a/src/kernel/ao_data.h +++ b/src/kernel/ao_data.h @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -40,6 +41,13 @@ #define AO_DATA_MPU6000 0 #endif +#if HAS_MPU9250 +#include +#define AO_DATA_MPU9250 (1 << 2) +#else +#define AO_DATA_MPU9250 0 +#endif + #if HAS_HMC5883 #include #define AO_DATA_HMC5883 (1 << 3) @@ -47,6 +55,13 @@ #define AO_DATA_HMC5883 0 #endif +#if HAS_MMC5983 +#include +#define AO_DATA_MMC5983 (1 << 3) +#else +#define AO_DATA_MMC5983 0 +#endif + #if HAS_MMA655X #include #define AO_DATA_MMA655X (1 << 4) @@ -54,12 +69,50 @@ #define AO_DATA_MMA655X 0 #endif +#if HAS_ADXL375 +#include +#define AO_DATA_ADXL375 (1 << 4) +#else +#define AO_DATA_ADXL375 0 +#endif + +#if HAS_MAX6691 +#include +#define AO_DATA_MAX6691 (1 << 4) +#else +#define AO_DATA_MAX6691 0 +#endif + +#if HAS_BMX160 +#include +#define AO_DATA_BMX160 (1 << 2) +#else +#define AO_DATA_BMX160 0 +#endif + +#if HAS_BMI088 +#include +#define AO_DATA_BMI088 (1 << 2) +#else +#define AO_DATA_BMI088 0 +#endif + +#ifndef HAS_SENSOR_ERRORS +#if HAS_IMU || HAS_MMA655X || HAS_MS5607 || HAS_MS5611 +#define HAS_SENSOR_ERRORS 1 +#endif +#endif + +#if HAS_SENSOR_ERRORS +extern uint8_t ao_sensor_errors; +#endif + #ifdef AO_DATA_RING -#define AO_DATA_ALL (AO_DATA_ADC|AO_DATA_MS5607|AO_DATA_MPU6000|AO_DATA_HMC5883|AO_DATA_MMA655X) +#define AO_DATA_ALL (AO_DATA_ADC|AO_DATA_MS5607|AO_DATA_MPU6000|AO_DATA_HMC5883|AO_DATA_MMA655X|AO_DATA_MPU9250|AO_DATA_ADXL375|AO_DATA_BMX160|AO_DATA_MMC5983|AO_DATA_BMI088) struct ao_data { - uint16_t tick; + AO_TICK_TYPE tick; #if HAS_ADC struct ao_adc adc; #endif @@ -73,12 +126,42 @@ struct ao_data { int16_t z_accel; #endif #endif +#if HAS_MPU9250 + struct ao_mpu9250_sample mpu9250; +#if !HAS_MMA655X + int16_t z_accel; +#endif +#endif #if HAS_HMC5883 struct ao_hmc5883_sample hmc5883; #endif +#if HAS_MMC5983 + struct ao_mmc5983_sample mmc5983; +#endif #if HAS_MMA655X uint16_t mma655x; #endif +#if HAS_ADXL375 + struct ao_adxl375_sample adxl375; +#endif +#if HAS_MAX6691 + struct ao_max6691_sample max6691; +#endif +#if HAS_ADS131A0X + struct ao_ads131a0x_sample ads131a0x; +#endif +#if HAS_BMX160 + struct ao_bmx160_sample bmx160; +#if !HAS_ADXL375 + int16_t z_accel; +#endif +#endif +#if HAS_BMI088 + struct ao_bmi088_sample bmi088; +#if !HAS_ADXL375 + int16_t z_accel; +#endif +#endif }; #define ao_data_ring_next(n) (((n) + 1) & (AO_DATA_RING - 1)) @@ -86,28 +169,36 @@ struct ao_data { /* Get a copy of the last complete sample set */ void -ao_data_get(__xdata struct ao_data *packet); +ao_data_get(struct ao_data *packet); -extern volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; -extern volatile __data uint8_t ao_data_head; -extern volatile __data uint8_t ao_data_present; -extern volatile __data uint8_t ao_data_count; +extern volatile struct ao_data ao_data_ring[AO_DATA_RING]; +extern volatile uint8_t ao_data_head; +extern volatile uint8_t ao_data_present; +extern volatile uint8_t ao_data_count; /* * Mark a section of data as ready, check for data complete */ #define AO_DATA_PRESENT(bit) (ao_data_present |= (bit)) +/* + * Mark sensor failed, and unblock the sample collection code by + * marking the data as present + */ +#define AO_SENSOR_ERROR(bit) (ao_data_present |= (ao_sensor_errors |= (bit))) + /* * Wait until it is time to write a sensor sample; this is * signaled by the timer tick */ -#define AO_DATA_WAIT() do { \ - ao_sleep(DATA_TO_XDATA ((void *) &ao_data_count)); \ - } while (0) +#define AO_DATA_WAIT() ao_sleep((void *) &ao_data_count) #endif /* AO_DATA_RING */ +#define AO_ALT_TYPE int32_t + +typedef AO_ALT_TYPE alt_t; + #if !HAS_BARO && HAS_MS5607 /* Either an MS5607 or an MS5611 hooked to a SPI port @@ -117,39 +208,19 @@ extern volatile __data uint8_t ao_data_count; typedef int32_t pres_t; -#define AO_ALT_TYPE int32_t - -typedef AO_ALT_TYPE alt_t; - #define ao_data_pres_cook(packet) ao_ms5607_convert(&packet->ms5607_raw, &packet->ms5607_cooked) #define ao_data_pres(packet) ((packet)->ms5607_cooked.pres) -#define ao_data_temp(packet) ((packet)->ms5607_cooked.temp) +#define ao_data_temp(packet) ((int16_t) (packet)->ms5607_cooked.temp) #define pres_to_altitude(p) ao_pa_to_altitude(p) #endif -#if !HAS_BARO && HAS_ADC - -#define HAS_BARO 1 - -typedef int16_t pres_t; -typedef int16_t alt_t; - -#define ao_data_pres(packet) ((packet)->adc.pres) -#define ao_data_temp(packet) ((packet)->adc.temp) -#define pres_to_altitude(p) ao_pres_to_altitude(p) -#define ao_data_pres_cook(p) - -#endif - /* * Need a few macros to pull data from the sensors: * - * ao_data_accel_sample - pull raw sensor and convert to normalized values - * ao_data_accel - pull normalized value (lives in the same memory) - * ao_data_set_accel - store normalized value back in the sensor location + * ao_data_accel_raw - pull raw sensor * ao_data_accel_invert - flip rocket ends for positive acceleration */ @@ -161,8 +232,7 @@ typedef int16_t alt_t; */ typedef int16_t accel_t; -#define ao_data_accel(packet) ((packet)->adc.accel) -#define ao_data_set_accel(packet, a) ((packet)->adc.accel = (a)) +#define ao_data_accel_raw(packet) ((packet)->adc.accel) #define ao_data_accel_invert(a) (0x7fff -(a)) /* @@ -248,12 +318,12 @@ typedef int16_t accel_t; #if HAS_ACCEL_REF -#define ao_data_accel_cook(packet) \ +#define ao_data_accel_raw(packet) \ ((uint16_t) ((((uint32_t) (packet)->adc.accel << 16) / ((packet)->adc.accel_ref << 1))) >> 1) #else -#define ao_data_accel_cook(packet) ((packet)->adc.accel) +#define ao_data_accel_raw(packet) ((packet)->adc.accel) #endif /* HAS_ACCEL_REF */ @@ -273,29 +343,49 @@ typedef int16_t accel_t; #error AO_MMA655X_INVERT not defined #endif -#define ao_data_accel(packet) ((packet)->mma655x) #if AO_MMA655X_INVERT -#define ao_data_accel_cook(packet) (AO_ACCEL_INVERT - (packet)->mma655x) +#define ao_data_accel_raw(packet) ((accel_t) (AO_ACCEL_INVERT - (packet)->mma655x)) #else -#define ao_data_accel_cook(packet) ((packet)->mma655x) +#define ao_data_accel_raw(packet) ((accel_t) (packet)->mma655x) #endif -#define ao_data_set_accel(packet, accel) ((packet)->mma655x = (accel)) #define ao_data_accel_invert(accel) (AO_ACCEL_INVERT - (accel)) #endif -#if !HAS_ACCEL && HAS_MPU6000 +#if !HAS_ACCEL && HAS_ADXL375 #define HAS_ACCEL 1 -#define AO_ACCEL_INVERT 0 +typedef int16_t accel_t; + +#ifndef AO_ADXL375_INVERT +#error AO_ADXL375_INVERT not defined +#endif + +#if AO_ADXL375_INVERT +#define ao_data_accel_raw(packet) (-(packet)->adxl375.AO_ADXL375_AXIS) +#else +#define ao_data_accel_raw(packet) ((packet)->adxl375.AO_ADXL375_AXIS) +#endif +#define ao_data_accel_invert(accel) (-(accel)) + +#if USE_ADXL375_IMU +#define ao_data_along(packet) ((packet)->adxl375.AO_ADXL375_AXIS) +#define ao_data_across(packet) ((packet)->adxl375.AO_ADXL375_ACROSS_AXIS) +#define ao_data_through(packet) ((packet)->adxl375.z) +#define ao_data_accel_to_sample(accel) ao_adxl375_accel_to_sample(accel) +#endif + +#endif /* HAS_ADXL375 */ + +#if !HAS_ACCEL && HAS_MPU6000 + +#define HAS_ACCEL 1 typedef int16_t accel_t; /* MPU6000 is hooked up so that positive y is positive acceleration */ -#define ao_data_accel(packet) ((packet)->z_accel) -#define ao_data_accel_cook(packet) (-(packet)->mpu6000.accel_y) -#define ao_data_set_accel(packet, accel) ((packet)->z_accel = (accel)) +#define ao_data_accel_raw(packet) (-(packet)->mpu6000.accel_y) #define ao_data_accel_invert(a) (-(a)) #endif @@ -311,6 +401,7 @@ typedef int16_t angle_t; /* in degrees */ /* X axis is aligned in the other board axis (across) */ /* Z axis is aligned perpendicular to the board (through) */ +#ifndef ao_data_along #define ao_data_along(packet) ((packet)->mpu6000.accel_y) #define ao_data_across(packet) ((packet)->mpu6000.accel_x) #define ao_data_through(packet) ((packet)->mpu6000.accel_z) @@ -318,6 +409,132 @@ typedef int16_t angle_t; /* in degrees */ #define ao_data_roll(packet) ((packet)->mpu6000.gyro_y) #define ao_data_pitch(packet) ((packet)->mpu6000.gyro_x) #define ao_data_yaw(packet) ((packet)->mpu6000.gyro_z) +#endif + +static inline float ao_convert_gyro(float sensor) +{ + return ao_mpu6000_gyro(sensor); +} + +static inline float ao_convert_accel(int16_t sensor) +{ + return ao_mpu6000_accel(sensor); +} + +#endif + +#if !HAS_ACCEL && HAS_MPU9250 + +#define HAS_ACCEL 1 + +typedef int16_t accel_t; + +/* MPU9250 is hooked up so that positive y is positive acceleration */ +#define ao_data_accel_raw(packet) (-(packet)->mpu9250.accel_y) +#define ao_data_accel_invert(a) (-(a)) + +#endif + +#if !HAS_GYRO && HAS_MPU9250 + +#define HAS_GYRO 1 + +typedef int16_t gyro_t; /* in raw sample units */ +typedef int16_t angle_t; /* in degrees */ + +/* Y axis is aligned with the direction of motion (along) */ +/* X axis is aligned in the other board axis (across) */ +/* Z axis is aligned perpendicular to the board (through) */ + +#ifndef ao_data_along +#define ao_data_along(packet) ((packet)->mpu9250.accel_y) +#define ao_data_across(packet) ((packet)->mpu9250.accel_x) +#define ao_data_through(packet) ((packet)->mpu9250.accel_z) + +#define ao_data_roll(packet) ((packet)->mpu9250.gyro_y) +#define ao_data_pitch(packet) ((packet)->mpu9250.gyro_x) +#define ao_data_yaw(packet) ((packet)->mpu9250.gyro_z) +#endif + +static inline float ao_convert_gyro(float sensor) +{ + return ao_mpu9250_gyro(sensor); +} + +static inline float ao_convert_accel(int16_t sensor) +{ + return ao_mpu9250_accel(sensor); +} + +#endif + +#if !HAS_ACCEL && HAS_BMX160 + +#define HAS_ACCEL 1 + +typedef int16_t accel_t; + +#define ao_data_accel_raw(packet) -ao_data_along(packet) +#define ao_data_accel_invert(a) (-(a)) +#define ao_data_accel_to_sample(accel) ao_bmx_accel_to_sample(accel) + +#endif + +#if !HAS_GYRO && HAS_BMX160 + +#define HAS_GYRO 1 + +typedef int16_t gyro_t; /* in raw sample units */ +typedef int16_t angle_t; /* in degrees */ + +/* X axis is aligned with the direction of motion (along) */ +/* Y axis is aligned in the other board axis (across) */ +/* Z axis is aligned perpendicular to the board (through) */ + +static inline float ao_convert_gyro(float sensor) +{ + return ao_bmx160_gyro(sensor); +} + +static inline float ao_convert_accel(int16_t sensor) +{ + return ao_bmx160_accel(sensor); +} + +#endif + +#if !HAS_ACCEL && HAS_BMI088 + +#define HAS_ACCEL 1 + +typedef int16_t accel_t; + +#define ao_data_accel_raw(packet) -ao_data_along(packet) +#define ao_data_accel_invert(a) (-(a)) +#define ao_data_accel_to_sample(accel) ao_bmi_accel_to_sample(accel) + +#endif + +#if !HAS_GYRO && HAS_BMI088 + +#define HAS_GYRO 1 + +typedef int16_t gyro_t; /* in raw sample units */ +typedef int16_t angle_t; /* in degrees */ + +/* X axis is aligned with the direction of motion (along) */ +/* Y axis is aligned in the other board axis (across) */ +/* Z axis is aligned perpendicular to the board (through) */ + +static inline float ao_convert_gyro(float sensor) +{ + return ao_bmi088_gyro(sensor); +} + +static inline float ao_convert_accel(int16_t sensor) +{ + return ao_bmi088_accel(sensor); +} #endif @@ -333,4 +550,82 @@ typedef int16_t ao_mag_t; /* in raw sample units */ #endif +#if !HAS_MAG && HAS_MMC5983 + +#define HAS_MAG 1 + +typedef int16_t ao_mag_t; /* in raw sample units */ + +#endif + +#if !HAS_MAG && HAS_MPU9250 + +#define HAS_MAG 1 + +typedef int16_t ao_mag_t; /* in raw sample units */ + +/* Note that this order is different from the accel and gyro. For some + * reason, the mag sensor axes aren't the same as the other two + * sensors. Also, the Z axis is flipped in sign. + */ + +#ifndef ao_data_mag_along +#define ao_data_mag_along(packet) ((packet)->mpu9250.mag_x) +#define ao_data_mag_across(packet) ((packet)->mpu9250.mag_y) +#define ao_data_mag_through(packet) ((packet)->mpu9250.mag_z) +#endif + +#endif + +#ifdef AO_DATA_RING + +static inline void +ao_data_fill(int head) { + if (ao_data_present == AO_DATA_ALL) { +#if HAS_MS5607 + ao_data_ring[head].ms5607_raw = ao_ms5607_current; +#endif +#if HAS_MMA655X + ao_data_ring[head].mma655x = ao_mma655x_current; +#endif +#if HAS_HMC5883 + ao_data_ring[head].hmc5883 = ao_hmc5883_current; +#endif +#if HAS_MMC5983 + ao_data_ring[head].mmc5983 = ao_mmc5983_current; +#endif +#if HAS_MPU6000 + ao_data_ring[head].mpu6000 = ao_mpu6000_current; +#endif +#if HAS_MPU9250 + ao_data_ring[head].mpu9250 = ao_mpu9250_current; +#endif +#if HAS_ADXL375 + ao_data_ring[head].adxl375 = ao_adxl375_current; +#endif +#if HAS_MAX6691 + ao_data_ring[head].max6691 = ao_max6691_current; +#endif +#if HAS_ADS131A0X + ao_data_ring[head].ads131a0x = ao_ads131a0x_current; +#endif +#if HAS_BMX160 + ao_data_ring[head].bmx160 = ao_bmx160_current; +#endif +#if HAS_BMI088 + ao_data_ring[head].bmi088 = ao_bmi088_current; +#endif + ao_data_ring[head].tick = ao_tick_count; + ao_data_head = ao_data_ring_next(head); + ao_wakeup((void *) &ao_data_head); + } +} + +#endif + +#if HAS_ACCEL +accel_t +ao_data_accel(volatile struct ao_data *packet); +#endif + #endif /* _AO_DATA_H_ */