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/adctemp.c

235 lines
3.3 KiB

#include "ax8052.h"
#include "libmfadc.h"
#if defined(SDCC)
__reentrantb int16_t adc_measure_temperature(void) __reentrant
{
__asm
clr a
mov b,_IE
mov _IE,a
mov r0,_EIE
mov _EIE,a
mov r1,_E2IE
mov _E2IE,a
mov dptr,#_ADCTUNE0
mov a,#0x01
movx @dptr,a
inc dptr
mov a,#0x06
movx @dptr,a
inc dptr
movx a,@dptr
mov r2,a
clr a
movx @dptr,a
mov r3,_ADCCLKSRC
mov _ADCCLKSRC,#0x30
mov r4,_ADCCH0CONFIG
mov _ADCCH0CONFIG,#0xd8
mov r5,_ADCCH1CONFIG
mov _ADCCH1CONFIG,#0xd8
mov r6,_ADCCH2CONFIG
mov _ADCCH2CONFIG,#0xd8
mov r7,_ADCCH3CONFIG
mov _ADCCH3CONFIG,#0xd8
mov _ADCCONV,#0x01
setb _EIE_6
00000$: mov a,_ADCCONV
jb acc.7,00001$
mov a,_PCON
anl a,#0x0c
orl a,#0x01
mov _PCON,a
nop
nop
nop
nop
nop
nop
nop
sjmp 00000$
00001$: ;; restore registers
mov _ADCCH0CONFIG,r4
mov _ADCCH1CONFIG,r5
mov _ADCCH2CONFIG,r6
mov _ADCCH3CONFIG,r7
mov _ADCCLKSRC,r3
mov dptr,#_ADCTUNE2
mov a,r2
movx @dptr,a
mov _EIE,r0
mov _E2IE,r1
mov dptr,#_ADCCH1VAL0
movx a,@dptr
mov r2,a
inc dptr
movx a,@dptr
mov r3,a
inc dptr
movx a,@dptr
mov r4,a
inc dptr
movx a,@dptr
mov r5,a
inc dptr
movx a,@dptr
mov r6,a
inc dptr
movx a,@dptr
mov r7,a
mov _IE,b
;; compute median
;; A=R5:R4 - R3:R2
mov a,r4
clr c
subb a,r2
mov a,r5
subb a,r3
jnb acc.7,00010$
;; if R3:R2 > R5:R4, swap
mov a,r2
xch a,r4
mov r2,a
mov a,r3
xch a,r5
mov r3,a
00010$:
;; A=R7:R6 - R5:R4
mov a,r6
clr c
subb a,r4
mov a,r7
subb a,r5
jnb acc.7,00011$
;; if R5:R4 > R7:R6, swap
mov a,r4
xch a,r6
mov r4,a
mov a,r5
xch a,r7
mov r5,a
00011$:
;; A=R5:R4 - R3:R2
mov a,r4
clr c
subb a,r2
mov a,r5
subb a,r3
jnb acc.7,00012$
;; if R3:R2 > R5:R4, swap
mov a,r2
xch a,r4
mov r2,a
mov a,r3
xch a,r5
mov r3,a
00012$:
;; return is in R5:R4
mov dpl,r4
mov dph,r5
__endasm;
}
#else
// returns 256*temperature [deg]
// median of ADC channels 1,2 and 3 is used.
// Note: MCU is put in standby mode with all interrupts disabled during conversion!
__reentrantb int16_t adc_measure_temperature(void) __reentrant
{
int16_t t1, t2, t3;
{
uint8_t ie_save = IE;
uint8_t eie_save = EIE;
uint8_t e2ie_save = E2IE;
uint8_t tune2save, clksrcsave, ch0cfgsave, ch1cfgsave, ch2cfgsave, ch3cfgsave;
IE = 0;
EIE = 0;
E2IE = 0;
ADCTUNE0 = 0x01;
ADCTUNE1 = 0x06;
tune2save = ADCTUNE2;
ADCTUNE2 = 0x00;
clksrcsave = ADCCLKSRC;
ADCCLKSRC = 0x30;
// configure all channels for TEMP
ch0cfgsave = ADCCH0CONFIG;
ADCCH0CONFIG = 0xD8;
ch1cfgsave = ADCCH1CONFIG;
ADCCH1CONFIG = 0xD8;
ch2cfgsave = ADCCH2CONFIG;
ADCCH2CONFIG = 0xD8;
ch3cfgsave = ADCCH3CONFIG;
ADCCH3CONFIG = 0xD8;
ADCCONV = 0x01;
EIE_6 = 1;
for (;;) {
if (ADCCONV & 0x80)
break;
enter_standby();
}
t1 = ADCCH1VAL1;
t1 <<= 8;
t1 |= ADCCH1VAL0;
t2 = ADCCH2VAL1;
t2 <<= 8;
t2 |= ADCCH2VAL0;
t3 = ADCCH3VAL1;
t3 <<= 8;
t3 |= ADCCH3VAL0;
ADCCH0CONFIG = ch0cfgsave;
ADCCH1CONFIG = ch1cfgsave;
ADCCH2CONFIG = ch2cfgsave;
ADCCH3CONFIG = ch3cfgsave;
ADCCLKSRC = clksrcsave;
ADCTUNE2 = tune2save;
E2IE = e2ie_save;
EIE = eie_save;
IE = ie_save;
}
// compute median
if (t1 > t2) {
int16_t x = t1;
t1 = t2;
t2 = x;
}
if (t2 > t3) {
int16_t x = t2;
t2 = t3;
t3 = x;
}
if (t1 > t2) {
int16_t x = t1;
t1 = t2;
t2 = x;
}
return t2;
}
#endif

Powered by TurnKey Linux.