1 /*
2 * HidUpdateManager.h
3 *
4 * Recovery for broken eZ-FETs and MSP-FET Debuggers
5 *
6 * Copyright (C) 2007 - 2011 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
19 * distribution.
20 *
21 * Neither the name of Texas Instruments Incorporated nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #include <pch.h>
39 #include "HidUpdateManager.h"
40
41 #include <hidapi.h>
42
43 #include <BSL430_DLL/Connections/MSPBSL_Connection5xxUSB.h>
44 #include <BSL430_DLL/MSPBSL_Factory.h>
45 #include <BSL430_DLL/Utility_Classes/MSPBSL_CRCEngine.h>
46
47 #include "MemoryContent.h"
48
49 #include "../../../../Bios/include/eZ_FetCore.h"
50 #include "../../../../Bios/include/MSP_FetCore.h"
51
52 using namespace TI::DLL430;
53 using namespace std;
54
55 struct BslFetWrapper
56 {
BslFetWrapperBslFetWrapper57 explicit BslFetWrapper(MSPBSL_Connection5xxUSB *ptr) : ptr_(ptr)
58 {
59 }
60
operator =BslFetWrapper61 BslFetWrapper& operator=(BslFetWrapper& bsl)
62 {
63 return *this;
64 }
65
~BslFetWrapperBslFetWrapper66 ~BslFetWrapper()
67 {
68 if (ptr_)
69 {
70 ptr_->closeBslconnection();
71 delete ptr_;
72 }
73
74 ptr_ = nullptr;
75
76 hid_exit();
77 }
78
getBslFetWrapper79 MSPBSL_Connection5xxUSB* get()
80 {
81 return ptr_;
82 }
83
isNullBslFetWrapper84 bool isNull() const
85 {
86 return ptr_ == nullptr;
87 }
88
89 MSPBSL_Connection5xxUSB *ptr_;
90 };
91
countHidDevices(uint16_t productId)92 uint32_t HidUpdateManager::countHidDevices(uint16_t productId)
93 {
94 hid_device_info *hidDevices = hid_enumerate(MSPBSL_STANDARD_USB_VID, productId);
95 hid_device_info *hidDevicesIt = hidDevices;
96
97 uint32_t count = 0;
98 while (hidDevicesIt != nullptr)
99 {
100 count++;
101 hidDevicesIt = hidDevicesIt->next;
102 }
103 hid_free_enumeration(hidDevices);
104 hid_exit();
105
106 return count;
107 }
108
109
HidUpdateManager()110 HidUpdateManager::HidUpdateManager ()
111 {
112 }
113
~HidUpdateManager()114 HidUpdateManager::~HidUpdateManager (){}
115
hid_firmWareUpdate(const char * fname,UpdateNotifyCallback callback)116 bool HidUpdateManager::hid_firmWareUpdate(const char * fname, UpdateNotifyCallback callback)
117 {
118 bool returnValue = false;
119 try
120 {
121 const bool eZRecoveryNeeded = (HidUpdateManager::countHidDevices(MSPBSL_EZ_FET_USB_PID) > 0);
122 const bool mspFetRecoveryNeeded = (HidUpdateManager::countHidDevices(MSPBSL_MSP_FET_USB_PID) > 0);
123
124 uint16_t currentPid = 0;
125 if (eZRecoveryNeeded)
126 {
127 currentPid = MSPBSL_EZ_FET_USB_PID;
128 }
129 else if (mspFetRecoveryNeeded)
130 {
131 currentPid = MSPBSL_MSP_FET_USB_PID;
132 }
133
134 //------------------------------------------------------------------------------------------
135 BslFetWrapper bslWrapper(hid_enumerateBSL(currentPid));
136
137 if (bslWrapper.isNull())
138 {
139 return false;
140 }
141
142 uint32_t requiredUpdates = 3;
143 const uint32_t percent = 100/requiredUpdates;
144
145 if (callback)
146 {
147 callback(BL_INIT, 0, 0);
148 callback(BL_PROGRAM_FIRMWARE, 0, 0);
149 callback(BL_DATA_BLOCK_PROGRAMMED, 0, 0);
150 }
151
152 MemoryContent firmware;
153
154 if (eZRecoveryNeeded)
155 {
156 uint16_t toolIdBSL = hid_getBSLToolId(bslWrapper.get());
157 if (toolIdBSL == eZ_FET_WITH_DCDC || toolIdBSL == eZ_FET_WITH_DCDC_0X3FF || toolIdBSL == eZ_FET_NO_DCDC || toolIdBSL == eZ_FET_WITH_DCDC_NO_FLOWCT || toolIdBSL == eZ_FET_WITH_DCDC_V2x)
158 {
159 //load eZ-FET CORE imag ewith TOOL ID 0xAAAA -> DCDC Sub mcu is present
160 firmware.fromSRec(eZ_FetCoreImage, eZ_FetCoreImage_address, eZ_FetCoreImage_length_of_sections, eZ_FetCoreImage_sections);
161 }
162 }
163 else if (mspFetRecoveryNeeded)
164 {
165 uint16_t toolIdBSL = hid_getBSLToolId(bslWrapper.get());
166 if (toolIdBSL == MSP_FET_WITH_DCDC || toolIdBSL == MSP_FET_WITH_DCDC_V2x)
167 {
168 firmware.fromSRec(MSP_FetCoreImage, MSP_FetCoreImage_address, MSP_FetCoreImage_length_of_sections, MSP_FetCoreImage_sections);
169 }
170 }
171
172 if (callback)
173 {
174 callback(BL_DATA_BLOCK_PROGRAMMED, (100-(--requiredUpdates)*percent), 0);
175 }
176
177 returnValue = hid_updateCore(firmware, bslWrapper.get());
178
179 if (callback)
180 {
181 callback(BL_DATA_BLOCK_PROGRAMMED, (100-(--requiredUpdates)*percent), 0);
182 }
183 }
184 catch (...)
185 {
186 returnValue = false;
187 }
188
189 if (callback)
190 {
191 callback(BL_DATA_BLOCK_PROGRAMMED, 100, 0);
192 callback(BL_UPDATE_DONE, 0, 0);
193 callback(BL_EXIT, 0, 0);
194 }
195 return returnValue;
196 }
197
hid_getBSLToolId(MSPBSL_Connection5xxUSB * bsl)198 uint16_t HidUpdateManager::hid_getBSLToolId(MSPBSL_Connection5xxUSB* bsl)
199 {
200 uint8_t data[2];
201 // read tool-ID stored in BSL memory
202 bsl->TX_DataBlock(data, 0x100e, 2);
203 uint16_t toolId = data[1];
204 toolId = toolId<<8;
205 toolId |= static_cast<uint16_t>(data[0]);
206 return toolId;
207 }
208
hid_enumerateBSL(uint16_t currentPid)209 MSPBSL_Connection5xxUSB* HidUpdateManager::hid_enumerateBSL(uint16_t currentPid)
210 {
211 string currentDevice = "";
212
213 if (currentPid == MSPBSL_MSP_FET_USB_PID)
214 {
215 currentDevice = "MSP430F6638";
216 }
217 if (currentPid == MSPBSL_EZ_FET_USB_PID)
218 {
219 currentDevice = "MSP430F5528";
220 }
221
222 MSPBSL_Connection5xxUSB* BslFet = dynamic_cast<MSPBSL_Connection5xxUSB*>(MSPBSL_Factory::getMSPBSL_Connection("DEVICE:" + currentDevice + " VID:0x2047 PID:0x"+ convertPid(currentPid) +"")); // works for 6638 and 5528 because of generic usb bsl
223
224 if (BslFet)
225 {
226 if (BslFet->loadRAM_BSL(currentPid) != 0)
227 {
228 //Reset FET
229 BslFet->closeBslconnection();
230 delete BslFet;
231 return 0;
232 }
233 string verString = "BUG";
234 BslFet->TX_BSL_Version(verString);
235 }
236
237 return BslFet;
238 }
239
hid_updateCore(const MemoryContent & firmware,MSPBSL_Connection5xxUSB * BslFet) const240 bool HidUpdateManager::hid_updateCore(const MemoryContent &firmware, MSPBSL_Connection5xxUSB* BslFet) const
241 {
242 // erase reset vector of core
243 BslFet->massErase();
244 BslFet->eraseSegment(0x197F);
245 BslFet->eraseSegment(0x18FF);
246 BslFet->eraseSegment(0x187F);
247
248 // Info A hanlding -> unlock it
249 BslFet->toggleInfo();
250 // erase Info A
251 BslFet->eraseSegment(0x19FF);
252
253 if (firmware.segments.empty())
254 {
255 return false;
256 }
257
258 for (size_t i = 0; i < firmware.segments.size(); i++)
259 {
260 const DataSegment& seg = firmware.segments[i];
261
262 vector<uint8_t> Buffer(seg.data.size());
263
264 MSPBSL_CRCEngine crcEngine("5xx_CRC");
265 crcEngine.initEngine(0xFFFF);
266
267 for (uint32_t n=0; n < seg.data.size(); n++)
268 {
269 Buffer[n]= (seg.data[n] & 0xff);
270 crcEngine.addByte(seg.data[n] & 0xff);
271 }
272
273 BslFet->RX_DataBlockFast(&Buffer[0], (uint32_t)seg.startAddress&0xfffffffe, (uint16_t)seg.data.size());
274
275 uint16_t currentCoreCRC[1];
276 BslFet->CRC_Check(currentCoreCRC, (uint32_t)seg.startAddress & 0xfffffffe, static_cast<uint16_t>(seg.data.size()));
277
278 uint32_t expectedCoreCRC = crcEngine.getHighByte()<<8;
279 expectedCoreCRC |= static_cast<uint32_t>(crcEngine.getLowByte());
280
281 if (expectedCoreCRC != currentCoreCRC[0])
282 {
283 if (i != 0)// just debug exeption
284 {
285 BslFet->closeBslconnection();
286 return false;
287 }
288 }
289
290 }
291 return true;
292 }
293