import sys
def fix_crosslink_nx_bitstream(input_file, output_file):
# Аппаратная преамбула для семейства Lattice Nexus (CrossLink-NX)
# Она переводит конфигурационный автомат ПЛИС в рабочий режим
PREAMBLE_SIGNATURE = b'\xB2\x99\xBB\x66'
ALIGNMENT = 4096
with open(input_file, 'rb') as f:
content = f.read()
# Попытка 1: Ищем аппаратную преамбулу Nexus
idx = content.find(PREAMBLE_SIGNATURE)
# Попытка 2: Если преамбула не найдена, ищем границу текстового заголовка Radiant
# Текст заканчивается, и начинается поток бинарных данных (обычно с байт CRC или NOP)
if idx == -1:
print("Преамбула B2 99 BB 66 не найдена. Ищем конец текстового заголовка...")
# Находим конец строки с метаданными Radiant (ищем контрольную сумму 'Bitstream CRC:')
text_end = content.find(b'Bitstream CRC:')
if text_end != -1:
# Смещаемся на 30 байт вперед, где гарантированно заканчивается текст заголовка
# и начинаются служебные байты 0x00 / 0xFF перед командами
search_zone = content[text_end:text_end+150]
# Находим первый бинарный нуль или FF после текстовой строки
for i, byte in enumerate(search_zone):
if byte == 0x00 or byte == 0xFF:
idx = text_end + i
break
if idx == -1:
print("Ошибка: Не удалось автоматически определить границу заголовка ПЛИС!")
sys.exit(1)
# Вырезаем чистый bitstream без текста
bitstream = bytearray(content[idx:])
print(f"Полезный bitstream успешно выделен со смещения {idx} (0x{idx:X}).")
# Делаем обязательное выравнивание (Padding) до 4096 байт под I2C драйвер
current_size = len(bitstream)
remainder = current_size % ALIGNMENT
if remainder != 0:
padding_needed = ALIGNMENT - remainder
# Заполняем остаток страницы байтами NOP (0xFF)
bitstream += b'\xFF' * padding_needed
print(f"Выравнивание: добавлено {padding_needed} байт 0xFF. Итоговый размер: {len(bitstream)} байт.")
else:
print(f"Размер файла уже кратен {ALIGNMENT} (выравнивание не требуется).")
# Сохраняем "чистый" файл (БЕЗ отзеркаливания бит, CrossLink-NX работает в MSB)
with open(output_file, 'wb') as f:
f.write(bitstream)
print(f"Готово! Бинарный файл сохранен как: {output_file}")
if __name__ == '__main__':
if len(sys.argv) < 3:
print("Использование: python3 lpc_convert.py <input.bit> <output.bin>")
sys.exit(1)
fix_crosslink_nx_bitstream(sys.argv[1], sys.argv[2])