firmware: Sayma RTM FPGA bitstream loading prototype (#813).

This commit is contained in:
whitequark 2018-02-28 16:46:23 +00:00
parent 2896dc619b
commit f95fb273f1
4 changed files with 79 additions and 12 deletions

View File

@ -1,4 +1,3 @@
#![feature(asm, lang_items)]
#![no_std]
#[macro_use]
@ -25,3 +24,5 @@ mod ad9154_reg;
pub mod ad9154;
#[cfg(has_allaki_atts)]
pub mod hmc542;
#[cfg(has_rtm_fpga_cfg)]
pub mod rtm_fpga;

View File

@ -0,0 +1,46 @@
use core::slice;
use board::csr::rtm_fpga_cfg;
use board::clock;
const ADDR: *const u8 = 0x150000 as *const u8;
pub fn program_bitstream() -> Result<(), ()> {
unsafe {
let length = *(ADDR as *const usize);
let bitstream = slice::from_raw_parts(ADDR.offset(4) as *const u32, length / 4);
debug!("resetting");
rtm_fpga_cfg::divisor_write(15);
rtm_fpga_cfg::program_write(1);
clock::spin_us(1000);
rtm_fpga_cfg::program_write(0);
clock::spin_us(1000);
while rtm_fpga_cfg::error_read() != 0 {}
debug!("programming");
for word in bitstream {
rtm_fpga_cfg::data_write(*word);
rtm_fpga_cfg::start_write(1);
while rtm_fpga_cfg::busy_read() == 1 {}
}
debug!("finishing");
loop {
if rtm_fpga_cfg::error_read() != 0 {
error!("programming error");
return Err(())
}
if rtm_fpga_cfg::done_read() != 0 {
debug!("done");
return Ok(())
}
}
}
}

View File

@ -49,11 +49,20 @@ mod moninj;
mod analyzer;
fn startup() {
log::set_max_level(log::LevelFilter::TRACE);
logger_artiq::BufferLogger::with(|logger|
logger.set_uart_log_level(log::LevelFilter::TRACE));
board::clock::init();
info!("ARTIQ runtime starting...");
info!("software version {}", include_str!(concat!(env!("OUT_DIR"), "/git-describe")));
info!("gateware version {}", board::ident::read(&mut [0; 64]));
#[cfg(has_rtm_fpga_cfg)]
board_artiq::rtm_fpga::program_bitstream().expect("cannot program RTM FPGA");
#[cfg(has_serwb_phy_amc)]
board_artiq::serwb::wait_init();
match config::read_str("log_level", |r| r.map(|s| s.parse())) {
Ok(Ok(log_level_filter)) => {
info!("log level set to {} by `log_level` config key",
@ -72,9 +81,6 @@ fn startup() {
_ => info!("UART log level set to INFO by default")
}
#[cfg(has_serwb_phy_amc)]
board_artiq::serwb::wait_init();
let t = board::clock::get_ms();
info!("press 'e' to erase startup and idle kernels...");
while board::clock::get_ms() < t + 1000 {

View File

@ -6,6 +6,7 @@ import subprocess
import tempfile
import shutil
import re
import io
import atexit
from functools import partial
from collections import defaultdict
@ -278,6 +279,7 @@ def main():
"bootloader": ("spi1", 0x000000),
"storage": ("spi1", 0x040000),
"firmware": ("spi1", 0x050000),
"rtm_gateware": ("spi1", 0x150000),
},
}[args.target]
@ -309,18 +311,30 @@ def main():
else:
return os.path.join(args.srcbuild, *path_filename)
def convert_gateware(bit_filename, prefix_size=False):
bin_io = io.BytesIO()
with open(bit_filename, "rb") as bit_file:
bit2bin(bit_file, bin_io)
bin_data = bin_io.getvalue()
bin_handle, bin_filename = tempfile.mkstemp(
prefix="artiq_", suffix="_" + os.path.basename(bit_filename))
with open(bin_handle, "wb") as bin_file:
if prefix_size:
bin_file.write(len(bin_data).to_bytes(4, byteorder="big"))
bin_file.write(bin_data)
atexit.register(lambda: os.unlink(bin_filename))
return bin_filename
try:
for action in args.action:
if action == "gateware":
gateware_bin = artifact_path(variant, "gateware", "top.bin")
if not os.access(gateware_bin, os.R_OK):
bin_handle, gateware_bin = tempfile.mkstemp()
gateware_bit = artifact_path(variant, "gateware", "top.bit")
with open(gateware_bit, "rb") as bit_file, open(bin_handle, "wb") as bin_file:
bit2bin(bit_file, bin_file)
atexit.register(lambda: os.unlink(gateware_bin))
gateware_bin = convert_gateware(artifact_path(variant, "gateware", "top.bit"))
programmer.write_binary(*config["gateware"], gateware_bin)
if args.target == "sayma":
rtm_gateware_bin = convert_gateware(artifact_path("rtm_gateware", "top.bit"))
programmer.write_binary(*config["rtm_gateware"], rtm_gateware_bin)
elif action == "bootloader":
bootloader_bin = artifact_path(variant, "software", "bootloader", "bootloader.bin")
programmer.write_binary(*config["bootloader"], bootloader_bin)