Цитата(FLTI @ Feb 9 2015, 15:53)

Где доступнее всего описано с примером ( в том числе с программой на С для NIOSа ) - как писать/читать EPCS через NIOS при помощи EPCS Controller-a ?
Можете взять в качестве примера немного подправив (используются только ф-ии alt_epcs_flash_init(), alt_epcs_flash_erase_block(), alt_epcs_flash_write_block(), ну и если читать надо, тогда - alt_epcs_flash_read_block()):
CODE
#include "altera_avalon_epcs_flash_controller.h"
static alt_flash_epcs_dev epcs_flash =
{
{
ALT_LLIST_ENTRY,
EPCS_FLASH_CONTROLLER_NAME,
NULL,
NULL,
alt_epcs_flash_write,
alt_epcs_flash_read,
alt_epcs_flash_get_info,
alt_epcs_flash_erase_block,
alt_epcs_flash_write_block,
((void*)(EPCS_FLASH_CONTROLLER_BASE))
},
(EPCS_FLASH_CONTROLLER_REGISTER_OFFSET + EPCS_FLASH_CONTROLLER_BASE)
};
short factory_cb(unsigned char *data, unsigned short size, unsigned short idx)
{
static int block_offset;
static int data_offset;
static unsigned long sec_addr = 0;
static unsigned int prev_idx;
if(idx == 1)
{
alt_epcs_flash_init(&epcs_flash);
block_offset = FACTORY_PAGE_START_ADDRESS;
data_offset = FACTORY_PAGE_START_ADDRESS;
prev_idx = 0;
sec_addr = FACTORY_PAGE_START_ADDRESS;
}
if(idx % 128 == 1) // 512*128 = 65536 = 64 kbyte
{
alt_epcs_flash_erase_block(&epcs_flash.dev, sec_addr);
sec_addr += CONFIG_DEV_SECTOR_SIZE;
}
if(size)
{
unsigned char buffer[512];
for(int i = 0; i < size; i++)
{
swap_bits(&data[i]);
buffer[i] = data[i];
}
alt_epcs_flash_write_block(&epcs_flash.dev, block_offset, data_offset, buffer, size);
data_offset += size;
if((data_offset % CONFIG_DEV_SECTOR_SIZE) == 0)
{
block_offset += CONFIG_DEV_SECTOR_SIZE;
}
}
prev_idx = idx;
return 1;
}
Ранее, для загрузки по CAN, использовался немного другой вариант:
CODE
#include "alt_types.h"
#include "system.h"
#define ALT_USE_EPCS_FLASH
#include "altera_avalon_epcs_flash_controller.h"
#include "epcs_loader.h"
#include "include/MCP2515.h"
ALTERA_AVALON_EPCS_FLASH_CONTROLLER_INSTANCE(EPCS_FLASH_CONTROLLER_0, epcs_flash);
void epcs_loader(unsigned int *data)
{
int i;
static int block_offset;
static int data_offset;
unsigned long tmp[2];
char buf[8];
if(data[0] == BOOT_START_CMD && data[1] == BOOT_START_CMD)
{
ALTERA_AVALON_EPCS_FLASH_CONTROLLER_INIT(EPCS_FLASH_CONTROLLER_0, epcs_flash);
block_offset = 0;
data_offset = 0;
for(i = 0; i < EPCS_NUMBER_SECTORS; i++)
{
alt_epcs_flash_erase_block(&epcs_flash.dev, block_offset);
block_offset += EPCS_SECTOR_BYTES;
}
block_offset = 0;
tmp[0] = BOOT_OK_RESPONSE;
tmp[1] = BOOT_OK_RESPONSE;
CmdTx(0, CAN_BOOT_API_ID, (alt_u16*) tmp, 8);
}
else if(data[0] == BOOT_END_CMD && data[1] == BOOT_END_CMD)
{
block_offset = 0;
data_offset = 0;
tmp[0] = BOOT_END_RESPONSE;
tmp[1] = BOOT_END_RESPONSE;
CmdTx(0, CAN_BOOT_API_ID, (alt_u16*) tmp, 8);
}
else
{
for(i = 0; i < 4; i++)
{
//buf[i] = (data[0] >> (8 * i)) & 0xFF;
//buf[i + 4] = (data[1] >> (8 * i)) & 0xFF;
buf[i] = data[0] & 0xFF;
buf[i + 4] = data[1] & 0xFF;
data[0] = data[0] >> 8;
data[1] = data[1] >> 8;
swap_bits(&buf[i]);
swap_bits(&buf[i + 4]);
}
alt_epcs_flash_write_block(&epcs_flash.dev, block_offset, data_offset, buf, 8);
data_offset += 8;
if((data_offset % EPCS_SECTOR_BYTES) == 0)
{
block_offset += EPCS_SECTOR_BYTES;
}
tmp[0] = BOOT_OK_RESPONSE;
tmp[1] = BOOT_OK_RESPONSE;
CmdTx(0, CAN_BOOT_API_ID, (alt_u16*) &tmp, 8);
}
}
Цитата(FLTI @ Feb 9 2015, 15:53)

Ок, понятно, надо писать в EPCS, но в другую её область, чтобы не затереть исходную прошивку.
Чтобы FPGA стартовала - записываете прошивку с адреса 0.