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(); }
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()); }