; ; Copyright (C) 2021-2023 Texas Instruments Incorporated ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions ; are met: ; ; Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; ; Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the ; distribution. ; ; Neither the name of Texas Instruments Incorporated nor the names of ; its contributors may be used to endorse or promote products derived ; from this software without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ; "AS IS" AND ANY EXPgResS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; .include "memory.inc" .include "defines.inc" .include "macros.inc" .ref transport_init .ref qm_add .ref calc_rssi .ref send_stuffing .ref send_header .ref send_trailer .ref wait_delay .ref datalink_loadfw .ref recv_dec .ref datalink_wait_vsynch .global datalink_reset .global datalink_init_start .global send_01 .global int_div .sect ".text" relocatable0: datalink_init_start: ;State RESET zero &r0, 124 ;send 2 times datalink_reset: ;setup ICSS encoder peripheral for Hiperface DSL ldi DISPARITY, 0x00 TX_EN SET_TX_CH0 REINIT_TX TX_FRAME_SIZE 0, REG_TMP0 .if $defined("HDSL_MULTICHANNEL") TX_CLK_DIV CLKDIV_FAST, REG_TMP0 .else TX_CLK_DIV CLKDIV_NORMAL, REG_TMP0 .endif zero &H_FRAME, (4*2) ;init transport layer here CALL transport_init ;QualityMonitor is initialized with 8 ldi QM, 8 ;free running mode frame size is 108 ldi EXTRA_SIZE, 0 ldi NUM_STUFFING, 0 ;reset PRST bit in SYS_CTRL lbco ®_TMP0, MASTER_REGS_CONST, SYS_CTRL, 1 clr REG_TMP0.b0, REG_TMP0.b0, SYS_CTRL_PRST sbco ®_TMP0, MASTER_REGS_CONST, SYS_CTRL, 1 ;reset SAFE_CTRL register zero ®_TMP0.b0, 1 sbco ®_TMP0.b0, MASTER_REGS_CONST, SAFE_CTRL, 1 ; Write the fixed bits and reset PRST bits in ONLINE_STATUS_D, ONLINE_STATUS_1 and ONLINE_STATUS_2 ; In ONLINE_STATUS_D high, bit 2 is FIX0, bit 4 is FIX1 and bit 5 is FIX0 ; In ONLINE_STATUS_D low, bit 0 is FIX0 and bit 3 is FIX0 lbco ®_TMP0.w0, MASTER_REGS_CONST, ONLINE_STATUS_D, 2 ; clearing bits with fix0 and PRST bit and REG_TMP0.w0, REG_TMP0.w0, ((~((1< vert == acc.b0 && par == acc.b1 && pipe.nibble0 == pipe.nibble1 ;second half of palindrome is actually our ENC_ID! qbne datalink_abort2, H_FRAME.vert, H_FRAME_acc0 qbne datalink_abort2, H_FRAME.s_par, H_FRAME_acc1 and REG_TMP0.b0, H_FRAME.pipe, 0xf lsr REG_TMP0.b1, H_FRAME.pipe, 4 qbne datalink_abort2, REG_TMP0.b0, REG_TMP0.b1; ;now store the encoder ID mov REG_TMP0.w0, H_FRAME.acc mov REG_TMP0.b2, H_FRAME.pipe ;now in memory for master registers ;big endian format mov REG_TMP1.b0, REG_TMP0.b2 mov REG_TMP1.b1, REG_TMP0.b1 mov REG_TMP1.b2, REG_TMP0.b0 sbco ®_TMP1, MASTER_REGS_CONST, ENC_ID2, 3 ;Safe QM + set LINK bit, which means we have established a link ;just add 0 to QM to update QM_ADD 0 ;Synchronization with Drive Cycle is enabled here! set H_FRAME.flags, H_FRAME.flags, FLAG_DRIVE_SYNC ;-------------------------------------------------------------------------------------------------- ;State ID COMPUTE datalink_id_compute: ;decode the ENC_ID here ;num of acc bits is always +8 and NUM_ACC_BITS, REG_TMP0, 0x0f add NUM_ACC_BITS, NUM_ACC_BITS, 8 ;num pos bits is +num acc bits lsr NUM_ST_BITS, REG_TMP0, 4 and NUM_ST_BITS, NUM_ST_BITS, 0x3f add NUM_ST_BITS, NUM_ST_BITS, NUM_ACC_BITS sub NUM_ST_BITS, NUM_ST_BITS, NUM_MT_BITS ;finding the mask for position add REG_TMP0.b0, NUM_ST_BITS, NUM_MT_BITS rsb REG_TMP0.b0, REG_TMP0.b0, 40 ldi32 REG_TMP1, 0xffffffff lsr REG_TMP1, REG_TMP1, REG_TMP0.b0 sbco ®_TMP1, MASTER_REGS_CONST, MASK_POS, 4 ;qba datalink_id_req CALL1 send_stuffing jmp datalink_wait_vsynch ;-------------------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------------------- ;Function: ;This functions receives data without deocoding. ;output: ; r20-r19: data ;-------------------------------------------------------------------------------------------------- receive: ldi LOOP_CNT.b0, 32 CALL1 wait_delay ldi REG_TMP0.w0, 0 ldi REG_TMP11, (PDMEM00+0x5a4);LUT_B2B) zero &r18, (4*5) datalink_receive_signal_0_31_1: qbbc datalink_receive_signal_0_31_1, r31, RX_VALID_FLAG POP_FIFO REG_TMP0.b0 CLEAR_VAL sub LOOP_CNT.b0, LOOP_CNT.b0, 1 qbbc datalink_receive_signal_0_31_received_0_1, REG_TMP0.w0, SAMPLE_EDGE set r20, r20, LOOP_CNT.b0 datalink_receive_signal_0_31_received_0_1: mov REG_TMP0.b1, REG_TMP0.b0 ;get edges lsr REG_TMP1.b0, REG_TMP0.w0, 1 xor CUR_EDGES, REG_TMP1.b0, REG_TMP0.b0 CALL1 calc_rssi qbne datalink_receive_signal_0_31_1, LOOP_CNT.b0, 0 ;receive next bits ldi LOOP_CNT.b0, 29 datalink_receive_signal_32_60_1: qbbc datalink_receive_signal_32_60_1, r31, RX_VALID_FLAG ;changed here from 24 to 26 POP_FIFO REG_TMP0.b0 CLEAR_VAL sub LOOP_CNT.b0, LOOP_CNT.b0, 1 qbbc datalink_receive_signal_32_60_received_0_1, REG_TMP0.w0, SAMPLE_EDGE set r19, r19, LOOP_CNT.b0 datalink_receive_signal_32_60_received_0_1: mov REG_TMP0.b1, REG_TMP0.b0 ;get edges lsr REG_TMP1.b0, REG_TMP0.w0, 1 xor CUR_EDGES, REG_TMP1.b0, REG_TMP0.b0 CALL1 calc_rssi qbne datalink_receive_signal_32_60_1, LOOP_CNT.b0, 1 datalink_receive_signal_last_1: qbbc datalink_receive_signal_last_1, r31, RX_VALID_FLAG ;changed here from 24 to 26 POP_FIFO REG_TMP0.b0 qbbc datalink_receive_signal_last_received_0_1, REG_TMP0.w0, SAMPLE_EDGE set r19, r19, 0 datalink_receive_signal_last_received_0_1: lsl r19, r19, 3 CLEAR_VAL ; same delay code as in learn ldi REG_TMP1, (74*CYCLES_BIT+7) ; -9 for 100 m READ_CYCLCNT REG_TMP0 qble receive_skip_wait, REG_TMP0, REG_TMP1 sub REG_TMP0, REG_TMP1, REG_TMP0 add r0,r0,1 WAIT REG_TMP0 receive_skip_wait: TX_EN ; datalink_receive_signal_no_delay_wait_1: CALL1 send_trailer CALL1 send_stuffing RET ;-------------------------------------------------------------------------------------------------- ;Function: sync_pulse (RET_ADDR1) ;functions bussy waits for sync pulse ;input: ;modifies: ;-------------------------------------------------------------------------------------------------- ;stores sync pulse period in R20 in unit of cycles sync_pulse: lbco ®_TMP1, c1, IEP_CAPR6_RISE, 4 wait_next_pulse: lbco &R20, c1, IEP_CAPR6_RISE, 4 QBEQ wait_next_pulse, R20, REG_TMP1 SUB R20, R20, REG_TMP1 RET1 ;-------------------------------------------------------------------------------------------------- ;Function: int_div (RET_ADDR1) ;integer divides ;input: ; REG_FNC.w0: Number ; REG_FNC.w2: Divisor ;output: ; REG_FNC.w2: Result ; REG_FNC.w0: Rest ;modifies: ;-------------------------------------------------------------------------------------------------- int_div: ldi REG_TMP0, 0 int_div_loop: qbgt int_div_end, REG_FNC.w0, REG_FNC.w2 sub REG_FNC.w0, REG_FNC.w0, REG_FNC.w2 add REG_TMP0, REG_TMP0, 1 qba int_div_loop int_div_end: mov REG_FNC.w2, REG_TMP0 RET1 ;-------------------------------------------------------------------------------------------------- ;Function: check_test_pattern (RET_ADDR1) ;This function checks if the test pattern was received ;input: ; r18-r20: data ;output: ; REG_FNC.b0: 1 if true ;modifies: ; REG_TMP0, REG_FNC ;-------------------------------------------------------------------------------------------------- check_test_pattern: ;load test pattern and mask from memory lbco ®_TMP0, MASTER_REGS_CONST, TEST_PATTERN0, 12 ;rm switch bit and REG_TMP11, r19, REG_TMP2 ldi REG_TMP2, 0xff8 and REG_TMP2, r19, REG_TMP2 lsl REG_TMP2, REG_TMP2, 1 or REG_TMP11, REG_TMP2, REG_TMP11 ;if found go to next step qbne check_test_pattern_false, r20, REG_TMP0 qbne check_test_pattern_false, REG_TMP11, REG_TMP1 check_test_pattern_true: ldi REG_FNC.b0, 1 RET1 check_test_pattern_false: ldi REG_FNC.b0, 0 RET1 ;-------------------------------------------------------------------------------------------------- ;Function: send_01 (RET_ADDR1) ;This function sends 01 pattern in RESET and SYNC state ;input: ; REG_FNC.b2: last two bits of parameter channel ;output: ;modifies: ;-------------------------------------------------------------------------------------------------- send_01: ;send 01 pattern ;2 para bits, 1 switch bit, 5 slave bit or REG_FNC.b2, REG_FNC.b2, 0x15;0bPPS10101 .if $defined("HDSL_MULTICHANNEL") mov FIFO_L,REG_FNC.b2 PUSH_FIFO_8x FIFO_L .else PUSH_FIFO REG_FNC.b2 .endif ;56+12 line delay slave bits ldi REG_TMP0.b0, 8 send_header_send_01_pattern_loop: ;;PUSH 8 bytes for 1 byte data (0x55) in FIFO WAIT_TX_FIFO_FREE .if $defined("HDSL_MULTICHANNEL") PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0xff WAIT_TX_FIFO_FREE PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0xff WAIT_TX_FIFO_FREE PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0xff WAIT_TX_FIFO_FREE PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0xff .else PUSH_FIFO_CONST 0x55 .endif sub REG_TMP0.b0, REG_TMP0.b0, 1 qbne send_header_send_01_pattern_loop, REG_TMP0.b0, 0 ;send last 0101 (4 bits) WAIT_TX_FIFO_FREE ;overclock(8x) PUSH_FIFO_CONST 0x00 ldi REG_TMP0, (9*(CLKDIV_NORMAL+1)-9) .if !$defined("HDSL_MULTICHANNEL") WAIT REG_TMP0 TX_CLK_DIV CLKDIV_FAST, REG_TMP0 .endif PUSH_FIFO_CONST 0xff WAIT_TX_FIFO_FREE PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0xff ;push TRAILER ;PUSH 8 bytes for 1 byte data (0x03) in FIFO WAIT_TX_FIFO_FREE .if $defined("HDSL_MULTICHANNEL") PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0x00 WAIT_TX_FIFO_FREE PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0x00 WAIT_TX_FIFO_FREE PUSH_FIFO_CONST 0x00 PUSH_FIFO_CONST 0x00 WAIT_TX_FIFO_FREE PUSH_FIFO_CONST 0xff PUSH_FIFO_CONST 0xff .else PUSH_FIFO_CONST 0x03 .endif .if $defined("FREERUN_300_MHZ") ldi REG_TMP0, (6*(CLKDIV_FAST+1)-8+2) .else ldi REG_TMP0, (6*(CLKDIV_FAST+1)-8) .endif .if !$defined("HDSL_MULTICHANNEL") WAIT REG_TMP0 TX_CLK_DIV CLKDIV_NORMAL, REG_TMP0 ;wait to have same timing as send_trailer ldi REG_TMP0, 30;6 WAIT REG_TMP0 .endif ;reset cyclecount RESET_CYCLCNT RET1