ccmdm-re/text.s

1106 lines
52 KiB
ArmAsm

; 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