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_END 1
#define RC_CAL_LOAD 2
#define RC_CAL_SAVE 3
struct rc_values {
int16_t chan[MAX_CHANNELS];

View File

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

View File

@ -23,8 +23,7 @@
#include "board.h"
#include "at91_adc.h"
#include "at91_pitc.h"
#include "fixed.h"
#include "at91_twi.h"
#define ADC_CAL_COUNT 1024
@ -32,6 +31,11 @@ static uint16_t adc_tmp[7];
static int16_t adc_result[7];
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;
volatile static uint32_t adc_cal_mode;
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_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",
adc_offset[ADC_GYRO_ROLL],
@ -96,11 +100,12 @@ static uint32_t adc_calibrate_cb(struct pitc_timer *timer)
// TODO: only 1/2 offset?
adc_offset[ADC_ACC_YAW] = adc_cal_data[2];
// TODO: save to eeprom
printf("ACC offsets: %4d/%4d/%4d\n\r",
adc_offset[ADC_ACC_ROLL],
adc_offset[ADC_ACC_NICK],
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;
@ -146,8 +151,6 @@ void at91_adc_init(void)
/* enable ADC clock */
*AT91C_PMC_PCER = (1 << AT91C_ID_ADC);
// TODO: load calibration data from eeprom / use default values
/* ADC Software reset */
AT91S_ADC *adc = AT91C_BASE_ADC;
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_SVR[AT91C_ID_ADC] = (uint32_t)at91_adc_isr;
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 "board.h"
#include "at91_tc1.h"
#include "at91_twi.h"
/* Hard limits for ISR */
#define PULSE_MIN 0x0500
@ -50,6 +51,11 @@ struct channel_data {
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 uint32_t count, valid, cal_in_progress;
@ -134,7 +140,7 @@ uint32_t rcontrol_getvalues(struct rc_values *rc)
if (tmp < -VALUE_RANGE)
tmp = -VALUE_RANGE;
// TODO: stick mapping from eeprom
// TODO: stick mapping
rc->chan[i] = tmp;
}
return cnt;
@ -163,6 +169,8 @@ uint32_t rcontrol_getswitches(struct rc_values *rc)
void rcontrol_calibrate(uint32_t mode)
{
uint32_t i;
uint8_t buf[EE_RC_CAL_DATA_SIZE];
uint16_t *ptr = (uint16_t *)buf;
switch (mode) {
case RC_CAL_START:
@ -190,6 +198,24 @@ void rcontrol_calibrate(uint32_t mode)
ch_data[i].mid = ch_data[i].max;
}
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_SVR[AT91C_ID_TC1] = (uint32_t)ppm_isr;
aic->AIC_IECR = (1 << AT91C_ID_TC1);
rcontrol_calibrate(RC_CAL_LOAD);
rcontrol_print_cal();
}