in src/de10nano/de10nano_mgr.h [379:548]
bool program_rbf(const char *rbf) {
monitor mon;
int rbf_fd;
uint32_t count = 0;
printf("DE10-Nano-Mgr: Programming FPGA from image %s\n", rbf);
try {
mon.init("Open RBF file");
rbf_fd = open(rbf, (O_RDONLY | O_SYNC));
mon.done(rbf_fd >= 0);
// 1. Set the cdratio and cfgwdth bits of the ctrl register in the
// FPGA manager registers (fpgamgrregs) to match the characteristics
// of the configuration image. Tese settings are dependent on the
// MSEL pins input.
// 2. Set the nce bit of the ctrl register to 0 to enable HPS
// configuration.
// 3. Set the en bit of the ctrl register to 1 to give the FPGA
// manager control of the configuration input signals.
// 4. Set the nconfigpull bit of the ctrl register to 1 to pull
// down the nCONFIG pin and put the FPGA portion of the device
// into the reset phase.
mon.init("Enable FPGA configuration");
stat.read();
if (stat.msel_is_invalid()) {
printf("DE10-Nano-Mgr: msel %x is not a valid HPS configuration\n", stat.msel);
} else {
ctrl.read();
ctrl.cdratio = msel_to_cdratio(stat.msel);
ctrl.cfgwdth = msel_to_cfgwdth(stat.msel);
ctrl.nce = 0;
ctrl.en = 1;
ctrl.nconfigpull = 1;
ctrl.write();
}
mon.done(!stat.msel_is_invalid());
// 5. Poll the mode bit of the stat register and wait until
// the FPGA enters the reset phase.
mon.init("Wait for FPGA to reset");
do {
stat.read();
} while (mon(stat.mode != stat::FPGA_RESET_PHASE));
mon.done();
stat.print();
// 6. Set the nconfigpull bit of the ctrl register to 0 to
// release the FPGA from reset.
mon.init("Release FPGA from reset");
ctrl.nconfigpull = 0;
ctrl.write();
mon.done();
// 7. Read the mode bit of the stat register and wait until
// the FPGA enters the configuration phase.
mon.init("Wait for configuration phase");
do {
stat.read();
} while (mon(stat.mode != stat::FPGA_CONFIG_PHASE));
mon.done();
stat.print();
// 8. Clear the interrupt bit of nSTATUS (ns) in the gpio interrupt
// register (fpgamgrregs.mon.gpio_porta_eoi).
mon.init("Clear nSTATUS interrupt bit");
gpio_porta_eoi.clear();
gpio_porta_eoi.ns = 1;
gpio_porta_eoi.write();
mon.done();
// 9. Set the axicfgen bit of the ctrl register to 1 to enable
// sending configuration data to the FPGA.
mon.init("Enable configuration on AXI");
ctrl.axicfgen = 1;
ctrl.write();
mon.done();
// 10. Write the configuration image to the configuration data register
// (data) in the FPGA manager module configuration data registers
// (fpgamgrdata). You can also choose to use a DMA controller to
// transfer the configuration image from a peripheral device to the
// FPGA manager.
ssize_t bytes;
mon.init("Write configuration Image");
do {
data.value = 0;
bytes = read(rbf_fd, &data.value, sizeof(data.value));
if (bytes > 0) {
if (!(count % (1<<16))) {
printf("\rDE10-Nano-Mgr: %-32s : %u B", mon.msg, count);
fflush(stdout);
}
data.write();
count += bytes;
}
} while (bytes == 4);
mon.done(count > 0);
printf("DE10-Nano-Mgr: %-32s : written %u B\n", mon.msg, count);
close(rbf_fd);
// 11. Use the fpgamgrregs.mon.gpio_ext_porta registers to monitor
// the CONF_DONE (cd) and nSTATUS (ns) bits.
mon.init("Wait for CONF_DONE");
do {
gpio_ext_porta.read();
} while (mon(gpio_ext_porta.cd != 1 && gpio_ext_porta.ns != 1));
mon.done();
stat.print();
// 12. Set the axicfgen bit of the ctrl register to 0 to disable
// configuration data on AXI slave.
mon.init("Disable configuration on AXI");
ctrl.axicfgen = 0;
ctrl.write();
mon.done();
// 13. Clear any previous DONE status by writing a 1 to the dcntdone
// bit of the DCLK status register (dclkstat) to clear the completed
// status flag.
mon.init("Clear DCLK DONE status");
dclkstat.dcntdone = 1;
dclkstat.write();
mon.done();
// 14. Send the DCLKs required by the FPGA to enter the
// initialization phase.
mon.init("Send DCLK for init phase");
dclkcnt.cnt = 4;
dclkcnt.write();
mon.done();
// 15. Poll the dcntdone bit of the DCLK status register (dclkstat)
// until it changes to 1, which indicates that all the DCLKs have
// been sent.
mon.init("Wait for DCLK");
do {
dclkstat.read();
} while (mon(dclkstat.dcntdone != 1));
mon.done();
// 16. Write a 1 to the dcntdone bit of the DCLK status register to
// clear the completed status flag.
mon.init("Clear DCLK status flag");
dclkstat.dcntdone = 1;
dclkstat.write();
mon.done();
// 17. Read the mode bit of the stat register to wait for the FPGA
// to enter user mode.
mon.init("Wait for FPGA user mode");
do {
stat.read();
} while (mon(stat.mode != stat::FPGA_USER_MODE));
mon.done();
// 18. Set the en bit of the ctrl register to 0 to allow the
// external pins to drive the configuration input signals.
mon.init("Release control");
ctrl.en = 0;
ctrl.write();
mon.done();
}
catch(int i) {
close(rbf_fd);
printf("DE10-Nano-Mgr: %-32s : written %u B\n", mon.msg, count);
print();
}
return mon.status();
}