public static HardwareRegisterSet[] ParsePeripheralRegisters(string sdkDir)
        {
            Dictionary <string, ConstructedRegisterSet> registerSets = new Dictionary <string, ConstructedRegisterSet>();
            Regex rgBaseDefinition = new Regex("#define[ \t]+DR_REG_(.*)_BASE[ \t]+0x([0-9a-fA-F]+)$");
            Regex rgRegisterDef    = new Regex("#define[ \t]+([^ \t]+)[ \t]+\\(DR_REG_(.*)_BASE \\+ (.*)\\)");
            Regex rgBitDef         = new Regex("#define[ \t]+([^ \t]+)_(S|V)[ \t]+\\(?(0x[0-9a-fA-F]+|[0-9]+)\\)?");

            foreach (var match in File.ReadAllLines(Path.Combine(sdkDir, @"components\esp32\include\soc\soc.h")).Select(line => rgBaseDefinition.Match(line)).Where(m => m.Success))
            {
                registerSets[match.Groups[1].Value] = new ConstructedRegisterSet
                {
                    Name    = match.Groups[1].Value,
                    Address = ulong.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber)
                }
            }
            ;

            foreach (var fn in Directory.GetFiles(Path.Combine(sdkDir, @"components\esp32\include\soc"), "*_reg.h"))
            {
                ConstructedRegister currentRegister = null;
                foreach (var line in File.ReadAllLines(fn))
                {
                    var m = rgRegisterDef.Match(line);
                    if (m.Success)
                    {
                        var    set  = registerSets[m.Groups[2].Value];
                        string name = m.Groups[1].Value;
                        if (name.Contains("("))
                        {
                            continue;   //One of the multiplexed registers. Skip for now.
                        }
                        currentRegister = new ConstructedRegister
                        {
                            Name    = m.Groups[1].Value,
                            Address = set.Address + ParseOffset(m.Groups[3].Value)
                        };

                        set.Registers.Add(currentRegister);
                        continue;
                    }

                    m = rgBitDef.Match(line);
                    if (m.Success && currentRegister != null)
                    {
                        string fieldName          = m.Groups[1].Value;
                        int    commonPrefixLength = 0;
                        for (int i = 0; i < currentRegister.Name.Length; i++)
                        {
                            if (i >= fieldName.Length || fieldName[i] != currentRegister.Name[i])
                            {
                                commonPrefixLength = i;
                                break;
                            }
                        }

                        if (commonPrefixLength == fieldName.Length)
                        {
                            fieldName = fieldName.Split('_').Last();
                        }
                        else if (commonPrefixLength > 0)
                        {
                            fieldName = fieldName.Substring(commonPrefixLength);
                        }
                        else
                        {
                            continue;
                            throw new Exception("Unexpected mismatching field name");
                        }

                        ConstructedField fld;
                        if (!currentRegister.Fields.TryGetValue(fieldName, out fld))
                        {
                            currentRegister.Fields[fieldName] = fld = new ConstructedField {
                                Name = fieldName
                            }
                        }
                        ;

                        uint value;
                        if (m.Groups[3].Value.StartsWith("0x"))
                        {
                            value = uint.Parse(m.Groups[3].Value.Substring(2), System.Globalization.NumberStyles.HexNumber);
                        }
                        else
                        {
                            value = uint.Parse(m.Groups[3].Value);
                        }


                        switch (m.Groups[2].Value)
                        {
                        case "V":
                            fld.Mask = value;
                            break;

                        case "S":
                            fld.Offset = value;
                            break;

                        default:
                            throw new Exception("Unexpected definition");
                        }
                    }
                }
            }

            return(registerSets.Values.Where(s => s.Registers.Count != 0).OrderBy(v => v.Address).Select(s => s.ToRegisterSet()).ToArray());
        }
        public static HardwareRegisterSet[] ParsePeripheralRegisters(string sdkDir)
        {
            Dictionary<string, ConstructedRegisterSet> registerSets = new Dictionary<string, ConstructedRegisterSet>();
            Regex rgBaseDefinition = new Regex("#define[ \t]+DR_REG_(.*)_BASE[ \t]+0x([0-9a-fA-F]+)$");
            Regex rgRegisterDef = new Regex("#define[ \t]+([^ \t]+)[ \t]+\\(DR_REG_(.*)_BASE \\+ (.*)\\)");
            Regex rgBitDef = new Regex("#define[ \t]+([^ \t]+)_(S|V)[ \t]+\\(?(0x[0-9a-fA-F]+|[0-9]+)\\)?");

            foreach (var match in File.ReadAllLines(Path.Combine(sdkDir, @"components\esp32\include\soc\soc.h")).Select(line => rgBaseDefinition.Match(line)).Where(m => m.Success))
                registerSets[match.Groups[1].Value] = new ConstructedRegisterSet
                {
                    Name = match.Groups[1].Value,
                    Address = ulong.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber)
                };

            foreach(var fn in Directory.GetFiles(Path.Combine(sdkDir, @"components\esp32\include\soc"), "*_reg.h"))
            {
                ConstructedRegister currentRegister = null;
                foreach (var line in File.ReadAllLines(fn))
                {
                    var m = rgRegisterDef.Match(line);
                    if (m.Success)
                    {
                        var set = registerSets[m.Groups[2].Value];
                        string name = m.Groups[1].Value;
                        if (name.Contains("("))
                            continue;   //One of the multiplexed registers. Skip for now.

                        currentRegister = new ConstructedRegister
                        {
                            Name = m.Groups[1].Value,
                            Address = set.Address + ParseOffset(m.Groups[3].Value)
                        };

                        set.Registers.Add(currentRegister);
                        continue;
                    }

                    m = rgBitDef.Match(line);
                    if (m.Success && currentRegister != null)
                    {
                        string fieldName = m.Groups[1].Value;
                        int commonPrefixLength = 0;
                        for (int i = 0; i < currentRegister.Name.Length; i++)
                            if (i >= fieldName.Length || fieldName[i] != currentRegister.Name[i])
                            {
                                commonPrefixLength = i;
                                break;
                            }

                        if (commonPrefixLength == fieldName.Length)
                            fieldName = fieldName.Split('_').Last();
                        else if (commonPrefixLength > 0)
                            fieldName = fieldName.Substring(commonPrefixLength);
                        else
                        {
                            continue;
                            throw new Exception("Unexpected mismatching field name");
                        }

                        ConstructedField fld;
                        if (!currentRegister.Fields.TryGetValue(fieldName, out fld))
                            currentRegister.Fields[fieldName] = fld = new ConstructedField { Name = fieldName };

                        uint value;
                        if (m.Groups[3].Value.StartsWith("0x"))
                            value = uint.Parse(m.Groups[3].Value.Substring(2), System.Globalization.NumberStyles.HexNumber);
                        else
                            value = uint.Parse(m.Groups[3].Value);

                        switch(m.Groups[2].Value)
                        {
                            case "V":
                                fld.Mask = value;
                                break;
                            case "S":
                                fld.Offset = value;
                                break;
                            default:
                                throw new Exception("Unexpected definition");
                        }
                    }
                }
            }

            return registerSets.Values.Where(s => s.Registers.Count != 0).OrderBy(v => v.Address).Select(s => s.ToRegisterSet()).ToArray();
        }
