public BitsRange Intersect(BitsRange bitsRange) { // bitsRange .....------........... // this .............-----.... // this .....------........... // bitsRange .............-----.... // bitsRange ...---------------.... // this ....--------.......... // this ...---------------.... // bitsRange ....--------.......... // bitsRange ........----------.... // this ....--------.......... // bitsRange ....--------.......... // this ........----------.... int from = Math.Max(FromBits, bitsRange.FromBits); int to = Math.Min(ToBits, bitsRange.ToBits); return(from > to ? Empty : new BitsRange(from, to)); }
private static string GetComposedValue( BitsRange bitsRange, int registerLength, int byteIndex, string[] byteParameterNames) { byte[] byteMasks = bitsRange.GetByteMasks(registerLength, byteIndex); bool anyMask = false; var byteMaskList = new List <string>(); for (int i = 0; i < byteMasks.Length; i++) { if (byteMasks[i] > 0) { bool needsMask = byteMasks[i] != 0xFF; string byteMask = !needsMask ? byteParameterNames[i] : $"({byteParameterNames[i]} & {ToHex(byteMasks[i], 2)})"; int shift = bitsRange.FromBits - (byteIndex - i) * 8; byteMask = ShiftValue(byteMask, shift); byteMaskList.Add(byteMask); if (needsMask) { anyMask = true; } } } string composedValue; bool needsCasting; if ((byteMaskList.Count == 1) && !anyMask) { needsCasting = false; composedValue = byteMaskList[0]; } else { needsCasting = true; composedValue = ((byteMaskList.Count == 1) && anyMask) ? $"{string.Join(" | ", byteMaskList)}" : $"({string.Join(" | ", byteMaskList)})"; } if (needsCasting) { composedValue = $"({GetIntegerType(bitsRange)})" + composedValue; } return(composedValue); }
private static BitsRange GetBitsRange(XElement element, int registerLength, BitsRange defaultBitsRange, out int byteIndex) { BitsRange bitsRange = GetBitsRange(element) ?? defaultBitsRange; byteIndex = registerLength - 1; while (bitsRange.FromBits > 7) { byteIndex--; bitsRange = new BitsRange(bitsRange.FromBits - 8, bitsRange.ToBits - 8); } return(bitsRange); }
private static uint GetIntegerTypeMaxValue(BitsRange bitsRange) { switch (bitsRange.ByteCount) { case 1: return(0xFF); case 2: return(0xFFFF); case 3: case 4: return(0xFFFFFFFF); default: throw new Exception($"Unsupported integer size: {bitsRange.ByteCount} bytes."); } }
private static string[] GetDecomposedValues( string name, BitsRange bitsRange, int registerLength, int byteIndex, bool isNumeric) { byte[] byteMasks = bitsRange.GetByteMasks(registerLength, byteIndex); var getAsBytesValues = new string[registerLength]; if (!isNumeric) { name = $"({GetIntegerType(bitsRange)}){name}"; } for (int i = 0; i < byteMasks.Length; i++) { if (byteMasks[i] > 0) { bool needsMask = byteMasks[i] != 0xFF; int shift = (byteIndex - i) * 8 - bitsRange.FromBits; string propertyMask = ShiftValue(name, shift); if (needsMask) { propertyMask = $"(byte)({propertyMask} & {ToHex(byteMasks[i], 2)})"; } else if (bitsRange.ByteCount > 1) { propertyMask = "(byte)" + propertyMask; } getAsBytesValues[i] = propertyMask; } } return(getAsBytesValues); }
private static string GetIntegerType(BitsRange bitsRange) { string type; switch (bitsRange.ByteCount) { case 1: type = "byte"; break; case 2: type = "ushort"; break; case 3: case 4: type = "uint"; break; default: throw new Exception($"Unsupported integer size: {bitsRange.ByteCount} bytes."); } return(type); }
public byte[] GetByteMasks(int registerLength, int byteIndex) { byte[] byteMasks = new byte[registerLength]; int addOn = (registerLength - 1 - byteIndex) * 8; BitsRange denormalizedBitsRange = addOn > 0 ? new BitsRange(FromBits + addOn, ToBits + addOn) : this; for (int i = 0; i < registerLength; i++) { BitsRange intersect = denormalizedBitsRange.Intersect(GetByteRange(i)); intersect = intersect.Shift(-i * 8); if (!intersect.IsEmpty) { byteMasks[registerLength - i - 1] = (byte)(intersect.MaxValue << intersect.FromBits); } } return(byteMasks); }
private void GenerateNumber( CodeWriter code, RegisterMode registerMode, int registerLength, List <RegisterProperty> properties, XElement element) { string name = GetName(element) ?? "Value"; string paramName = GetLocalName(name); int byteIndex; BitsRange bitsRange = GetBitsRange(element, registerLength, null, out byteIndex); uint defaultValue; if (registerMode == RegisterMode.ReadWrite) { defaultValue = ConvertToInteger(element.Attribute("default")?.Value) << bitsRange.FromBits; } else { defaultValue = 0; } string integerType = GetIntegerType(bitsRange); Action <CodeWriter, string> appendPropertyAssigmentValidation = (codeWriter, actualParamName) => { uint integerTypeMaxValue = GetIntegerTypeMaxValue(bitsRange); if (integerTypeMaxValue != bitsRange.MaxValue) { AppendVerboseComment(codeWriter, "Validating the numerical range."); codeWriter.AppendLine($"if ({actualParamName} > {ToHex(bitsRange.MaxValue, bitsRange.NibbleCount)})"); codeWriter.AppendLine("{"); codeWriter.Indent++; codeWriter.AppendLine($"throw new ArgumentException($\"{{nameof({actualParamName})}} must be in the range of [{ToHex(0, bitsRange.NibbleCount)} - {ToHex(bitsRange.MaxValue, bitsRange.NibbleCount)}].\");"); codeWriter.Indent--; codeWriter.AppendLine("}"); codeWriter.AppendLine(); } }; Action <CodeWriter, string[]> appendPropertyAssigmentFromBytes = (codeWriter, byteParameterNames) => { AppendVerboseComment(codeWriter, "Assigning the composed numerical value."); string composedValue = GetComposedValue(bitsRange, registerLength, byteIndex, byteParameterNames); codeWriter.AppendLine($"{name} = {composedValue};"); }; Func <string[]> getByteIndexAsByteStrings = () => GetDecomposedValues(name, bitsRange, registerLength, byteIndex, true); properties.Add(new RegisterProperty( PropertyType.Numeric, registerMode, name, paramName, integerType, ToHex(defaultValue, bitsRange.NibbleCount), GetDescription(element), appendPropertyAssigmentValidation, appendPropertyAssigmentFromBytes, getByteIndexAsByteStrings, byteIndex)); }