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