Exemple #3
0
        public static HardwareRegisterSet[] ParsePeripheralRegisters(string sdkDir)
        {
            Dictionary <string, ConstructedRegisterSet> registerSets = new Dictionary <string, ConstructedRegisterSet>();
            Regex rgBaseDefinition       = new Regex("#define[ \t]+DR_REG_(.*)_BASE[ \t]+0x([0-9a-fA-F]+)$");
            Regex rgRegisterDef          = new Regex("#define[ \t]+([^ \t]+)[ \t]+\\(DR_REG_(.*)_BASE \\+ (.*)\\)");
            Regex rgRegisterDefWithIndex = new Regex(@"#define[ \t]+([^ \t]+)[ \t]+\(([0-9A-Za-z_]+_BASE)[ \t]*\(i\) \+ (.*)\)");
            Regex rgBitDef = new Regex("#define[ \t]+([^ \t]+)_(S|V)[ \t]+\\(?(0x[0-9a-fA-F]+|[0-9]+)\\)?");

            Regex rgiTimesNumber = new Regex(@"^[ (\t]*i[ \t)]*\*[ \t]*[ \t(]*0x([0-9a-fA-F]+)[ \t)]*$");

            foreach (var match in File.ReadAllLines(Path.Combine(sdkDir, @"components\soc\esp32\include\soc\soc.h")).Select(line => rgBaseDefinition.Match(line)).Where(m => m.Success))
            {
                registerSets[match.Groups[1].Value] = new ConstructedRegisterSet
                {
                    Name    = match.Groups[1].Value,
                    Address = ulong.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber)
                }
            }
            ;

            foreach (var fn in Directory.GetFiles(Path.Combine(sdkDir, @"components\soc\esp32\include\soc"), "*_reg.h"))
            {
                Dictionary <string, MultiInstanceRegister> multiInstanceRegisterBases = new Dictionary <string, MultiInstanceRegister>();

                ConstructedRegister currentRegister = null;
                foreach (var line in File.ReadAllLines(fn))
                {
                    var  m = rgRegisterDef.Match(line);
                    bool isIndexedRegister = false;
                    if (!m.Success)
                    {
                        m = rgRegisterDefWithIndex.Match(line);
                        if (m.Success)
                        {
                            isIndexedRegister = true;
                        }
                    }

                    if (m.Success)
                    {
                        if (!registerSets.TryGetValue(m.Groups[2].Value, out var set))
                        {
                            if (isIndexedRegister && multiInstanceRegisterBases.TryGetValue(m.Groups[2].Value, out var multiRegSet))
                            {
                                if (registerSets.TryGetValue(multiRegSet.BaseName, out set))
                                {
                                    set.MultipleInstanceMultiplier = multiRegSet.Multiplier;
                                }
                            }

                            if (set == null)
                            {
                                continue;
                            }
                        }

                        string name = m.Groups[1].Value;
                        if (name.Contains("("))
                        {
                            if (!name.EndsWith("(i)"))
                            {
                                continue;   //Unexpected syntax.
                            }
                            name = name.Substring(0, name.Length - 3).Trim();

                            if (name.EndsWith("_BASE"))
                            {
                                var m2 = rgiTimesNumber.Match(m.Groups[3].Value);
                                if (!m2.Success)
                                {
                                    Console.WriteLine("Unexpected base definition: " + line);
                                    continue;
                                }

                                multiInstanceRegisterBases[name] = new MultiInstanceRegister {
                                    BaseName = m.Groups[2].Value, Multiplier = int.Parse(m2.Groups[1].Value, System.Globalization.NumberStyles.HexNumber)
                                };
                                continue;
                            }
                        }

                        currentRegister = new ConstructedRegister
                        {
                            Name    = name,
                            Address = set.Address + ParseOffset(m.Groups[3].Value)
                        };

                        set.Registers.Add(currentRegister);
                        continue;
                    }

                    m = rgBitDef.Match(line);
                    if (m.Success && currentRegister != null)
                    {
                        string fieldName          = m.Groups[1].Value;
                        int    commonPrefixLength = 0;
                        for (int i = 0; i < currentRegister.Name.Length; i++)
                        {
                            if (i >= fieldName.Length || fieldName[i] != currentRegister.Name[i])
                            {
                                commonPrefixLength = i;
                                break;
                            }
                        }

                        if (commonPrefixLength == fieldName.Length)
                        {
                            fieldName = fieldName.Split('_').Last();
                        }
                        else if (commonPrefixLength > 0)
                        {
                            fieldName = fieldName.Substring(commonPrefixLength);
                        }
                        else
                        {
                            continue;
                            throw new Exception("Unexpected mismatching field name");
                        }

                        ConstructedField fld;
                        if (!currentRegister.Fields.TryGetValue(fieldName, out fld))
                        {
                            currentRegister.Fields[fieldName] = fld = new ConstructedField {
                                Name = fieldName
                            }
                        }
                        ;

                        uint value;
                        if (m.Groups[3].Value.StartsWith("0x"))
                        {
                            value = uint.Parse(m.Groups[3].Value.Substring(2), System.Globalization.NumberStyles.HexNumber);
                        }
                        else
                        {
                            value = uint.Parse(m.Groups[3].Value);
                        }


                        switch (m.Groups[2].Value)
                        {
                        case "V":
                            fld.Mask = value;
                            break;

                        case "S":
                            fld.Offset = value;
                            break;

                        default:
                            throw new Exception("Unexpected definition");
                        }
                    }
                }
            }

            foreach (var set in registerSets.Values.Where(s => s.MultipleInstanceMultiplier != 0))
            {
                var possibleNextInstances = registerSets.Values.Where(s => s != set && s.Registers.Count == 0 && s.IsPossibleInstanceOf(set, 1)).ToArray();

                foreach (var set2 in possibleNextInstances)
                {
                    var offset = set2.Address - set.Address;
                    foreach (var reg in set.Registers)
                    {
                        set2.Registers.Add(reg.CloneWithOffset(offset));
                    }
                }
            }

            var emptyRegisterSets = registerSets.Values.Where(s => s.Registers.Count == 0).ToArray();

            return(registerSets.Values.Where(s => s.Registers.Count != 0).OrderBy(v => v.Address).Select(s => s.ToRegisterSet()).ToArray());
        }