1 /**
2 * \ingroup MODULMACROS
3 *
4 * \file SyncJtag_AssertPor_SaveContext.c
5 *
6 * \brief Sync with device, assert a Power On Reset and save processor context
7 *
8 */
9 /*
10 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
11 *
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the
23 * distribution.
24 *
25 * Neither the name of Texas Instruments Incorporated nor the names of
26 * its contributors may be used to endorse or promote products derived
27 * from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42 #include "error_def.h"
43 #include "arch.h"
44 #include "edt.h"
45 #include "hal.h"
46 #include "hal_ref.h"
47 #include "stream.h"
48 #include "EEM_defs.h"
49 #include "global_variables.h"
50
51 extern DeviceSettings deviceSettings;
52
53 /**
54 SyncJtag_AssertPor_SaveContext
55 inData: <wdtAddr(16)> <wdtCtrl(16)>
56 outData: <wdtCtrl(16)> <PC(32)> <SR(16)>
57 wdtAddr: watchdog timer address
58 wdtCtrl: watchdog timer control value
59 PC: program counter register (R0)
60 SR: status register (R2)
61 */
HAL_FUNCTION(_hal_SyncJtag_AssertPor_SaveContext)62 HAL_FUNCTION(_hal_SyncJtag_AssertPor_SaveContext)
63 {
64 unsigned short i = 0, lOut = 0, ctl_sync = 0;
65 unsigned short MyOut[4]; //! Output
66 unsigned short address;
67 unsigned short wdtVal;
68 unsigned short* syncWithRunVarAddress = 0;
69
70 // Check input parameters before we proceed
71 if(STREAM_get_word(&address) != 0)
72 {
73 return (HALERR_SYNC_JTAG_ASSERT_POR_NO_WDT_ADDRESS);
74 }
75 if(STREAM_get_word(&wdtVal) != 0)
76 {
77 return (HALERR_SYNC_JTAG_ASSERT_POR_NO_WDT_VALUE);
78 }
79
80 syncWithRunVarAddress = getTargetRunningVar();
81 if(syncWithRunVarAddress)
82 {
83 *syncWithRunVarAddress = 0x0000;
84 }
85
86 // Sync the JTAG
87 cntrl_sig_16bit();
88 SetReg_16Bits(0x2401);
89
90 if(cntrl_sig_capture() != JTAGVERSION)
91 {
92 return (HALERR_JTAG_VERSION_MISMATCH);
93 }
94
95 cntrl_sig_capture();
96 lOut = SetReg_16Bits(0x0000); // read control register once
97
98 IHIL_Tclk(1);
99
100 if(!(lOut & CNTRL_SIG_TCE))
101 {
102 // If the JTAG and CPU are not already synchronized ...
103 // Initiate Jtag and CPU synchronization. Read/Write is under CPU control. Source TCLK via TDI.
104 // Do not effect bits used by DTC (CPU_HALT, MCLKON).
105 cntrl_sig_high_byte();
106 SetReg_8Bits((CNTRL_SIG_TAGFUNCSAT | CNTRL_SIG_TCE1 | CNTRL_SIG_CPU) >> 8); // initiate CPU synchronization but release low byte of CNTRL sig register to CPU control
107
108 // Address Force Sync special handling
109 eem_data_exchange(); // read access to EEM General Clock Control Register (GCLKCTRL)
110 SetReg_16Bits(MX_GCLKCTRL + MX_READ);
111 lOut = SetReg_16Bits(0); // read the content of GCLKCNTRL into lOUt
112 // Set Force Jtag Synchronization bit in Emex General Clock Control register.
113 lOut |= 0x0040; // 0x0040 = FORCE_SYN in DLLv2
114 eem_data_exchange(); // Stability improvement: should be possible to remove this, required only once at the beginning
115 SetReg_16Bits(MX_GCLKCTRL + MX_WRITE); // write access to EEM General Clock Control Register (GCLKCTRL)
116 lOut = SetReg_16Bits(lOut); // write into GCLKCNTRL
117 // Reset Force Jtag Synchronization bit in Emex General Clock Control register.
118 lOut &= ~0x0040;
119 eem_data_exchange(); // Stability improvement: should be possible to remove this, required only once at the beginning
120 SetReg_16Bits(MX_GCLKCTRL + MX_WRITE); // write access to EEM General Clock Control Register (GCLKCTRL)
121 lOut = SetReg_16Bits(lOut); // write into GCLKCNTRL
122
123 ctl_sync = SyncJtag();
124
125 if(!(ctl_sync & CNTRL_SIG_CPU_HALT))
126 { // Synchronization failed!
127 return (HALERR_SYNC_JTAG_ASSERT_POR_JTAG_TIMEOUT);
128 }
129 }// end of if(!(lOut & CNTRL_SIG_TCE))
130
131 if(ctl_sync & CNTRL_SIG_CPU_HALT)
132 {
133 IHIL_Tclk(0);
134 cntrl_sig_16bit();
135 SetReg_16Bits(0x2401);
136 IHIL_Tclk(1);
137 }
138 else
139 {
140 cntrl_sig_16bit();
141 SetReg_16Bits(0x2401);
142 }
143
144 if (deviceSettings.assertBslValidBit)
145 {
146 // here we add bit de assert bit 7 in JTAG test reg to enalbe clocks again
147 test_reg();
148 lOut = SetReg_8Bits(0x00);
149 lOut |= 0x80; //DE_ASSERT_BSL_VALID;
150 test_reg();
151 SetReg_8Bits(lOut); // Bit 7 is de asserted now
152 }
153
154 // execute a dummy instruction here
155 data_16bit();
156 IHIL_Tclk(1); // Stability improvement: should be possible to remove this TCLK is already 1
157 SetReg_16Bits(0x4303); // 0x4303 = NOP
158 IHIL_Tclk(0);
159 data_capture();
160 IHIL_Tclk(1);
161
162 // step until next instruction load boundary if not being already there
163 if(instrLoad() != 0)
164 {
165 return (HALERR_INSTRUCTION_BOUNDARY_ERROR);
166 }
167
168 if (deviceSettings.clockControlType == GCC_EXTENDED)
169 {
170 // Perform the POR
171 eem_data_exchange();
172 SetReg_16Bits(MX_GENCNTRL + MX_WRITE); // write access to EEM General Control Register (MX_GENCNTRL)
173 SetReg_16Bits(EMU_FEAT_EN | EMU_CLK_EN | CLEAR_STOP | EEM_EN); // write into MX_GENCNTRL
174
175 eem_data_exchange(); // Stability improvement: should be possible to remove this, required only once at the beginning
176 SetReg_16Bits(MX_GENCNTRL + MX_WRITE); // write access to EEM General Control Register (MX_GENCNTRL)
177 SetReg_16Bits(EMU_FEAT_EN | EMU_CLK_EN); // write into MX_GENCNTRL
178 }
179 if (deviceSettings.clockControlType == GCC_STANDARD_I)
180 {
181 eem_data_exchange();
182 SetReg_16Bits(MX_GENCNTRL + MX_WRITE); // write access to EEM General Control Register (MX_GENCNTRL)
183 SetReg_16Bits(EMU_FEAT_EN); // write into MX_GENCNTRL
184 }
185
186 IHIL_Tclk(0);
187 cntrl_sig_16bit();
188 SetReg_16Bits(CNTRL_SIG_READ | CNTRL_SIG_TCE1 | CNTRL_SIG_PUC | CNTRL_SIG_TAGFUNCSAT); // Assert PUC
189 IHIL_Tclk(1);
190 cntrl_sig_16bit();
191 SetReg_16Bits(CNTRL_SIG_READ | CNTRL_SIG_TCE1 | CNTRL_SIG_TAGFUNCSAT); // Negate PUC
192
193 IHIL_Tclk(0);
194 cntrl_sig_16bit();
195 SetReg_16Bits(CNTRL_SIG_READ | CNTRL_SIG_TCE1 | CNTRL_SIG_PUC | CNTRL_SIG_TAGFUNCSAT); // Assert PUC
196 IHIL_Tclk(1);
197 cntrl_sig_16bit();
198 SetReg_16Bits(CNTRL_SIG_READ | CNTRL_SIG_TCE1 | CNTRL_SIG_TAGFUNCSAT); // Negate PUC
199
200 // Explicitly set TMR
201 SetReg_16Bits(CNTRL_SIG_READ | CNTRL_SIG_TCE1); // Enable access to Flash registers
202
203 flash_16bit_update(); // Disable flash test mode
204 SetReg_16Bits(FLASH_SESEL1); // Pulse TMR
205 SetReg_16Bits(FLASH_SESEL1 | FLASH_TMR);
206 SetReg_16Bits(FLASH_SESEL1);
207 SetReg_16Bits(FLASH_SESEL1 | FLASH_TMR); // Set TMR to user mode
208
209 cntrl_sig_high_byte();
210 SetReg_8Bits((CNTRL_SIG_TAGFUNCSAT | CNTRL_SIG_TCE1) >> 8); // Disable access to Flash register
211
212 // step until an appropriate instruction load boundary
213 for(i = 0; i < 10; i++)
214 {
215 addr_capture();
216 lOut = SetReg_16Bits(0x0000);
217 if(lOut == 0xFFFE || lOut == 0x0F00)
218 {
219 break;
220 }
221 IHIL_TCLK();
222 }
223 if(i == 10)
224 {
225 return (HALERR_INSTRUCTION_BOUNDARY_ERROR);
226 }
227 IHIL_TCLK();
228 IHIL_TCLK();
229
230 IHIL_Tclk(0);
231 addr_capture();
232 SetReg_16Bits(0x0000);
233 IHIL_Tclk(1);
234
235 // step until next instruction load boundary if not being already there
236
237 if(instrLoad() != 0)
238 {
239 return (HALERR_INSTRUCTION_BOUNDARY_ERROR);
240 }
241
242 // Hold Watchdog
243 MyOut[0] = ReadMemWord(address); // safe WDT value
244 wdtVal |= (MyOut[0] & 0xFF); // set original bits in addition to stop bit
245 WriteMemWord(address, wdtVal);
246
247 // read MAB = PC here
248 addr_capture();
249 MyOut[1] = SetReg_16Bits(0);
250 MyOut[2] = 0; // high PC always 0 for MSP430 architecture
251
252 // set PC to a save address pointing to ROM to avoid RAM corruption on certain devices
253 SetPc(ROM_ADDR);
254
255 // read status register
256 MyOut[3] = ReadCpuReg(2);
257
258 // return output
259 STREAM_put_bytes((unsigned char*)MyOut,8);
260
261 return(0);
262 }
263
264