1109 lines
52 KiB
NASM
1109 lines
52 KiB
NASM
; vim: set ft=nasm:
|
|
|
|
%include 'isa.inc'
|
|
%include 'defs.inc'
|
|
|
|
org 0
|
|
jmp START_PROCESS
|
|
|
|
;org LMD_DATA_SPACE
|
|
|
|
DEMENABLE0_RX_IQDUMP:
|
|
dw 0x2FCF ; DEMENABLE0 settings (felp, frac,fidc,chfi,bdec,iqmc,mge2,codc,cmix)
|
|
DEMENABLE1_RX_IQDUMP:
|
|
dw 0x3F9D ; DEMENABLE1
|
|
|
|
VITACCCTRL_REG_DEFAULT: ; Transp, downsample + IIR filter setting
|
|
dw 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
|
|
dw 0x003F
|
|
IQDUMP_MASK_BITS_15_8:
|
|
dw 0xFF00
|
|
|
|
IQDUMP_TEST_MAX_VAL:
|
|
dw 0x0FFF
|
|
IQDUMP_MAX_POS_VAL:
|
|
dw 0x07FF ; 2^11 - 1 = 2047
|
|
IQDUMP_MIN_NEG_VAL:
|
|
dw 0xF800 ; -2048
|
|
TRANSPARENT_CAPT:
|
|
dw 0x0300 ; Combined RDCAPT0_DEMPDIF0 and RDCAPT0_DEMFIFE2
|
|
CORR_DEFG_THR:
|
|
dw 0x8080
|
|
TX_TONE_COUNT:
|
|
dw 0x06 ; Default number of clock ticks for tone in front of preamble
|
|
|
|
;org MDMCONF_IQDUMP
|
|
|
|
dw 0x0003 ; ADCDIGCONF
|
|
dw 0x0017 ; MODPRECTRL
|
|
dw 0x3D1F ; MODSYMMAP0
|
|
dw 0x0000 ; MODSYMMAP1
|
|
dw 0x0000 ; MODSOFTTX
|
|
dw 0x0800 ; MDMBAUD
|
|
dw 0x000F ; MDMBAUDPRE
|
|
dw 0x0000 ; MODMAIN
|
|
dw 0x0387 ; DEMMISC0
|
|
dw 0x0000 ; DEMMISC1
|
|
dw 0x4074 ; DEMMISC2
|
|
dw 0x0043 ; DEMMISC3
|
|
dw 0x8000 ; DEMIQMC0
|
|
dw 0x0082 ; DEMDSBU
|
|
dw 0x0080 ; DEMDSBU2
|
|
dw 0x06F0 ; DEMCODC0
|
|
dw 0x0000 ; DEMFIDC0
|
|
dw 0x091E ; DEMFEXB0
|
|
dw 0x0510 ; DEMDSXB0
|
|
dw 0x0054 ; DEMD2XB0
|
|
dw 0x0007 ; DEMFIFE0
|
|
dw 0x0000 ; DEMMAFI0
|
|
dw 0x5014 ; DEMMAFI1
|
|
dw 0x0050 ; DEMMAFI2
|
|
dw 0x0000 ; DEMMAFI3
|
|
dw 0xC02F ; DEMC1BE0
|
|
dw 0x0C30 ; DEMC1BE1
|
|
dw 0x017F ; DEMC1BE2
|
|
dw 0x0000 ; DEMC1BE10
|
|
dw 0x0000 ; DEMC1BE11
|
|
dw 0x0000 ; DEMC1BE12
|
|
dw 0x0000 ; MDMSYNC0
|
|
dw 0x0000 ; MDMSYNC1
|
|
dw 0x0000 ; MDMSYNC2
|
|
dw 0xAA00 ; MDMSYNC3
|
|
dw 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 3;"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 4;"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 5;"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 6;"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 7;"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 8;"########################### 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 9;"########################### 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 10;"########################### 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 11;"########################### 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 12;"########################### 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 13;"########################### 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 14;"########################### 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 15;"########################### 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 16;"########################### 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 17;"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
|
|
|