/***********************************************************************
*                    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: Script which shows how to use the JLINK_CORESIGHT_WriteDAPMultiple, JLINK_CORESIGHT_WriteDAPRepeatData, JLINK_CORESIGHT_ReadDAPMultiple and JLINK_CORESIGHT_ReadDAPMultipleCheck function.
         This can be used to output custom sequences (e.g. if they are required to enable the device)
Literature:
  [1]  J-Link User Guide

Additional information:
  For more information about public functions that can be implemented in order to customize J-Link actions, please refer to [1]
*/

/*********************************************************************
*
*       Constants (similar to defines)
*
**********************************************************************
*/

//
// Device specific SFRs
//
__constant U32 _INDEX_AHB_AP                  = 0;

__constant U32 _BANK0                         = 0;
__constant U32 _BANK5                         = 5;

__constant U32 _DAP_ACC_32BIT_AUTO_INC        = (1 << 29) | (1 << 25) | (1 << 24) | (1 << 4) | (2 << 0);  // HMASTER = DEBUG, Private access, Auto-increment, Access size: word;
__constant U32 _DAP_ACC_8BIT_NO_AUTO_INC      = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (0 << 0);  // HMASTER = DEBUG, Private access, no Auto-increment, Access size: byte;
__constant U32 _DAP_ACC_16BIT_NO_AUTO_INC     = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (1 << 0);  // HMASTER = DEBUG, Private access, no Auto-increment, Access size: half word;
__constant U32 _DAP_ACC_32BIT_NO_AUTO_INC     = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (2 << 0);  // HMASTER = DEBUG, Private access, no Auto-increment, Access size: word;
__constant U32 _DP_CTRL_STAT_BIT_DBGPWRUPREQ  = (1 << 30);
__constant U32 _DP_CTRL_STAT_BIT_SYSPWRUPREQ  = (1 << 28);
__constant U32 _DP_CTRL_STAT_BIT_STICKYERR    = (1 <<  5);
//
// Generic defines
//
__constant U32 _ACCESS_DP                     = 0;
__constant U32 _ACCESS_AP                     = 1;

/*********************************************************************
*
*       Global variables
*
**********************************************************************
*/
  
/*********************************************************************
*
*       Local functions
*
**********************************************************************
*/

/*********************************************************************
*
*       _PrepDAP
*
*  Function description
*    Prepares the DAP for further usage, meaning enabling the power for different domains, make sure that no sticky error flags are set etc.
*/
static void _PrepDAP(void) {
  U32 v;
  //
  // The DP is slightly different for JTAG and SWD, especially regarding clearing sticky error bits
  //
  if (JLINK_ActiveTIF == JLINK_TIF_SWD) {
    v = _DP_CTRL_STAT_BIT_DBGPWRUPREQ | _DP_CTRL_STAT_BIT_SYSPWRUPREQ;
    JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_ABORT, 0x1E);                          // Clear sticky error flags
  } else {
    v = _DP_CTRL_STAT_BIT_DBGPWRUPREQ | _DP_CTRL_STAT_BIT_SYSPWRUPREQ | _DP_CTRL_STAT_BIT_STICKYERR;   // Clear sticky error flag
  }
  JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_CTRL_STAT, v);
}

/*********************************************************************
*
*       Global functions
*
**********************************************************************
*/

static U32 _aData[0x100];  // 0x100 * 4 bytes = 1024 bytes = 1 KB

/*********************************************************************
*
*       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 Addr;
  U32 NumBytesAtOnce;
  U32 NumBytesRem;
  U32 v;
  int i;
  int t;
  int tDelta;
  //
  // Initialize 512 KB RAM.
  // As we do not have 512 KB continuous RAM, we init the same area multiple times
  //
  JLINK_SYS_Report("InitTarget()");
  JLINK_CORESIGHT_IndexAHBAPToUse = 0;
  JLINK_CORESIGHT_Configure("");
  _PrepDAP();
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, _ACCESS_DP, (_INDEX_AHB_AP << 24) | (_BANK0 << 4));
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_CTRL,   _ACCESS_AP, _DAP_ACC_32BIT_AUTO_INC);                  // Configure AHB-AP for 32-bit memory accesses
  //
  // Fast block write
  // Needs a buffer of block size
  //
  t = JLINK_GetTime();
  NumBytesRem = 0x1000;
  Addr = 0x20000000;
  do {
    //
    // Use 1 KB auto-increment capability of AHB-AP
    //
    NumBytesAtOnce = 0x400;
    NumBytesRem -= NumBytesAtOnce;
    JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, Addr);
    JLINK_CORESIGHT_WriteDAPMultiple(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, &_aData[0], 0x100);  // Write 0x100 * 4 bytes = 0x400 bytes
    Addr = Addr + NumBytesAtOnce;
  } while (NumBytesRem);
  tDelta = JLINK_GetTime() - t;
  JLINK_SYS_Report1("Fast method took [ms (hex)]: ", tDelta);
  //
  // Fast repeated data write
  //
  t = JLINK_GetTime();
  NumBytesRem = 0x1000;
  Addr = 0x20000000;
  do {
    //
    // Use 1 KB auto-increment capability of AHB-AP
    //
    NumBytesAtOnce = 0x400;
    NumBytesRem -= NumBytesAtOnce;
    JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, Addr);
    JLINK_CORESIGHT_WriteDAPRepeatData(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, 0x00000000, 0x100);  // Write 0x100 * 4 bytes = 0x400 bytes
    Addr = Addr + NumBytesAtOnce;
  } while (NumBytesRem);
  tDelta = JLINK_GetTime() - t;
  JLINK_SYS_Report1("Fast repeat method took [ms (hex)]: ", tDelta);
  //
  // Fast read back
  //
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, 0x200000000);
  JLINK_CORESIGHT_ReadDAPMultiple(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, &_aData[0], 0x0100);
  //
  // Fast read check
  //
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, _ACCESS_AP, 0x20000F80);
  v = JLINK_CORESIGHT_ReadDAPMultipleCheck(JLINK_CORESIGHT_AP_REG_DATA, _ACCESS_AP, 0x00000000, 0x100);
  JLINK_SYS_Report1("Index not 0x00000000: ", v);
  return 0;
}

/*************************** end of file ****************************/
