1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
 * JLink Script (Hook Functions) for PAN107X SoC downloading/debugging
 */
 
/*
 * PAN107X RCC Registers Map:
 *
 * #define CLK_BASE                    (0x40040000UL)
 *
 * #define CLK_RSTSTS                (0x40040000UL)
 * #define CLK_IPRST0                (0x40040004UL)
 * #define CLK_IPRST1                (0x40040008UL)
 * #define CLK_BODCTL_3V            (0x4004000CUL)
 * #define CLK_BLDBCTL_3V            (0x40040010UL)
 * #define CLK_CLK_TOP_CTRL_3V        (0x40040014UL)
 * #define CLK_RCL_CTRL_3V            (0x40040018UL)
 * #define CLK_RCH_CTRL                (0x4004001CUL)
 * #define CLK_XTL_CTRL_3V            (0x40040020UL)
 * #define CLK_XTH_CTRL                (0x40040024UL)
 * #define CLK_DPLL_CTRL            (0x40040028UL)
 * #define CLK_AHB_CLK_CTRL            (0x4004002CUL)
 * #define CLK_APB1_CLK_CTRL        (0x40040030UL)
 * #define CLK_APB2_CLK_CTRL        (0x40040034UL)
 * #define CLK_MEAS_CLK_CTRL        (0x40040038UL)
 */
 
/*
 * PAN107X ANA Registers Map:
 *
 * #define ANA_BASE                    (0x40070000UL)
 *
 * #define ANA_LP_REG_SYNC            (0x40070000UL)
 * #define ANA_LP_FL_CTRL_3V        (0x40070004UL)
 * #define ANA_CPU_ADDR_REMAP_CTRL    (0x4007005CUL)
 */
 
/*********************************************************************
*
*       Constants, fixed
*
**********************************************************************
*/
 
//
// Registers (PAN107X)
//
__constant U32 ANA_CPU_ADDR_REMAP_CTRL_REG_ADDR     = 0x4007005C; // SoC CPU Remap Ctrl Register
__constant U32 ANA_LP_FL_CTRL_3V_REG_ADDR           = 0x40070004; // SoC Low Power Ctrl Register
 
//
// Registers (ARM)
//
__constant U32 _AIRCR_ADDR         = 0xE000ED0C; // Application Interrupt and Reset Control Register
__constant U32 _DHCSR_ADDR         = 0xE000EDF0; // Debug Halting Control and Status Register
__constant U32 _DEMCR_ADDR         = 0xE000EDFC; // Debug Exception and Monitor Control Register
 
//
// Bits & Shifts (ARM)
//
__constant U32 _DP_CTRL_STAT_BIT_STICKYERR = (1 <<  5);
 
__constant U32 _DHCSR_DBGKEY               = (0xA05F << 16);
__constant U32 _DHCSR_C_DEBUGEN            = (1 <<  0);
__constant U32 _DHCSR_C_HALT               = (1 <<  1);
__constant U32 _DHCSR_S_HALT               = (1 << 17);
__constant U32 _DHCSR_S_RESET_ST           = (1 << 25);
 
__constant U32 _DEMCR_VC_CORERESET         = (1 <<  0);
__constant U32 _DEMCR_TRCENA               = (1 << 24);
 
__constant U32 _AIRCR_VECTKEY              = (0x05FA << 16);
__constant U32 _AIRCR_SYSRESETREQ          = (1 <<  2);
 
/*********************************************************************
*
*       Constants, configurable
*
**********************************************************************
*/
 
__constant U32 _DEF_POST_RESET_DELAY        = 50;
 
/*********************************************************************
*
*       Global functions
*
**********************************************************************
*/
 
/*
 * Do Panchip customized Cortex-M system reset flow
 * NOTE: __probe attribute specifies that this function is executed in the J-Link firmware
 *       rather than on the PC side, so changes to global variables may only be temporarily
 *       valid inside this function (not guaranteed to be valid later)
 */
__probe int DoSysReset(void)
{
    int r;
    U32 v;
    int t;
 
    JLINK_SYS_Report("Reset: Halt core after reset via DEMCR.VC_CORERESET.");
    // Halt the CPU
    JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN));
    // Set vector catch on reset (to halt the CPU immediately after reset)
    JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA));
    // Make sure that no sticky error bits are set on the DP
    JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_ABORT, 0x1E);
 
    JLINK_SYS_Report("Reset: Clear CPU Remap Ctrl Register.");
    // Clear CPU Remap ctrl reg before reset triggering
    JLINK_MEM_WriteU32(ANA_CPU_ADDR_REMAP_CTRL_REG_ADDR, 0x0);
 
    // Reset SoC Low Power ctrl reg (Clear BIT6 to indicate SysReset)
    JLINK_MEM_WriteU32(ANA_LP_FL_CTRL_3V_REG_ADDR, 0x00000008);
 
    // Make sure that no sticky error bits are set on the DP
    JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_ABORT, 0x1E);
 
    JLINK_SYS_Report("Reset: Reset device via AIRCR.SYSRESETREQ.");
    // Issue reset request via AIRCR.SYSRESETREQ
    JLINK_MEM_WriteU32(_AIRCR_ADDR, (_AIRCR_VECTKEY | _AIRCR_SYSRESETREQ));
    // The spec does not guarantee that the reset takes place immediately, so we give the target some time.
    JLINK_SYS_Sleep(_DEF_POST_RESET_DELAY);
 
    // Now the SoC is expected to be reset successfully and CPU core is expected to be halted
    // at the 1st instruction to be executed (in Reset_Handler).
    // NOTE:
    //   For PAN107X SoC, sys_reset would cause swd connection lost, and here we re-init DAP module
    //   before exiting this ResetTarget() hook function.
 
    //
    // Output DAP init sequence
    //
    r  = JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_ABORT, 0x1E);                       // Make sure that no sticky error flags are set
    r |= JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_CTRL_STAT, (1 << 30) | (1 << 28));  // Set DBGPWRUPREQ and SYSPWRUPREQ to power up the complete DAP. Usually, no need to wait for the DAP to power up.
    r |= JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_SELECT, (0 << 24) | (0 << 4));      // Select AP[0] (AHB-AP), bank 0
    if (r < 0) {
      JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_ABORT, 0x1E);                          // Make sure that no sticky error flags are set
      JLINK_SYS_Report("Reset: SWD sticky error occurred.");
      return 1;
    }
 
    //
    // Here we should clear the vector catch we have set before
    //
    JLINK_MEM_WriteU32(_DEMCR_ADDR, (0x0 | _DEMCR_TRCENA));
 
    return 0;
}
 
/*********************************************************************
*
*  ResetTarget()
*
*  Function description
*    Replaces reset strategies of DLL. No matter what reset type is selected in the DLL, if this function is present,
*    it will be called instead of the DLL internal reset.
*
*  Notes
*    (1) DLL expects target CPU to be halted / in debug mode, when leaving this function
*    (2) May use MEM_ API functions
*/
int ResetTarget(void)
{
    int r;
 
    // Do Cortex-M sys reset
    if (DoSysReset()) {
        return 1;
    }
 
    return 0;
}