"""
  Copyright 2025 Texas Instruments Incorporated. All rights reserved.

  IMPORTANT: Your use of this Software is limited to those specific rights
  granted under the terms of a software license agreement between the user who
  downloaded the software, his/her employer (which must be your employer) and
  Texas Instruments Incorporated (the "License"). You may not use this Software
  unless you agree to abide by the terms of the License. The License limits your
  use, and you acknowledge, that the Software may not be modified, copied or
  distributed unless embedded on a Texas Instruments microcontroller which is
  integrated into your product. Other than for the foregoing purpose, you may
  not use, reproduce, copy, prepare derivative works of, modify, distribute,
  perform, display or sell this Software and/or its documentation for any
  purpose.

  YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL TEXAS
  INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL
  EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT
  LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL
  DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS,
  TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT
  LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.

  Should you have any questions regarding your right to use this Software,
  contact Texas Instruments Incorporated at www.TI.com.
"""
# Fill in I2C addresses and aliases
devAddr = 0x60 # 960 deserializer 8-bit I2C address
serAddr = [0x30,0x30,0x30,0x30] # 953 serializer 8-bit I2C addresses connected to 960 RX port0, port1, port2, port3
serAlias = [0x1A,0x2A,0x3A,0x4A] # 8-bit I2C aliases to read/write serializers connected to 960 RX port0, port1, port2, port3
imgAddr = [0x32,0x32,0x32,0x32] # imager 8-bit I2C addresses connected to 960 RX port0, port1, port2, port3
imgAlias = [0x1C,0x2C,0x3C,0x4C] # 8-bit I2C aliases to read/write imagers connected to 960 RX port0, port1, port2, port3
ispAddr = [0x34,0x34,0x34,0x34] # ISP 8-bit I2C addresses connected to 960 RX port0, port1, port2, port3
ispAlias = [0x1E,0x2E,0x3E,0x4E] # 8-bit I2C aliases to read/write ISPs connected to 960 RX port0, port1, port2, port3

import time

for i in range(0,4):
    if i==0:
        board.WriteI2C(devAddr,0x4C,0x01) # select RX port 0
    elif i==1: 
        board.WriteI2C(devAddr,0x4C,0x12) # select RX port 1
    elif i==2:
        board.WriteI2C(devAddr,0x4C,0x24) # select RX port 2
    elif i==3:
        board.WriteI2C(devAddr,0x4C,0x38) # select RX port 3

    # auto ACK setup
    board.WriteI2C(devAddr,0x5B,serAddr[i]+1) # set serializer address with freeze
    board.WriteI2C(devAddr,0x5C,serAlias[i]+1) # set SER alias and auto ACK
    board.WriteI2C(devAddr,0x58,0x7A) # Enable I2C passthrough with auto ACK, BC rate = 10Mbps

    # 953 config
    board.WriteI2C(serAlias[i],0x02,0x73) # continuous clock, 4 lanes
    board.WriteI2C(serAlias[i],0xE,0x1E) # disable 935 GPIO0 input and enable output
    board.WriteI2C(serAlias[i],0xD,0x10) # Enable remote Des GPIO0 data on local GPIO0
    board.WriteI2C(serAlias[i],0x03,0x12) # MODE override async external clock
    board.WriteI2C(serAlias[i],0x01,0x01) # soft reset
    time.sleep(0.01)

    # I2C address and alias setup
    board.WriteI2C(devAddr,0x58,0x5A) # Disable auto ACK
    board.WriteI2C(devAddr,0x5B,serAddr[i]) # remove freeze
    board.WriteI2C(devAddr,0x5C,serAlias[i]) # disable auto ACK
    board.WriteI2C(devAddr,0x5D,imgAddr[i]) # configure imager address
    board.WriteI2C(devAddr,0x65,imgAlias[i]) # configure imager alias
    board.WriteI2C(devAddr,0x5E,ispAddr[i]) # configure ISP address
    board.WriteI2C(devAddr,0x66,ispAlias[i]) # configure ISP alias

    # 960 config
    board.WriteI2C(devAddr,0x6D,0x7C) # FPD3 CSI-2 input mode
    board.WriteI2C(devAddr,0x6E,0x8A) # map Fsync signal to 953 GPIO0 output
    board.WriteI2C(devAddr,0x72,0x00) # map VC-ID to 0

    # FrameSync: 25Hz, 10%/90% duty cycle
    board.WriteI2C(devAddr,0x19,0x05) # FS_HIGH_TIME_1
    board.WriteI2C(devAddr,0x1A,0x34) # FS_HIGH_TIME_0
    board.WriteI2C(devAddr,0x1B,0x2E) # FS_LOW_TIME_1
    board.WriteI2C(devAddr,0x1C,0xDF) # FS_LOW_TIME_0
    board.WriteI2C(devAddr,0x18,0x01) # enable internally generated FrameSync

    # Clear error/status
    time.sleep(0.1)
    board.ReadI2C(devAddr,0x4D)
    board.ReadI2C(devAddr,0x4E)
    board.ReadI2C(devAddr,0x55)
    board.ReadI2C(devAddr,0x56)
    board.ReadI2C(devAddr,0x7A)
    board.ReadI2C(devAddr,0x7B)

# CSI Output / Forwarding Config
board.WriteI2C(devAddr,0x1F,0x00) # 1.472 - 1.664Gbps serial rate
board.WriteI2C(devAddr,0x32,0x01) # select CSI port 0
board.WriteI2C(devAddr,0x33,0x43) # enable skew cal, 4 lanes, continuous clock, enable CSI output
board.WriteI2C(devAddr,0x21,0x04) # basic sync forwarding on CSI port 0
board.WriteI2C(devAddr,0x20,0x00) # forward all RX port to CSI port 0, enable forwarding
