You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CubeSatSim/libs/libmf/source/adccalt.c

371 lines
6.3 KiB

#include "ax8052.h"
#include "libmfadc.h"
SFRX(ADCCALTEMPGAIN0, 0x7038) /* ADC Calibration Temperature Gain Low Byte */
SFRX(ADCCALTEMPGAIN1, 0x7039) /* ADC Calibration Temperature Gain High Byte */
SFRX(ADCCALTEMPOFFS0, 0x703A) /* ADC Calibration Temperature Offset Low Byte */
SFRX(ADCCALTEMPOFFS1, 0x703B) /* ADC Calibration Temperature Offset High Byte */
#if defined(SDCC)
void adc_calibrate_temp(void)
{
__asm
ar2 = 0x02
ar3 = 0x03
ar4 = 0x04
ar5 = 0x05
ar6 = 0x06
ar7 = 0x07
ar0 = 0x00
ar1 = 0x01
clr a
push _IE
mov _IE,a
push _EIE
mov _EIE,#0x40
push _E2IE
mov _E2IE,a
mov _ADCCONV,a
mov r0,a
mov r1,a
mov r2,a
mov r3,a
mov _ADCCLKSRC,#0x28 ; 0.625MHz/16
mov _ADCCH0CONFIG,#0xf8
mov _ADCCH1CONFIG,#0xf9
mov _ADCCH2CONFIG,#0xff
mov _ADCCH3CONFIG,#0xff
mov dptr,#_ADCTUNE1
mov a,#0xf2
movx @dptr,a
mov dptr,#_ADCCH0VAL0
movx a,@dptr
mov b,#0x10
adccaltloop:
mov _ADCCONV,#0x01
adcwait1:
mov a,_PCON
anl a,#0x0C
orl a,#0x01
mov _PCON,a
mov a,_ADCCLKSRC
jb acc.7,adcwait1
mov dptr,#_ADCCH0VAL0
;; channel 0
movx a,@dptr
inc dptr
swap a
anl a,#0x0f
mov r6,a
movx a,@dptr
inc dptr
swap a
mov r7,a
anl a,#0xf0
orl a,r6
add a,r0
mov r0,a
mov a,r7
anl a,#0x0f
addc a,r1
mov r1,a
;; channel 1
movx a,@dptr
inc dptr
swap a
anl a,#0x0f
mov r6,a
movx a,@dptr
inc dptr
swap a
mov r7,a
anl a,#0xf0
orl a,r6
add a,r2
mov r2,a
mov a,r7
anl a,#0x0f
addc a,r3
mov r3,a
djnz b,adccaltloop
;; switch off ADC
mov dptr,#_ADCTUNE1
mov a,#0x02
movx @dptr,a
mov _ADCCLKSRC,#0x07 ; off
pop _E2IE
pop _EIE
pop _IE
;; convert calibration constant to calibration value
caltconst0 = 0x13C08312 ; 0.96*82.3*2^-6*2^8*2^14*2^6
caltconst1 = 0x0000A532 ; 82.3*4.0145*2^8/2
;caltconst2 = 0x00014877 ; (82.3*3.68+25.6)*2^8
caltconst2 = 0x00013F77 ; (82.3*3.68+25.6-9)*2^8
push ar0
push ar1
;; first compute offset
mov __mullong_PARM_2,r2
mov (__mullong_PARM_2+1),r3
mov a,r3
rlc a
subb a,acc
mov (__mullong_PARM_2+2),a
mov (__mullong_PARM_2+3),a
mov dptr,#caltconst1&0xffff
mov b,#caltconst1>>16
mov a,#caltconst1>>24
lcall __mullong
mov r1,a
pop acc
pop ar0
push ar0
push acc
clr c
rrc a
mov (__divslong_PARM_2 + 1),a
mov a,r0
rrc a
mov __divslong_PARM_2,a
clr a
mov (__divslong_PARM_2 + 2),a
mov (__divslong_PARM_2 + 3),a
mov a,r1
lcall __divslong
mov r0,dph
mov a,dpl
add a,#caltconst2&0xff
mov dptr,#_ADCCALTEMPOFFS0
movx @dptr,a
inc dptr
mov a,r0
addc a,#caltconst2>>8
movx @dptr,a
;; second compute gain
pop (__divslong_PARM_2 + 1)
pop __divslong_PARM_2
clr a
mov (__divslong_PARM_2 + 2),a
mov (__divslong_PARM_2 + 3),a
mov dptr,#caltconst0&0xffff
mov b,#caltconst0>>16
mov a,#caltconst0>>24
lcall __divslong
mov a,dpl
mov r0,dph
mov dptr,#_ADCCALTEMPGAIN0
movx @dptr,a
inc dptr
mov a,r0
movx @dptr,a
__endasm;
}
#elif defined __CX51__ || defined __C51__
void adc_calibrate_temp(void)
{
#pragma asm
using 0
extrn CODE (?C?LMUL)
extrn CODE (?C?SLDIV)
clr a
push IE
mov IE,a
push EIE
mov EIE,#0x40
push E2IE
mov E2IE,a
mov ADCCONV,a
mov r0,a
mov r1,a
mov r2,a
mov r3,a
mov ADCCLKSRC,#0x28 ; 0.625MHz/16
mov ADCCH0CONFIG,#0xf8
mov ADCCH1CONFIG,#0xf9
mov ADCCH2CONFIG,#0xff
mov ADCCH3CONFIG,#0xff
mov dptr,#ADCTUNE1
mov a,#0xf2
movx @dptr,a
mov dptr,#ADCCH0VAL0
movx a,@dptr
mov b,#0x10
adccaltloop:
mov ADCCONV,#0x01
adcwait1:
mov a,PCON
anl a,#0x0C
orl a,#0x01
mov PCON,a
mov a,ADCCLKSRC
jb acc.7,adcwait1
mov dptr,#ADCCH0VAL0
;; channel 0
movx a,@dptr
inc dptr
swap a
anl a,#0x0f
mov r6,a
movx a,@dptr
inc dptr
swap a
mov r7,a
anl a,#0xf0
orl a,r6
add a,r0
mov r0,a
mov a,r7
anl a,#0x0f
addc a,r1
mov r1,a
;; channel 1
movx a,@dptr
inc dptr
swap a
anl a,#0x0f
mov r6,a
movx a,@dptr
inc dptr
swap a
mov r7,a
anl a,#0xf0
orl a,r6
add a,r2
mov r2,a
mov a,r7
anl a,#0x0f
addc a,r3
mov r3,a
djnz b,adccaltloop
;; switch off ADC
mov dptr,#ADCTUNE1
mov a,#0x02
movx @dptr,a
mov ADCCLKSRC,#0x07 ; off
pop E2IE
pop EIE
pop IE
;; convert calibration constant to calibration value
caltconst0l equ 0x8312 ; 0.96*82.3*2^-6*2^8*2^14*2^6
caltconst0h equ 0x13C0
caltconst1l equ 0xA532 ; 82.3*4.0145*2^8/2
caltconst1h equ 0x0000
;caltconst2l equ 0x4877 ; (82.3*3.68+25.6)*2^8
;caltconst2h equ 0x0001
caltconst2l equ 0x3F77 ; (82.3*3.68+25.6-9)*2^8
caltconst2h equ 0x0001
push ar0
push ar1
;; first compute offset
mov r7,ar2
mov a,r3
mov r6,a
rlc a
subb a,acc
mov r5,a
mov r4,a
mov r3,#caltconst1l&0xff
mov r2,#caltconst1l>>8
mov r1,#caltconst1h&0xff
mov r0,#caltconst1h>>8
lcall ?C?LMUL
pop acc
pop ar3
push ar3
push acc
clr c
rrc a
mov r2,a
mov a,r3
rrc a
mov r3,a
clr a
mov r1,a
mov r0,a
lcall ?C?SLDIV
mov a,r7
add a,#caltconst2l&0xff
mov dptr,#ADCCALTEMPOFFS0
movx @dptr,a
inc dptr
mov a,r6
addc a,#caltconst2l>>8
movx @dptr,a
;; second compute gain
pop ar2
pop ar3
clr a
mov r1,a
mov r0,a
mov r7,#caltconst0l&0xff
mov r6,#caltconst0l>>8
mov r5,#caltconst0h&0xff
mov r4,#caltconst0h>>8
lcall ?C?SLDIV
mov a,r7
mov dptr,#ADCCALTEMPGAIN0
movx @dptr,a
inc dptr
mov a,r6
movx @dptr,a
#pragma endasm
}
#else
void adc_calibrate_temp(void)
{
static const int32_t caltconst0 = 0x13C08312; /* 0.96*82.3*2^-6*2^8*2^14*2^6 */
static const int32_t caltconst1 = 0x0000A532; /* 82.3*4.0145*2^8/2 */
/*static const uint16_t caltconst2 = 0x00014877; */ /* (82.3*3.68+25.6)*2^8 */
static const uint16_t caltconst2 = 0x00013F77; /* (82.3*3.68+25.6-9)*2^8 */
uint8_t __autodata iesave = IE, eiesave = EIE, e2iesave = E2IE, cnt = 0x10;
uint16_t __autodata adcv0 = 0, adcv1 = 0, v;
int32_t __autodata x;
IE = 0;
EIE = 0x40;
E2IE = 0;
ADCCONV = 0;
ADCCLKSRC = 0x28; /* 0.625MHz/16 */
ADCCH0CONFIG = 0xf8;
ADCCH1CONFIG = 0xf9;
ADCCH2CONFIG = 0xff;
ADCCH3CONFIG = 0xff;
ADCTUNE1 = 0xf2;
ADCCH0VAL0;
do {
ADCCONV = 0x01;
do {
enter_standby();
} while (ADCCLKSRC & 0x80);
v = ADCCH0VAL1;
v <<= 4;
v |= ADCCH0VAL0 >> 4;
adcv0 += v;
v = ADCCH1VAL1;
v <<= 4;
v |= ADCCH1VAL0 >> 4;
adcv1 += v;
} while (--cnt);
/* switch off ADC */
ADCTUNE1 = 0x02;
ADCCLKSRC = 0x07;
E2IE = e2iesave;
EIE = eiesave;
IE = iesave;
/* convert calibration constant to calibration value */
/* first compute offset */
v = (caltconst1 * (int16_t)adcv1) / (adcv0 >> 1);
v += caltconst2;
ADCCALTEMPOFFS0 = v;
ADCCALTEMPOFFS1 = v >> 8;
/* second compute gain */
v = caltconst0 / adcv0;
ADCCALTEMPGAIN0 = v;
ADCCALTEMPGAIN1 = v >> 8;
}
#endif

Powered by TurnKey Linux.