! @brief Generate dictionary with info about all supported targets.
        
        Output version history:
        - 1.0, initial version
        - 1.1, added part_families
        - 1.2, added source

def list_targets():
        """! @brief Generate dictionary with info about all supported targets.
        
        Output version history:
        - 1.0, initial version
        - 1.1, added part_families
        - 1.2, added source
        """
        targets = []
        obj = {
            'pyocd_version' : __version__,
            'version' : { 'major' : 1, 'minor' : 2 },
            'status' : 0,
            'targets' : targets
            }

        for name in TARGET.keys():
            s = Session(None) # Create empty session
            t = TARGET[name](s)
            d = {
                'name' : name,
                'vendor' : t.vendor,
                'part_families' : t.part_families,
                'part_number' : t.part_number,
                'source': 'pack' if hasattr(t, '_pack_device') else 'builtin',
                }
            if t._svd_location is not None:
                svdPath = t._svd_location.filename
                if isinstance(svdPath, six.string_types) and os.path.exists(svdPath):
                    d['svd_path'] = svdPath
            targets.append(d)
        
        # Add targets from cmsis-pack-manager cache.
        for dev in pack_target.ManagedPacks.get_installed_targets():
            try:
                targets.append({
                    'name' : dev.part_number.lower(),
                    'part_families' : dev.families,
                    'part_number' : dev.part_number,
                    'vendor' : dev.vendor,
                    'source' : 'pack',
                    })
            except KeyError:
                pass

        return obj