mint-core 1.3.1

Core library for building hex files from data and layout definitions.
Documentation
# Combined test layout file containing all blocks for testing
#
# Blocks:
#   - block, block2, block3, block_bitmap: require Excel data
#   - simple_block: inline values only (no Excel needed)
#   - pg_block: compatible with both JSON and Excel data sources

[mint]
endianness = "little"

[mint.checksum.crc32]
polynomial = 0x04C11DB7
start = 0xFFFFFFFF
xor_out = 0xFFFFFFFF
ref_in = true
ref_out = true

# =============================================================================
# block - main test block with Excel data references
# =============================================================================
[block.header]
start_address = 0x8B000
length = 0x1000
padding = 0xC0

[block.data]
# Literal numeric value
some.struct.value = { value = 0x1234, type = "u32" }
# Single value from Excel by name (numeric)
some.struct.value2 = { name = "Value 2", type = "u32" }
# Fixed-size string literal (padded with padding byte)
some.struct.value3 = { value = "Value 3", type = "u8", size = 10 }

# Strings and scalars from Excel
device.info.name = { name = "DeviceName", type = "u8", size = 16 }
device.info.serial = { name = "SerialNumber", type = "u32" }
device.info.version.major = { name = "FWVersionMajor", type = "u16" }
device.info.version.minor = { name = "FWVersionMinor", type = "u16" }
device.info.version.patch = { name = "FWVersionPatch", type = "u16" }

# Network and credentials
wifi.ssid = { name = "WiFiSSID", type = "u8", size = 32 }
wifi.key = { name = "WiFiKey", type = "u8", size = 64 }
net.ip = { value = [192, 168, 1, 100], type = "u8", size = 4 }

# Arrays from Excel
calibration.coefficients = { name = "Coefficients1D", type = "f32", size = 8 }
calibration.matrix = { name = "CalibrationMatrix", type = "i16", size = [3, 3] }

# Another fixed-size string literal
message = { value = "Hello, world!", type = "u8", size = 16 }
# Magic constant
magic = { value = 0xDEADBEEF, type = "u32" }

# Deeper nesting example (inline scalar and 1D array)
nested.complex.level1.level2.level3.scalar16 = { value = 0x42, type = "u16" }
nested.complex.level1.level2.level3.array1d = { value = [
    1,
    2,
    3,
    4,
], type = "i16", size = 4 }

# Arrays-of-structs as 2D arrays
structs.astruct_array = { name = "AStructs", type = "f32", size = [10, 2] }

# Inline checksum
checksum = { checksum = "crc32", type = "u32" }

# =============================================================================
# block2 - secondary test block
# =============================================================================
[block2.header]
start_address = 0x8C000
length = 0x1000

[block2.data]
# 2D array of u16 read from Excel sheet referenced by the Main sheet value
another.struct.value = { name = "Array", type = "u16", size = [10, 2] }
# 1D numeric array literal
another.struct.arr = { value = [2, 2], type = "u16", size = 2 }
# String from Excel (or sheet name for byte array)
another.struct.description = { name = "Block2Description", type = "u8", size = 32 }
# Inline checksum
checksum = { checksum = "crc32", type = "u32" }

# =============================================================================
# block3 - wider and signed types
# =============================================================================
[block3.header]
start_address = 0x8D000
length = 0x1000

[block3.data]
counters.boot_count = { name = "BootCount", type = "u64" }
limits.temperature_min = { name = "TemperatureMin", type = "i16" }
limits.temperature_max = { name = "TemperatureMax", type = "i16" }
thresholds.voltage = { name = "VoltageThresholds", type = "f32", size = 4 }
dlegal.notice = { name = "LegalNotice", type = "u8", size = 128 }
# Inline checksum
checksum = { checksum = "crc32", type = "u32" }

# =============================================================================
# block_bitmap - bitmap field tests
# =============================================================================
[block_bitmap.header]
start_address = 0x8E000
length = 0x100

[block_bitmap.data]
# Normal scalar before bitmaps
prefix.marker = { value = 0xBEEF, type = "u16" }
prefix.count = { name = "BitmapTestCount", type = "u8" }

# Signed i16 bitmap - tests two's complement and negative field values
config.flags = { type = "i16", bitmap = [
    { bits = 1, name = "AllowDebug" },
    { bits = 3, name = "ModeSelect" },
    { bits = 1, value = true },
    { bits = 4, name = "RegionCode" },
    { bits = 7, value = 0 },
] }

# Unsigned u32 bitmap - tests larger storage and mixed sources
hw.status = { type = "u32", bitmap = [
    { bits = 1, name = "PowerGood" },
    { bits = 1, name = "FanRunning" },
    { bits = 6, value = 0 },
    { bits = 8, name = "ErrorCode" },
    { bits = 4, name = "HwRevision" },
    { bits = 12, value = 0xABC },
] }

# Normal scalars after bitmaps
suffix.checkval = { name = "BitmapCheckVal", type = "u32" }
suffix.trailer = { value = 0xCAFE, type = "u16" }
# Inline checksum
checksum = { checksum = "crc32", type = "u32" }

# =============================================================================
# simple_block - all inline values, no Excel dependency
# =============================================================================
[simple_block.header]
start_address = 0x8000
length = 0x100
padding = 0xFF

[simple_block.data]
device.id = { value = 0x1234, type = "u32" }
device.name = { value = "TestDevice", type = "u8", size = 16 }
config.enable = { value = true, type = "u8" }
config.timeout = { value = 5000, type = "u16" }
network.ip = { value = [192, 168, 1, 100], type = "u8", size = 4 }
constants.pi = { value = 3.14159, type = "f32" }
array.values = { value = [10, 20, 30, 40, 50], type = "u16", size = 5 }
magic = { value = 0xDEADBEEF, type = "u32" }
checksum = { checksum = "crc32", type = "u32" }

# =============================================================================
# pg_block - JSON/Excel interchangeable block
# Uses names that exist in both data sources for cross-source testing
# =============================================================================
[pg_block.header]
start_address = 0x1000
length = 0x100
padding = 0xFF

[pg_block.data]
# Values available in both JSON and Excel
limits.temperature_max = { name = "TemperatureMax", type = "i16" }
config.value2 = { name = "Value 2", type = "u32" }
config.enabled = { name = "boolean", type = "u8" }
checksum = { checksum = "crc32", type = "u32" }