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] #![no_std]
#[macro_use] #[macro_use]
@ -25,3 +24,5 @@ mod ad9154_reg;
pub mod ad9154; pub mod ad9154;
#[cfg(has_allaki_atts)] #[cfg(has_allaki_atts)]
pub mod hmc542; 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; mod analyzer;
fn startup() { 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(); board::clock::init();
info!("ARTIQ runtime starting..."); info!("ARTIQ runtime starting...");
info!("software version {}", include_str!(concat!(env!("OUT_DIR"), "/git-describe"))); info!("software version {}", include_str!(concat!(env!("OUT_DIR"), "/git-describe")));
info!("gateware version {}", board::ident::read(&mut [0; 64])); 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())) { match config::read_str("log_level", |r| r.map(|s| s.parse())) {
Ok(Ok(log_level_filter)) => { Ok(Ok(log_level_filter)) => {
info!("log level set to {} by `log_level` config key", 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") _ => 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(); let t = board::clock::get_ms();
info!("press 'e' to erase startup and idle kernels..."); info!("press 'e' to erase startup and idle kernels...");
while board::clock::get_ms() < t + 1000 { while board::clock::get_ms() < t + 1000 {

View File

@ -6,6 +6,7 @@ import subprocess
import tempfile import tempfile
import shutil import shutil
import re import re
import io
import atexit import atexit
from functools import partial from functools import partial
from collections import defaultdict from collections import defaultdict
@ -278,6 +279,7 @@ def main():
"bootloader": ("spi1", 0x000000), "bootloader": ("spi1", 0x000000),
"storage": ("spi1", 0x040000), "storage": ("spi1", 0x040000),
"firmware": ("spi1", 0x050000), "firmware": ("spi1", 0x050000),
"rtm_gateware": ("spi1", 0x150000),
}, },
}[args.target] }[args.target]
@ -309,18 +311,30 @@ def main():
else: else:
return os.path.join(args.srcbuild, *path_filename) 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: try:
for action in args.action: for action in args.action:
if action == "gateware": if action == "gateware":
gateware_bin = artifact_path(variant, "gateware", "top.bin") gateware_bin = convert_gateware(artifact_path(variant, "gateware", "top.bit"))
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))
programmer.write_binary(*config["gateware"], gateware_bin) 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": elif action == "bootloader":
bootloader_bin = artifact_path(variant, "software", "bootloader", "bootloader.bin") bootloader_bin = artifact_path(variant, "software", "bootloader", "bootloader.bin")
programmer.write_binary(*config["bootloader"], bootloader_bin) programmer.write_binary(*config["bootloader"], bootloader_bin)