/***********************************************************************
*                    SEGGER Microcontroller GmbH                       *
*                        The Embedded Experts                          *
************************************************************************
*                                                                      *
*                  (c) SEGGER Microcontroller GmbH                     *
*                        All rights reserved                           *
*                          www.segger.com                              *
*                                                                      *
************************************************************************
*                                                                      *
************************************************************************
*                                                                      *
*                                                                      *
*  Licensing terms                                                     *
*                                                                      *
* This software may be distributed to your customers free of charge.   *
* This grant of redistribution does not entitle YOU or enduser to      *
* receive from SEGGER hard-copy documentation, technical support,      *
* phone assistance, or enhancements or updates to the Software unless  *
* a specific agreement clearly states otherwise.                       *
*                                                                      *
*                                                                      *
* THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "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 COPYRIGHT HOLDER 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.                                                              *
*                                                                      *
************************************************************************

-------------------------- END-OF-HEADER -----------------------------

Purpose: Example showing the SWD => JTAG switching sequence as documented by ARM.
Literature:
  [1]  J-Link documentation: https://wiki.segger.com/J-Link_script_files
  [2]  Cortex-M Technical Reference Manual
*/

/*********************************************************************
*
*       Constants
*
**********************************************************************
*/
//
// Data to be sent to target (LSB first!).
//
// SWD => JTAG Switching sequence.
//
const U8 _aTMSSwitch[] = {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,    // JTAG/SWD line reset.
  0x3C, 0xE7,                                  // SWD -> JTAG switching sequence.
  0xFF, 0x00                                   // Ensures that JTAG is in Idle state.
};

const U8 _aTDISwitch[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    // Nothing to do (NTD)
  0x00, 0x00,                                  // NTD
  0x00, 0x00                                   // NTD
};

//
// Read IDCODE.
// Technically we are in IDCODE state already, but for the sake of this example, we will still switch to it 
//
const U8 _aTMSReadID[] = {
  0x03,                         // Go to "Capture-IR" and send IDCODE command (b'1100_0000: Idle => DR-Scan => IR-Scan => Capture-IR => Shift-IR => 4x Shift-IR)
  0x70,                         // Send BYPASS command and go to Capture-DR (b'0000_1110: 4x Shift-IR => Exit1-IR => Update-IR => DR-Scan => Capture-DR)
  0x00, 0x00, 0x00, 0x00,       // Receive ID (4x 0x00: 32x Shift-DR)
  0x03                          // Return to Idle (b'1100_0000: Exit1-DR => Update-DR => 6x Idle).
};

const U8 _aTDIReadID[] = {
  0xE0,                         // 4 bits NTD + send READIDCODE command LSB (b'1110 => b'0111 (LSB))
  0x0F,                         // Send BYPASS command (b'1111) + 4bits NTD
  0x00, 0x00, 0x00, 0x00,       // NTD
  0x00                          // NTD
};

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/

/*********************************************************************
*
*       _SWD_BufGetU32
*
*  Function descripton
*    Get unsigned 32 bit value from an SWD transmission buffer.
*
*  Parameters
*    pData  Buffer containing data read via SWD.
*    Pos    Position from which the U32 should be read.
*
*  Return value
*    >= 0:  U32 read.
*/
static U32 _JTAG_BufGetU32(U8* pData, U32 Pos) {
  U32 iStart;
  U32 BitsRem;
  U32 Shift;
  U32 Result;
  U8  v;
  U8 Mask;
  
  iStart  = Pos >> 3;              // Divide by 8.
  BitsRem = (Pos & 7);             // Modulo 8 to get remaining bits.
  Shift   = 31 - (BitsRem - 1);    // Get required shift.
  Mask    = 0xFF >> (8 - BitsRem); // Get mask for remaining bits
  Result = 0
         | (*(pData + iStart + 0) <<  0)
         | (*(pData + iStart + 1) <<  8)
         | (*(pData + iStart + 2) << 16)
         | (*(pData + iStart + 3) << 24)
         ;
  Result >>= BitsRem;              // Shift to be 32-bit aligned.
  if (BitsRem != 0) {              // We have remaining bits? => Add them.
    v  = *(pData + iStart + 4);
    v &= Mask;
    Result |= (v << Shift);
  }
  return Result;
}

/*********************************************************************
*
*       Global functions
*
**********************************************************************
*/

/*********************************************************************
*
*       InitTarget()
*
*  Function description
*    If present, called right before performing generic connect sequence.
*    Usually used for targets which need a special connect sequence.
*    E.g.: TI devices with ICEPick TAP on them where core TAP needs to be enabled via specific ICEPick sequences first.
*
*  Return value
*    >= 0:  O.K.
*     < 0:  Error
*
*  Notes
*    (1) Must not use high-level API functions like JLINK_MEM_ etc.
*    (2) For target interface JTAG, this device has to setup the JTAG chain + JTAG TAP Ids.
*/
int InitTarget(void) {
  U32 Id;
  U8  aTDO[16];
  //
  // Execute Switching sequence
  //
  JLINK_SYS_Report("  Executing SWD => JTAG switching sequence...");
  JLINK_JTAG_ReadWriteBits(&_aTDISwitch[0], &_aTMSSwitch[0], &aTDO[0], 11 * 8);
  //
  // Execute ReadID command
  //   NumBits  Meaning
  //   8        Execute READID command
  //   4        Execute BYPASS command
  //   4        Go to Shift-DR
  //   4*8      Receive ID
  //   8        Return to Idle state.
  // => IDCODE can be from position 17 of the TDO buffer.
  //
  JLINK_JTAG_ReadWriteBits(&_aTDIReadID[0], &_aTMSReadID[0], &aTDO[0], 7 * 8);
  Id = _JTAG_BufGetU32(&aTDO[0], 2 * 8 + 1);
  if ((Id & 0x0FF00FFF) == 0xBA00477) {
    JLINK_SYS_Report1("  Found JTAG-DP with ID ", Id);
  } else {
    JLINK_SYS_Report1("  No valid JTAG-DP found. Expected pattern 0xBA00477, found pattern: ", Id);
  }
  return 0;
}

/*************************** end of file ****************************/
