; /wista.jp/Xmitter.htm
;Refer to the parent page of /wista.jp/FMXmit.htm .
;FM Transmitter NS73M driver code, on 12F509
; by T. Fujiwara 12/11/2013
; version 1.0
LIST P=12F509, c=132, n=0
include <p12f509.inc> ; processor specific variable definitions
__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC
radix DEC
;bit definitions
bit0 equ 0
bit1 equ 1
bit2 equ 2
bit3 equ 3
bit4 equ 4
bit5 equ 5
bit6 equ 6
bit7 equ 7
w equ 0
f equ 1
z equ 2
;signal definitions, GPIO
bck equ 5 ;clock to NS73M
bda equ 1 ;data to NS73M
bla equ 2 ;latch to NS73M
teb equ 4 ;TEB from NS73M, 0=unlocked, 1=locked
;reg definitions
regadr equ 0x07 ;gpr7 for 73M register address
regdata equ 0x08 ;gpr8 for 73M reg data
work equ 0x09 ;work reg
work1 equ 0x0a ;work reg1
counter equ 0x0b ;wait loop counter low
counter1 equ 0x0c ;wait loop counter high
status equ 0x03
fsr equ 0x04
OSCCAL equ 0x05
gpio equ 0x06
;========== code ============
start:
org 0
movwf OSCCAL
call wait ;wait for power stabilization
movlw 0
movwf fsr ;bank 0
clrf gpio
movlw b'00011001' ;port bit, 1=in 0=out, bit(0,3,4)=in, bit(1,2,5)=out
tris gpio
clrf gpio
movlw b'10001111' ;WPullUp
option
;== NS73M control ==
;software reset: address E, data xxxx 0101
movlw .14 ;R14
movwf regadr
movlw b'00000101' ;software reset
movwf regdata
call send
;pilot on, force subcarrier
movlw .1 ;R1
movwf regadr
movlw b'10110100' ;d6(subcarrier) on(0), d3(pilot) on(0)
movwf regdata
call send
;unlock detect on, power 0.5, 1 or 2 mW
movlw .2
movwf regadr
movlw b'00000101' ;d2=1 unlock detect, d0,d1=01=0.5mW
; movlw b'00000101' ;d2=1 unlock detect, d0,d1=10=1mW
; movlw b'00000111' ;d2=1 unlock detect, d0,d1=11=2mW
movwf regdata
call send
;set frequency
call whatfreq ;read jumper and find which freq
movlw .3
movwf regadr
movf work,w
movwf regdata
call send
movlw .4
movwf regadr
movf work1,w
movwf regdata
call send
;set local OSC band
movlw .8
movwf regadr
movlw b'00011011' ;last two bits define the band.
; 3:<90M, 2:<96M, 1:<102M, 0:<108M
movwf regdata
call send
;clear 5, 7, 9, 10, 11
movlw .5
call send0
movlw .7
call send0
movlw .9
call send0
movlw .10
call send0
movlw .11
call send0
;set input level, pre-emphasis, pwr-on
movlw .0
movwf regadr
movlw b'00000001' ;00:100mV, 0:50uS, 0:preemf-on, 0,test-off,
;0:mute-off 0:xtal-off, 1:pwr-on
movwf regdata
call send
;set charge 1.25uA
movlw .6
movwf regadr
movlw b'00011010' ;000:test, 11:generator charge pump 320uA,
;01:PLL charge pump=1.25uA, 0:test
movwf regdata
call send
call wait ;locks within about 400ms (340ms)
call wait
call wait ;600ms wait
btfsc gpio,teb ;test TEB, 1=locked, 0=not-locked(Err)
;locked
goto keepsleep
;unlocked
call wait
btfsc gpio,teb
goto keepsleep
bsf gpio,bck ;unlocked, seeLED
keepsleep:
sleep
goto keepsleep
;====== subroutines ==========
wait: ;wait 200ms
movlw .0
movwf counter
movlw .195
movwf counter1
wt1: nop
decfsz counter,f
goto wt1 ;4us*256-1=1023us
decfsz counter1,f
goto wt1 ;(1023us+3)*195-1=200.069ms
retlw .0
send0: ;clear target reg
movwf regadr
movlw b'00000000'
movwf regdata
send: ;set target reg
clrf gpio
btfsc regadr,bit0
bsf gpio,bda ;data
bsf gpio,bck ;clock pulse, 1/4MHz * 4 = 1us, s/b >250ns
bcf gpio,bck
bcf gpio,bda ;1st bit comp
btfsc regadr,bit1
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;2nd bit comp
btfsc regadr,bit2
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;3rd bit comp
btfsc regadr,bit3
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;4th bit comp, address complete
btfsc regdata,bit0
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;1st bit comp
btfsc regdata,bit1
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;2nd bit comp
btfsc regdata,bit2
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;3rd bit comp
btfsc regdata,bit3
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;4th bit comp
btfsc regdata,bit4
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;5th bit comp
btfsc regdata,bit5
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;6th bit comp
btfsc regdata,bit6
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;7th bit comp
btfsc regdata,bit7
bsf gpio,bda
bsf gpio,bck
bcf gpio,bck
bcf gpio,bda ;8th bit comp, data complete
bsf gpio,bla ;latch pulse, 1us
bcf gpio,bla
retlw 0
;constant definitions
table0l equ b'11110111' ;87.7MHz
table0h equ b'00101001'
table1l equ b'00001111' ;87.9MHz
table1h equ b'00101010'
table2l equ b'01110001' ;88.7MHz
table2h equ b'00101010'
table3l equ b'10001001' ;88.9MHz
table3h equ b'00101010'
table4l equ b'10100010' ;89.1MHz
table4h equ b'00101010'
whatfreq:
;read frequency jumper
;first, test if 5th state
movlw b'00011000' ;GP0 as out
tris gpio
bsf gpio,0
btfss gpio,3 ;on= possible 5th state
goto not5th
bcf gpio,0
btfsc gpio,3 ;off= 5th state
goto not5th
movlw b'00011001' ;set tris back to original
tris gpio
jumper5th:
movlw table4l
movwf work
movlw table4h
movwf work1
goto exwhat
not5th:
movlw b'00011001' ;enable bit 0 input
tris gpio
;test F0 and F1 for GND
btfss gpio,0 ;read jumper pin, bit3(f1) and bit0(f0)
goto testx1 ;bit0 is off (jumper0 exists)
;come here if x0 case (jumper 0 not exists)
btfss gpio,3 ;test jumper3
goto jumper10 ;jumper on,off
goto jumper00 ;jumper off,off
testx1: ;come here if jumper0 exists
btfss gpio,3
goto jumper11 ;two jumpers
goto jumper01 ;no jumper3
jumper00:
movlw table0l
movwf work
movlw table0h
movwf work1
goto exwhat
jumper01:
movlw table1l
movwf work
movlw table1h
movwf work1
goto exwhat
jumper10:
movlw table2l
movwf work
movlw table2h
movwf work1
goto exwhat
jumper11:
movlw table3l
movwf work
movlw table3h
movwf work1
exwhat: retlw 0
end
;NS73M Frequency setting
;MHz N N:rounded Err(kHz) N:hex N:bin
;87.5 10718.26 10718 -2.144 29DE 00101001 11011110
;87.6 10730.47 10730 -3.840 29EA 00101001 11101010
;87.7 10742.68 10743 +2.656 29F7 00101001 11110111 <==0
;87.8 10754.88 10755 +0.960 2A03 00101010 00000011
;87.9 10767.09 10767 -0.736 2A0F 00101010 00001111 <==1
;88.0 10779.30 10779 -2.432 2A1B 00101010 00011011
;88.1 10791.50 10792 +4.064 2A28 00101010 00101000
;88.2 10803.71 10804 +2.368 2A34 00101010 00110100
;88.3 10815.92 10816 +0.672 2A40 00101010 01000000
;88.4 10828.13 10828 -1.024 2A4C 00101010 01001100
;88.5 10840.33 10840 -2.720 2A58 00101010 01011000
;88.6 10852.54 10853 +3.776 2A65 00101010 01100101
;88.7 10864.75 10865 +2.080 2A71 00101010 01110001 <==2
;88.8 10876.95 10877 +0.384 2A7D 00101010 01111101
;88.9 10889.16 10889 -1.312 2A89 00101010 10001001 <==3
;89.0 10901.37 10901 -3.008 2A95 00101010 10010101
;89.1 10913.57 10914 +3.488 2AA2 00101010 10100010 <==4
;89.2 10925.78 10926 +1.792 2AAE 00101010 10101110
;89.3 10937.99 10938 +0.096 2ABA 00101010 10111010
;89.4 10950.20 10950 -1.600 2AC6 00101010 11000110
;89.5 10962.40 10962 -3.296 2AD2 00101010 11010010
;89.6 10974.61 10975 +3.200 2ADF 00101010 11011111
;89.7 10986.82 10987 +1.504 2AEB 00101010 11101011
;89.8 10999.02 10999 -0.192 2AF7 00101010 11110111
;89.9 11011.23 11011 -1.888 2B03 00101011 00000011
;kyoto open, 89.1, 89.0, 88.9, 88.8, 88.7, 88.5, 87.9, 87.8, 87.7
;band= 3:<90M, 2:<96M, 1:<102M, 0:<108M