#! /usr/bin/env python3

# SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.

"""
This script is to toggle the TCK signal of PM342 debug board.
There are 4 interface in FTDI chip and only interface B is used as JTAG
interface in PM342 board.

Use command `sudo tckctrl low` to set the TCK to low
Use command `sudo tckctrl reset` to reset the mode to MPSSE (TCK high)
"""

import os
import sys
import ftdi_wrapper
import time
import struct
from optparse import OptionParser


if __name__=="__main__":

    parser = OptionParser()
    parser.set_defaults()
    parser.add_option("--serial", "-s", action="store", type="string",
                      dest="serial", help="Serial of debug board. Defaults to the value of PMXXX_SERIAL environment variable.")
    (options, args) = parser.parse_args()

    if options.serial is None and "PMXXX_SERIAL" in os.environ:
        options.serial = os.environ["PMXXX_SERIAL"]
        print("NOTE: Using --serial=%s from environment." % options.serial)

    if options.serial is None:
        print("NOTE: Using first found PM342.")


    if len(args) != 1:
        print("Must give a TCK control command: low | reset", file=sys.stderr)
        sys.exit(1)

    # initialize
    ftdic = ftdi_wrapper.context()
    ftdi_wrapper.init(ftdic)
    if ftdic == 0:
        print('new failed: %d' % ret, file=sys.stderr)
        sys.exit( 1 )

    # open usb
    ftdi_wrapper.set_interface(ftdic, ftdi_wrapper.INTERFACE_B)
    if options.serial is not None:
        print('Use serial number %s' % options.serial)

    ret = ftdi_wrapper.usb_open_desc(ftdic, 0x0403, 0x6011, None, options.serial)
    if ret < 0:
        print('unable to open ftdi device: %d (%s)' % ( ret, ftdi_wrapper.get_error_string( ftdic ) ), file=sys.stderr)
        sys.exit( 1 )

    ftdi_wrapper.usb_reset(ftdic)
    ftdi_wrapper.set_latency_timer(ftdic, 16)

    # reset mode and set to MPSSE
    print('Reset bit mode')
    ret = ftdi_wrapper.set_bitmode( ftdic, 0, ftdi_wrapper.BITMODE_RESET )
    if ret < 0:
        print('Cannot reset MPSSE', file=sys.stderr)
        sys.exit( 1 )

    time.sleep( 1 )
    print('Enter MPSSE mode')
    ret = ftdi_wrapper.set_bitmode( ftdic, 0, ftdi_wrapper.BITMODE_MPSSE )
    if ret < 0:
        print('Cannot enable MPSSE', file=sys.stderr)
        sys.exit( 1 )
    time.sleep( 1 )

    if args[0] == 'low':
    # JTAG HEADER LOW BYTE FORMAT:
    # 0 FT_B_JTAG_TCK
    # 1 FT_B_JTAG_TD1
    # 2 FT_B_JTAG_TD0
    # 3 FT_B_JTAG_TMS
    # 4 FT_B_JTAG_TRST_L
    # 5 FT_B_JTAG_TRST_SW_EN
    # 6 FT_B_JTAG_SRST_L
    # 7 FT_B_JTAG_RCK

        # Write data
        # 0x80;  #This is the command code
        # 0x50;  #clear bit 0
        # 0xff;  #MASK: output all JTAG bits
        cmd = struct.pack("<BBB", 0x80, 0x50, 0xff)
        ftdi_wrapper.write_data(ftdic, cmd, len(cmd))
        print('Set TCK to low')

    # close usb
    ret = ftdi_wrapper.usb_close( ftdic )
    if ret < 0:
        print('unable to close ftdi device: %d (%s)' % ( ret, ftdi_wrapper.get_error_string( ftdic ) ), file=sys.stderr)
        sys.exit( 1 )

    print('DONE.  (It may be useful to probe pin9 on PM342\'s connector J32 to make sure it is expected)')
