Пример кода загрузки Altera FPGA

Copyright (C) Сергей Вакуленко vak@cronyx.ru, распространяется на условиях GPL

/*
 * Управление сигналами загрузки Альтеры.
 */
#define set_isp_nconfig(on)	...
#define set_isp_1kdata(on)	...
#define set_isp_dclk(on)	...
#define get_isp_nstatus()	...
#define get_isp_confdone()	...
 
/*
 * Выдача одного бита данных и синхроимпульса.
 */
static inline void putbit (int bit)
{
	if (bit)
		set_isp_1kdata (1);
	else
		set_isp_1kdata (0);
 
	set_isp_dclk (1);
	set_isp_dclk (0);
}
 
/*
 * Загрузка прошивки Альтеры.
 * Параметры: адрес и длина массива данных из файла TTF.
 * Возвращает 1 при успехе, 0 в случае неудачи.
 */
int download (unsigned char *fwaddr, unsigned long bytes)
{
	unsigned int val;
 
	/* Установка NCONFIG, задержка 100 микросекунд. */
	set_isp_nconfig (1);
	usleep (100);
 
	/* Сброс NCONFIG, задержка 2 микросекунды, проверка NSTATUS. */
	set_isp_nconfig (0);
	usleep (2);
	if (get_isp_nstatus()) {
		/* Неправильный NSTATUS в начале загрузки. */
		return 0;
	}
 
	/* Установка NCONFIG, задержка 5 микросекунд. */
	set_isp_nconfig (1);
	usleep (5);
	for (;;) {
		if (get_isp_nstatus() == 0) {
			/* Неправильный NSTATUS в процессе загрузки. */
			return 0;
		}
		if (get_isp_confdone())
			break;
 
		if (bytes <= 0) {
			/* Нет CONFDONE при завершении загрузки. */
			return 0;
		}
		val = *fwaddr++;
		--bytes;
 
		putbit (val & 0x01);
		putbit (val & 0x02);
		putbit (val & 0x04);
		putbit (val & 0x08);
		putbit (val & 0x10);
		putbit (val & 0x20);
		putbit (val & 0x40);
		putbit (val & 0x80);
	}
 
	/* Десять дополнительных синхроимпульсов. */
	for (val=0; val<10; ++val) {
		set_isp_dclk (1);
		set_isp_dclk (0);
	}
 
	if (get_isp_nstatus() == 0) {
		/* Неправильный NSTATUS в конце загрузки. */
		return 0;
	}
 
	/* Успешно. */
	return 1;
}