|
楼主 |
发表于 2011-12-6 21:35:26
|
显示全部楼层
;-----------------------------------------------------------------------------;
; Radio Spectrum Monitor R0.2 October 8, 2011 ;
; (C)ChaN, 2012; http://elm-chan.org/ ;
;-----------------------------------------------------------------------------;
;
.include "m8def.inc"
.include "avr.inc"
.include "akiglcd.inc"
.equ SYSCLK = 16000000 ;MCU clock
.equ FCLK = 1400000 ;SCF clock (50fc)
.equ FFT_N = 128 ;Number of samples
;Port C bit definitions
.equ RES = 4
.equ ADCS = 3
.equ ADCK = 2
; Port B bit definitions
.equ RW = 5
.equ DI = 4
.equ E = 2
.equ CSL = 1
.equ CSR = 0
; Port D bit definitions (LCD data and Key input)
.equ K_UP = 0b10000000
.equ K_DOWN = 0b01000000
.equ K_RIGHT = 0b00010000
.equ K_LEFT = 0b00001000
.equ K_PUSH = 0b00000100
.equ K_MASK = 0b11011100
.def _0 = r15 ;Zero register
;----------------------------------------------------------;
; Data memory area
.dseg
.org RAMTOP
BflyBuf:.byte FFT_N*4 ;Butterfly operation table, Wave form buffer
LvlBuf: .byte FFT_N ;Spectrum bar length
LvlBufA:.byte FFT_N*2 ;Spectrum bar length averaging buffer
Offset: .byte 6+6 ;DC null level for I,Q input
Null: .byte 2 ;
Freq: .byte 2 ;
Key: .byte 3 ;Key input buffer {Cmd, Stat, Filter}
Modes: .byte 3 ;Operation mode { Acquire Mode, Bar Mode, Window }
Run: .byte 1 ;1=Enable display
Ave: .byte 1 ;Averaging count
Pool: .byte 16
;----------------------------------------------------------;
; Program code area
.cseg
rjmp reset ; RESET
rjmp 0 ; INT0
rjmp 0 ; INT1
rjmp 0 ; TC2 COMP
rjmp 0 ; TC2 OVF
rjmp 0 ; TC1 CAPT
rjmp 0 ; TC1 COMPA
rjmp 0 ; TC1 COMPB
rjmp 0 ; TC1 OVF
rjmp isr_tc0_ovf ; TC0 OVF
rjmp 0 ; SPI
rjmp 0 ; USART RXC
rjmp 0 ; USART UDRE
rjmp 0 ; USART TXC
rjmp 0 ; ADC
rjmp 0 ; EE_RDY
rjmp 0 ; ANA_COMP
rjmp 0 ; TWI
rjmp 0 ; SPM_RDY
;----------------------------------------------------------;
; 100Hz timer interrupt
isr_tc0_ovf:
push AL
in AL, SREG
pushw A
outi TCNT0, -(SYSCLK/100/1024)
in AL, PIND ;Get key input
com AL ;
andi AL, K_MASK ;/
lds AH, Key+2 ;Check if stabled or not.
sts Key+2, AL ;
cp AL, AH ;
brne isc_exit ;/
lds AL, Key+1 ;Check button down.
sts Key+1, AH ;
eor AL, AH ;
and AL, AH ;
breq isc_exit ;/
sts Key+0, AL ;Store pressed button as a key command.
isc_exit:
popw A
out SREG, AL
pop AL
reti
;----------------------------------------------------------;
; Initialize peripherals (ATmega8-16AC @16MHz)
reset:
clr _0 ;Zero reg.
ldiw A, RAMEND ;SP
outw SP, A ;/
ldiw Z, RAMTOP ;Clear SRAM
ldiw X, RAMEND-RAMTOP+1 ;
st Z+, _0 ;
sbiw XL, 1 ;
brne PC-2 ;/
outi PORTC, 0b00101100 ;Port C
outi DDRC, 0b00011100
outi PORTB, 0b00000011 ;Port B
outi DDRB, 0b00111111
outi PORTD, 0b11111111 ;Port D
; Start TC2 with FCLK on OC2 pin (for MAX295 clock)
outi OCR2, SYSCLK/FCLK/2-1
outi TCCR2, 0b00011001
; Start TC0 (100Hz interval timer)
outi TCCR0, 0b00000101
outi TIMSK, (1<<TOIE0)
rcall lcd_init
ldiw A, 4096/2 ;Initial offset (=0.5Vcc)
stsw Offset+0, A ;
stsw Offset+6, A ;/
stsi Null, 1
sei
ldi AL, K_PUSH
;----------------------------------------------------------;
; Main
main:
rcall menu
lds AL, Modes+0
cpi AL, 0
brne main_w
main_s: ; Spectrum Mode (60 cycles/sec)
rcall capture ; Fill butterfly table
rcall normalize ; Normalize A-D value to int16
rcall do_window ; Apply hamming window
rcall do_fft ; Butterfly operations
rcall make_bars ; Get scalar values, update spectrum
rcall rfsh_bars ; Display spectrum bars into LCD
rcall get_key
breq main_s
rjmp main
main_w:
rcall capture
rcall normalize
rcall rfsh_wave
rcall get_key
breq main_w
rjmp main
menu:
cpi AL, K_PUSH
breq mn_enter
cpi AL, K_UP
breq mn_hold
cpi AL, K_DOWN
breq mn_clr
cpi AL, K_LEFT
breq mn_null
ret
mn_null:
stsi Null, 1
ret
mn_clr:
sts Ave, _0
ret
mn_hold:
ldi AH, 1
lds AL, Run
eor AL, AH
sts Run, AL
ret
mn_enter:
ldiw E, 0
ldiw X, 128*6
ldi AL, 0
rcall lcd_putb
sbiw XL, 1
brne PC-3
ldi EH, 2
rcall disp_item0
ldi EH, 1
rcall disp_item0
ldi EH, 0
menu_l: rcall disp_item1
rcall get_key
breq PC-1
cpi AL, K_UP
breq mm_up
cpi AL, K_DOWN
breq mm_down
cpi AL, K_RIGHT
breq mm_right
cpi AL, K_PUSH
brne menu_l
stsi Run, 1
sts Ave, _0
ret
mm_up:
cpi EH, 0
breq menu_l
rcall disp_item0
dec EH
rjmp menu_l
mm_down:
cpi EH, 2
brcc menu_l
rcall disp_item0
inc EH
rjmp menu_l
mm_right:
ldiw X, Modes
add XL, EH
adc XH, _0
ldiw Z, ms_tbl*2
ldi AL, 10
mul AL, EH
addw Z, T0
lpm AH, Z
ld AL, X
inc AL
cp AL, AH
brcs PC+2
clr AL
st X, AL
rjmp menu_l
disp_item0:
clt
rjmp PC+2
disp_item1:
set
push EH
ldi AL, 5*2
mul AL, EH
ldiw Z, ms_tbl*2 + 2
addw Z, T0
lpmw T4, Z+
ldiw Y, Modes
add YL, EH
adc YH, _0
ld AL, Y
lsl AL
add ZL, AL
adc ZH, _0
lpmw T2, Z+
movw ZL, T4L
clr EL
rcall lcd_puts
ldi AL, ' '
brtc PC+2
ldi AL, '['
rcall lcd_putc
movw ZL, T2L
rcall lcd_puts
ldi AL, ' '
brtc PC+2
ldi AL, ']'
rcall lcd_putc
pop EH
ret
get_key:
cli
ldsw A, Key+0
sts Key+0, _0
sei
cpi AL, 0
ret
ms_tbl: .dw 2, ms_m1*2, ms_s10*2, ms_s11*2, 0
.dw 3, ms_m2*2, ms_s20*2, ms_s21*2, ms_s22*2
.dw 5, ms_m3*2, ms_s30*2, ms_s31*2, ms_s32*2, ms_s33*2, ms_s34*2
ms_m1: .db "Acq Moce:",0
ms_s10: .db "Spectrum",0
ms_s11: .db "Waveform",0
ms_s20: .db "Sampling ",0
ms_m2: .db "DispMode:",0
ms_s21: .db "Peak Hold",0
ms_s22: .db "Averaging",0
ms_m3: .db "Window :",0
ms_s30: .db "Hann ",0
ms_s31: .db "Hamming ",0
ms_s32: .db "Blackman ",0
ms_s33: .db "Flattop ",0
ms_s34: .db "Rectangle",0
;----------------------------------------------------------;
;Sampling functions
;----------------------------------------;
;Capture IQ signal (128samples in 64ksps)
;Ret: BflyBuf = captured data, Freq = number of osc clocks during captureing process
capture:
ldiw Y, BflyBuf
out TCNT1H, _0
out TCNT1L, _0
cli
outi TCCR1B, 7
ldi CL, FFT_N
cap_l1: cbi PORTC, ADCS ;Read I and Q channel into A and B. (229clk)
clr DL ;
ldi CH, 16 ;
cap_l2: cbi PORTC, ADCK ;
lsr DL ;
rolw B ;
lsr DL ;
in DL, PINC ;
sbi PORTC, ADCK ;
rolw A ;
dec CH ;
brne cap_l2 ;
sbi PORTC, ADCS ;/
stw Y+, A ;Store A and B into fft buffer. (8clk)
stw Y+, B ;/
rjmp PC+1 ;Delay (10clk)
rjmp PC+1 ;
rjmp PC+1 ;
rjmp PC+1 ;
rjmp PC+1 ;/
dec CL ;loop (3clk)
brne cap_l1 ;/
out TCCR1B, _0 ;Stop counter
sei
inw A, TCNT1 ;Freq = osc frequency in unit of 500Hz
stsw Freq, A ;/
ret
;----------------------------------------;
;Normalize captured IQ data
;Call: BflyBuf = captured data to be normalized
normalize:
ldiw Z, Offset
lddw T0, Z+0 ;T0 = Null value for I
lddw T2, Z+6 ;T2 = Null value for Q
clrw T4 ;T6:T4 = 0 (averaging reg for I)
clrw T6 ;/
clrw T8 ;T10:T8 = 0 (averaging reg for Q)
clrw T10 ;/
ldiw Y, BflyBuf
ldi CL, FFT_N
nm_l1: lddw A, Y+0 ;A = I data (0..4095);
addw T4, A ;T6:T4 += A;
adc T6L, _0 ;/
subw A, T0 ;A -= T0;
lslw A ;A *= 16;
lslw A ;
lslw A ;
lslw A ;/
stw Y+, A ;Write it back
lddw A, Y+0 ;Apply same porcess to Q data
addw T8, A ;
adc T10L, _0 ;
subw A, T2 ;
lslw A ;
lslw A ;
lslw A ;
lslw A ;
stw Y+, A ;/
dec CL ;Repeat
brne nm_l1 ;/
lds AL, Null
sbrs AL, 0
ret
lddw A, Z+2 ;B:A = averaging reg for I
lddw B, Z+4 ;/
lddw C, Z+8 ;D:C = averaging reg for Q
lddw D, Z+10 ;/
ldi EL, 7 ;T6:T4 /= 128;
lsrw T6 ;T10:T8 /= 128;
rorw T4 ;
lsrw T10 ;
rorw T8 ;
dec EL ;
brne PC-9 ;/
addw A, T4 ;B:A += T6:T4;
adcw B, T6 ;/
addw C, T8 ;D:C += T10:T8;
adcw D, T10 ;/
lds EL, Null+1 ;averaging count ++
inc EL ;
sts Null+1, EL ;/
brne PC+15 ;Null values are updated every 256 cycles to cancel DC offset at A-D input.
std Z+0, AH ;
std Z+1, BL ;
std Z+6, CH ;
std Z+7, DL ;
clrw A ;
clrw B ;
clrw C ;
clrw D ;
sts Null+0, _0 ;/
stdw Z+2, A ;Restore averaging regs...
stdw Z+4, B ;
stdw Z+8, C ;
stdw Z+10, D ;/
ret
;----------------------------------------------------------;
; FFT functions
;----------------------------------------;
;Apply window function
;Call: BflyBuf = IQ waveform to be processed
do_window:
lds ZL, Modes+2 ;Window table
lsl ZL
clr ZH
addiw Z, dw_tbl*2
lpmw T0, Z+
movw ZL, T0L
ldiw Y, BflyBuf ;Destination
ldi CL, FFT_N
ms_l1: lpmw A, Z+ ;Get a window attenuation ratio
lddw B, Y+0 ;Get an I data
FMULS16 A, B, T4, T2 ;Apply window
stw Y+, T4 ;Restore it
lddw B, Y+0 ;Get a Q data
FMULS16 A, B, T4, T2 ;Apply window
stw Y+, T4 ;Restore it
dec CL ;Repeat for all samples
brne ms_l1 ;/
ret
dw_tbl: .dw tw_hann*2, tw_hamming*2, tw_blackman*2, tw_flattop1*2, tw_rect*2
;----------------------------------------;
;Execute an FFT
do_fft: ; Execute butterfly operations (not optimized)
ldi XH, 1 ;u
ldi EL, FFT_N/2 ;l
df_l1: ldiw Z, BflyBuf ;Z = BflyBuf
ldiw Y, BflyBuf ;Y = BflyBuf + l * 4
muli EL, 4 ;
addw Y, T0 ;/
mul AL, XH ;T10L = u * 4
mov T10L, T0L ;/
mov XL, XH ;w = u
df_l2: clr T14L ;p=0
df_l3: lddw A, Z+0 ;A = [Z+0] - [Y+0], [Z+0] += [Y+0]
asrw A ;
movw CL, AL ;B = [Z+2] - [Y+2], [Z+2] += [Y+2]
lddw D, Y+0 ;
asrw D ;
subw A, D ;
addw C, D ;
stw Z+, C ;
lddw B, Z+0 ;
asrw B ;
movw CL, BL ;
lddw D, Y+2 ;
asrw D ;
subw B, D ;
addw C, D ;
stw Z+, C ;/
movw T0L, ZL
movw ZL, T14L ;C=cos(p), D=sin(p)
addiw Z, t_cos_sin*2 ;
lpmw C, Z+ ;
lpmw D, Z+ ;/
movw ZL, T0L
FMULS16 A, C, T4, T2 ;[Y+0] = A * C + B * D
FMULS16 B, D, T8, T6 ;[Y+2] = B * C - A * D
addw T2, T6 ;
adcw T4, T8 ;
stw Y+, T4 ;
FMULS16 B, C, T4, T2 ;
FMULS16 A, D, T8, T6 ;
subw T2, T6 ;
sbcw T4, T8 ;
stw Y+, T4 ;/
add T14L, T10L ;p += u
rjne df_l3
muli EL, 4 ;Y += l * 4, Z += l * 4; (skip split segment)
addw Y, T0 ;
addw Z, T0 ;/
dec XL ;--w
rjne df_l2
lsl XH ;u *= 2
lsr EL ;l /= 2
rjne df_l1
ret
;----------------------------------------;
;Get scalar spectrum and update spectrum bar buffer
make_bars:
ldiw Z, t_reorder*2 ;Reordering table
ldi CH, FFT_N ;Number of elements
lds AL, Modes+1
cpi AL, 1
breq mb_m1
cpi AL, 2
breq mb_m2
mb_m0: ldiw Y, LvlBuf ;Bar length buffer
mb_l0: rcall get_scaler
st Y+, CL ;Update bar length
dec CH
brne mb_l0
ret
mb_m1: ldiw Y, LvlBuf ;Bar length buffer
lds EH, Ave
mb_l1: rcall get_scaler
clr AL
sbrc EH, 0
ld AL, Y
cp AL, CL
brcc PC+2
mov AL, CL
st Y+, AL ;Update bar length
dec CH
brne mb_l1
stsi Ave, 1
ret
mb_m2: ldiw Y, LvlBufA ;Bar length buffer
lds EH, Ave
mb_l2: rcall get_scaler
mov AL, CL
clr AH
lddw B, Y+0
cpi EH, 0
breq PC+3
addw A, B
stw Y+, A
dec CH
brne mb_l2
inc EH
andi EH, 7
sts Ave, EH
breq PC+2
ret
ldiw Y, LvlBufA
ldiw X, LvlBuf
ldi CH, FFT_N
mb_v2: ldw A, Y+
lsrw A
lsrw A
lsrw A
st X+, AL
dec CH
brne mb_v2
ret
get_scaler:
lpmw A, Z+ ;Get a vector value (A = r, B = i)
ldiw X, BflyBuf ;
addw X, A ;
ldw A, X+ ;
ldw B, X+ ;/
FMULS16 A, A, T4, T2 ;A = sqrt(A * A + B * B); 0..32767 (scalar)
FMULS16 B, B, T8, T6 ;
addw T2, T6 ;
adcw T4, T8 ;
SQRT32 ;/
pushw Z ;CL = log(A)
lds BL, Freq+1 ;
cpi BL, 0 ;
ldiw Z, logs48*2 ;
breq PC+3 ;
ldiw Z, logs40*2 ;
ldi CL, 0 ;
lpmw B, Z+ ;
cpw A, B ;
brcs PC+3 ;
inc CL ;
rjmp PC-6 ;
popw Z ;/
ret
; These tables must be rebuilt when change FFT_N
t_cos_sin: ; {cos(x),sin(x)} table (0 <= x < pi, in 64 steps)
.dw 32767, 0, 32727, 1607, 32609, 3211, 32412, 4807
.dw 32137, 6392, 31785, 7961, 31356, 9511, 30851, 11038
.dw 30272, 12539, 29621, 14009, 28897, 15446, 28105, 16845
.dw 27244, 18204, 26318, 19519, 25329, 20787, 24278, 22004
.dw 23169, 23169, 22004, 24278, 20787, 25329, 19519, 26318
.dw 18204, 27244, 16845, 28105, 15446, 28897, 14009, 29621
.dw 12539, 30272, 11038, 30851, 9511, 31356, 7961, 31785
.dw 6392, 32137, 4807, 32412, 3211, 32609, 1607, 32727
.dw 0, 32767, -1607, 32727, -3211, 32609, -4807, 32412
.dw -6392, 32137, -7961, 31785, -9511, 31356, -11038, 30851
.dw -12539, 30272, -14009, 29621, -15446, 28897, -16845, 28105
.dw -18204, 27244, -19519, 26318, -20787, 25329, -22004, 24278
.dw -23169, 23169, -24278, 22005, -25329, 20787, -26318, 19519
.dw -27244, 18204, -28105, 16845, -28897, 15446, -29620, 14009
.dw -30272, 12539, -30851, 11038, -31356, 9511, -31784, 7961
.dw -32137, 6392, -32412, 4807, -32609, 3211, -32727, 1607
tw_hamming: ; Hamming window (for 128 samples)
.dw 2621, 2639, 2693, 2784, 2910, 3073, 3270, 3502
.dw 3768, 4068, 4401, 4765, 5161, 5587, 6042, 6525
.dw 7036, 7571, 8132, 8715, 9320, 9945, 10588, 11249
.dw 11926, 12616, 13318, 14031, 14753, 15482, 16216, 16954
.dw 17694, 18433, 19171, 19905, 20634, 21356, 22069, 22772
.dw 23462, 24138, 24799, 25443, 26068, 26673, 27256, 27816
.dw 28352, 28862, 29345, 29800, 30226, 30622, 30987, 31319
.dw 31619, 31885, 32117, 32315, 32477, 32603, 32694, 32748
.dw 32767, 32748, 32694, 32603, 32477, 32315, 32117, 31885
.dw 31619, 31319, 30987, 30622, 30226, 29800, 29345, 28862
.dw 28352, 27816, 27256, 26673, 26068, 25443, 24799, 24138
.dw 23462, 22772, 22069, 21356, 20634, 19905, 19171, 18433
.dw 17694, 16954, 16216, 15482, 14753, 14031, 13318, 12616
.dw 11926, 11249, 10588, 9945, 9320, 8715, 8132, 7571
.dw 7036, 6526, 6042, 5587, 5161, 4765, 4401, 4068
.dw 3768, 3502, 3270, 3073, 2910, 2784, 2693, 2639
tw_hann: ; Hann Window
.dw 0, 19, 78, 177, 314, 490, 705, 957
.dw 1247, 1572, 1934, 2330, 2761, 3224, 3718, 4244
.dw 4798, 5381, 5989, 6623, 7281, 7960, 8660, 9378
.dw 10113, 10864, 11627, 12402, 13187, 13979, 14777, 15579
.dw 16383, 17187, 17989, 18787, 19579, 20364, 21139, 21902
.dw 22653, 23388, 24106, 24806, 25485, 26143, 26777, 27385
.dw 27968, 28522, 29048, 29542, 30005, 30436, 30832, 31193
.dw 31519, 31809, 32061, 32275, 32452, 32589, 32688, 32747
.dw 32766, 32747, 32688, 32589, 32452, 32276, 32061, 31809
.dw 31519, 31194, 30832, 30436, 30005, 29542, 29048, 28522
.dw 27968, 27386, 26777, 26143, 25485, 24806, 24106, 23388
.dw 22653, 21902, 21139, 20364, 19579, 18787, 17989, 17187
.dw 16383, 15579, 14777, 13979, 13187, 12402, 11627, 10864
.dw 10113, 9378, 8660, 7960, 7281, 6623, 5989, 5381
.dw 4798, 4244, 3718, 3224, 2761, 2330, 1934, 1573
.dw 1247, 957, 705, 491, 314, 177, 78, 19
tw_blackman: ; Blackman window (for 128 samples)
.dw 0, 7, 28, 64, 115, 181, 263, 362
.dw 479, 614, 769, 945, 1142, 1363, 1608, 1879
.dw 2177, 2502, 2857, 3241, 3656, 4103, 4582, 5094
.dw 5638, 6216, 6826, 7469, 8144, 8849, 9585, 10349
.dw 11140, 11957, 12796, 13657, 14536, 15431, 16338, 17255
.dw 18178, 19103, 20028, 20949, 21861, 22760, 23644, 24507
.dw 25346, 26158, 26938, 27682, 28387, 29050, 29667, 30235
.dw 30752, 31214, 31619, 31966, 32252, 32476, 32637, 32734
.dw 32766, 32734, 32637, 32476, 32252, 31966, 31619, 31214
.dw 30752, 30235, 29667, 29050, 28387, 27682, 26938, 26158
.dw 25347, 24507, 23644, 22760, 21861, 20949, 20028, 19104
.dw 18178, 17255, 16338, 15431, 14536, 13657, 12797, 11957
.dw 11140, 10349, 9585, 8849, 8144, 7469, 6826, 6216
.dw 5638, 5094, 4582, 4103, 3656, 3241, 2857, 2502
.dw 2177, 1879, 1608, 1363, 1142, 945, 769, 614
.dw 479, 362, 263, 181, 115, 64, 28, 7
tw_flattop1:
.dw 0, -41, -86, -134, -189, -250, -319, -397
.dw -484, -582, -690, -807, -934, -1067, -1207, -1350
.dw -1493, -1633, -1766, -1887, -1993, -2077, -2135, -2160
.dw -2147, -2090, -1983, -1820, -1597, -1307, -947, -512
.dw 0, 593, 1269, 2029, 2872, 3798, 4803, 5886
.dw 7041, 8263, 9546, 10883, 12265, 13683, 15127, 16586
.dw 18049, 19504, 20940, 22344, 23704, 25007, 26243, 27400
.dw 28467, 29434, 30292, 31033, 31649, 32134, 32484, 32696
.dw 32766, 32696, 32484, 32134, 31649, 31033, 30292, 29434
.dw 28467, 27400, 26243, 25008, 23704, 22344, 20940, 19504
.dw 18049, 16586, 15127, 13683, 12265, 10883, 9547, 8263
.dw 7041, 5886, 4803, 3798, 2872, 2029, 1269, 593
.dw 0, -512, -947, -1307, -1597, -1820, -1983, -2090
.dw -2147, -2160, -2135, -2077, -1993, -1887, -1766, -1633
.dw -1493, -1350, -1207, -1067, -934, -807, -690, -582
.dw -484, -397, -319, -250, -189, -134, -86, -41
tw_rect: ; Rectanguler window (for 128 samples)
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
.dw 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767
t_reorder: ;Reordering table (for 128 point complex FFT)
.dw 1*4, 65*4, 33*4, 97*4, 17*4, 81*4, 49*4, 113*4, 9*4, 73*4, 41*4, 105*4, 25*4, 89*4, 57*4, 121*4
.dw 5*4, 69*4, 37*4, 101*4, 21*4, 85*4, 53*4, 117*4, 13*4, 77*4, 45*4, 109*4, 29*4, 93*4, 61*4, 125*4
.dw 3*4, 67*4, 35*4, 99*4, 19*4, 83*4, 51*4, 115*4, 11*4, 75*4, 43*4, 107*4, 27*4, 91*4, 59*4, 123*4
.dw 7*4, 71*4, 39*4, 103*4, 23*4, 87*4, 55*4, 119*4, 15*4, 79*4, 47*4, 111*4, 31*4, 95*4, 63*4, 127*4
.dw 0*4, 64*4, 32*4, 96*4, 16*4, 80*4, 48*4, 112*4, 8*4, 72*4, 40*4, 104*4, 24*4, 88*4, 56*4, 120*4
.dw 4*4, 68*4, 36*4, 100*4, 20*4, 84*4, 52*4, 116*4, 12*4, 76*4, 44*4, 108*4, 28*4, 92*4, 60*4, 124*4
.dw 2*4, 66*4, 34*4, 98*4, 18*4, 82*4, 50*4, 114*4, 10*4, 74*4, 42*4, 106*4, 26*4, 90*4, 58*4, 122*4
.dw 6*4, 70*4, 38*4, 102*4, 22*4, 86*4, 54*4, 118*4, 14*4, 78*4, 46*4, 110*4, 30*4, 94*4, 62*4, 126*4
logs40: ; 60dB - 40 point log conversion table
.dw 15, 18, 22, 26, 31, 37, 45, 53, 63, 75, 89, 106, 126, 150, 179, 213, 253, 301, 357, 425, 505, 600, 714, 848, 1009, 1199, 1425, 1694, 2013, 2393, 2844, 3380, 4018, 4775, 5675, 6746, 8017, 9529, 11326, 13461, 16000, 0xFFFF
logs48: ; 60dB - 48 point log conversion table
.dw 19, 23, 26, 30, 35, 41, 47, 54, 63, 72, 84, 97, 112, 129, 149, 173, 199, 230, 266, 307, 355, 410, 473, 547, 632, 729, 842, 973, 1124, 1298, 1499, 1731, 1999, 2308, 2666, 3078, 3555, 4105, 4741, 5475, 6323, 7302, 8432, 9738, 11245, 12986, 14997, 17318, 20000, 0xFFFF
;-------------------------------------------------------------------------------;
; Drawing functions
;----------------------------------------;
;Draw in spectrum mode
;Call: LvlBuf=bar data buffer
rfsh_bars:
lds AL, Run
sbrs AL, 0
ret
clrw E
lds BL, Freq+1
cpi BL, 0
ldi CH, 48
breq PC+2
ldi CH, 40
rb_l2: subi CH, 8
ldi CL, FFT_N
ldiw Y, LvlBuf
rb_l3: ld BL, Y+
clr AL
sub BL, CH
brcs PC+8
ldi AL, -1
cpi BL, 8
brcc PC+5
lsr AL
subi BL, 1
brcc PC-2
com AL
rcall lcd_putb
dec CL
brne rb_l3
cpi CH, 0
brne rb_l2
ldsw A, Freq
cpi AH, 0
brne PC+2
ret
subiw A, (455-32)*2
clr DH
ldi CL, 16
lslw A
rol DH
cpi DH, 36
brcs PC+3
subi DH, 36
inc AL
dec CL
brne PC-8
subi DH, 36+8
addiw A, 1
ldi AH, 18
mul AL, AH
movw AL, T0L
ldi CL, 5
push CL
rcall put_valn2
subiw A, 18
pop CL
dec CL
brne PC-6
ret
put_valn2:
pushw A
ldi CH, 0
pv_l1: inc CH
clr BL
ldi CL, 16
pv_l2: lslw A
rol BL
cpi BL, 10
brcs PC+3
subi BL, 10
inc AL
dec CL
brne pv_l2
push BL
cp AL, _0
cpc AH, _0
brne pv_l1
cpi CH, 4
brcc PC+5
inc CH
ldi BL, 10
push BL
rjmp PC-5
ldiw X, Pool
pop AL
rcall lcd_putn
dec CH
brne PC-3
ldiw X, Pool
clr CL
ld AL, X+
cpi CL, 8
brne PC+2
ori AL, 3
rcall lcd_putbm
inc CL
cpi CL, 16
brcs PC-7
ldi AL, 0
cpi CL, 8+18
brne PC+2
ori AL, 3
rcall lcd_putbm
inc CL
cpi CL, 36
brcs PC-7
popw A
ret
lcd_putn:
pushw Z
ldi AH, 3
mul AL, AH
ldiw Z, font35*2
addw Z, T0
lpm AL, Z+
st X+, AL
lpm AL, Z+
st X+, AL
lpm AL, Z+
st X+, AL
st X+, _0
popw Z
ret
lcd_putbm:
sbrs DH, 7
rcall lcd_putb
inc DH
ret
;----------------------------------------;
;Draw in wave form mode
;Call: BflyBuf = normalized IQ wave form
rfsh_wave:
lds AL, Run
sbrs AL, 0
ret
clrw E
ldi CH, 64-8
rw_l2: subi CH, 8
ldi CL, FFT_N
ldiw Y, BflyBuf
rw_l3: clrw A
ldw B, Y+
addi BH, 128
lsr BH
lsr BH
sub BH, CH
brcs rw_s1
cpi BH, 8
brcc rw_s1
ror AL
subi BH, 1
brcc PC-2
rw_s1: ldw B, Y+
addi BH, 128
lsr BH
lsr BH
sub BH, CH
brcs rw_s2
cpi BH, 8
brcc rw_s2
ror AH
subi BH, 1
brcc PC-2
rw_s2: or AL, AH
rcall lcd_putb
dec CL
brne rw_l3
cpi CH, 8
brne rw_l2
ret
;-------------------------------------------------------------------------------;
; LCD control functions (for dual HD61202 based LCD module)
;
;----------------------------------------;
;Initialize LCD module
lcd_init:
sbi PORTC, RES ;RES,CS = H
cbi PORTB, CSL ;Enable Display
cbi PORTB, CSR ;
cbi PORTB, DI ;
ldi AL, 0x3F ;
rcall lcd_write ;
ldi AL, 0xC0 ;
rcall lcd_write ;/
ret
;----------------------------------------;
;Put an ascii character
; Call: AL = data, EL = X(0..127), EH = Y(0..5)
; Ret: EL,EH = next address
lcd_putc:
pushw Z
subi AL, ' '
ldi AH, 5
mul AL, AH
ldiw Z, font58*2
addw Z, T0
ldi AH, 5
lpm AL, Z+
rcall lcd_putb
dec AH
brne PC-3
clr AL
rcall lcd_putb
popw Z
ret
lcd_puts:
lpm AL, Z+
cpi AL, 0
brne PC+2
ret
rcall lcd_putc
rjmp lcd_puts
font58:
.include "font5x8.asm"
font35:
.include "font3x5.asm"
;----------------------------------------;
; Put a pattern byte into LCDC memory
; Call: AL = data, EL = X(0..127), EH = Y(0..5)
; Ret: EL,EH = next address
lcd_putb:
push AL
mov AL, EL
andi AL, 63
brne pd_s
cbi PORTB, DI
sbrc EL, 6
rjmp pd_rh
pd_lh: sbi PORTB, CSR
cbi PORTB, CSL
mov AL, EH
ori AL, 0b10111000
rcall lcd_write
ldi AL, 0b01000000
rcall lcd_write
rjmp pd_s
pd_rh: sbi PORTB, CSL
cbi PORTB, CSR
mov AL, EH
ori AL, 0b10111000
rcall lcd_write
ldi AL, 0b01000000
rcall lcd_write
inc EH
pd_s: pop AL
sbi PORTB, DI
rcall lcd_write
inc EL
ret
;----------------------------------------;
;Write a byte to LCDC register
;Call: AL=data, CSL,CLR,D/I=destination
lcd_write:
cli
in T0L, PORTB ;Save D/I,R/W bit
cbi PORTB, DI ;D/I = L
sbi PORTB, RW ;R/W = H
sbi PORTB, E ;E = H
rjmp PC+1 ;Delay
rjmp PC+1 ;
rjmp PC+1 ;
rjmp PC+1 ;/
in T0H, PIND ;Read data
cbi PORTB, E ;E = L
sbrc T0H, 7 ;Loop while not ready
rjmp PC-8 ;/
out PORTB, T0L ;Restore D/I,R/W bit
sbi PORTB, E ;E = H
out PORTD, AL ;PORTD = data
outi DDRD, -1 ;/
rjmp PC+1 ;Delay
rjmp PC+1 ;/
cbi PORTB, E ;E = L
out PORTD, AL ;PD = pull-up
out DDRD, _0 ;/
sei
ret |
|