; vim: set ft=nasm: .ORG 0 jmp START_PROCESS .ORG LMD_DATA_SPACE DEMENABLE0_RX_IQDUMP: .DATA 0x2FCF ; DEMENABLE0 settings (felp, frac,fidc,chfi,bdec,iqmc,mge2,codc,cmix) DEMENABLE1_RX_IQDUMP: .DATA 0x3F9D ; DEMENABLE1 VITACCCTRL_REG_DEFAULT: ; Transp, downsample + IIR filter setting .DATA 0x0001 ; [7:0]=0: no filter ; [7:0]=1: k=1/2 ; [7:0]=2: k=1/4 ; [7:0]=3: k=1/8 ; [15: 8]=0, no transparent downsample ; [15: 8]=1, transparent downsample by two ; [15: 8]=2, transparent downsample by four ; [15: 8]=3, transparent downsample by eight ; [15: 8]=4, transparent downsample by sixteen DEMC1BE0_MASKA_BITS: ; Various bit masks .DATA 0x003F IQDUMP_MASK_BITS_15_8: .DATA 0xFF00 IQDUMP_TEST_MAX_VAL: .DATA 0x0FFF IQDUMP_MAX_POS_VAL: .DATA 0x07FF ; 2^11 - 1 = 2047 IQDUMP_MIN_NEG_VAL: .DATA 0xF800 ; -2048 TRANSPARENT_CAPT: .DATA 0x0300 ; Combined RDCAPT0_DEMPDIF0 and RDCAPT0_DEMFIFE2 CORR_DEFG_THR: .DATA 0x8080 TX_TONE_COUNT: .DATA 0x06 ; Default number of clock ticks for tone in front of preamble .ORG MDMCONF_IQDUMP .DATA 0x0003 ; ADCDIGCONF .DATA 0x0017 ; MODPRECTRL .DATA 0x3D1F ; MODSYMMAP0 .DATA 0x0000 ; MODSYMMAP1 .DATA 0x0000 ; MODSOFTTX .DATA 0x0800 ; MDMBAUD .DATA 0x000F ; MDMBAUDPRE .DATA 0x0000 ; MODMAIN .DATA 0x0387 ; DEMMISC0 .DATA 0x0000 ; DEMMISC1 .DATA 0x4074 ; DEMMISC2 .DATA 0x0043 ; DEMMISC3 .DATA 0x8000 ; DEMIQMC0 .DATA 0x0082 ; DEMDSBU .DATA 0x0080 ; DEMDSBU2 .DATA 0x06F0 ; DEMCODC0 .DATA 0x0000 ; DEMFIDC0 .DATA 0x091E ; DEMFEXB0 .DATA 0x0510 ; DEMDSXB0 .DATA 0x0054 ; DEMD2XB0 .DATA 0x0007 ; DEMFIFE0 .DATA 0x0000 ; DEMMAFI0 .DATA 0x5014 ; DEMMAFI1 .DATA 0x0050 ; DEMMAFI2 .DATA 0x0000 ; DEMMAFI3 .DATA 0xC02F ; DEMC1BE0 .DATA 0x0C30 ; DEMC1BE1 .DATA 0x017F ; DEMC1BE2 .DATA 0x0000 ; DEMC1BE10 .DATA 0x0000 ; DEMC1BE11 .DATA 0x0000 ; DEMC1BE12 .DATA 0x0000 ; MDMSYNC0 .DATA 0x0000 ; MDMSYNC1 .DATA 0x0000 ; MDMSYNC2 .DATA 0xAA00 ; MDMSYNC3 .DATA 0x0000 ; DEMSWQU0 MDMCONF_IQDUMP_END: .ORG MAIN START_PROCESS: ;; Do hard initialization of all submodules of the modem outclr RFESEND ; Clear RFE send jsr MODCTRL_CLR ; outbclr DEMMISC2_MLSERUN,DEMMISC2 ; Make sure MLSE can be stopped outbclr DEMSWQU0_RUN, DEMSWQU0 ; Make sure door is open for init outset DEMENABLE0 ; outset DEMINIT0 ; outclr DEMENABLE0 ; outset DEMENABLE1 ; outset DEMINIT1 ; outclr DEMENABLE1 ; outset TIMCTRL ; outclr TIMCTRL ; outbset MDMENABLE_FB2PLL, MDMENABLE ; enable fb2pll module so that can be reset lli 0x3FC, r0 ; dont't touch fifo and topsm output r0, MDMINIT ; outbclr MDMENABLE_FB2PLL, MDMENABLE ; disable fb2pll module again outclr MCEEVENTMSK0 ; outclr MCEEVENTMSK1 ; outclr MCEEVENTMSK2 ; outclr MCEEVENTMSK3 ; ;;; Move into Command processing ;;; -------------------------------------------------------------------------------- ;;; Step 1. Main Command Processing Loop CMD_PROC: outbset MCEEVENT0_MDMAPI_WR, MCEEVENTMSK0 ; Enable event 0 = MDMAPI write wait ; Waits until a command arrives outbset MCEEVENT0_MDMAPI_WR, MCEEVENTCLR0 ; Clear the event 0 outbclr MCEEVENT0_MDMAPI_WR, MCEEVENTMSK0 ; Clear the event 0 outclr MDMSTATUS ; input MDMAPI, r2 ; Protocol ID [15:8] API [7:0] put together as [4:3][2:0] mov r2, r0 ; Copy first into R0 sr0 5, r2 ; Shift 5 positions R2 and 7, r0 ; Clear all above bit 2 in R0 or r2, r0 ; Put them together add 3, r0 ; offset +3 mov pc, r1 add r0, r1 jmp (r1) jmp MNOP_Entry ; Jump tables Prot 0 Call 0 (MNOP) jmp MCFG_Entry ; Jump tables Prot 0 Call 1 (MCFG) jmp MTX_Entry ; Jump tables Prot 0 Call 2 (MTX) jmp MRX_Entry_REG_BLIND ; Jump tables Prot 0 Call 3 (MRX-BLIND-REGISTER MODE) jmp MNOP_Entry ; Jump tables Prot 0 Call 4 jmp MNOP_Entry ; Jump tables Prot 0 Call 5 jmp MNOP_Entry ; Jump tables Prot 0 Call 6 jmp MNOP_Entry ; Jump tables Prot 0 Call 7 jmp MNOP_Entry ; Jump tables Prot 1 Call 0 jmp MCFG_Entry ; Jump tables Prot 1 Call 1 (MCFG) jmp MTX_Entry ; Jump tables Prot 1 Call 2 (MTX) jmp MRX_Entry_REG_SYNC ; Jump tables Prot 1 Call 3 (MRX-SYNC-REGISTER MODE) jmp MNOP_Entry ; Jump tables Prot 1 Call 4 jmp MNOP_Entry ; Jump tables Prot 1 Call 5 jmp MNOP_Entry ; Jump tables Prot 1 Call 6 jmp MNOP_Entry ; Jump tables Prot 1 Call 7 jmp MNOP_Entry ; Jump tables Prot 2 Call 0 jmp MCFG_Entry ; Jump tables Prot 2 Call 1 (MCFG) jmp MTX_Entry ; Jump tables Prot 2 Call 2 (MTX) jmp MRX_Entry_FIFO_BLIND ; Jump tables Prot 2 Call 3 (MRX-BLIND-RFC FIFO MODE) jmp MNOP_Entry ; Jump tables Prot 2 Call 4 jmp MNOP_Entry ; Jump tables Prot 2 Call 5 jmp MNOP_Entry ; Jump tables Prot 2 Call 6 jmp MNOP_Entry ; Jump tables Prot 2 Call 7 jmp MNOP_Entry ; Jump tables Prot 3 Call 0 jmp MCFG_Entry ; Jump tables Prot 3 Call 1 (MCFG) jmp MTX_Entry ; Jump tables Prot 3 Call 2 (MTX) jmp MRX_Entry_FIFO_SYNC ; Jump tables Prot 3 Call 3 (MRX-SYNC-RFC FIFO MODE) jmp MNOP_Entry ; Jump tables Prot 3 Call 4 jmp MNOP_Entry ; Jump tables Prot 3 Call 5 jmp MNOP_Entry ; Jump tables Prot 3 Call 6 jmp MNOP_Entry ; Jump tables Prot 3 Call 7 jmp MNOP_Entry ; Jump tables Prot 4 Call 0 jmp MCFG_Entry ; Jump tables Prot 4 Call 1 (MCFG) jmp MTX_Entry ; Jump tables Prot 4 Call 2 (MTX) jmp MRX_Entry_TRANSPARENT_FIFO ; Jump tables Prot 4 Call 3 (MRX-TRANSPARENT-RFC FIFO MODE) jmp MNOP_Entry ; Jump tables Prot 4 Call 5 jmp MNOP_Entry ; Jump tables Prot 4 Call 6 jmp MNOP_Entry ; Jump tables Prot 4 Call 7 jmp MNOP_Entry ; Jump tables Prot 5 Call 0 jmp MCFG_Entry ; Jump tables Prot 5 Call 1 (MCFG) jmp MTX_MFSK ; Jump tables Prot 5 Call 2 (MTX multi mode) jmp MRX_Entry_FIFO_BLIND ; Jump tables Prot 5 Call 3 (MRX-BLIND-RFC FIFO MODE) ;;; End of Command Processing, start of the commands themselves ;;; -------------------------------------------------------------------------------- ;;; General end of command routine ;;; CMD_OK_END: mov CMD_OK, r0 ; Normal end of command CPE_NOTIFY: outclr RFESEND ; Clear RFE send outset MCEEVENTCLR0 ; Clear all events: NOTE, this will BREAK command pipelining! outset MCEEVENTCLR1 ; Clear all events outset MCEEVENTCLR2 ; Clear all events input MDMSTATUS, r1 ; or r1, r0 ; output r0, MDMSTATUS outbset 0, MCESTROBES0 ; Notify CPE of completion jmp CMD_PROC ; Ready for another command ;;; -------------------------------------------------------------------------------- ;;; MNOP ;;; MNOP_Entry: jmp CMD_OK_END ;;; -------------------------------------------------------------------------------- ;;; iqdump IQDUMP (Generic FSK) ;;; ;;; This iqdump supports a Generic 2(G)FSK modem in which most of the parameters ;;; are configured by the upper layer. ;;; In general, it uses the standard 2(G)FSK configuration, and supports three FECs ;;; Option 1) No FEC (use MLSE in RX) ;;; Option 2) 1/2 K=4 FEC, as defined in the 802.15.4g FSK standard ;;; Option 3) TBD ;;; ;;; -------------------------------------------------------------------------------- ;;; -------------------------------------------------------------------------------- ;;; MCFG ;;; -------------------------------------------------------------------------------- MCFG_Entry: ; NOTE: = lli text, r0; jsr _DBG_PRINT DBG_PRINT0 "MCFG - IQ Dump Configuration" lli MDMCONF_IQDUMP, r1 ; Points R1 to the WMBUS data lli MDMCONF_IQDUMP_FIRST_REG, r2 ; Points to the first IO address for configiration lli MDMCONF_IQDUMP_LAST_REG, r0 ; Points to the last of the IO address sub r2,r0 ; R0 now holds number of iterations for CONF_LOOP, r0 implitly used by loop instruction MCFG_Iqdump_Loop: lmd (r1), r3 ; Load ROM data output r3, (r2) ; Send to register bank add 1, r1 ; Increase memory pointer add 1, r2 ; Increase regbank pointer loop MCFG_Iqdump_Loop ; lmd VITACCCTRL_REG_DEFAULT,r0 output r0,VITACCCTRL lmd CORR_DEFG_THR, r0 output r0, DEMC1BE11 output r0, DEMC1BE12 lli DEMFB2P0, r2 ; First register to clear lli VITCTRL, r0 ; Last register to clear sub r2,r0 ; R0 now holds number of iterations for first zero loop, r0 implitly used by loop instruction beq ZERO_DONE ; No values to write mov 0, r3 ; Set all regs to 0 ZERO_LOOP: output r3, (r2) ; Send to register bank add 1, r2 ; Increase regbank pointer loop ZERO_LOOP ; ZERO_DONE: ;; Set tone duration in BRMACC0 lmd TX_TONE_COUNT, r0 ; output r0, BRMACC0 ; ;; Set Collision restart for CDC FIFO outclr MODCTRL ; outbset MODCTRL_CDC_COL_RESTART, MODCTRL ; jmp CMD_OK_END ; Done ;;; -------------------------------------------------------------------------------- ;;; MTX Common Entry ;;; -------------------------------------------------------------------------------- ;;; -------------------------------------------------------------------------- ;;; MTX GenericFSK Send Preamble and Sync Word function ;;; MTX_Iqdump_Common_Preamble: ;; Fetch information from MDMPAR0|2: Preamble settings input MDMCMDPAR2, r0 output r0, MODPREAMBLE ; Send directly to MODPREAMBLE input MDMCMDPAR0, r0 sr0 8, r0 ; [15:8] => Sync Word Length bclr 7, r0 mov r0, r1 ; R1 = SyncWordLength add 1, r1 ; In [32..1] format ;; We are now going to process the SyncWord, and prepare it for later ;; In general this is where we are putting things: ;; R2 = MDMSYNC0, R3 = 15, R4 = MDMSYNC1, R5 = 15 ;; This would apply to a full 32-bit sync word. If the syncword is ;; between 32 to 17 bits, we would transmit both. If is 16 or less ;; only the second one (R4) would be transmitted. ;; Also, those syncwords come left-aligned. We need to bit-shift to be ;; right aligned. ;; Step 0. General Case (32-bit case) input MDMSYNC0, r2 input MDMSYNC1, r4 lli 15, r3 lli 15, r5 ;; Step 1. Check if SyncWord is 32 bits lli 32, r0 cmp r0, r1 ; Special case, 32 bits beq MTX_Iqdump_Common_Preamble_RFESEND ; if yes, we are done ;; Step 2. Check if in [31..17] bits range lli 16, r0 cmp r1, r0 beq MTX_Iqdump_Common_Preamble_16bitSyncWord bpl MTX_Iqdump_Common_Preamble_ShortSyncWord ;; R2 = MDMSYNC0-right-aligned, R3 = num of bits, R4 = MDMSYNC1, R5 = 15 MTX_Iqdump_Common_Preamble_LongSyncWord: mov r1, r3 ; R3 = [32..17] sub r0, r3 ; R3 = R3-16 sub r3, r0 ; R0 = 16-R3 sub 1, r3 ; R3 = # bits to send sub 1, r0 ; R0 = # bits to shift down MTX_Iqdump_Common_Preamble_SyncWord_ShiftLoop1: sr0 1, r2 ; MDMSYNC0-right-aligned loop MTX_Iqdump_Common_Preamble_SyncWord_ShiftLoop1 jmp MTX_Iqdump_Common_Preamble_RFESEND ;; Step 3. Must be in [16..1] bits range MTX_Iqdump_Common_Preamble_16bitSyncWord: mov 0x1F, r3 ; Illegal value to indicate 16 bit or shorter sw jmp MTX_Iqdump_Common_Preamble_RFESEND MTX_Iqdump_Common_Preamble_ShortSyncWord: ;; Results, R2 = XXX, R3 = 0, R4 = MDMSYNC1, R5 = num of bits mov 0x1F, r3 ; Illegal value to indicate 16 bit or shorter sw mov r1, r5 ; R5 = [16..1] lli 16, r0 ; R0 = 16 sub r5, r0 ; R0 = 16-R5 sub 1, r5 ; R5 = # bits to send sub 1, r0 ; R0 = # bits to shift down MTX_Iqdump_Common_Preamble_SyncWord_ShiftLoop2: sr0 1, r4 ; MDMSYNC0-right-aligned loop MTX_Iqdump_Common_Preamble_SyncWord_ShiftLoop2 ;; and done with SyncWordProcessing MTX_Iqdump_Common_Preamble_RFESEND: ;; ============================================ ;; Wait for RAT event outbset MCEEVENT1_RAT_EVENT0, MCEEVENTMSK1 ; enable wait for RAT wait outbset MCEEVENT1_RAT_EVENT0, MCEEVENTCLR1 ; Clear event again outbclr MCEEVENT1_RAT_EVENT0, MCEEVENTMSK1 ; disable wait for RAT ;; Send message to RFE that modulation is starting outbset 0,RFESEND ;; Set up timer for tone in front of preamble outbset TIMCTRL_ENABLETIMER, TIMCTRL ; input BRMACC0, r0 ; Tone count output r0, TIMPERIOD ; outbset MCEEVENT0_TIMER_IRQ, MCEEVENTCLR0 ; Clear IRQ ;; A delay to precisely time the start of the Preamble outbset MCEEVENT0_TIMER_IRQ, MCEEVENTMSK0 ; Enable the mask! wait ;; Enable modulator and timebase now outbset MDMENABLE_TIMEBASE, MDMENABLE outbset MDMINIT_TIMEBASE, MDMINIT outbset MCEEVENT0_TIMER_IRQ, MCEEVENTCLR0 ; Clear IRQ outbclr MCEEVENT0_TIMER_IRQ, MCEEVENTMSK0 ; Disable Mask outclr TIMCTRL ; Switch off timer ;; Step 2. Go to Preamble insert, Send MDMSYNC0, MDMSYNC1 outbset MODCTRL_PREAMBLEINSERT, MODCTRL ; Go to preamble insert mode outbset MDMENABLE_MODULATOR, MDMENABLE outbset MDMINIT_MODULATOR, MDMINIT ;; Preamble insert mode from start MTX_Iqdump_FirstBit: outclr MODPRECTRL ; Send ONE bit outbset MCEEVENT1_PREAMBLE_DONE, MCEEVENTMSK1 ; wait for preamble done wait outbset MCEEVENT1_PREAMBLE_DONE, MCEEVENTCLR1 ; Clear Preamble Done ;; Reload MOCPRECTRL with proper value now input MDMCMDPAR0, r0 output r0, MODPRECTRL ; Send directly to MODPRECTRL again MTX_Iqdump_Common_Preamble_Loop: wait outbset MCEEVENT1_PREAMBLE_DONE, MCEEVENTCLR1 ; Clear Preamble Done ;; Infinite preamble? Indicated by MSB of MDMCMDPAR0 input MDMCMDPAR0, r0 btst 15, r0 bne MTX_Iqdump_Common_Preamble_Loop ;; Preamble is done now, start with SyncWord. Use the R2, R3, R4, R5 values from above mov 0x1F, r0 ; cmp r0, r3 ; check if less than 16 bit SW beq MTX_Iqdump_Common_Preamble_Send_One_SW MTX_Iqdump_Common_Preamble_Send_Two_SW: output r3, MODPRECTRL output r2, MODPREAMBLE wait outbset MCEEVENT1_PREAMBLE_DONE, MCEEVENTCLR1 ; Clear Preamble Done MTX_Iqdump_Common_Preamble_Send_One_SW: output r5, MODPRECTRL output r4, MODPREAMBLE wait outbset MCEEVENT1_PREAMBLE_DONE, MCEEVENTCLR1 ; Clear Preamble Done outbset MCEEVENT1_PREAMBLE_DONE, MCEEVENTMSK1 ; Disable PREAMBLE_DONE from now on outbclr MODCTRL_PREAMBLEINSERT, MODCTRL ; No more preamble insert rts ;;; -------------------------------------------------------------------------- ;;; MTX GenericFSK Termination ;;; MTX_Iqdump_Termination: ;; Termination, Step 2. wait 4 clock baud periods before switching off outbclr MCEEVENT1_CLKEN_BAUD, MCEEVENTMSK1 ; Disable CLKEN_BAUD events lli 0x03,r0 ; Wait for 4 baud periods before switching output r0, TIMCTRL ; the modulator off lli 0x04, r0 ; Four periods output r0, TIMPERIOD outbset MCEEVENT0_TIMER_IRQ, MCEEVENTCLR0 ; Clear IRQ outbset MCEEVENT0_TIMER_IRQ, MCEEVENTMSK0 ; Enable the mask! wait outbset MCEEVENT0_TIMER_IRQ, MCEEVENTCLR0 ; Clear IRQ outbclr MCEEVENT0_TIMER_IRQ, MCEEVENTMSK0 ; Disable Mask outclr TIMCTRL ; Switch off counter outbclr MDMENABLE_MODULATOR, MDMENABLE ; Disable modulator, timebase outbclr MDMENABLE_TIMEBASE, MDMENABLE ;; Send message to RFE that modulation is stopping outbclr 0, RFESEND ; rts ;;; -------------------------------------------------------------------------- ;;; No FEC, directly read data from FIFO and send out. TOPsm is mostly free ;;; MTX_Entry: outset MCEEVENTCLR0 outset MCEEVENTCLR1 ;; Normal mode (1bit per symbol) proceeds here DBG_PRINT0 "IQDump___ NoFEC, TX Started" lli 0x10, r0 ; MDMFIFORDCTRL, 1 bits reads, from modem output r0, MDMFIFORDCTRL jsr MTX_Iqdump_Common_Preamble ; Send Preamble outbset MODCTRL_FECENABLE, MODCTRL ; And enable the noFEC-"FEC" outbset MCEEVENT0_FIFO_ERR_UNDERFLOW, MCEEVENTCLR0 ; clear any previous outbset MCEEVENT0_FIFO_ERR_UNDERFLOW, MCEEVENTMSK0 ; allow FIFO UNDERFLOW errors wait ; WAITS for FIFO underflow here outbclr MCEEVENT0_FIFO_ERR_UNDERFLOW, MCEEVENTMSK0 ; Remove FIFO UNDERFLOW events jsr MTX_Iqdump_Termination jmp CMD_OK_END ;;; -------------------------------------------------------------------------- ;;; Multi-level FSK modulation, directly feed 4-bits into SOFT TX register, at baud rate ;;; MTX_MFSK: outset MCEEVENTCLR0 outset MCEEVENTCLR1 DBG_PRINT0 "IQDump___ Multi-level FSK TX Mode" lli 0x03, r0 ; 4 bit reads, from register output r0, MDMFIFORDCTRL ;; Set modctrl to read from modsofftx: outbset MODCTRL_SOFTTXENABLE, MODCTRL ;; ============================================ ;; Wait for RAT event outbset MCEEVENT1_RAT_EVENT0, MCEEVENTMSK1 ; enable wait for RAT wait outbset MCEEVENT1_RAT_EVENT0, MCEEVENTCLR1 ; Clear event again outbclr MCEEVENT1_RAT_EVENT0, MCEEVENTMSK1 ; disable wait for RAT ;; Send message to RFE that modulation is starting outbset 0,RFESEND ;; Enable modulator and timebase now outbset MDMENABLE_TIMEBASE, MDMENABLE outbset MDMINIT_TIMEBASE, MDMINIT outbset MDMENABLE_MODULATOR, MDMENABLE outbset MDMINIT_MODULATOR, MDMINIT ;; This mode uses no preamble or SW, just direct symbols from the FIFO. ;; It starts by waiting if no symbols are present mov 0, r0 ; Start by sending symbol 0 output r0, MODSOFTTX ; ready to go outbset MCEEVENT1_CLKEN_BAUD, MCEEVENTCLR1 ; Clear CLKEN Baud outbset MCEEVENT1_CLKEN_BAUD, MCEEVENTMSK1 ; will iterate on CLKEN baud ticks MTX_MFSK_ToneLoop: wait outbset MCEEVENT1_CLKEN_BAUD, MCEEVENTCLR1 ; Clear CLKEN Baud input MDMFIFOSTA, r0 and 2, r0 ; Check with bit 1 (data present) cmp 2, r0 bne MTX_MFSK_ToneLoop ;; At this point, we can actually read data from the FIFO, 4 bits at a time DBG_PRINT0 "Starting MFSK Symbol Loop" MTX_MFSK_SymbolLoop: wait outbset MCEEVENT1_CLKEN_BAUD, MCEEVENTCLR1 ; Clear CLKEN Baud input MDMFIFORD, r1 ; get new nibble output r1, MODSOFTTX ; send to MODISF nop nop nop input MDMFIFOSTA, r2 and 2, r2 ; check with bit 1 (data present) ;; DEBUG: ;sl0 8, r1 ; Make signed ;sl0 4, r1 ;srx 8, r1 ; make signed ;srx 4, r1 ;DBG_PRINT1 "Payload: %d", r1 ;; END OF DEBUG cmp 2, r2 beq MTX_MFSK_SymbolLoop ;; ;; FIFO is now empty, so terminate DBG_PRINT0 "Stopping MFSK Symbol Loop" outbclr MODCTRL_SOFTTXENABLE, MODCTRL jsr MTX_Iqdump_Termination jmp CMD_OK_END ;;; -------------------------------------------------------------------------- ;;; MRX IQdump REGISTER Blind MODE, update the following registers DEMFRAC4/DEMFRAC5/DEMPDIF0 ;;; Infinite, must be end by abort command ;;; MRX_Entry_REG_BLIND: ;;; Just to be sure those interrupts are disabled, there is no normal termination. outbclr MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; disable the clkenbaud_4f event outbclr MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outbclr MCEEVENT2_C1BE_B_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outset MCEEVENTCLR0 outset MCEEVENTCLR1 jsr MRX_SETUP DBG_PRINT0 "########################### Blind REGISTER MODE -> IQ Dump starting at once ########################" outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; enable the clkenbaud_4f event lli 3, r5 ; to trigger capture of I and Q LOOP_SAMPLES_BLIND: wait output r5, RDCAPT1 ; capture I + Q from FRAC outbset RDCAPT0_DEMPDIF0, RDCAPT0 ; capture instantaneous frequency outbset MCESTROBES0_EVENT0, MCESTROBES0 ; signal 4BAUD outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4f event jmp LOOP_SAMPLES_BLIND ; ;;; -------------------------------------------------------------------------- ;;; MRX IQdump blind FIFO MODE started where IQ samples are moved into RFC FIFO ;;; - Packet size can be programmed by the API ;;; MRX_Entry_FIFO_BLIND: ;;; Just to be sure those interrupts are disabled, there is no normal termination. outbclr MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; disable the clkenbaud_4f event outbclr MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outbclr MCEEVENT2_C1BE_B_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outset MCEEVENTCLR0 outset MCEEVENTCLR1 jsr MRX_SETUP lli 24, r11 ; Set Word Counter lli 0x0, r0 ; MDMFIFOWRCTRL, 1 bits write, from modem output r0, MDMFIFOWRCTRL mov 0, r12 ; Clear bit counter mov 1, r8 ; preload register for known pattern generation lmd IQDUMP_TEST_MAX_VAL, r10 ; Test pattern wrap value lmd IQDUMP_MAX_POS_VAL, r13 ; Positive Saturation value for 12 bit resolution lmd IQDUMP_MIN_NEG_VAL, r14 ; Negative Saturation value for 12 bit resolution mov r10, r9 ; preload register for known pattern generation outbset MCESTROBES0_EVENT0, MCESTROBES0 ; signal Sync Found immediately outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; enable the clkenbaud_4 event ;;; Add delay between sync found is signalled and first RFC FIFO write. ;;; Wait loop for cm0 to be ready to do full speed readout from RFC FIFO (otherwise longer delay than 8.4us has been observed!) lli 5, r0 LOOP_SAMPLES_FIFO_BLIND_WAIT: outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4 event wait loop LOOP_SAMPLES_FIFO_BLIND_WAIT DBG_PRINT0 "########################### Blind RFC FIFO Mode -> IQ Dump starting at once (DataRate <= 12,5 kbps) ########################" lli 3, r5 ; to trigger capture of I and Q LOOP_SAMPLES_FIFO_BLIND: outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4 event wait ; Only 4baud event wakes up TopSM output r5, RDCAPT1 ; capture I + Q from FRAC input DEMFRAC4, r0 jsr SignExt_and_Saturate ; Saturate to 12 bit word input MDMSPAR2, r1 ; MDMSPAR2[0] 0-> IQ data, 1 -> Known Test pattern (counter value) btst 0, r1 beq LOOP_SAMPLES_FIFO_BLIND_DEMFRAC4WR mov r8, r0 ; Known link test pattern cmp r10, r8 bne TEST_PATTERN_ADD_BLIND mov 0, r8 TEST_PATTERN_ADD_BLIND: add 1, r8 LOOP_SAMPLES_FIFO_BLIND_DEMFRAC4WR: jsr MDMFIFOWR_AND_WAIT10 input DEMFRAC5, r0 jsr SignExt_and_Saturate ; Saturate to 12 bit word input MDMSPAR2, r1 ; MDMSPAR2[0] 0-> IQ data, 1 -> Known Test pattern (counter value) btst 0, r1 beq LOOP_SAMPLES_FIFO_BLIND_DEMFRAC5WR mov r9, r0 ; Known link test pattern sub 1, r9 cmp 0, r9 bne LOOP_SAMPLES_FIFO_BLIND_DEMFRAC5WR mov r10, r9 LOOP_SAMPLES_FIFO_BLIND_DEMFRAC5WR: jsr MDMFIFOWR_AND_WAIT10 input MDMCMDPAR1, r4 ; check if length has been given cmp 0, r4 ; if length is zero, infinite length is assumed beq LOOP_SAMPLES_FIFO_BLIND add r11, r12 ; increment bit counter cmp r4, r12 ; End if rxbits - pktLen >= 0 bpl MRX_GenFSK_CommonEnd ; if so jump to end jmp LOOP_SAMPLES_FIFO_BLIND ; ;;; -------------------------------------------------------------------------- ;;; MRX Transparent FIFO MODE started where pdiff hard decisions are moved into FIFO ;;; - Packet size and stop AGC can be programmed by the API ;;; MRX_Entry_TRANSPARENT_FIFO: ;;; Just to be sure those interrupts are disabled, there is no normal termination. outbclr MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; disable the clkenbaud_4f event outbclr MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outbclr MCEEVENT2_C1BE_B_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outset MCEEVENTCLR0 outset MCEEVENTCLR1 jsr MRX_SETUP outclr MDMFIFOWRCTRL ; MDMFIFOWRCTRL, 1 bits write, from modem mov 0, r12 ; Clear bit counter mov 0, r5 ; Data filtered soft samples outbset MCESTROBES0_EVENT0, MCESTROBES0 ; signal Sync Found immediately outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; enable the clkenbaud_4 event ;;; Add delay between sync found is signalled and first RFC FIFO write. ;;; Wait loop for cm0 to be ready to do full speed readout from RFC FIFO (otherwise longer delay than 8.4us has been observed!) lli 5, r0 LOOP_SAMPLES_TRANSPARENT_FIFO_WAIT: outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4 event wait loop LOOP_SAMPLES_TRANSPARENT_FIFO_WAIT DBG_PRINT0 "########################### Transparent FIFO Mode -> PDIFF streaming starting at once ########################" lmd TRANSPARENT_CAPT, r13 ; Combined RDCAPT0_DEMPDIF0 and RDCAPT0_DEMFIFE2 input VITACCCTRL, r14 ; Capture for later use, time optimization LOOP_SAMPLES_TRANSPARENT_FIFO: outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4 event wait ; Only 4baud event wakes up TopSM input MDMSPAR1, r0 btst 0, r0 beq CAPT_FREQUENCY input RFESEND, r0 btst 1, r0 bne CAPT_FREQUENCY outbset 1, RFESEND ; Notify by bit 1 in RFESEND (i.e. Stop AGC) DBG_PRINT0 "########################### Transparent FIFO Mode Stop AGC ########################" CAPT_FREQUENCY: output r13, RDCAPT0 ; capture instantaneous frequency and fife input DEMPDIF0, r2 sl0 8, r2 ; Sign Extend srx 8, r2 input DEMFIFE2,r0 sl0 8, r0 ; Sign Extend srx 8, r0 ; ;mov r0, r9 ; For debug only sub r0, r2 ; Subtract Frequency offset and 3, r14 ; extract lower two bits cmp 0, r14 ; beq NO_IIR_FILTER ; cmp 2, r14 ; beq IIR_K4 ; cmp 3, r14 ; beq IIR_K8 ; IIR_K2: ;; make a simple IIR y[n] = y[n-1]/2 + x[n]/2 ;; r5 = y ;; first calculate y[n-1]*2 mov r5, r6 ; y[n-1] into r6 add r2, r6 ; add new sample srx 1, r6 ; scale back to normal again mov r6, r5 ; copy to r5 jmp HARD_DECISION ; IIR_K4: ;; make a simple IIR y[n] = y[n-1]3/4 + x[n]/4 ;; r5 = y ;; first calculate y[n-1]*3/4 mov r5, r6 ; y[n-1] into r6 sl0 2, r6 ; multiply by 4 sub r5,r6 ; sub x1 to get multiply by 3 add r2, r6 ; add new sample srx 2, r6 ; scale back to normal again mov r6, r5 ; copy to r5 jmp HARD_DECISION ; IIR_K8: ;; make a simple IIR y[n] = y[n-1]7/8 + x[n]/8 ;; r5 = y ;; first calculate y[n-1]*7/8 mov r5, r6 ; y[n-1] into r6 sl0 3, r6 ; multiply by 8 sub r5,r6 ; sub x1 to get multiply by 7 add r2, r6 ; add new sample srx 3, r6 ; scale back to normal again mov r6, r5 ; copy to r5 jmp HARD_DECISION ; NO_IIR_FILTER: mov r2, r6 ; HARD_DECISION: ;mov r6, r8 ; For debugging only sr0 7, r6 output r6, MDMFIFOWR ; Send hard decision to FIFO ;DBG_PRINT1 "Sample: %d", r8 input MDMCMDPAR1, r4 ; check if length has been given cmp 0, r4 ; if length is zero, infinite length is assumed beq LOOP_SAMPLES_TRANSPARENT_FIFO add 1, r12 ; increment bit counter cmp r4, r12 ; End if rxbits - pktLen >= 0 bpl MRX_GenFSK_CommonEnd ; if so jump to end jmp LOOP_SAMPLES_TRANSPARENT_FIFO ; ;;; -------------------------------------------------------------------------- ;;; Sub-routine wirte to FIFO and wait ;;; ;;; MDMFIFOWR_AND_WAIT10: mov r0, r1 lli 11, r0 LOOP_MDMFIFOWR: output r1, MDMFIFOWR sr0 1, r1 mov r0, r0 ; mov r0, r0 ; mov r0, r0 ; loop LOOP_MDMFIFOWR rts ;;; -------------------------------------------------------------------------- ;;; Sub-routine doing sign extension and Saturate to 12 bits ;;; ;;; SignExt_and_Saturate: sl0 3, r0 srx 3, r0 ; Sign extend to 16 bits cmp r13, r0 ; bpl Pos_Sat ; if r0 is > MAX_VAL, saturate to MAX_VAL cmp r14, r0 bmi Neg_Sat ; if r0 is < MIN_VAL, saturate to MIN_VAL rts Pos_Sat: mov r13, r0 rts Neg_Sat: mov r14, r0 rts ;;; -------------------------------------------------------------------------- ;;; MRX IQdump REGISTER Sync MODE, update the following registers DEMFRAC4/DEMFRAC5/DEMPDIF0 ;;; Infinite, must be end by abort command ;;; IQ dump start after SFD detection ;;; MRX_Entry_REG_SYNC: DBG_PRINT0 "########################### IQ Dump REGISTER MODE, RX started, Wait for Sync ########################" ;;; Just to be sure those interrupts are disabled, there is no normal termination. outbclr MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; disable the clkenbaud_4f event outbclr MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outbclr MCEEVENT2_C1BE_B_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outset MCEEVENTCLR0 outset MCEEVENTCLR1 jsr MRX_SETUP ;; Enable Correlator event outbset MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTCLR2 ; Clear correlator event outbset MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; enable correlation event SYNC_SEARCH: wait input MCEEVENT2, r0 ; btst MCEEVENT2_C1BE_A_POS_PEAK, r0 ; check if correlator peak bne DUMP_SAMPLES ; jmp SYNC_SEARCH ; otherwise continue sync search DUMP_SAMPLES: outbset 1, RFESEND ; Notify by bit 1 in RFESEND (sync found) DBG_PRINT0 "########################### Sync Found REGISTER MODE -> IQ Dump starting ########################" outbset MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTCLR2 ; clear the event flag outbclr MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; enable the clkenbaud_4f event lli 3, r5 ; to trigger capture of I and Q LOOP_SAMPLES: wait output r5, RDCAPT1 ; capture I + Q from FRAC outbset RDCAPT0_DEMPDIF0, RDCAPT0 ; capture instantaneous frequency outbset MCESTROBES0_EVENT0, MCESTROBES0 ; signal 4BAUD to cm0/cm3 outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4f event jmp LOOP_SAMPLES ; ;;; -------------------------------------------------------------------------- ;;; MRX IQdump Sync FIFO MODE started where IQ samples are moved into RFC FIFO ;;; - Packet size can be programmed by the API ;;; - IQ dump start after SFD detection ;;; MRX_Entry_FIFO_SYNC: DBG_PRINT0 "########################### IQ Dump through RFC FIFO, RX started, Wait for Sync (DataRate <= 12.5 kbps) ########################" ;;; Just to be sure those interrupts are disabled, there is no normal termination. outbclr MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; disable the clkenbaud_4f event outbclr MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outbclr MCEEVENT2_C1BE_B_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outset MCEEVENTCLR0 outset MCEEVENTCLR1 jsr MRX_SETUP lli 24, r11 ; Set Word Counter lli 0x0, r0 ; MDMFIFOWRCTRL, 1 bits write, from modem output r0, MDMFIFOWRCTRL mov 0, r12 ; Clear bit counter mov 1, r8 ; preload register for known pattern generation lmd IQDUMP_TEST_MAX_VAL, r10 ; Test pattern wrap value lmd IQDUMP_MAX_POS_VAL, r13 ; Positive Saturation value for 12 bit resolution lmd IQDUMP_MIN_NEG_VAL, r14 ; Negative Saturation value for 12 bit resolution mov r10, r9 ; preload register for known pattern generation ;; Enable Correlator event outbset MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTCLR2 ; Clear correlator event outbset MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; enable correlation event SYNC_SEARCH_FIFO: wait input MCEEVENT2, r0 ; btst MCEEVENT2_C1BE_A_POS_PEAK, r0 ; check if correlator peak bne DUMP_SAMPLES_FIFO ; jmp SYNC_SEARCH_FIFO ; otherwise continue sync search DUMP_SAMPLES_FIFO: outbset MCESTROBES0_EVENT0, MCESTROBES0 ; signal Sync Found outbset 1, RFESEND ; Notify by bit 1 in RFESEND (sync found) DBG_PRINT0 "########################### Sync Found RFC FIFO MODE-> IQ samples through FIFO starting ########################" outbset MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTCLR2 ; clear the event flag outbclr MCEEVENT2_C1BE_A_POS_PEAK, MCEEVENTMSK2 ; disable correlation event outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; enable the clkenbaud_4 event ;;; Add delay between sync found is signalled and first RFC FIFO write. ;;; Wait loop for cm0 to be ready to do full speed readout from RFC FIFO (otherwise longer delay than 8.4us has been observed!) lli 2, r0 LOOP_SAMPLES_FIFO_SYNC_WAIT: outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4 event wait loop LOOP_SAMPLES_FIFO_SYNC_WAIT lli 3, r5 ; to trigger capture of I and Q LOOP_SAMPLES_FIFO_SYNC: outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4 event wait ; Only 4baud event wakes up TopSM output r5, RDCAPT1 ; capture I + Q from FRAC input DEMFRAC4, r0 jsr SignExt_and_Saturate ; Saturate to 12 bit word input MDMSPAR2, r1 ; MDMSPAR2[0] 0-> IQ data, 1 -> Known Test pattern (counter value) btst 0, r1 beq LOOP_SAMPLES_FIFO_SYNC_DEMFRAC4WR mov r8, r0 ; Known link test pattern cmp r10, r8 bne TEST_PATTERN_ADD_SYNC mov 0, r8 TEST_PATTERN_ADD_SYNC: add 1, r8 LOOP_SAMPLES_FIFO_SYNC_DEMFRAC4WR: jsr MDMFIFOWR_AND_WAIT10 input DEMFRAC5, r0 jsr SignExt_and_Saturate ; Saturate to 12 bit word input MDMSPAR2, r1 ; MDMSPAR2[0] 0-> IQ data, 1 -> Known Test pattern (counter value) btst 0, r1 beq LOOP_SAMPLES_FIFO_SYNC_DEMFRAC5WR mov r9, r0 ; Known link test pattern sub 1, r9 cmp 0, r9 bne LOOP_SAMPLES_FIFO_SYNC_DEMFRAC5WR mov r10, r9 LOOP_SAMPLES_FIFO_SYNC_DEMFRAC5WR: jsr MDMFIFOWR_AND_WAIT10 input MDMCMDPAR1, r4 ; check if length has been given cmp 0, r4 ; if length is zero, infinite length is assumed beq LOOP_SAMPLES_FIFO_SYNC add r11, r12 ; increment bit counter cmp r4, r12 ; End if rxbits - pktLen >= 0 bpl MRX_GenFSK_CommonEnd ; if so jump to end jmp LOOP_SAMPLES_FIFO_SYNC ; MRX_SETUP: ;; Wait for RFE to finish enabling Rx chain input RFERCEV, r0 ; btst 3, r0 ; bne RFE_Started ; outbset MCEEVENT0_RFECMD_IRQ, MCEEVENTMSK0 wait ; Wait for RFE to be done outbset MCEEVENT0_RFECMD_IRQ, MCEEVENTCLR0 ;; Disable event outbclr MCEEVENT0_RFECMD_IRQ, MCEEVENTMSK0 jmp MRX_SETUP ; Go back to test received event RFE_Started: DBG_PRINT0 "########################### RX Started ########################" outbset MCEEVENT0_CPEFWEVENT0, MCEEVENTCLR0 ; Clear any pending CPEFWEVENT0 ;; Enable Demodulator, ADCDIG, Timebase and submodules ;;; Enable ADCDIG, and start sync search outbset MDMENABLE_ADCDIG, MDMENABLE outbset MDMINIT_ADCDIG, MDMINIT ;;; Enable RX, and start sync search outbset MDMENABLE_DEMODULATOR, MDMENABLE outbset MDMINIT_DEMODULATOR, MDMINIT ;; Enable timebase now. outbset MDMENABLE_TIMEBASE, MDMENABLE outbset MDMINIT_TIMEBASE, MDMINIT ;; Compute MASKA+MASKB for SyncWords < 32 bits ;; (the threshold adjusted automatically by the CPE) input DEMC1BE0, r0 ; Load DEMC1BE0 lmd DEMC1BE0_MASKA_BITS, r2 ; Clear only bits [15:6], keep rest and r2, r0 ; input MDMCMDPAR0, r3 ; Get number of bits in SyncWord again sr0 8, r3 ; MDMCMDPAR0[15:8] bclr 7, r3 ; Ignore MSB always output r3, DEMSWQU0 ; set SyncWordBits-1 in DEMSWQU0 for future reference lli 31, r2 ; Compute 31-X sub r3, r2 ; R2 = 31-SyncWordBits sl0 DEMC1BE0_MASKA, r2 ; Shift to proper position mov r2, r1 ; copy sl0 5, r1 ; shift to mask b position or r1, r2 ; combine mask a + mask b or r2, r0 ; put together output r0, DEMC1BE0 ; and done ;; IQDUMP use running sum hardware in DSBU for frequency offset estimation, FOE (for supporting non random data) ;; The DSBU delay shall be the synw word length+a few samples for processing delay ;; DSBBU avg length shall be set to 8, 16 or 32 symbols (rounded down from the sync word length) due to division needed ;;; Start calculating DSBU.LEN mov r3, r0 ; Load r0 with SyncWordBits-1 add 1,r0 ; Calculate SyncWordBits sr0 3,r0 ; Floor(SyncWordBits/8) (number of whole bytes in sw) btst 1, r0 ; we don't allow 3 bytes averaging, set this to two bytes beq GEN_FSK_AVG_LEN_CORRECT mov 2, r0 ; force a 16 bit avg length GEN_FSK_AVG_LEN_CORRECT: sl0 5,r0 ; 4*8*Floor(SyncWordBits/8), i.e. osr = 4 (number of samples in DSBU averaging) mov r0, r3 ; DSBUAVGLENGTH for future use sl0 8, r0 ; Shift to proper position add 3,r0 ; DSBUDELAY = DSBUAVGLENGTH+3 output r0, DEMDSBU ;; Find imbalance in that part of sync word which is used in dsbu averaging ;; Implement this equation: DEMSWIMBAL = (sum(sw)-DEMDSBU.dsbuavglength/2)*4*32/DEMDSBU.dsbuavglength mov 0, r2 ; mov 0, r4 ; GEN_FSK_DSBU_AVG_LEN_32_SYMBOLS_CHECK: btst 7, r3 ; Check if we got 128 sample averaging beq GEN_FSK_DSBU_AVG_LEN_16_SYMBOLS_CHECK ; GEN_FSK_DSBU_AVG_LEN_32_SYMBOLS: input MDMSYNC0, r0 ; 16 first symbols of sw A is in MDMSYNC0 output r0, COUNT1IN ; Find number of ones input COUNT1RES, r2 ; r2 is keeping the number of 1s in the sw A sub 8, r2 ; subtract 8 to get imbalance between 1's and 0's in this 16 bits part of SW input MDMSYNC2, r0 ; 16 first symbols of sw A is in MDMSYNC2 output r0, COUNT1IN ; Find number of ones input COUNT1RES, r4 ; r4 is keeping the number of 1s in the sw B sub 8, r4 ; subtract 8 to get imbalance between 1's and 0's in this 16 bits part of SW jmp GEN_FSK_DSBU_AVG_LEN_16_SYMBOLS ; For 32 bit sync use both SYNC0 and SYNC1 GEN_FSK_DSBU_AVG_LEN_16_SYMBOLS_CHECK: btst 6, r3 ; Check if DSBU memory is 16 symbols (or 64 samples) beq GEN_FSK_DSBU_AVG_LEN_8_SYMBOLS ; GEN_FSK_DSBU_AVG_LEN_16_SYMBOLS: input MDMSYNC1, r0 ; 16 Last transmitted sync bits of sw A is located in SYNC1, swlen>=16 output r0, COUNT1IN ; Find number of ones in the sw and store in DEMSWIMBAL for future reference input COUNT1RES, r0 ; sub 8, r0 ; subtract 8 to get imbalance in this 16 bit part of sw A add r0, r2 ; load r2 = sum(x) input MDMSYNC3, r0 ; 16 Last transmitted sync bits of sw B is located in SYNC1, swlen>=16 output r0, COUNT1IN ; Find number of ones in the sw and store in DEMSWIMBAL for future reference input COUNT1RES, r0 ; sub 8, r0 ; subtract 8 to get imbalance in this 16 bit part of sw B add r0, r4 ; load r4 = sum(x) jmp GEN_FSK_CALC_DEMSWIMBAL ; sum(sw) done for 32 symbols FOE GEN_FSK_DSBU_AVG_LEN_8_SYMBOLS: input MDMSYNC1, r0 ;8 Last transmitted sync bits of SW A is located in SYNC1(31:24), swlen>=8 lmd IQDUMP_MASK_BITS_15_8, r1 and r1,r0 output r0, COUNT1IN ; Find number of ones in the sw A and store in DEMSWIMBAL for future reference input COUNT1RES, r2 ; load r2 = sum(x) sub 4, r2 ; subtract 4 to get imbalance in this byte of SW A input MDMSYNC3, r0 ;8 Last transmitted sync bits of SW B is located in SYNC3(31:24), swlen>=8 lmd IQDUMP_MASK_BITS_15_8, r1 and r1,r0 output r0, COUNT1IN ; Find number of ones in the sw B and store in DEMSWIMBAL for future reference input COUNT1RES, r4 ; load r4 = sum(x) sub 4, r4 ; subtract 4 to get imbalance in this byte of SW B GEN_FSK_CALC_DEMSWIMBAL: ;; balance between 1's and 0's in SW will have to be scaled with the dsbu avg length ;; 32 bit avg length we shall multiply by 4 ;; 16 bit avg length we shall multiply by 8 ;; 8 bit avg length we shall multiply by 16 ;; to make a more efficient shift below we start with a multiply by 32 sl0 5, r2 ; always multiply sw a imbalance by 32 sl0 5, r4 ; always multiply sw b imbalance by 32 sr0 6, r3 ; shift avg length down and 3, r3 ; mask other bits add 1, r3 ; sr0 r3, r2 ; divide with 2 or 4 or 8 depending on avg length sr0 r3, r4 ; divide with 2 or 4 or 8 depending on avg length sl0 8, r2 ; sr0 8, r2 ; sl0 8, r4 ; or r4, r2 ; combine swA and sw b output r2, DEMSWIMBAL ; GEN_FSK_CALC_DEMSWIMBAL_DONE: ;; Copy all sync registers to new correlator registers input MDMSYNC0, r0 output r0, DEMC1BEREF0 input MDMSYNC1, r0 output r0, DEMC1BEREF1 input MDMSYNC2, r0 output r0, DEMC1BEREF2 input MDMSYNC3, r0 output r0, DEMC1BEREF3 ;; Initial Module Enables lmd DEMENABLE0_RX_IQDUMP, r0 output r0, DEMENABLE0 ; cmix, ctil, bdec, chfi, fidc, frac ,iqmc, enable output r0, DEMINIT0 lmd DEMENABLE1_RX_IQDUMP, r0 output r0, DEMENABLE1 ; output r0, DEMINIT1 outbset 5, RFESEND ; send message to rfe that reception is starting lli 0xD9, r0 ; output r0, MDMCMDPAR0 ; rts ;;; ============================================================================================ ;;; Common End of RX function MRX_GenFSK_CommonEnd: outbclr 5, RFESEND ; tell RFE packet is ending ;;; Wait to let RFE end outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4 event wait outbclr MCEEVENT0_CLKEN_4BAUD, MCEEVENTMSK0 ; disable the clkenbaud_4f event outbset MCEEVENT0_CLKEN_4BAUD, MCEEVENTCLR0 ; clear the clkenbaud_4f event outbset RDCAPT0_DEMLQIE0, RDCAPT0 ; Capture LQI into MDMSTATUS[15:8] input MDMSTATUS, r0 input DEMLQIE0, r4 sr0 2, r4 ; Divide by 4 first sl0 8, r4 or r0,r4 output r4, MDMSTATUS ; Warning: CPE use MDMSTATUS[1:0] for CMD_DONE checking DBG_PRINT0 "All bits received, MCE Ending" ;; Hard init of all modules except FIFO outset TIMCTRL ; outclr TIMCTRL ; jsr MODCTRL_CLR ; outclr MDMENABLE_ADCDIG, MDMENABLE ; outclr MDMENABLE_TIMEBASE, MDMENABLE ; outclr MDMENABLE_DEMODULATOR, MDMENABLE ; outset DEMINIT0 ; outset DEMINIT1 ; jmp CMD_OK_END ;; clear all bits in MODCTRL exept bit 12 (keep bit 12) MODCTRL_CLR: input MODCTRL, r0 ; lli 0x80, r1 ; sl0 5, r1 ; set bit 12 to 1 and r1, r0 ; output r0, MODCTRL ; rts DBG_FUNC