1 /*
2  * DeviceInfo.h
3  *
4  * Data of device currently under control.
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 #pragma once
39 
40 #include <MSP430_Debug.h>
41 
42 #include "MemoryAreaBase.h"
43 #include "MpuFRx.h"
44 #include "WriteProtection.h"
45 #include "FuncletCode.h"
46 #include "../MSP432P4xx_FlashLibFc.h"
47 #include "../MSP432P4xx_PG11_FlashLibFc.h"
48 #include "../DAP_LOCK.h"
49 
50 #include <boost/fusion/include/adapt_struct.hpp>
51 #include <boost/fusion/include/define_struct.hpp>
52 
53 #include <DeviceDb/adapt_enum.h>
54 
55 
56 namespace TI
57 {
58 	namespace DLL430
59 	{
60 		DEFINE_ENUM(Architecture, (Cpu)(CpuX)(CpuXv2)(ArmCpu))
61 
62 		DEFINE_ENUM(ClockSystemType, (BC_1xx)(BC_2xx)(FLLPLUS)(MOD_OSC))
63 
64 		DEFINE_ENUM(PsaType, (Regular)(Enhanced))
65 
66 		DEFINE_ENUM(MemoryType, (Flash)(Rom)(Ram)(Register))
67 
68 		ADAPT_ENUM(DEVICE_CLOCK_CONTROL,
69 			(GCC_NONE)(GCC_STANDARD)(GCC_EXTENDED)(GCC_STANDARD_I))
70 
71 		ADAPT_ENUM(EMEX_MODE,
72 		(EMEX_NONE)(EMEX_LOW)(EMEX_MEDIUM)(EMEX_HIGH)(EMEX_EXTRA_SMALL_5XX)(EMEX_SMALL_5XX)(EMEX_MEDIUM_5XX)(EMEX_LARGE_5XX)(EMEX_CORTEX_M4))
73 
fromString(const char * txt,TI::DLL430::MemoryArea::Name & v)74 		inline void fromString(const char* txt, TI::DLL430::MemoryArea::Name& v)
75 		{
76 			std::string str(txt);
77 
78 			//Memory name can continue after initial part (ie. Ram2, CpuXYZ, etc.)
79 			if      (str.find("None") == 0) v = TI::DLL430::MemoryArea::None;
80 			else if (str.find("Main") == 0) v = TI::DLL430::MemoryArea::Main;
81 			else if (str.find("Info") == 0) v = TI::DLL430::MemoryArea::Info;
82 			else if (str.find("Bsl") == 0) v = TI::DLL430::MemoryArea::Bsl;
83 			else if (str.find("BootCode") == 0) v = TI::DLL430::MemoryArea::BootCode;
84 			else if (str.find("Ram") == 0) v = TI::DLL430::MemoryArea::Ram;
85 			else if (str.find("UsbRam") == 0) v = TI::DLL430::MemoryArea::UsbRam;
86 			else if (str.find("Lcd") == 0) v = TI::DLL430::MemoryArea::Lcd;
87 			else if (str.find("Cpu") == 0) v = TI::DLL430::MemoryArea::Cpu;
88 			else if (str.find("Eem") == 0) v = TI::DLL430::MemoryArea::Eem;
89 			else if (str.find("Peripheral8bit") == 0) v = TI::DLL430::MemoryArea::Peripheral8bit;
90 			else if (str.find("Peripheral16bit") == 0) v = TI::DLL430::MemoryArea::Peripheral16bit;
91 			else if (str.find("IrVec") == 0) v = TI::DLL430::MemoryArea::IrVec;
92 			else if (str.find("Lib") == 0) v = TI::DLL430::MemoryArea::Lib;
93 			else if (str.find("LeaPeripheral") == 0) v = TI::DLL430::MemoryArea::LeaPeripheral;
94 			else if (str.find("LeaRam") == 0) v = TI::DLL430::MemoryArea::LeaRam;
95 			else if (str.find("TinyRam") == 0) v = TI::DLL430::MemoryArea::TinyRam;
96 			else if (str.find("MidRom") == 0) v = TI::DLL430::MemoryArea::MidRom;
97 			else if (str.find("UssPeripheral") == 0) v = TI::DLL430::MemoryArea::UssPeripheral;
98 			else throw std::runtime_error("invalid memory name: " + str);
99 		}
100 	}
101 }
102 
103 
104 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), IdCode,
105 	(uint16_t, version)
106 	(uint16_t, subversion)
107 	(uint8_t, revision)
108 	(uint8_t, maxRevision)
109 	(uint8_t, fab)
110 	(uint16_t, self)
111 	(uint8_t, config)
112 	(uint8_t, fuses)
113 	(uint32_t, activationKey)
114 )
115 
116 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), IdMask,
117 	(uint16_t, version)
118 	(uint16_t, subversion)
119 	(uint8_t, revision)
120 	(uint8_t, maxRevision)
121 	(uint8_t, fab)
122 	(uint16_t, self)
123 	(uint8_t, config)
124 	(uint8_t, fuses)
125 	(uint32_t, activationKey)
126 )
127 
128 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), ClockPair,
129 	(std::string, name)
130 	(uint8_t, value)
131 	(bool, defaultStop)
132 )
133 
134 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), PowerSettings,
135 	(uint32_t, testRegMask)
136 	(uint32_t, testRegDefault)
137 	(uint32_t, testRegEnableLpm5)
138 	(uint32_t, testRegDisableLpm5)
139 	(uint16_t, testReg3VMask)
140 	(uint16_t, testReg3VDefault)
141 	(uint16_t, testReg3VEnableLpm5)
142 	(uint16_t, testReg3VDisableLpm5)
143 )
144 
145 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), Features,
146 	(TI::DLL430::ClockSystemType, clockSystem)
147 	(bool, i2c)
148 	(bool, lcfe)
149 	(bool, quickMemRead)
150 	(bool, stopFllDbg)
151 	(bool, hasFram)
152 )
153 
154 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), ExtendedFeatures,
155 	(bool, tmr)
156 	(bool, jtag)
157 	(bool, dtc)
158 	(bool, sync)
159 	(bool, instr)
160 	(bool, _1377)
161 	(bool, psach)
162 	(bool, eemInaccessibleInLPM)
163 )
164 
165 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), VoltageInfo,
166 	(uint16_t, vccMin)
167 	(uint16_t, vccMax)
168 	(uint16_t, vccFlashMin)
169 	(uint16_t, vccSecureMin)
170 	(uint16_t, vppSecureMin)
171 	(uint16_t, vppSecureMax)
172 	(bool, testVpp)
173 )
174 
175 
176 namespace TI
177 {
178 	namespace DLL430
179 	{
180 		typedef std::map<hal_id, hal_id> FunctionMapping;
181 
182 		typedef std::map<FuncletCode::Type, FuncletCode> FuncletMapping;
183 
184 		static const size_t nrUsedClockModules = 32;
185 		typedef std::array<ClockPair, 32> ClockMapping;
186 
187 		typedef std::array<std::string, 32> ClockNames;
188 	}
189 }
190 
191 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), ClockInfo,
192 	(DEVICE_CLOCK_CONTROL, clockControl)
193 	(uint32_t, mclkCntrl0)
194 	(TI::DLL430::ClockMapping, eemTimers)
195 	(TI::DLL430::ClockNames, eemClocks)
196 )
197 
198 namespace TI
199 {
200 	namespace DLL430
201 	{
202 		struct WriteProtectionInfo
203 		{
204 			uint32_t address;
205 			uint32_t unlockAddress;
206 			uint16_t bits;
207 			uint16_t mask;
208 			uint16_t pwd;
209 
WriteProtectionInfoWriteProtectionInfo210 			WriteProtectionInfo() : address(0), unlockAddress(0), bits(0), mask(0xFFFF), pwd(0) {}
211 		};
212 	}
213 }
214 
215 BOOST_FUSION_ADAPT_STRUCT(TI::DLL430::WriteProtectionInfo,
216 	(uint32_t, address)
217 	(uint32_t, unlockAddress)
218 	(uint16_t, bits)
219 	(uint16_t, mask)
220 	(uint16_t, pwd)
221 	)
222 
223 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), MemoryAccess,
224 	(std::string, type)
225 	(bool, mpu)
226 	(TI::DLL430::WriteProtectionInfo, writeProtection)
227 )
228 
229 
230 namespace TI
231 {
232 	namespace DLL430
233 	{
234 		struct MemoryCreatorBase
235 		{
236 			virtual TI::DLL430::MemoryAreaBase* operator()(MemoryArea::Name, TI::DLL430::IDeviceHandle*,
237 				uint32_t, uint32_t, uint32_t, uint32_t,
238 				bool, const bool, IMemoryManager*, uint8_t) const = 0;
239 		};
240 		typedef std::shared_ptr<TI::DLL430::MemoryCreatorBase> MemoryCreatorPtr;
241 
242 		template<class MemoryType>
243 		struct MemoryCreatorFR : public TI::DLL430::MemoryCreatorBase
244 		{
MemoryCreatorFRMemoryCreatorFR245 			MemoryCreatorFR(const MemoryAccess& access)
246 				: hasMpu(access.mpu)
247 				, address(access.writeProtection.address)
248 				, bits(access.writeProtection.bits)
249 				, mask(access.writeProtection.mask)
250 				, pwd(access.writeProtection.pwd) {}
251 
operatorMemoryCreatorFR252 			virtual TI::DLL430::MemoryAreaBase* operator()(MemoryArea::Name name,
253 				TI::DLL430::IDeviceHandle* devHandle,
254 				uint32_t start, uint32_t end,
255 				uint32_t seg, uint32_t banks,
256 				bool mapped, const bool protectable,
257 				TI::DLL430::IMemoryManager* mm, uint8_t psa) const
258 			{
259 				IMpu* mpu = hasMpu ? static_cast<IMpu*>(new MpuFRx(devHandle, mm)) : static_cast<IMpu*>(new NoMpu());
260 				IWriteProtection* writeProt = address ?
261 					static_cast<IWriteProtection*>(new WriteProtection(mm, address, bits, mask, pwd)) :
262 					static_cast<IWriteProtection*>(new NoWriteProtection(mm));
263 				return new MemoryType(name, devHandle, start, end, seg, banks, mapped, protectable, mm, psa, writeProt, mpu);
264 			}
265 
266 			const bool hasMpu;
267 			const uint32_t address;
268 			const uint16_t bits;
269 			const uint16_t mask;
270 			const uint16_t pwd;
271 		};
272 
273 		template<class MemoryType>
274 		struct MemoryCreator432 : public TI::DLL430::MemoryCreatorBase
275 		{
MemoryCreator432MemoryCreator432276 			MemoryCreator432(const MemoryAccess& access)
277 				: address(access.writeProtection.address)
278 				, bits(access.writeProtection.bits)
279 				, mask(access.writeProtection.mask)
280 				, pwd(access.writeProtection.pwd)
281 				, unlockAddress(access.writeProtection.unlockAddress) {}
282 
operatorMemoryCreator432283 			virtual TI::DLL430::MemoryAreaBase* operator()(MemoryArea::Name name,
284 				TI::DLL430::IDeviceHandle* devHandle,
285 				uint32_t start, uint32_t end,
286 				uint32_t seg, uint32_t banks,
287 				bool mapped, const bool protectable,
288 				TI::DLL430::IMemoryManager* mm, uint8_t psa) const
289 			{
290 				IWriteProtection* writeProt = address ?
291 					static_cast<IWriteProtection*>(new WriteProtection432(mm, address, bits, mask, pwd, unlockAddress)) :
292 					static_cast<IWriteProtection*>(new NoWriteProtection(mm));
293 				return new MemoryType(name, devHandle, start, end, seg, banks, mapped, protectable, mm, psa, writeProt);
294 			}
295 
296 			const uint32_t address;
297 			const uint32_t unlockAddress;
298 			const uint16_t bits;
299 			const uint16_t mask;
300 			const uint16_t pwd;
301 		};
302 
303 		template<class MemoryType>
304 		struct MemoryCreator : public TI::DLL430::MemoryCreatorBase
305 		{
operatorMemoryCreator306 			virtual TI::DLL430::MemoryAreaBase* operator()(MemoryArea::Name name,
307 				TI::DLL430::IDeviceHandle* devHandle,
308 				uint32_t start, uint32_t end,
309 				uint32_t seg, uint32_t banks,
310 				bool mapped, const bool protectable,
311 				TI::DLL430::IMemoryManager* mm, uint8_t psa) const
312 			{
313 				return new MemoryType(name, devHandle, start, end, seg, banks, mapped, protectable, mm, psa);
314 			}
315 		};
316 
317 		typedef std::vector<uint8_t> MemoryMask;
318 
319 		struct MemoryInfo
320 		{
321 			MemoryArea::Name name;
322 			MemoryType type;
323 			uint8_t bits;
324 			uint32_t size;
325 			uint32_t start;
326 			uint32_t segmentSize;
327 			uint32_t banks;
328 			bool mapped;
329 			bool protectable;
330 			MemoryMask mask;
331 			MemoryCreatorPtr memoryCreatorPtr;
332 
MemoryInfoMemoryInfo333 			MemoryInfo() :
334 				name(MemoryArea::None),
335 				type(MemoryType::Flash),
336 				bits(0),
337 				size(0),
338 				start(0),
339 				segmentSize(0),
340 				banks(0),
341 				mapped(false),
342 				protectable(false)
343 			{}
344 		};
345 	}
346 }
347 
348 BOOST_FUSION_ADAPT_STRUCT(TI::DLL430::MemoryInfo,
349 	(TI::DLL430::MemoryArea::Name, name)
350 	(TI::DLL430::MemoryType, type)
351 	(uint8_t, bits)
352 	(uint32_t, size)
353 	(uint32_t, start)
354 	(uint32_t, segmentSize)
355 	(uint32_t, banks)
356 	(bool, mapped)
357 	(bool, protectable)
358 )
359 
360 namespace TI
361 {
362 	namespace DLL430
363 	{
364 		typedef std::map<std::string, MemoryInfo> MemoryLayout;
365 	}
366 }
367 
368 
369 BOOST_FUSION_DEFINE_STRUCT((TI)(DLL430), DeviceInfo,
370 	(std::string, description)
371 	(std::string, warning)
372 	(uint8_t, bits)
373 	(TI::DLL430::PsaType, psa)
374 	(TI::DLL430::Architecture, architecture)
375 	(EMEX_MODE, eem)
376 	(TI::DLL430::IdMask, idMask)
377 	(TI::DLL430::IdCode, idCode)
378 	(TI::DLL430::VoltageInfo, voltageInfo)
379 	(TI::DLL430::ClockInfo, clockInfo)
380 	(TI::DLL430::FunctionMapping, functionMap)
381 	(TI::DLL430::FuncletMapping, funcletMap)
382 	(TI::DLL430::Features, features)
383 	(TI::DLL430::ExtendedFeatures, extFeatures)
384 	(TI::DLL430::PowerSettings, powerSettings)
385 	(TI::DLL430::MemoryLayout, memoryLayout)
386 )
387 
388 
389 namespace TI
390 {
391 	namespace DLL430
392 	{
393 		struct Match
394 		{
395 			IdMask idMask;
396 			IdCode idCode;
397 		};
398 
399 		inline bool operator<(const Match& lhs, const Match& rhs)
400 		{
401 			if (lhs.idCode.version != rhs.idCode.version)
402 				return lhs.idCode.version < rhs.idCode.version;
403 
404 			else if (lhs.idCode.subversion != rhs.idCode.subversion)
405 				return  lhs.idCode.subversion < rhs.idCode.subversion;
406 
407 			else if (lhs.idCode.revision != rhs.idCode.revision)
408 				return  lhs.idCode.revision < rhs.idCode.revision;
409 
410 			else if (lhs.idCode.fab != rhs.idCode.fab)
411 				return  lhs.idCode.fab < rhs.idCode.fab;
412 
413 			else if (lhs.idCode.self != rhs.idCode.self)
414 				return  lhs.idCode.self < rhs.idCode.self;
415 
416 			else if (lhs.idCode.config != rhs.idCode.config)
417 				return  lhs.idCode.config < rhs.idCode.config;
418 
419 			else if (lhs.idCode.fuses != rhs.idCode.fuses)
420 				return  lhs.idCode.fuses < rhs.idCode.fuses;
421 
422 			else
423 				return  lhs.idCode.activationKey < rhs.idCode.activationKey;
424 		}
425 
426 		inline bool operator==(const Match& match, const IdCode& idCode)
427 		{
428 			bool revisionMatch = ((idCode.revision & match.idMask.revision) == match.idCode.revision);
429 			if (match.idMask.maxRevision != 0)
430 			{
431 				revisionMatch = ((idCode.revision & match.idMask.revision) >= match.idCode.revision) &&
432 					((idCode.revision & match.idMask.maxRevision) <= match.idCode.maxRevision);
433 			}
434 
435 			return ((idCode.version & match.idMask.version) == match.idCode.version
436 				&& (idCode.subversion & match.idMask.subversion) == match.idCode.subversion
437 				&& revisionMatch
438 				&& (idCode.fab & match.idMask.fab) == match.idCode.fab
439 				&& (idCode.self & match.idMask.self) == match.idCode.self
440 				&& (idCode.config & match.idMask.config) == match.idCode.config
441 				&& (idCode.fuses & match.idMask.fuses) == match.idCode.fuses
442 				&& (idCode.activationKey & match.idMask.activationKey) == match.idCode.activationKey);
443 		}
444 
445 		typedef std::map<const Match, const DeviceInfo> DeviceMap;
446 	}
447 }
448