use eeprom to store calibration parameters

This commit is contained in:
Olaf Rempel 2008-03-11 23:13:00 +01:00
parent a8256718ab
commit 24b566fc7e
5 changed files with 68 additions and 11 deletions

View File

@ -5,6 +5,8 @@
#define RC_CAL_START 0 #define RC_CAL_START 0
#define RC_CAL_END 1 #define RC_CAL_END 1
#define RC_CAL_LOAD 2
#define RC_CAL_SAVE 3
struct rc_values { struct rc_values {
int16_t chan[MAX_CHANNELS]; int16_t chan[MAX_CHANNELS];

View File

@ -58,6 +58,19 @@ struct blmc_param {
uint16_t crc16; uint16_t crc16;
} __attribute__ ((packed)); } __attribute__ ((packed));
#define EE_PARAMETER_SET_START 0x0000
/* remote control calibration data */
#define EE_RC_CAL_DATA (EE_PARAMETER_SET_START)
#define EE_RC_CAL_DATA_SIZE 48
/* ACC calibration data */
#define EE_ACC_CAL_DATA (EE_RC_CAL_DATA + EE_RC_CAL_DATA_SIZE)
#define EE_ACC_CAL_DATA_SIZE 6
#define EE_PARAMETER_SET_END (EE_ACC_CAL_DATA + EE_ACC_CAL_DATA_SIZE)
struct twi_cmd { struct twi_cmd {
uint32_t cmd; /* cmd byte(s) */ uint32_t cmd; /* cmd byte(s) */
uint8_t mode; /* read/write, cmdlen (1-3 bytes) */ uint8_t mode; /* read/write, cmdlen (1-3 bytes) */

11
main.c
View File

@ -58,6 +58,7 @@ static uint32_t stick_timer_cb(struct pitc_timer *timer)
stick_cal_count--; stick_cal_count--;
if (stick_cal_count == 0) { if (stick_cal_count == 0) {
rcontrol_calibrate(RC_CAL_END); rcontrol_calibrate(RC_CAL_END);
rcontrol_calibrate(RC_CAL_SAVE);
rcontrol_print_cal(); rcontrol_print_cal();
global_state &= ~STICK_CALIBRATION; global_state &= ~STICK_CALIBRATION;
} }
@ -135,21 +136,23 @@ int main(void)
/* timer */ /* timer */
at91_pitc_init(); at91_pitc_init();
at91_rttc_test_init(); at91_rttc_test_init();
at91_tc1_init();
/* twi */ /* twi */
at91_twi_init(); at91_twi_init();
at91_twi_test(); at91_twi_test();
/* remote control, needs twi */
at91_tc1_init();
/* usb */ /* usb */
at91_udp_init(); at91_udp_init();
printf("static alloc: %5ld bytes\n\r", static_alloc_used()); /* adc, need timer, twi */
/* adc, need timer */
at91_adc_init(); at91_adc_init();
pitc_schedule_timer(&stick_timer); pitc_schedule_timer(&stick_timer);
printf("static alloc: %5ld bytes\n\r", static_alloc_used());
while (1); while (1);
} }

View File

@ -23,8 +23,7 @@
#include "board.h" #include "board.h"
#include "at91_adc.h" #include "at91_adc.h"
#include "at91_pitc.h" #include "at91_pitc.h"
#include "at91_twi.h"
#include "fixed.h"
#define ADC_CAL_COUNT 1024 #define ADC_CAL_COUNT 1024
@ -32,6 +31,11 @@ static uint16_t adc_tmp[7];
static int16_t adc_result[7]; static int16_t adc_result[7];
static uint16_t adc_offset[6]; static uint16_t adc_offset[6];
/* check eeprom parameter size (3x uint16_t) */
#if ((3 * 2) != EE_ACC_CAL_DATA_SIZE)
#error "invalid EE_ACC_CAL_DATA_SIZE"
#endif
static uint32_t adc_cal_count; static uint32_t adc_cal_count;
volatile static uint32_t adc_cal_mode; volatile static uint32_t adc_cal_mode;
static uint32_t adc_cal_data[3]; static uint32_t adc_cal_data[3];
@ -82,7 +86,7 @@ static uint32_t adc_calibrate_cb(struct pitc_timer *timer)
adc_offset[ADC_GYRO_NICK] = adc_cal_data[1]; adc_offset[ADC_GYRO_NICK] = adc_cal_data[1];
adc_offset[ADC_GYRO_YAW] = adc_cal_data[2]; adc_offset[ADC_GYRO_YAW] = adc_cal_data[2];
// TODO: check for invalid values (not centered) -> return value? // TODO: check for invalid values (not centered)
printf("GYRO offsets: %4d/%4d/%4d\n\r", printf("GYRO offsets: %4d/%4d/%4d\n\r",
adc_offset[ADC_GYRO_ROLL], adc_offset[ADC_GYRO_ROLL],
@ -96,11 +100,12 @@ static uint32_t adc_calibrate_cb(struct pitc_timer *timer)
// TODO: only 1/2 offset? // TODO: only 1/2 offset?
adc_offset[ADC_ACC_YAW] = adc_cal_data[2]; adc_offset[ADC_ACC_YAW] = adc_cal_data[2];
// TODO: save to eeprom
printf("ACC offsets: %4d/%4d/%4d\n\r", printf("ACC offsets: %4d/%4d/%4d\n\r",
adc_offset[ADC_ACC_ROLL], adc_offset[ADC_ACC_ROLL],
adc_offset[ADC_ACC_NICK], adc_offset[ADC_ACC_NICK],
adc_offset[ADC_ACC_YAW]); adc_offset[ADC_ACC_YAW]);
twi_write_eeprom(EE_ACC_CAL_DATA, (uint8_t *)&(adc_offset[ADC_ACC_ROLL]), EE_ACC_CAL_DATA_SIZE);
} }
adc_cal_mode = ADC_CAL_NONE; adc_cal_mode = ADC_CAL_NONE;
@ -146,8 +151,6 @@ void at91_adc_init(void)
/* enable ADC clock */ /* enable ADC clock */
*AT91C_PMC_PCER = (1 << AT91C_ID_ADC); *AT91C_PMC_PCER = (1 << AT91C_ID_ADC);
// TODO: load calibration data from eeprom / use default values
/* ADC Software reset */ /* ADC Software reset */
AT91S_ADC *adc = AT91C_BASE_ADC; AT91S_ADC *adc = AT91C_BASE_ADC;
adc->ADC_CR = AT91C_ADC_SWRST; adc->ADC_CR = AT91C_ADC_SWRST;
@ -181,4 +184,11 @@ void at91_adc_init(void)
aic->AIC_SMR[AT91C_ID_ADC] = IRQPRIO_ADC | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; aic->AIC_SMR[AT91C_ID_ADC] = IRQPRIO_ADC | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
aic->AIC_SVR[AT91C_ID_ADC] = (uint32_t)at91_adc_isr; aic->AIC_SVR[AT91C_ID_ADC] = (uint32_t)at91_adc_isr;
aic->AIC_IECR = (1<<AT91C_ID_ADC); aic->AIC_IECR = (1<<AT91C_ID_ADC);
/* load ACC calibration data */
twi_read_eeprom(EE_ACC_CAL_DATA, (uint8_t *)&(adc_offset[ADC_ACC_ROLL]), EE_ACC_CAL_DATA_SIZE);
printf("ACC offsets: %4d/%4d/%4d\n\r",
adc_offset[ADC_ACC_ROLL],
adc_offset[ADC_ACC_NICK],
adc_offset[ADC_ACC_YAW]);
} }

