Загрузка данных
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
unsigned char mirror_byte(unsigned char b) {
b = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
b = ((b & 0xCC) >> 2) | ((b & 0x33) << 2);
b = ((b & 0xAA) >> 1) | ((b & 0x55) << 1);
return b;
}
/* Функция для принудительного чтения статуса 0x3C прямо внутри процесса */
void read_embedded_status(int fd, const char *label) {
unsigned char cmd[] = { mirror_byte(0x3C), 0x00, 0x00, 0x00 };
unsigned char buf[8] = {0};
// Записываем команду чтения статуса
write(fd, cmd, 4);
usleep(1000);
// Читаем 8 байт ответа
if (read(fd, buf, 8) == 8) {
printf("[STATUS %s]: 0x%02X%02X%02X%02X%02X%02X%02X%02X\n", label,
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
} else {
printf("[STATUS %s]: Failed to read status bytes\n", label);
}
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Usage: %s <i2c-dev-path> <bitstream.bit>\n", argv);
return 1;
}
int fd = open(argv[1], O_RDWR);
if (fd < 0) { perror("Failed to open I2C bus"); return 1; }
if (ioctl(fd, I2C_SLAVE_FORCE, 0x40) < 0) { perror("Failed to set slave address"); return 1; }
FILE *f_bit = fopen(argv[2], "rb");
if (!f_bit) { perror("Failed to open bit file"); return 1; }
printf("[DEBUG_FLASH] Connected to 0x40. Absolute mirroring mode...\n");
/* 1. Ключ активации */
unsigned char act_key[] = { 0xA4, 0xC6, 0xF4, 0x8A };
write(fd, act_key, 4); usleep(5000);
/* 2. ISC_ENABLE */
unsigned char isc_enable[] = { mirror_byte(0xC6), 0x00, 0x00, 0x00 };
write(fd, isc_enable, 4); usleep(10000);
/* 3. ISC_ERASE */
unsigned char isc_erase[] = { mirror_byte(0x0E), mirror_byte(0x01), 0x00, 0x00 };
write(fd, isc_erase, 4); usleep(100000);
// Смотрим статус сразу после очистки памяти ПЛИС
read_embedded_status(fd, "AFTER_ERASE");
/* 4. LSC_BITSTREAM_BURST */
unsigned char burst_cmd[] = { mirror_byte(0x7A), 0x00, 0x00, 0x00 };
write(fd, burst_cmd, 4); usleep(2000);
/* 5. Потоковая передача всего файла с полным отзеркалированием */
unsigned char block;
size_t read_bytes, total_sent = 0;
while ((read_bytes = fread(block, 1, sizeof(block), f_bit)) > 0) {
for (size_t i = 0; i < read_bytes; i++) {
block[i] = mirror_byte(block[i]);
}
write(fd, block, read_bytes);
total_sent += read_bytes;
}
printf("[DEBUG_FLASH] Sent %zu bytes of bitstream payload.\n", total_sent);
usleep(5000);
/* ================================================================== */
/* КРИТИЧЕСКАЯ ТОЧКА: Читаем статус ДО закрытия режима прошивки */
/* ================================================================== */
read_embedded_status(fd, "BEFORE_ISC_DISABLE");
/* ================================================================== */
/* 6. Добивка FIFO */
unsigned char padding[1024];
for(int i=0; i<1024; i++) padding[i] = 0xFF;
write(fd, padding, 1024); usleep(5000);
/* 7. ISC_DISABLE */
unsigned char isc_disable[] = { mirror_byte(0x26), 0x00, 0x00, 0x00 };
write(fd, isc_disable, 4); usleep(5000);
/* 8. LSC_REFRESH */
unsigned char refresh[] = { mirror_byte(0x79), 0x00, 0x00, 0x00 };
write(fd, refresh, 4); usleep(5000);
read_embedded_status(fd, "FINAL_STAGE");
fclose(f_bit); close(fd);
return 0;
}