motor-control-sdk/source/position_sense/bissc/firmware/bissc_main.asm
Dhaval Khandla 2c4dd5bfc0 am243x: bissc: Add examples, driver and firmwares
- Add support for single channel
- Add support for multi channel using single PRU
- Add support for multi channel using multiple PRUs with load share mode

Fixes: PINDSW-5468, PINDSW-5479, PINDSW-5488, PINDSW-5494, PINDSW-5495

Signed-off-by: Dhaval Khandla <dhavaljk@ti.com>
2023-12-04 15:54:58 +05:30

665 lines
26 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; Copyright (C) 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 EXPRESS 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.
;
;************************************************************************************
;*   File:     bissc_main.asm                                            *
;*                                                                                  *
;*   Brief:    Firmware initialization, Storing position data, Control communication*
;************************************************************************************
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;/
; Assembler Directives Section
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;/
.sect ".text"
.retain ; Required for building .out with assembly file
.retainrefs ; Required for building .out with assembly file
.global BISSC_INIT
.include "bissc_icss_reg_defs.h"
.include "bissc_params.h"
.include "bissc_interface.h"
.include "firmware_version.h"
.include "bissc_macros.h"
;bissc main starts from here
BISSC_INIT:
JMP BISSC_MAIN
.word ICSS_FIRMWARE_RELEASE_1, ICSS_FIRMWARE_RELEASE_2
BISSC_MAIN:
.if $isdefed("PRU0")
.asg PRU0_DMEM, PRUx_DMEM
.asg ICSS_CFG_PRU0_ENDAT_CH0_CFG1, ICSS_CFG_PRUx_BISSC_CH0_CFG1
.asg ICSS_CFG_PRU0_ENDAT_CH1_CFG1, ICSS_CFG_PRUx_BISSC_CH1_CFG1
.asg ICSS_CFG_PRU0_ENDAT_CH2_CFG1, ICSS_CFG_PRUx_BISSC_CH2_CFG1
.asg ICSS_CFG_PRU0_ENDAT_CH0_CFG0, ICSS_CFG_PRUx_BISSC_CH0_CFG0
.asg ICSS_CFG_PRU0_ENDAT_CH1_CFG0, ICSS_CFG_PRUx_BISSC_CH1_CFG0
.asg ICSS_CFG_PRU0_ENDAT_CH2_CFG0, ICSS_CFG_PRUx_BISSC_CH2_CFG0
.asg ICSS_CFG_PRU0_ENDAT_TXCFG, ICSS_CFG_PRUx_BISSC_TXCFG
.asg ICSS_CFG_PRU0_ENDAT_RXCFG, ICSS_CFG_PRUx_BISSC_RXCFG
.endif
.if $isdefed("PRU1")
.asg PRU1_DMEM, PRUx_DMEM
.asg ICSS_CFG_PRU1_ENDAT_CH0_CFG1, ICSS_CFG_PRUx_BISSC_CH0_CFG1
.asg ICSS_CFG_PRU1_ENDAT_CH1_CFG1, ICSS_CFG_PRUx_BISSC_CH1_CFG1
.asg ICSS_CFG_PRU1_ENDAT_CH2_CFG1, ICSS_CFG_PRUx_BISSC_CH2_CFG1
.asg ICSS_CFG_PRU1_ENDAT_CH0_CFG0, ICSS_CFG_PRUx_BISSC_CH0_CFG0
.asg ICSS_CFG_PRU1_ENDAT_CH1_CFG0, ICSS_CFG_PRUx_BISSC_CH1_CFG0
.asg ICSS_CFG_PRU1_ENDAT_CH2_CFG0, ICSS_CFG_PRUx_BISSC_CH2_CFG0
.asg ICSS_CFG_PRU1_ENDAT_TXCFG, ICSS_CFG_PRUx_BISSC_TXCFG
.asg ICSS_CFG_PRU1_ENDAT_RXCFG, ICSS_CFG_PRUx_BISSC_RXCFG
.endif
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
M_BISSC_LS_WAIT_FOR_SYNC
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
M_BISSC_LS_WAIT_FOR_SYNC
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
M_BISSC_LS_WAIT_FOR_SYNC
.endif
; clear all registers
ZERO &R0, 120
SBCO &R0, PRUx_DMEM, BISSC_REG_BACKUP, 24
LBCO &FIFO_BIT_IDX, PRUx_DMEM, BISSC_FIFO_BIT_IDX_OFFSET, 1 ;bit_idx - 4 th bit(middle one) of 8x over clock or 2nd bit for 4x oversampling
LDI VALID_BIT_IDX, BISSC_CH0_VALID_BIT_IDX ;Valid bit index base(24)
LBCO &PRIMARY_CORE, PRUx_DMEM, BISSC_MASK_FOR_PRIMARY_CORE, 1 ;load the primary core mask
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
ZERO &SCRATCH1, 1
SBCO &SCRATCH1, PRUx_DMEM, BISSC_LS_EXEC_RTU_STATE, 1
QBBC BISSC_SKIP_GLOBAL_REINIT0?, PRIMARY_CORE, 0 ;global reinit to be done only by primary core
SET R31, BISSC_TX_GLOBAL_REINIT ; Set TX_EN low
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
ZERO &SCRATCH1, 1
SBCO &SCRATCH1, PRUx_DMEM, BISSC_LS_EXEC_PRU_STATE, 1
QBBC BISSC_SKIP_GLOBAL_REINIT0?, PRIMARY_CORE, 1
SET R31, BISSC_TX_GLOBAL_REINIT
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
ZERO &SCRATCH1, 1
SBCO &SCRATCH1, PRUx_DMEM, BISSC_LS_EXEC_TXPRU_STATE, 1
QBBC BISSC_SKIP_GLOBAL_REINIT0?, PRIMARY_CORE, 2
SET R31, BISSC_TX_GLOBAL_REINIT
.else
SET R31, BISSC_TX_GLOBAL_REINIT
.endif
BISSC_SKIP_GLOBAL_REINIT0?:
LBCO &CH_MASK, PRUx_DMEM, BISSC_CHANNEL_CONFIG_OFFSET, 1
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
LDI CH_MASK, BISSC_CONFIG_CH0 ;change the channel mask it self, so individual PRU work as channel agnostic, single channel single PRU firmware.
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
LDI CH_MASK, BISSC_CONFIG_CH1
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
LDI CH_MASK, BISSC_CONFIG_CH2
.endif
;Measure the Processing delay upon initialization
LDI SCRATCH1.b0, 0 ;clear the re measure flag for processing delay before proc measurement
SBCO &SCRATCH1, PRUx_DMEM, BISSC_RE_MEASURE_PROC_DELAY, 1
M_MEASURE_MAX_PROC_TIME
;update the status to notify application
LDI STATUS_REG1, 1
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_STATUS_CH0_CONFIG_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_STATUS_CH1_CONFIG_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_STATUS_CH2_CONFIG_OFFSET, 1
.else
;ch0 status offset is the base status offset and only ch0 offset is going to be used in single ch or multi ch single pru
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_STATUS_CH0_CONFIG_OFFSET, 1
.endif
BISSC_HANDLE_HOST_TRIGGER:
;If Host Trigger=1, request made by R5F to Firmware, now Firmware do processing and when done set trigger to 0 so that R5F application can act further.
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
LBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH0_STATUS_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
LBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH1_STATUS_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
LBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH2_STATUS_OFFSET, 1
.else
;ch0 cycle trigger offset is the base cycle trigger offset and only ch0 offset is going to be used in single ch or multi ch single pru
LBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH0_STATUS_OFFSET, 1
.endif
LBCO &STATUS_REG2, PRUx_DMEM, BISSC_MEAS_PROC_DELAY_OFFSET, 1
LBCO &FIFO_BIT_IDX, PRUx_DMEM, BISSC_FIFO_BIT_IDX_OFFSET, 1
QBBC BISSC_SKIP_MEASURE_PROC_DELAY?, STATUS_REG2, 0
;Measure the Processing delay upon host trigger
LDI SCRATCH1.b0, 0
SBCO &SCRATCH1, PRUx_DMEM, BISSC_RE_MEASURE_PROC_DELAY, 1
M_MEASURE_MAX_PROC_TIME
BISSC_SKIP_MEASURE_PROC_DELAY?:
QBBS BISSC_CTRL_CMD_DONE, BISSC_FLAGS_REG, 0
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
LBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH0_CONFIG_OFFSET, 4
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
LBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH1_CONFIG_OFFSET, 4
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
LBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH2_CONFIG_OFFSET, 4
.else
;ch0 ctrl command offset is the base ctrl command offset and only ch0 ctrl command offset is going to be used in single ch or multi ch single pru
LBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH0_CONFIG_OFFSET, 4
.endif
QBEQ BISSC_CTRL_CMD_SKIP, SCRATCH, 0
MOV BISSC_CTRL_CMD, SCRATCH
SET BISSC_FLAGS_REG, BISSC_FLAGS_REG, 0
ZERO &SCRATCH, 4
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
SBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH0_CONFIG_OFFSET, 4
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
SBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH1_CONFIG_OFFSET, 4
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
SBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH2_CONFIG_OFFSET, 4
.else
SBCO &SCRATCH, PRUx_DMEM, BISSC_CTRL_CMD_CH0_CONFIG_OFFSET, 4
.endif
ZERO &BISSC_CTRL_FF, 4
LDI BISSC_CTRL_CRC, 0
LDI BISSC_CTRL_CYCLE_CNTR, 0
LDI BISSC_CTRL_CMD_RES, 0
LDI BISSC_CTRL_OTF_CRC, 0
LDI BISSC_CMD_BIT_PTR, 31 ; CMD bit pointer will points to MSB always, decremented only when we transmit one bit from hex command
QBA BISSC_CTRL_CMD_DONE
BISSC_CTRL_CMD_SKIP:
CLR BISSC_FLAGS_REG, BISSC_FLAGS_REG, 0
BISSC_CTRL_CMD_DONE:
;wait till host trigger is set to 1.
QBEQ BISSC_HANDLE_HOST_TRIGGER, STATUS_REG1, 0
;BiSS-C position data/control communication loop start here
;clock mode in freerunning/stop low/stop high and ch0 is selected
QBBC BISSC_IS_CH1?, CH_MASK, 0
LDI R30.w2, (BISSC_TX_CLK_MODE_FREERUN_STOPHIGH | BISSC_TX_CH0_SEL)
LBCO &SCRATCH2.w2, PRUx_DMEM, BISSC_CH0_PROC_DELAY_OFFSET, 2
LDI R30.b0, 0
BISSC_IS_CH1?:
QBBC BISSC_IS_CH2?, CH_MASK, 1
LDI R30.w2, (BISSC_TX_CLK_MODE_FREERUN_STOPHIGH | BISSC_TX_CH1_SEL)
LBCO &SCRATCH2.w2, PRUx_DMEM, BISSC_CH1_PROC_DELAY_OFFSET, 2
LDI R30.b0, 0
BISSC_IS_CH2?:
QBBC BISSC_SKIP_CH_SEL1?, CH_MASK, 2
LDI R30.w2, (BISSC_TX_CLK_MODE_FREERUN_STOPHIGH | BISSC_TX_CH2_SEL)
LBCO &SCRATCH2.w2, PRUx_DMEM, BISSC_CH2_PROC_DELAY_OFFSET, 2
LDI R30.b0, 0
BISSC_SKIP_CH_SEL1?:
; since ENABLE_RUNTIME_CH is kept enabled with all 3 channels selected for multi channel, last channel would have been selected by now
.if $isdefed("ENABLE_MULTI_CHANNEL")
LOOP BISSC_SEND_RECEIVE_BISSC_MULTI_CHANNEL, 3
SUB R30.b2, R30.b2, 1
BISSC_SEND_RECEIVE_BISSC_MULTI_CHANNEL:
.endif
;clock mode in freerunning/stop low/stop high and ch0 is selected
LBCO &FIFO_BIT_IDX, PRUx_DMEM, BISSC_FIFO_BIT_IDX_OFFSET, 1
LBCO &SCRATCH2.b1, PRUx_DMEM, BISSC_POS_CRC_LEN_CONFIG_OFFSET, 1
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
LBCO &DAISY_CHAIN, PRUx_DMEM, BISSC_NUM_SLAVE_CH0_CONFIG_OFFSET, 4
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
LBCO &DAISY_CHAIN, PRUx_DMEM, BISSC_NUM_SLAVE_CH1_CONFIG_OFFSET, 4
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
LBCO &DAISY_CHAIN, PRUx_DMEM, BISSC_NUM_SLAVE_CH2_CONFIG_OFFSET, 4
.else
;ch0 number of slaves and encoder data lengths is the base daisychain offset and only ch0 offset is going to be used in single ch or multi ch single pru
LBCO &DAISY_CHAIN, PRUx_DMEM, BISSC_NUM_SLAVE_CH0_CONFIG_OFFSET, 4
.endif
;compute RX frame size from input arguments. ACK length will be taken from processing delay.
ADD SCRATCH2.w2, SCRATCH2.w2, DAISY_CHAIN.b1 ;data length of slave 0
ADD SCRATCH2.w2, SCRATCH2.w2, SCRATCH2.b1 ;crc length
ADD SCRATCH2.w2, SCRATCH2.w2, BISSC_EW_LEN ;E + W
ADD SCRATCH2.w2, SCRATCH2.w2, BISSC_SB_CDS_LEN ;SB + CDS
QBEQ BISSC_SKIP_DAISY_CHAIN, DAISY_CHAIN.b2, 0
ADD SCRATCH2.w2, SCRATCH2.w2, DAISY_CHAIN.b2 ;data length of slave 1
ADD SCRATCH2.w2, SCRATCH2.w2, SCRATCH2.b1 ;crc length
ADD SCRATCH2.w2, SCRATCH2.w2, BISSC_EW_LEN ;E + W
QBEQ BISSC_SKIP_DAISY_CHAIN, DAISY_CHAIN.b3, 0
ADD SCRATCH2.w2, SCRATCH2.w2, DAISY_CHAIN.b3 ;data length of slave 2
ADD SCRATCH2.w2, SCRATCH2.w2, SCRATCH2.b1 ;crc length
ADD SCRATCH2.w2, SCRATCH2.w2, BISSC_EW_LEN ;E + W
BISSC_SKIP_DAISY_CHAIN:
LDI SCRATCH2.w0, 0
; store Rx and Tx frame size to ICSS_CFG_PRUx_ED_CHx for all configured channels
M_BISSC_CLK_CONFIG CH_MASK, SCRATCH2
LDI SCRATCH1, 0 ;clear the syn bits for load share.
SBCO &SCRATCH1, PRUx_DMEM, BISSC_LS_EXEC_RTU_STATE, 4
LDI R30.b0, 0
.if $isdefed("ENABLE_MULTI_CHANNEL")
SET R31, BISSC_TX_GLOBAL_GO
.else
SET R31, BISSC_TX_CHANNEL_GO
.endif
;enable Rx for channel 0
QBBC BISSC_IS_CH1_EN?, CH_MASK, 0
SET R30, BISSC_CH0_RX_EN
BISSC_IS_CH1_EN?:
QBBC BISSC_IS_CH2_EN?, CH_MASK, 1
SET R30, BISSC_CH1_RX_EN
BISSC_IS_CH2_EN?:
QBBC BISSC_ACK_BIT1?, CH_MASK, 2
SET R30, BISSC_CH2_RX_EN
;ack bit
BISSC_ACK_BIT1?:
; wait for valid bit
AND SCRATCH1.b0, R31.b3, CH_MASK
QBNE BISSC_ACK_BIT1?, SCRATCH1.b0, CH_MASK ; wait for valid
MOV SCRATCH1, R31
;Set the valid bit for clearing flag so that next bit can come.
QBBC BISSC_IS_CH1_VALID_ACK?, CH_MASK, 0
SET R31, R31, BISSC_CH0_RX_VALID_BIT_OFFSET
BISSC_IS_CH1_VALID_ACK?:
QBBC BISSC_IS_CH2_VALID_ACK?, CH_MASK, 1
SET R31, R31, BISSC_CH1_RX_VALID_BIT_OFFSET
BISSC_IS_CH2_VALID_ACK?:
QBBC BISSC_SKIP_RX_VALID_ACK?, CH_MASK, 2
SET R31, R31, BISSC_CH2_RX_VALID_BIT_OFFSET
BISSC_SKIP_RX_VALID_ACK?:
;must maintain 3 cycles before checking next valid bit
NOP
NOP
QBBC BISSC_IS_CH1_FIFO_ACK?, CH_MASK, 0
QBBC BISSC_ACK_FOUND1?, SCRATCH1.b0, FIFO_BIT_IDX
BISSC_IS_CH1_FIFO_ACK?:
QBBC BISSC_IS_CH2_FIFO_ACK?, CH_MASK, 1
QBBC BISSC_ACK_FOUND1?, SCRATCH1.b1, FIFO_BIT_IDX
BISSC_IS_CH2_FIFO_ACK?:
QBBC BISSC_ACK_BIT1?, CH_MASK, 2
QBBS BISSC_ACK_BIT1?, SCRATCH1.b2, FIFO_BIT_IDX
BISSC_ACK_FOUND1?:
;start bit
BISSC_START_BIT1?:
; wait for valid bit
AND SCRATCH1.b0, R31.b3, CH_MASK
QBNE BISSC_START_BIT1?, SCRATCH1.b0, CH_MASK ; wait for valid
MOV SCRATCH1, R31
QBBC BISSC_IS_CH1_VALID_SB?, CH_MASK, 0
SET R31, R31, BISSC_CH0_RX_VALID_BIT_OFFSET
BISSC_IS_CH1_VALID_SB?:
QBBC BISSC_IS_CH2_VALID_SB?, CH_MASK, 1
SET R31, R31, BISSC_CH1_RX_VALID_BIT_OFFSET
BISSC_IS_CH2_VALID_SB?:
QBBC BISSC_SKIP_RX_VALID_SB?, CH_MASK, 2
SET R31, R31, BISSC_CH2_RX_VALID_BIT_OFFSET
BISSC_SKIP_RX_VALID_SB?:
NOP
NOP
;must maintain 3 cycles before checking next valid bit
QBBC BISSC_IS_CH1_FIFO_SB?, CH_MASK, 0
QBBS BISSC_START_BIT_FOUND?, SCRATCH1.b0, FIFO_BIT_IDX
BISSC_IS_CH1_FIFO_SB?:
QBBC BISSC_IS_CH2_FIFO_SB?, CH_MASK, 1
QBBS BISSC_START_BIT_FOUND?, SCRATCH1.b1, FIFO_BIT_IDX
BISSC_IS_CH2_FIFO_SB?:
QBBC BISSC_START_BIT1?, CH_MASK, 2
QBBC BISSC_START_BIT1?, SCRATCH1.b2, FIFO_BIT_IDX
BISSC_START_BIT_FOUND?:
; cds bit
BISSC_CDS_BIT1?:
; wait for valid bit
AND SCRATCH1.b0, R31.b3, CH_MASK
QBNE BISSC_CDS_BIT1?, SCRATCH1.b0, CH_MASK
MOV BISSC_CDS_BACKUP, R31
QBBC BISSC_IS_CH1_VALID_CDS?, CH_MASK, 0
SET R31, R31, BISSC_CH0_RX_VALID_BIT_OFFSET
BISSC_IS_CH1_VALID_CDS?:
QBBC BISSC_IS_CH2_VALID_CDS?, CH_MASK, 1
SET R31, R31, BISSC_CH1_RX_VALID_BIT_OFFSET
BISSC_IS_CH2_VALID_CDS?:
QBBC BISSC_CDS_BIT_DETECTED?, CH_MASK, 2
SET R31, R31, BISSC_CH2_RX_VALID_BIT_OFFSET
BISSC_CDS_BIT_DETECTED?:
.if $isdefed("ENABLE_MULTI_CHANNEL")
ADD RAW_DATA_LEN, DAISY_CHAIN.b1, (BISSC_EW_LEN + BISSC_RX_CRCBITS)
.else
QBBC BISSC_RCV_CH1?, CH_MASK, 0
LDI SCRATCH2.b3, BISSC_POS_DATA_WORD_CH0_OFFSET
LDI SCRATCH2.b1, BISSC_POS_CRC_ERR_COUNT_CH0_OFFSET
LDI SCRATCH2.b2, BISSC_POS_OTF_CRC_CH0_OFFSET
JMP BISSC_SKIP_RCV?
BISSC_RCV_CH1?:
QBBC BISSC_RCV_CH2?, CH_MASK, 1
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 8
LDI SCRATCH2.b3, BISSC_POS_DATA_WORD_CH1_OFFSET
LDI SCRATCH2.b1, BISSC_POS_CRC_ERR_COUNT_CH1_OFFSET
LDI SCRATCH2.b2, BISSC_POS_OTF_CRC_CH1_OFFSET
JMP BISSC_SKIP_RCV?
BISSC_RCV_CH2?:
QBBC BISSC_SKIP_RCV?, CH_MASK, 2
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 16
LDI SCRATCH2.b3, BISSC_POS_DATA_WORD_CH2_OFFSET
LDI SCRATCH2.b1, BISSC_POS_CRC_ERR_COUNT_CH2_OFFSET
LDI SCRATCH2.b2, BISSC_POS_OTF_CRC_CH2_OFFSET
BISSC_SKIP_RCV?:
.endif
BISSC_POSITION_DATA?:
QBEQ BISSC_END_RECEIVE?, DAISY_CHAIN.b0,0
ZERO &RAW_DATA1_0, 24
QBEQ BISSC_SLAVE3_DATA?, DAISY_CHAIN.b0, 3 ;check if slave 2 is connected
QBEQ BISSC_SLAVE2_DATA?, DAISY_CHAIN.b0, 2 ;check if slave 1 is connected
.if !$isdefed("ENABLE_MULTI_CHANNEL")
ADD RAW_DATA_LEN, DAISY_CHAIN.b1, (BISSC_EW_LEN + BISSC_RX_CRCBITS)
.endif
LDI SCRATCH2.b0, BISSC_POS_DATA_RES_SLAVE0_OFFSET
QBA BISSC_START_RECEIVE?
BISSC_SLAVE2_DATA?:
.if !$isdefed("ENABLE_MULTI_CHANNEL")
ADD RAW_DATA_LEN, DAISY_CHAIN.b2, (BISSC_EW_LEN + BISSC_RX_CRCBITS)
.endif
LDI SCRATCH2.b0, BISSC_POS_DATA_RES_SLAVE1_OFFSET
QBA BISSC_START_RECEIVE?
BISSC_SLAVE3_DATA?:
.if !$isdefed("ENABLE_MULTI_CHANNEL")
ADD RAW_DATA_LEN, DAISY_CHAIN.b3, (BISSC_EW_LEN + BISSC_RX_CRCBITS)
.endif
LDI SCRATCH2.b0, BISSC_POS_DATA_RES_SLAVE2_OFFSET
BISSC_START_RECEIVE?:
.if $isdefed("ENABLE_MULTI_CHANNEL")
;receive pos data for multiple channel at once
M_OTF_RECEIVE_MC RAW_DATA1_0, RAW_DATA2_0, RAW_DATA1_1, RAW_DATA2_1, RAW_DATA1_2, RAW_DATA2_2, SCRATCH2.b0
.else
;receive pos data for single channel
M_OTF_RECEIVE RAW_DATA1_0, RAW_DATA2_0, SCRATCH2.b0
.endif
SUB DAISY_CHAIN.b0, DAISY_CHAIN.b0, 1
QBA BISSC_POSITION_DATA?
BISSC_END_RECEIVE?:
; Control communication starts from here
QBBC BISSC_CTRL_COMMUNICATION_SKIP?, BISSC_FLAGS_REG, 0
ADD BISSC_CTRL_CYCLE_CNTR, BISSC_CTRL_CYCLE_CNTR, 1
QBLE BISSC_CTRL_START_BIT?, BISSC_CTRL_CYCLE_CNTR, 16
QBA BISSC_CTRL_CMD_BIT_SEND_SKIP?
BISSC_CTRL_START_BIT?:
LBCO &FIFO_BIT_IDX, PRUx_DMEM, BISSC_FIFO_BIT_IDX_OFFSET, 1
QBNE BISSC_CTRL_CMD_NEXT_BIT?, BISSC_CTRL_CYCLE_CNTR, 16
;enable clock override for setting clock to low during timeout
ZERO &SCRATCH1, 4
SET SCRATCH1, SCRATCH1, 29
M_BISSC_CLK_CONFIG CH_MASK, SCRATCH1
QBA BISSC_CTRL_CMD_START_BIT_SENT?
BISSC_CTRL_CMD_NEXT_BIT?:
QBBC BISSC_SEND_HIGH?, BISSC_CTRL_CMD, BISSC_CMD_BIT_PTR
BISSC_SEND_LOW?:
;enable clock override for setting clock to low during timeout
ZERO &SCRATCH1, 4
SET SCRATCH1, SCRATCH1, 29
M_BISSC_CLK_CONFIG CH_MASK, SCRATCH1
BISSC_SEND_HIGH?:
QBNE BISSC_CTRL_NO_WAIT_FOR_SLAVE_START_BIT?, BISSC_CMD_BIT_PTR, 13
QBBC BISSC_CTRL_SB_CH1?, CH_MASK, 0
QBBS BISSC_CTRL_NO_WAIT_FOR_SLAVE_START_BIT?, BISSC_CDS_BACKUP.b0, FIFO_BIT_IDX
BISSC_CTRL_SB_CH1?:
QBBC BISSC_CTRL_SB_CH2?, CH_MASK, 1
QBBS BISSC_CTRL_NO_WAIT_FOR_SLAVE_START_BIT?, BISSC_CDS_BACKUP.b1, FIFO_BIT_IDX
BISSC_CTRL_SB_CH2?:
QBBC BISSC_SKIP_CTRL_SB?, CH_MASK, 2
QBBS BISSC_CTRL_NO_WAIT_FOR_SLAVE_START_BIT?, BISSC_CDS_BACKUP.b2, FIFO_BIT_IDX
BISSC_SKIP_CTRL_SB?:
ZERO &SCRATCH1, 4
SET SCRATCH1, SCRATCH1, 29
M_BISSC_CLK_CONFIG CH_MASK, SCRATCH1
QBA BISSC_CTRL_CMD_BIT_SEND_SKIP?
BISSC_CTRL_NO_WAIT_FOR_SLAVE_START_BIT?:
SUB BISSC_CMD_BIT_PTR, BISSC_CMD_BIT_PTR, 1
QBLE BISSC_CTRL_CMD_DATA_RCV_SKIP? , BISSC_CMD_BIT_PTR, 12
QBGT BISSC_READ_CTRL_CRC_BITS? , BISSC_CMD_BIT_PTR, 4
LBCO &FIFO_BIT_IDX, PRUx_DMEM, BISSC_FIFO_BIT_IDX_OFFSET, 1
.if $isdefed("ENABLE_MULTI_CHANNEL")
LDI SCRATCH.b0, BISSC_REG_BACKUP
LOOP BISSC_READ_CDS_BITS_PER_CH?, 3
LBCO &BISSC_CTRL_FF, PRUx_DMEM, SCRATCH.b0, 8
.else
QBBS BISSC_SKIP_FIFO_CTRL_DATA?, CH_MASK, 0
QBBC BISSC_IS_CH2_FIFO_CTRL_DATA?, CH_MASK, 1
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 8
JMP BISSC_SKIP_FIFO_CTRL_DATA?
BISSC_IS_CH2_FIFO_CTRL_DATA?:
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 16
BISSC_SKIP_FIFO_CTRL_DATA?:
.endif
LSL BISSC_CTRL_CMD_RES, BISSC_CTRL_CMD_RES, 1
QBBS BISSC_CDS_BIT_SET?, BISSC_CDS_BACKUP, FIFO_BIT_IDX
XOR EX.b0, BISSC_CTRL_FF.b3, 0
QBA BISSC_CTRL_CMD_OTF_CRC?
BISSC_CDS_BIT_SET?:
XOR EX.b0, BISSC_CTRL_FF.b3, 1
SET BISSC_CTRL_CMD_RES, BISSC_CTRL_CMD_RES, 0
BISSC_CTRL_CMD_OTF_CRC?:
MOV BISSC_CTRL_FF.b3, BISSC_CTRL_FF.b2
MOV BISSC_CTRL_FF.b2, BISSC_CTRL_FF.b1
XOR BISSC_CTRL_FF.b1, BISSC_CTRL_FF.b0, EX.b0
MOV BISSC_CTRL_FF.b0, EX.b0
.if $isdefed("ENABLE_MULTI_CHANNEL")
SBCO &BISSC_CTRL_FF, PRUx_DMEM, SCRATCH.b0, 8
ADD SCRATCH.b0, SCRATCH.b0, 8
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 8
BISSC_READ_CDS_BITS_PER_CH?:
.endif
QBA BISSC_CTRL_CMD_BIT_SEND_SKIP?
BISSC_READ_CTRL_CRC_BITS?:
LBCO &FIFO_BIT_IDX, PRUx_DMEM, BISSC_FIFO_BIT_IDX_OFFSET, 1
.if $isdefed("ENABLE_MULTI_CHANNEL")
LDI SCRATCH.b0, BISSC_REG_BACKUP
LOOP BISSC_READ_CTRL_CRC_BITS_PER_CH?, 3
LBCO &BISSC_CTRL_FF, PRUx_DMEM, SCRATCH.b0, 8
.else
QBBS BISSC_SKIP_FIFO_CTRL_CRC?, CH_MASK, 0
QBBC BISSC_IS_CH2_FIFO_CTRL_CRC?, CH_MASK, 1
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 8
JMP BISSC_SKIP_FIFO_CTRL_CRC?
BISSC_IS_CH2_FIFO_CTRL_CRC?:
QBBC BISSC_SKIP_FIFO_CTRL_CRC?, CH_MASK, 2
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 16
BISSC_SKIP_FIFO_CTRL_CRC?:
.endif
LSL BISSC_CTRL_CRC, BISSC_CTRL_CRC, 1
QBBC BISSC_CDS_BIT_CLEAR?, BISSC_CDS_BACKUP, FIFO_BIT_IDX
SET BISSC_CTRL_CRC, BISSC_CTRL_CRC, 0
QBA BISSC_READ_CDS_CRC_OF_NEXT_CH?
BISSC_CDS_BIT_CLEAR?:
CLR BISSC_CTRL_CRC, BISSC_CTRL_CRC, 0
BISSC_READ_CDS_CRC_OF_NEXT_CH?:
.if $isdefed("ENABLE_MULTI_CHANNEL")
SBCO &BISSC_CTRL_FF, PRUx_DMEM, SCRATCH.b0, 8
ADD SCRATCH.b0, SCRATCH.b0, 8
ADD FIFO_BIT_IDX, FIFO_BIT_IDX, 8
BISSC_READ_CTRL_CRC_BITS_PER_CH?:
.endif
BISSC_CTRL_CMD_BIT_SEND_SKIP?:
BISSC_CTRL_CMD_DATA_RCV_SKIP?:
BISSC_CTRL_CMD_START_BIT_SENT?:
QBEQ BISSC_CTRL_CMD_COMPLETED?, BISSC_CMD_BIT_PTR, 0
QBA BISSC_CTRL_COMMUNICATION_SKIP?
BISSC_CTRL_CMD_COMPLETED?:
.if $isdefed("ENABLE_MULTI_CHANNEL")
LDI BASE_OFFSET, BISSC_CH0_CTRL_BASE_OFFSET
LDI SCRATCH.b0, BISSC_REG_BACKUP
LOOP BISSC_STORE_CTRL_RES?, 3
LBCO &BISSC_CTRL_FF, PRUx_DMEM, SCRATCH.b0, 8
.else
QBBC BISSC_STORE_CH1_CTRL_RES?, CH_MASK, 0
LDI BASE_OFFSET, BISSC_CH0_CTRL_BASE_OFFSET
JMP BISSC_SKIP_CH2_CTRL_RES?
BISSC_STORE_CH1_CTRL_RES?:
QBBC BISSC_STORE_CH2_CTRL_RES?, CH_MASK, 1
LDI BASE_OFFSET, BISSC_CH1_CTRL_BASE_OFFSET
JMP BISSC_SKIP_CH2_CTRL_RES?
BISSC_STORE_CH2_CTRL_RES?:
QBBC BISSC_SKIP_CH2_CTRL_RES?, CH_MASK, 2
LDI BASE_OFFSET, BISSC_CH2_CTRL_BASE_OFFSET
BISSC_SKIP_CH2_CTRL_RES?:
.endif
LDI BISSC_CTRL_OTF_CRC, 0
QBBS BISSC_CTRL_CRC_BIT?, BISSC_CTRL_FF.b0, 0
SET BISSC_CTRL_OTF_CRC, BISSC_CTRL_OTF_CRC, 0
BISSC_CTRL_CRC_BIT?:
QBBS BISSC_CTRL_CRC_BIT1?, BISSC_CTRL_FF.b1, 0
SET BISSC_CTRL_OTF_CRC, BISSC_CTRL_OTF_CRC, 1
BISSC_CTRL_CRC_BIT1?:
QBBS BISSC_CTRL_CRC_BIT2?, BISSC_CTRL_FF.b2, 0
SET BISSC_CTRL_OTF_CRC, BISSC_CTRL_OTF_CRC, 2
BISSC_CTRL_CRC_BIT2?:
QBBS BISSC_CTRL_CRC_END?, BISSC_CTRL_FF.b3, 0
SET BISSC_CTRL_OTF_CRC, BISSC_CTRL_OTF_CRC, 3
BISSC_CTRL_CRC_END?:
AND BISSC_CTRL_OTF_CRC, BISSC_CTRL_OTF_CRC, 0xF
AND BISSC_CTRL_CRC, BISSC_CTRL_CRC, 0xF
ADD SCRATCH3.b0, BASE_OFFSET, BISSC_CTRL_CMD_RESULT_OFFSET
SBCO &BISSC_CTRL_CMD_RES, PRUx_DMEM, SCRATCH3.b0, 1
ADD SCRATCH3.b0, BASE_OFFSET, BISSC_CTRL_CMD_DATA_CRC_OFFSET
SBCO &BISSC_CTRL_CRC, PRUx_DMEM, SCRATCH3.b0, 1
ADD SCRATCH3.b0, BASE_OFFSET, BISSC_CTRL_CMD_OTF_CRC_OFFSET
SBCO &BISSC_CTRL_OTF_CRC, PRUx_DMEM, SCRATCH3.b0, 1
QBEQ BISSC_CTRL_CRC_SUCCESS?, BISSC_CTRL_OTF_CRC, BISSC_CTRL_CRC
ADD SCRATCH3.b0, BASE_OFFSET, BISSC_CTRL_CMD_CRC_ERROR_COUNT_OFFSET
LBCO &SCRATCH1, PRUx_DMEM, SCRATCH3.b0, 4
ADD SCRATCH1, SCRATCH1, 1
SBCO &SCRATCH1, PRUx_DMEM, SCRATCH3.b0, 4
BISSC_CTRL_CRC_SUCCESS?:
LDI BISSC_CTRL_CRC, 0
LDI BISSC_CTRL_OTF_CRC, 0
.if $isdefed("ENABLE_MULTI_CHANNEL")
ZERO &BISSC_CTRL_FF, 4
SBCO &BISSC_CTRL_FF, PRUx_DMEM, SCRATCH.b0, 8
ADD SCRATCH.b0, SCRATCH.b0, 8
ADD BASE_OFFSET, BASE_OFFSET, 8
BISSC_STORE_CTRL_RES?:
.endif
BISSC_HOST_CMD_END:
CLR BISSC_FLAGS_REG, BISSC_FLAGS_REG, 0 ;clear the flag which indicate the control communication
LDI STATUS_REG1, 0
;Clear Host Trigger
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CTRL_CMD_CH0_STATUS_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CTRL_CMD_CH1_STATUS_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CTRL_CMD_CH2_STATUS_OFFSET, 1
.else
;ch0 ctrl command offset is the base offset and only ch0 offset is going to be used in single ch or multi ch single pru
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CTRL_CMD_CH0_STATUS_OFFSET, 1
.endif
BISSC_CTRL_COMMUNICATION_SKIP?:
LBCO &SCRATCH2, PRUx_DMEM, BISSC_CONFIG_DELAY_40US_OFFSET, 4 ;wait here for 40(biss_timeout)) useconds
LSR SCRATCH2, SCRATCH2, 1
BISSC_DELAY_LOOP1?:
SUB SCRATCH2, SCRATCH2, 1
QBNE BISSC_DELAY_LOOP1?, SCRATCH2, 0
LBCO &FIFO_BIT_IDX, PRUx_DMEM, BISSC_FIFO_BIT_IDX_OFFSET, 1
BISSC_RESET_BIT?:
; wait for valid bit
AND SCRATCH1.b0, R31.b3, CH_MASK
QBNE BISSC_RESET_BIT?, CH_MASK, SCRATCH1.b0
MOV SCRATCH1, R31
QBBC BISSC_IS_CH1_VALID_RB?, CH_MASK, 0
SET R31, R31, BISSC_CH0_RX_VALID_BIT_OFFSET
BISSC_IS_CH1_VALID_RB?:
QBBC BISSC_IS_CH2_VALID_RB?, CH_MASK, 1
SET R31, R31,BISSC_CH1_RX_VALID_BIT_OFFSET
BISSC_IS_CH2_VALID_RB?:
QBBC BISSC_SKIP_RX_VALID_RB?, CH_MASK, 2
SET R31, R31,BISSC_CH2_RX_VALID_BIT_OFFSET
BISSC_SKIP_RX_VALID_RB?:
;must maintain 3 cycles before checking next valid bit
NOP
NOP
QBBC BISSC_IS_CH1_FIFO_RB?, CH_MASK, 0
QBBS BISSC_SKIP_RESET_BIT?, SCRATCH1.b0, FIFO_BIT_IDX
BISSC_IS_CH1_FIFO_RB?:
QBBC BISSC_IS_CH2_FIFO_RB?, CH_MASK, 1
QBBS BISSC_SKIP_RESET_BIT?, SCRATCH1.b1, FIFO_BIT_IDX
BISSC_IS_CH2_FIFO_RB?:
QBBC BISSC_RESET_BIT?, CH_MASK, 2
QBBC BISSC_RESET_BIT?, SCRATCH1.b2, FIFO_BIT_IDX
BISSC_SKIP_RESET_BIT?:
;disable clock override by default
ZERO &SCRATCH1, 4
M_BISSC_CLK_CONFIG CH_MASK, SCRATCH1
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
M_BISSC_LS_WAIT_FOR_SYNC
QBBC BISSC_SKIP_GLOBAL_REINIT?, PRIMARY_CORE, 0
NOP
NOP
SET R31, R31, 19 ;ENDAT_TX_GLOBAL_REINIT ; Set TX_EN low
; rx_en = 0 : Disable RX mode
LDI R30.b3, 0
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
M_BISSC_LS_WAIT_FOR_SYNC
QBBC BISSC_SKIP_GLOBAL_REINIT?, PRIMARY_CORE, 1
NOP
NOP
SET R31, R31, 19 ;ENDAT_TX_GLOBAL_REINIT ; Set TX_EN low
; rx_en = 0 : Disable RX mode
LDI R30.b3, 0
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
M_BISSC_LS_WAIT_FOR_SYNC
QBBC BISSC_SKIP_GLOBAL_REINIT?, PRIMARY_CORE, 2
NOP
NOP
SET R31, R31, 19 ;ENDAT_TX_GLOBAL_REINIT ; Set TX_EN low
; rx_en = 0 : Disable RX mode
LDI R30.b3, 0
.else
SET R31, R31, 19 ;ENDAT_TX_GLOBAL_REINIT ; Set TX_EN low
; rx_en = 0 : Disable RX mode
LDI R30.b3, 0
.endif
BISSC_SKIP_GLOBAL_REINIT?:
LDI STATUS_REG1, 0
;Clear Host Trigger
.if $isdefed("ENABLE_MULTI_MAKE_RTU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH0_STATUS_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_PRU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH1_STATUS_OFFSET, 1
.elseif $isdefed("ENABLE_MULTI_MAKE_TXPRU")
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH2_STATUS_OFFSET, 1
.else
;ch0 cycle trigger offset is the base cycle trigger offset and only ch0 offset is going to be used in single ch or multi ch single pru
SBCO &STATUS_REG1, PRUx_DMEM, BISSC_CYCLE_TRIGGER_CH0_STATUS_OFFSET, 1
.endif
;Handle next Position request by user.
JMP BISSC_HANDLE_HOST_TRIGGER
;never reach here
HALT