View File

@ -22,6 +22,7 @@
#include "AT91SAM7S256.h" #include "AT91SAM7S256.h"
#include "board.h" #include "board.h"
#include "at91_tc1.h" #include "at91_tc1.h"
#include "at91_twi.h"
/* Hard limits for ISR */ /* Hard limits for ISR */
#define PULSE_MIN 0x0500 #define PULSE_MIN 0x0500
@ -50,6 +51,11 @@ struct channel_data {
uint16_t max; /* maximum value */ uint16_t max; /* maximum value */
}; };
/* check eeprom parameter size (uint16_t min/mid/max) */
#if ((MAX_CHANNELS * 3 * 2) != EE_RC_CAL_DATA_SIZE)
#error "invalid EE_RC_CAL_DATA_SIZE"
#endif
static struct channel_data ch_data[MAX_CHANNELS]; static struct channel_data ch_data[MAX_CHANNELS];
static uint32_t count, valid, cal_in_progress; static uint32_t count, valid, cal_in_progress;
@ -134,7 +140,7 @@ uint32_t rcontrol_getvalues(struct rc_values *rc)
if (tmp < -VALUE_RANGE) if (tmp < -VALUE_RANGE)
tmp = -VALUE_RANGE; tmp = -VALUE_RANGE;
// TODO: stick mapping from eeprom // TODO: stick mapping
rc->chan[i] = tmp; rc->chan[i] = tmp;
} }
return cnt; return cnt;
@ -163,6 +169,8 @@ uint32_t rcontrol_getswitches(struct rc_values *rc)
void rcontrol_calibrate(uint32_t mode) void rcontrol_calibrate(uint32_t mode)
{ {
uint32_t i; uint32_t i;
uint8_t buf[EE_RC_CAL_DATA_SIZE];
uint16_t *ptr = (uint16_t *)buf;
switch (mode) { switch (mode) {
case RC_CAL_START: case RC_CAL_START:
@ -190,6 +198,24 @@ void rcontrol_calibrate(uint32_t mode)
ch_data[i].mid = ch_data[i].max; ch_data[i].mid = ch_data[i].max;
} }
break; break;
case RC_CAL_LOAD:
twi_read_eeprom(EE_RC_CAL_DATA, buf, EE_RC_CAL_DATA_SIZE);
for (i = 0; i < ARRAY_SIZE(ch_data); i++) {
ch_data[i].min = *ptr++;
ch_data[i].mid = *ptr++;
ch_data[i].min = *ptr++;
}
break;
case RC_CAL_SAVE:
for (i = 0; i < ARRAY_SIZE(ch_data); i++) {
*ptr++ = ch_data[i].min;
*ptr++ = ch_data[i].mid;
*ptr++ = ch_data[i].min;
}
twi_write_eeprom(EE_RC_CAL_DATA, buf, EE_RC_CAL_DATA_SIZE);
break;
} }
} }
@ -228,4 +254,7 @@ void at91_tc1_init(void)
aic->AIC_SMR[AT91C_ID_TC1] = IRQPRIO_TC1 | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; aic->AIC_SMR[AT91C_ID_TC1] = IRQPRIO_TC1 | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
aic->AIC_SVR[AT91C_ID_TC1] = (uint32_t)ppm_isr; aic->AIC_SVR[AT91C_ID_TC1] = (uint32_t)ppm_isr;
aic->AIC_IECR = (1 << AT91C_ID_TC1); aic->AIC_IECR = (1 << AT91C_ID_TC1);
rcontrol_calibrate(RC_CAL_LOAD);
rcontrol_print_cal();
} }