di2513.txt ;**************************************************************************************************** ; LISTING 1 - FIRMWARE ; ; "Spread-spectrum method identifies audio path," EDN, April 13, 2000, pg 204 ; ; http://www.ednmag.com/ednmag/reg/2000/041300/designideas.htm#08di4 ;**************************************************************************************************** MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 1 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00001 SUBTITLE "MAIN (PRNG.ASM) PSEUDO RANDOM NOISE GEN" 00002 ; 00003 ;=================================================================== 00004 ; 00005 TITLE "PSEUDO RANDOM NOISE GEN" 00006 LIST P = 12C508A, N = 66, X = ON 00007 ; 00008 ;=================================================================== 00009 ; 00010 ; CONFIGURATION BITS (Instruction to Assembler) 00011 ; 00012 ;------------------------------------------------------------------- 00013 ; 0FFF 000D 00014 __CONFIG B'01101' ;MSB MCLR disabled 00015 ; Code Protect off 00016 ; Watch Dog on 00017 ;2 LSBs XT osc selected 00018 ; 00019 ;=================================================================== 00020 ; 00021 ; HEADERS 00022 ; 00023 ;purpose and theory of operation 00024 include ; 00001 00002 SUBTITLE "TEXT LEADER (prng.txt)" 00003 ; 00004 ;self-serving retoric containing whining rationalizations, 00005 ;lame excuses, and pathetic whimpers, 00006 ; 00007 ;=================================================================== 00008 ; 00009 ; This program is for a Microchip Technology Inc. PIC 12C508A: 00010 ; 00011 ;=================================================================== 00012 ; 00013 ; REVISION HISTORY 00014 ; 00015 ;------------------------------------------------------------------- 00016 ; 00017 ;Rev: Date: Reason: 00018 ; 00019 ;1.00 7/13/99 1st Release 00020 ; 00021 ;=================================================================== 00022 ; 00023 ; HOW I THINK (HOPE) THIS THING WORKS 00024 ; 00025 ;------------------------------------------------------------------- 00026 ; 00027 ; The purpose of this firmware, psuedo random, linear feedback, 00028 ; shift register is to output a 9 KHz square wave carrier and a 00029 ; 6 KHz psuedo random bit stream for a spread spectrum tag 00030 ; signal. 00031 ; 00032 ; The real time clock register TMR0 is hardware clocked once 00033 ; each instruction - at 1 MHz. The register is 8 bits wide so 00034 ; it folds every 256 micro seconds. I need 18 KHz (55.55556 us). 00035 ; 00036 ; As the RTC increments in 1 instruction steps, exactly 18 MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 2 PSEUDO RANDOM NOISE GEN TEXT LEADER (prng.txt) LOC OBJECT CODE LINE SOURCE TEXT VALUE 00037 ; KHz is not available: 55 us = 18.18182 KHz and 56 us = 00038 ; 17.85714 KHz. I chose 56 us so the carrier is 8.928571 KHz 00039 ; and the noise is 5.952381 KHz (I still call it 18 KHz, 9 KHz, 00040 ; and 6 KHz though). 00041 ; 00042 ; If the RTC starts from zero, the MSB goes pos at 128 us. The 00043 ; 56 us real time clock is generated by preloading register TMR0 00044 ; with a count so it goes positive in 56 us (instructions) 00045 ; rather than 128 us. TMR0 is then preloaded for the next clock 00046 ; and the carrier, shift register and noise bit are updated. 00047 ; 00048 ; The carrier is generated by dividing the internal 18 KHz real 00049 ; time clock by two; that is, it complements the carrier bit 00050 ; each positive edge of the 18 KHz. 00051 ; 00052 ; The 6 KHz psuedo random bit stream is generated by dividing 00053 ; the internal 18 KHz real time clock by three; that is, every 00054 ; third (counted) positive edge of the 18 KHz real time clock, 00055 ; the 16 bit shift register is clocked which updates the noise 00056 ; bit. 00057 ; 00058 ; The psuedo random noise output is taken as the MSB of the 00059 ; maximal length, 16 bit, linear feedback, shift register. The 00060 ; four taps are XORed together and feed in as the LSB. 00061 ; 00062 ;=================================================================== 00063 ; 00025 ; 00026 ;registers, variables, & constants declarations 00027 include ; 00001 SUBTITLE "HEADER (PRNG.H) PSEUDO RANDOM NOISE GEN" 00002 ; 00003 ;------------------------------------------------------------------- 00004 ; 00005 ;Bank 0 - PRNG specific I/O ports, 00006 ; 00007 ;The PIC12C508A has 6 I/O pins in 1 general purpose reg 00008 ; 00000006 00009 gpio EQU 06 ;general purpose i/o 00010 ; input pins - 00011 ; output pins - 00012 #define carrier gpio,0 ;output 00013 #define noise gpio,1 ;output 00014 #define gp2 gpio,2 ;input 00015 #define gp3 gpio,3 ;input 00016 #define gp4 gpio,4 ;osc2 00017 #define gp5 gpio,5 ;input (osc1) 00018 #define gp6 gpio,6 ;n/a 00019 #define gp7 gpio,7 ;n/a 00020 ; 00021 ;------------------------------------------------------------------- 00022 ; 00023 ;Bank 0 pre-defined registers 00024 ; 00025 ;option 00026 ; 00000000 00027 indf EQU 0 ;Reg 0 indirect addr 00000001 00028 tmr0 EQU 01 ;Reg 1 real time clock 00029 #define clk18 tmr0,7 ;18 KHz clock bit 00000002 00030 pcl EQU 02 ;Reg 2 program counter MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 3 PSEUDO RANDOM NOISE GEN HEADER (PRNG.H) PSEUDO RANDOM NOISE GEN LOC OBJECT CODE LINE SOURCE TEXT VALUE 00000003 00031 status EQU 03 ;Reg 3 status (keys) 00032 #define carry status,0 ; carry 00033 #define dc status,1 ; nibble carry 00034 #define z status,2 ; zero result bit 00035 #define pd_ status,3 ; power down bit 00036 #define to_ status,4 ; time out bit 00037 #define pa0 status,5 ; program page preselect bit 00038 #define status6 status,6 ; n/a, pgrm 0 00039 #define gpwuf status,7 ; gpio reset bit 00000004 00040 fsr EQU 04 ;indirect addr pointer 00041 ; 00000005 00042 osccal EQU 05 ;osc cal bits 00043 ; 00044 ;Register 06 is the general purpose I/O Port, see above 00045 ; 00046 ;------------------------------------------------------------------- 00047 ; 00048 ;Bank 0 General Purpose Registers 00049 ; 00050 ;two, concatinated, 8 bit, shift regs & their taps makes the 00051 ; 16 bit shift register 00052 ; 00000007 00053 lfsr0 EQU 07 ; 00054 #define tap01 lfsr0,0 ; 00055 #define tap03 lfsr0,2 ; 00056 #define tap08 lfsr0,7 ;MSB out from lfsr0 00057 ; and shifted 00000008 00058 lfsr1 EQU 08 ; into 00059 #define tap09 lfsr1,0 ;LSB of lfsr1 00060 #define tap12 lfsr1,3 ; 00061 #define tap16 lfsr1,7 ; 00062 ; 00000009 00063 xor EQU 09 ; 00064 #define xorMSB xor,7 ; 00065 ; 0000000A 00066 div_x EQU 0A ; 00067 ; 00068 ;Spare Bank 0 Registers 00069 ; 00070 ;spar10 EQU 0B ; 00071 ; thru 00072 ;spar1F EQU 1F ; 00073 ; 00074 ;------------------------------------------------------------------- 00075 ; 00076 ;Bank 1 Registers mapped back into bank 0 - 00077 ; 00078 ;spar20 EQU 20 ; 00079 ; thru 00080 ;spar2F EQU 2F ; 00081 ; 00082 ;Spare Bank 1 registers 00083 ; 00084 ;spar30 EQU 30 ; 00085 ; thru 00086 ;spar3F EQU 3F ; 00087 ; 00088 ;------------------------------------------------------------------- 00089 ; 00090 ;Constants MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 4 PSEUDO RANDOM NOISE GEN HEADER (PRNG.H) PSEUDO RANDOM NOISE GEN LOC OBJECT CODE LINE SOURCE TEXT VALUE 00091 ; 00000003 00092 div_by EQU H'03' ;18 KHz clks for 6 KHz 0000004E 00093 cnt56 EQU H'4E' ;count clks for 56 us 00094 ; 00028 ; 00029 ;=================================================================== 00030 ; 0000 00031 pwrup: ; 0000 00032 ORG 0x000 ;counter folds to 0 0000 0A01 00033 GOTO start ;The reset vector herself 0001 00034 ORG 0x001 ; Interrupt vector location 00035 ; 00036 ;=================================================================== 00037 ; 00038 ; INITIALIZATION 00039 ; 00040 include ; 00001 00002 SUBTITLE "INITIALIZATION (prng.int)" 00003 ; 00004 ; Confidential and Proprietary. 00005 ; Copyright 1999 Nielsen Media Research 00006 ; All Rights Reserved. 00007 ; 00008 ;------------------------------------------------------------------- 00009 ; 0001 00010 start: 00011 ; 0001 04A3 00012 BCF pa0 ;select bank 0 0002 0507 00013 BSF tap01 ; (lfsr not = 0) 00014 ; 0003 0C03 00015 MOVLW div_by ;initialize div by 3 0004 002A 00016 MOVWF div_x ; count down reg 00017 ; 0005 0C3C 00018 MOVLW B'111100' ;Set gpio[5..0] I/O pins 0006 0006 00019 tris gpio ; carrier & noise are outputs 00020 ; all others are inputs 00021 ; 0007 0C8F 00022 MOVLW B'10001111' ;Setup real time clock 0008 0002 00023 OPTION ; & watch dog time out 00024 ;MSB disable wakeup on chg 00025 ; 6 ena weak pullups 00026 ; 5 clk RTC on cycle clk 00027 ; 4 clk RTC on lo to hi 00028 ; 3 WDT assig prescale 00029 ;LSBs 2.3 sec watch dog 00030 ; 0009 0004 00031 CLRWDT ;kick the watchdog 00041 ; 00042 ;=================================================================== 00043 ; 000A 00044 main: ;program loop begins here 00045 ; 00046 ;As the RTC increments in 1 instruction steps, exactly 18 00047 ;KHz is not available: 55 us = 18.18182 KHz and 56 us = 00048 ;17.85714 KHz. I chose 56 us so the carrier is 8.928571 KHz 00049 ;and the noise is 5.952381 KHz (I still call it 18 KHz 00050 ;though). 00051 ; 00052 ;wait for 56 us (17.857 KHz) clk bit positive going edge MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 5 PSEUDO RANDOM NOISE GEN INITIALIZATION (prng.int) LOC OBJECT CODE LINE SOURCE TEXT VALUE 00053 ; TMR0 has been loaded with a count so it is 56 instructions 00054 ; till TMR0's MSB goes hi. 00055 ; 00056 ;if clk is lo, loop till it goes hi, reload it 00057 ;and fall thru. 00058 ; 000A 07E1 00059 BTFSS clk18 ;test clk bit for hi 000B 0A0A 00060 GOTO main ; clock is still lo 000C 0C4E 00061 MOVLW cnt56 ; reload real time clk 000D 0021 00062 MOVWF tmr0 ; (takes clk18 back lo) 00063 ; 00064 ;50% duty cycle 9 KHz carrier - on each 18 KHz event, 00065 ; complement the carrier bit. 00066 ; 000E 00067 carrier_set: ; 000E 0706 00068 BTFSS carrier ;complement the carrier 000F 0A11 00069 GOTO carrier_is_lo ; each 18 KHz event 0010 0A14 00070 GOTO carrier_is_hi ; 00071 ; 0011 00072 carrier_is_lo: ;so make carrier hi 0011 0000 00073 NOP ;pad time 0012 0506 00074 BSF carrier ; 0013 0A16 00075 GOTO update_noise ; 00076 ; 0014 00077 carrier_is_hi: ;so make carrier lo 0014 0406 00078 BCF carrier ; 0015 0A16 00079 GOTO update_noise ; 00080 ; 00081 ;now do the 6 KHz noise bit - divide the 18 KHz clk 00082 ;by 3 (update the noise bit every third 18 KHz event). 00083 ; 0016 00084 update_noise: ; 00085 ; 0016 02EA 00086 DECFSZ div_x,1 ;is this the 3rd clk? 0017 0A30 00087 GOTO noise_exit ;no, exit 00088 ; 0018 06E8 00089 BTFSC tap16 ;yes, output noise bit 0019 0A1C 00090 GOTO noise_is_hi ; 00091 ; 001A 00092 noise_is_lo: ;make noise bit lo 001A 0426 00093 BCF noise ; 001B 0A1D 00094 GOTO next_noise_bit ; 00095 ; 001C 00096 noise_is_hi: ;make noise bit hi 001C 0526 00097 BSF noise ; 00098 ; 00099 ;------------------------------------------------------------------- 00100 ; 00101 ;Generate the next noise bit 00102 ; 00103 include ; 00001 00002 SUBTITLE "NEXT NOISE BIT (NEXT_BIT.ASM)" 00003 ; 00004 ;=================================================================== 00005 ; 001D 00006 next_noise_bit: ;1st do the feedback bit 00007 ; 00008 ;This pseudo random, maximal length, linear feedback, 16 bit 00009 ;shift register has a cycle length of 65,535 clks (2^16 - 1). MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 6 PSEUDO RANDOM NOISE GEN NEXT NOISE BIT (NEXT_BIT.ASM) LOC OBJECT CODE LINE SOURCE TEXT VALUE 00010 ;It's taps are 1, 3, 12, and 16. These 4 bits, XOR'ed 00011 ;together, become the feedback bit. At 6 KHz, it cycles thru 00012 ;all of it's combinations in 10.92 seconds. 00013 ; 00014 ;There are 16 possible states for the four taps. If there are 00015 ;an odd number of hi bits among the four taps, the XOR result 00016 ;is hi. If there are an even number of hi bits, the XOR result 00017 ;is lo. 00018 ; 00019 ;So, XOR is accomplished by first clearing the xor register, 00020 ;then complementing it for each tap that is a "1". If there 00021 ;are an even number of "1's" the result is a cleared xor reg. 00022 ;If there are an odd number of "1's" the result is an all hi 00023 ;xor reg. As the PIC doesn't have a complement bit instruction, 00024 ;but does have a complement register instruction I am using it. 00025 ;Any bit of the xor reg can be used as the feedback bit. Here 00026 ;I am using the MSB. 00027 ; 001D 0069 00028 CLRF xor ; 001E 0607 00029 BTFSC tap01 ;if tap 1 is hi, 001F 0269 00030 COMF xor,f ; complement register 00031 ; 0020 0647 00032 BTFSC tap03 ;if tap 3 is hi, 0021 0269 00033 COMF xor,f ; complement 00034 ; 0022 0668 00035 BTFSC tap12 ;if tap 12 is hi, 0023 0269 00036 COMF xor,f ; complement 00037 ; 0024 06E8 00038 BTFSC tap16 ;if tap 16 is hi, 0025 0269 00039 COMF xor,f ; complement. 00040 ; xor's MSB is now 00041 ; the feedback bit 00042 ; 00043 ;------------------------------------------------------------------- 00044 ; 00045 ;The 16 bit reg is shifted right and it's feedback bit 00046 ;(determined above) is shifted into the LSB. The new MSB 00047 ;becomes the noise bit output. 00048 ; 00049 ;In this case, with 6 KHz noise modulating a 9 KHz carrier, 00050 ;in a hardware double balanced mixer - the main lobe will 00051 ;extend from 3 KHz to 15 KHz - in the frequency domain it 00052 ;has a (sin x)/x spectrum. This is called "direct sequence 00053 ;spread spectrum". 00054 ; 0026 00055 shift_it: ;then shift the register 00056 ; 0026 0368 00057 RLF lfsr1,1 ;rotate upper reg left, MSB 00058 ; thru carry 00059 ; 0027 0408 00060 BCF tap09 ;put MSB of lower reg 0028 06E7 00061 BTFSC tap08 ; into LSB of upper reg, 0029 0508 00062 BSF tap09 ; re-placing carrier bit 00063 ; 002A 0367 00064 RLF lfsr0,1 ;rotate lower reg left, MSB 00065 ; thru carry 00066 ; 002B 0407 00067 BCF tap01 ;put (inverted) feedback bit 002C 07E9 00068 BTFSS xorMSB ; into LSB of lower reg, 002D 0507 00069 BSF tap01 ; re-placing carrier bit MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 7 PSEUDO RANDOM NOISE GEN NEXT NOISE BIT (NEXT_BIT.ASM) LOC OBJECT CODE LINE SOURCE TEXT VALUE 00070 ; 00071 ; 002E 0C03 00072 MOVLW div_by ;re-initialize div_by 002F 002A 00073 MOVWF div_x ; for 6 KHz 00104 ; 00105 ;------------------------------------------------------------------- 00106 ; 0030 00107 noise_exit: ; 0030 0004 00108 CLRWDT ;kick the watchdog 0031 0A0A 00109 GOTO main ;repeat main program loop 00110 ; 00111 ;=================================================================== 00112 ; 00113 END ; MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 8 PSEUDO RANDOM NOISE GEN NEXT NOISE BIT (NEXT_BIT.ASM) SYMBOL TABLE LABEL VALUE __12C508A 00000001 carrier gpio,0 carrier_is_hi 00000014 carrier_is_lo 00000011 carrier_set 0000000E carry status,0 clk18 tmr0,7 cnt56 0000004E dc status,1 div_by 00000003 div_x 0000000A fsr 00000004 gp2 gpio,2 gp3 gpio,3 gp4 gpio,4 gp5 gpio,5 gp6 gpio,6 gp7 gpio,7 gpio 00000006 gpwuf status,7 indf 00000000 lfsr0 00000007 lfsr1 00000008 main 0000000A next_noise_bit 0000001D noise gpio,1 noise_exit 00000030 noise_is_hi 0000001C noise_is_lo 0000001A osccal 00000005 pa0 status,5 pcl 00000002 pd_ status,3 pwrup 00000000 shift_it 00000026 start 00000001 status 00000003 status6 status,6 tap01 lfsr0,0 tap03 lfsr0,2 tap08 lfsr0,7 tap09 lfsr1,0 tap12 lfsr1,3 tap16 lfsr1,7 tmr0 00000001 to_ status,4 update_noise 00000016 xor 00000009 xorMSB xor,7 z status,2 MPASM 02.20 Released PRNG.ASM 7-13-1999 16:02:02 PAGE 9 PSEUDO RANDOM NOISE GEN NEXT NOISE BIT (NEXT_BIT.ASM) MEMORY USAGE MAP ('X' = Used, '-' = Unused) 0000 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XX-------------- 0FC0 : ---------------- ---------------- ---------------- ---------------X All other memory blocks unused. Program Memory Words Used: 50 Program Memory Words Free: 462 Errors : 0 Warnings : 0 reported, 0 suppressed Messages : 0 reported, 0 suppressed