Compare commits

..

4 Commits

Author SHA1 Message Date
morgan 7dc57dc24e WRPLL firmware
satman main & si549: add WRPLL select_recovered_clock
satman main & si549: add helper si549 & interrupt setup
si549: add set_adpll for main & helper si549
si549: add freq counter to set BASE_ADPLL
si549: add tag collector to process gtx & main tags
si549: add main & helper PLL
IRQ & si549: add handler for gtx & main tags irq
IRQ: add docs for IRQ id
2024-01-04 15:46:59 +08:00
morgan 6a47c2fcf2 Si549 firmware
satman main: drive CLK_SEL to true when si549 is used
satman main: add main DCXO setup
io_expander: set CLK_SEL pin to output when si549 is used
si549: add bit bang i2c
si549: add si549 programming & main setup
2024-01-04 12:41:36 +08:00
morgan b9251c0b26 WRPLL gateware
kasli_soc satellite: add wrpll
kasli_soc satellite: add gtx & main tag IRQs for sateelite
ddmtd: add ddmtd and deglitcher
wrpll: add helper clockdomain
wrpll: add frequency counter
wrpll: add gtx_tag and main_tag csr
wrpll: add gtx & main tag collection
wrpll: add gtx & main tag eventmanager for shared peripheral interrupt
2024-01-04 12:38:01 +08:00
morgan c761958816 si549 gateware
kasli_soc: add option to select si5324 over si549 using --with-wrpll arg
kasli_soc: add main and helper si549 for satellite
kasli_soc: default to use si5435
si549: add i2c and adpll programming for si549
si549: add option to switch between bitbang and gateware i2c
2024-01-04 12:28:40 +08:00
7 changed files with 211 additions and 212 deletions

View File

@ -31,7 +31,7 @@ class DDMTDSamplerGTX(Module):
class DDMTDDeglitcherFirstEdge(Module):
def __init__(self, input_signal, blind_period=128):
def __init__(self, input_signal, blind_period=200):
self.detect = Signal()
rising = Signal()
input_signal_r = Signal()
@ -70,87 +70,3 @@ class DDMTD(Module):
self.h_tag.eq(counter)
)
]
class Collector(Module):
"""
A phase and period collector for DDMTD
"""
def __init__(self, N):
self.gtx_stb = Signal()
self.main_stb = Signal()
self.tag_gtx = Signal(N)
self.tag_main = Signal(N)
self.out_period_stb = Signal()
self.out_beating_period = Signal(N)
last_gtx_tag = Signal(N)
beating_period_r = Signal(N)
self.out_phase_stb = Signal()
self.out_tag_gtx = Signal(N)
self.out_tag_main = Signal(N)
tag_gtx_r = Signal(N)
tag_main_r = Signal(N)
# # #
# Period collector
# collect the difference between each gtx tags
self.submodules.period_colr_fsm = period_colr_fsm = FSM(reset_state="IDLE")
period_colr_fsm.act("IDLE",
NextValue(self.out_period_stb, 0),
If(self.gtx_stb,
NextValue(beating_period_r, self.tag_gtx - last_gtx_tag),
NextValue(last_gtx_tag, self.tag_gtx),
NextState("OUTPUT")
)
)
period_colr_fsm.act("OUTPUT",
NextValue(self.out_beating_period, beating_period_r),
NextValue(self.out_period_stb, 1),
NextState("IDLE")
)
# Phase collector
# collect main and gtx tag
self.submodules.phase_colr_fsm = phase_colr_fsm = FSM(reset_state="IDLE")
phase_colr_fsm.act("IDLE",
NextValue(self.out_phase_stb, 0),
If(self.gtx_stb & self.main_stb,
NextValue(tag_gtx_r, self.tag_gtx),
NextValue(tag_main_r, self.tag_main),
NextState("OUTPUT")
).Elif(self.gtx_stb,
NextValue(tag_gtx_r, self.tag_gtx),
NextState("WAITMAIN")
).Elif(self.main_stb,
NextValue(tag_main_r, self.tag_main),
NextState("WAITGTX")
)
)
phase_colr_fsm.act("WAITGTX",
If(self.gtx_stb,
NextValue(tag_gtx_r, self.tag_gtx),
NextState("OUTPUT")
)
)
phase_colr_fsm.act("WAITMAIN",
If(self.main_stb,
NextValue(tag_main_r, self.tag_main),
NextState("OUTPUT")
)
)
phase_colr_fsm.act("OUTPUT",
NextValue(self.out_tag_gtx, tag_gtx_r),
NextValue(self.out_tag_main, tag_main_r),
NextValue(self.out_phase_stb, 1),
NextState("IDLE")
)

View File

@ -107,7 +107,7 @@ class GTPBootstrapClock(Module):
class GenericStandalone(SoCCore):
def __init__(self, description, acpki=False, si5324=False):
def __init__(self, description, acpki=False, with_wrpll=False):
self.acpki = acpki
clk_freq = description["rtio_frequency"]
@ -207,7 +207,7 @@ class GenericStandalone(SoCCore):
class GenericMaster(SoCCore):
def __init__(self, description, acpki=False, si5324=False):
def __init__(self, description, acpki=False, with_wrpll=False):
clk_freq = description["rtio_frequency"]
has_drtio_over_eem = any(peripheral["type"] == "shuttler" for peripheral in description["peripherals"])
@ -400,7 +400,7 @@ class GenericMaster(SoCCore):
class GenericSatellite(SoCCore):
def __init__(self, description, acpki=False, si5324=False):
def __init__(self, description, acpki=False, with_wrpll=False):
clk_freq = description["rtio_frequency"]
self.acpki = acpki
@ -553,16 +553,7 @@ class GenericSatellite(SoCCore):
self.config["RTIO_FREQUENCY"] = str(clk_freq/1e6)
self.config["CLOCK_FREQUENCY"] = int(clk_freq)
if si5324:
self.submodules.siphaser = SiPhaser7Series(
si5324_clkin=platform.request("cdr_clk"),
rx_synchronizer=self.rx_synchronizer,
ultrascale=False,
rtio_clk_freq=self.gt_drtio.rtio_clk_freq)
self.csr_devices.append("siphaser")
self.config["HAS_SI5324"] = None
self.config["SI5324_SOFT_RESET"] = None
else:
if with_wrpll:
self.submodules.main_dcxo = si549.Si549(platform.request("ddmtd_main_dcxo_i2c"))
self.submodules.helper_dcxo = si549.Si549(platform.request("ddmtd_helper_dcxo_i2c"))
self.submodules.wrpll = wrpll.WRPLL(
@ -573,10 +564,19 @@ class GenericSatellite(SoCCore):
self.csr_devices.append("helper_dcxo")
self.csr_devices.append("wrpll")
self.comb += [
self.ps7.interrupt[0].eq(self.wrpll.period_ev.irq), # IRQ_ID = 61
self.ps7.interrupt[1].eq(self.wrpll.phase_ev.irq) # IRQ_ID = 62
self.ps7.interrupt[0].eq(self.wrpll.gtx_tag_ev.irq), # IRQ_ID = 61
self.ps7.interrupt[1].eq(self.wrpll.main_tag_ev.irq) # IRQ_ID = 62
]
self.config["HAS_SI549"] = None
else:
self.submodules.siphaser = SiPhaser7Series(
si5324_clkin=platform.request("cdr_clk"),
rx_synchronizer=self.rx_synchronizer,
ultrascale=False,
rtio_clk_freq=self.gt_drtio.rtio_clk_freq)
self.csr_devices.append("siphaser")
self.config["HAS_SI5324"] = None
self.config["SI5324_SOFT_RESET"] = None
gtx0 = self.gt_drtio.gtxs[0]
platform.add_false_path_constraints(
@ -606,8 +606,8 @@ def main():
help="build gateware into the specified directory")
parser.add_argument("--acpki", default=False, action="store_true",
help="enable ACPKI")
parser.add_argument("--si5324", default=False, action="store_true",
help="use si5324 over si549")
parser.add_argument("--with-wrpll", default=False, action="store_true",
help="enable WRPLL")
parser.add_argument("description", metavar="DESCRIPTION",
help="JSON system description file")
args = parser.parse_args()
@ -625,7 +625,7 @@ def main():
else:
raise ValueError("Invalid DRTIO role")
soc = cls(description, acpki=args.acpki, si5324=args.si5324)
soc = cls(description, acpki=args.acpki, with_wrpll=args.with_wrpll)
soc.finalize()
if args.r is not None:

View File

@ -3,7 +3,7 @@ from migen.genlib.cdc import MultiReg, AsyncResetSynchronizer, PulseSynchronizer
from misoc.interconnect.csr import *
from misoc.interconnect.csr_eventmanager import *
from ddmtd import DDMTDSamplerGTX, DDMTD, Collector
from ddmtd import DDMTDSamplerGTX, DDMTD
class FrequencyCounter(Module, AutoCSR):
@ -49,18 +49,15 @@ class FrequencyCounter(Module, AutoCSR):
class WRPLL(Module, AutoCSR):
def __init__(self, gtx, main_dcxo_pads, helper_dcxo_pads, COUNTER_BIT=32):
self.gtx_period = CSRStatus(COUNTER_BIT)
self.gtx_tag = CSRStatus(COUNTER_BIT)
self.main_tag = CSRStatus(COUNTER_BIT)
ddmtd_counter = Signal(COUNTER_BIT)
gtx_period_sys = Signal(COUNTER_BIT)
gtx_tag_sys = Signal(COUNTER_BIT)
main_tag_sys = Signal(COUNTER_BIT)
period_colr_stb_sys = Signal()
phase_colr_stb_sys = Signal()
gtx_tag_stb_sys = Signal()
main_tag_stb_sys = Signal()
# # #
@ -84,57 +81,46 @@ class WRPLL(Module, AutoCSR):
# DDMTD tags collection
self.submodules.collector = ClockDomainsRenamer("helper")(Collector(COUNTER_BIT))
self.comb += [
self.collector.gtx_stb.eq(self.ddmtd_gtx.h_tag_update),
self.collector.main_stb.eq(self.ddmtd_main.h_tag_update),
self.collector.tag_gtx.eq(self.ddmtd_gtx.h_tag),
self.collector.tag_main.eq(self.ddmtd_main.h_tag)
self.specials += [
MultiReg(self.ddmtd_gtx.h_tag, gtx_tag_sys),
MultiReg(self.ddmtd_main.h_tag, main_tag_sys)
]
period_colr_stb_ps = PulseSynchronizer("helper", "sys")
phase_colr_stb_ps = PulseSynchronizer("helper", "sys")
gtx_tag_stb_ps = PulseSynchronizer("helper", "sys")
main_tag_stb_ps = PulseSynchronizer("helper", "sys")
self.submodules += [
period_colr_stb_ps,
phase_colr_stb_ps
gtx_tag_stb_ps,
main_tag_stb_ps
]
self.sync.helper += [
period_colr_stb_ps.i.eq(self.collector.out_period_stb),
phase_colr_stb_ps.i.eq(self.collector.out_phase_stb)
gtx_tag_stb_ps.i.eq(self.ddmtd_gtx.h_tag_update),
main_tag_stb_ps.i.eq(self.ddmtd_main.h_tag_update)
]
self.sync += [
period_colr_stb_sys.eq(period_colr_stb_ps.o),
phase_colr_stb_sys.eq(phase_colr_stb_ps.o)
]
self.specials += [
MultiReg(self.collector.out_beating_period, gtx_period_sys),
MultiReg(self.collector.out_tag_gtx, gtx_tag_sys),
MultiReg(self.collector.out_tag_main, main_tag_sys)
gtx_tag_stb_sys.eq(gtx_tag_stb_ps.o),
main_tag_stb_sys.eq(main_tag_stb_ps.o)
]
self.sync += [
If(period_colr_stb_sys,
self.gtx_period.status.eq(gtx_period_sys),
),
If(phase_colr_stb_sys,
If(gtx_tag_stb_sys,
self.gtx_tag.status.eq(gtx_tag_sys),
),
If(main_tag_stb_sys,
self.main_tag.status.eq(main_tag_sys)
)
]
# PL-PS shared peripheral interrupt (SPI)
self.submodules.period_ev = EventManager()
self.period_ev.stb = EventSourcePulse()
self.period_ev.finalize()
self.submodules.gtx_tag_ev = EventManager()
self.gtx_tag_ev.stb = EventSourcePulse()
self.gtx_tag_ev.finalize()
self.submodules.phase_ev = EventManager()
self.phase_ev.stb = EventSourcePulse()
self.phase_ev.finalize()
self.submodules.main_tag_ev = EventManager()
self.main_tag_ev.stb = EventSourcePulse()
self.main_tag_ev.finalize()
self.sync += [
self.period_ev.stb.trigger.eq(period_colr_stb_sys),
self.phase_ev.stb.trigger.eq(phase_colr_stb_sys)
self.gtx_tag_ev.stb.trigger.eq(gtx_tag_stb_sys),
self.main_tag_ev.stb.trigger.eq(main_tag_stb_sys)
]

View File

@ -12,11 +12,6 @@ struct Registers {
gpiob: u8, // Output Port 1
}
#[cfg(has_si549)]
const USE_SI549: u8 = 0xFF;
#[cfg(has_si5324)]
const USE_SI549: u8 = 0x00;
//IO expanders pins
const IODIR_OUT_SFP_TX_DISABLE: u8 = 0x02;
const IODIR_OUT_SFP_LED: u8 = 0x40;
@ -24,12 +19,15 @@ const IODIR_OUT_SFP_LED: u8 = 0x40;
const IODIR_OUT_SFP0_LED: u8 = 0x40;
#[cfg(hw_rev = "v1.1")]
const IODIR_OUT_SFP0_LED: u8 = 0x80;
const IODIR_OUT_CLK_SEL: u8 = 0x80;
#[cfg(has_si549)]
const IODIR_CLK_SEL: u8 = 0x80; // out
#[cfg(has_si5324)]
const IODIR_CLK_SEL: u8 = 0x00; // in
//IO expander port direction
const IODIR0: [u8; 2] = [
0xFF & !IODIR_OUT_SFP_TX_DISABLE & !IODIR_OUT_SFP0_LED,
0xFF & !IODIR_OUT_SFP_TX_DISABLE & !IODIR_OUT_SFP_LED & !(IODIR_OUT_CLK_SEL & USE_SI549),
0xFF & !IODIR_OUT_SFP_TX_DISABLE & !IODIR_OUT_SFP_LED & !IODIR_CLK_SEL,
];
const IODIR1: [u8; 2] = [

View File

@ -12,7 +12,7 @@ const ADDRESS: u8 = 0x67;
mod i2c {
use super::*;
#[derive(Debug, Clone, Copy)]
#[derive(Clone, Copy)]
pub enum DCXO {
Main,
#[cfg(has_wrpll)]
@ -287,6 +287,7 @@ pub fn main_setup(timer: &mut GlobalTimer) -> Result<(), &'static str> {
#[cfg(has_wrpll)]
pub mod wrpll {
use libboard_zynq::gic;
use super::*;
@ -296,13 +297,107 @@ pub mod wrpll {
const TIMER_WIDTH: u32 = 24;
const COUNTER_DIV: u32 = 2;
const BEATING_PERIOD: i32 = 0x4000;
const BEATING_HALFPERIOD: i32 = 0x2000;
const ADPLL_MAX: i32 = (950.0 / 0.0001164) as i32;
static mut BASE_ADPLL: i32 = 0;
static mut H_INTEGRATOR: i32 = 0;
static mut M_INTEGRATOR: i32 = 0;
#[derive(Clone, Copy)]
pub enum IRQ {
GTXTag,
MainTag,
}
mod tag_collector {
use super::IRQ;
use crate::pl::csr;
const BEATING_PERIOD: i32 = 0x4000;
const BEATING_HALFPERIOD: i32 = 0x2000;
// for helper PLL
static mut LAST_GTX_TAG: u32 = 0;
static mut FIRST_GTX_INTERRUPT: bool = true;
static mut PERIOD_DET_READY: bool = false;
// for main PLL
static mut GTX_TAG: u32 = 0;
static mut GTX_TAG_READY: bool = false;
static mut MAIN_TAG: u32 = 0;
static mut MAIN_TAG_READY: bool = false;
pub fn reset() {
clear_period_det_ready();
clear_phase_det_ready();
unsafe {
LAST_GTX_TAG = 0;
FIRST_GTX_INTERRUPT = true;
GTX_TAG = 0;
MAIN_TAG = 0;
}
}
pub fn clear_period_det_ready() {
unsafe {
PERIOD_DET_READY = false;
}
}
pub fn clear_phase_det_ready() {
unsafe {
GTX_TAG_READY = false;
MAIN_TAG_READY = false;
}
}
pub fn collect_tags(interrupt: IRQ) {
match interrupt {
IRQ::GTXTag => unsafe {
if !FIRST_GTX_INTERRUPT {
LAST_GTX_TAG = GTX_TAG;
PERIOD_DET_READY = true;
}
GTX_TAG = csr::wrpll::gtx_tag_read();
FIRST_GTX_INTERRUPT = false;
GTX_TAG_READY = true;
},
IRQ::MainTag => unsafe {
MAIN_TAG = csr::wrpll::main_tag_read();
MAIN_TAG_READY = true;
},
}
}
pub fn period_det_ready() -> bool {
unsafe { PERIOD_DET_READY }
}
pub fn phase_det_ready() -> bool {
unsafe { GTX_TAG_READY && MAIN_TAG_READY }
}
pub fn get_period_error() -> i32 {
// when gtx tag roll over, overflowing_sub prevent the difference to overflow and still get the correct period
unsafe { BEATING_PERIOD - (GTX_TAG.overflowing_sub(LAST_GTX_TAG).0) as i32 }
}
pub fn get_phase_error() -> i32 {
let mut phase_error: i32;
unsafe {
// unwrap tag difference
phase_error = MAIN_TAG.overflowing_sub(GTX_TAG).0.rem_euclid(BEATING_PERIOD as u32) as i32;
}
// mapping tags from [0, 2π] -> [-π, π]
if phase_error > BEATING_HALFPERIOD {
phase_error -= BEATING_PERIOD
}
phase_error
}
}
pub fn helper_setup(timer: &mut GlobalTimer) -> Result<(), &'static str> {
unsafe {
@ -327,9 +422,9 @@ pub mod wrpll {
Ok(())
}
pub fn wrpll_interrupt_setup(interrupt_controller: &mut gic::InterruptController) {
pub fn interrupt_setup(interrupt_controller: &mut gic::InterruptController) {
for id in IRQ_ID.iter() {
// configure registers on cpu for shared peripheral interrupts (SPI)
// setup shared peripheral interrupts (SPI)
interrupt_controller.enable(
gic::InterruptId(*id),
gic::CPUCore::Core0,
@ -339,11 +434,11 @@ pub mod wrpll {
}
}
fn set_wrpll_interrupt(en: bool) {
fn set_irq(en: bool) {
let val = if en { 1 } else { 0 };
unsafe {
// enable the gateware event managers
csr::wrpll::period_ev_enable_write(en as u8);
csr::wrpll::phase_ev_enable_write(en as u8);
csr::wrpll::gtx_tag_ev_enable_write(val);
csr::wrpll::main_tag_ev_enable_write(val);
}
}
@ -393,39 +488,6 @@ pub mod wrpll {
Ok(())
}
fn get_freq_counts(timer: &mut GlobalTimer) -> (u32, u32, u32) {
unsafe {
csr::wrpll::frequency_counter_update_en_write(1);
timer.delay_us(150_000); // 8ns << TIMER_WIDTH
csr::wrpll::frequency_counter_update_en_write(0);
let gtx = csr::wrpll::frequency_counter_counter_gtx0_rtio_rx_read();
let main = csr::wrpll::frequency_counter_counter_sys_read();
let helper = csr::wrpll::frequency_counter_counter_helper_read();
(gtx, main, helper)
}
}
fn get_beating_period_error() -> i32 {
unsafe { BEATING_PERIOD - csr::wrpll::gtx_period_read() as i32 }
}
fn get_phase_error() -> i32 {
let (tag_main, tag_gtx): (u32, u32);
unsafe {
tag_main = csr::wrpll::main_tag_read();
tag_gtx = csr::wrpll::gtx_tag_read();
}
// unwrap tag difference
let mut phase_error = tag_main.overflowing_sub(tag_gtx).0.rem_euclid(BEATING_PERIOD as u32) as i32;
// mapping tags from [0, 2π] -> [-π, π]
if phase_error > BEATING_HALFPERIOD {
phase_error -= BEATING_PERIOD
}
phase_error
}
fn set_base_adpll(timer: &mut GlobalTimer) -> Result<(), &'static str> {
let count2adpll =
|error: i32| (((error) as f64 * 1e6) / (0.0001164 * (1 << (TIMER_WIDTH - COUNTER_DIV)) as f64)) as i32;
@ -440,15 +502,54 @@ pub mod wrpll {
Ok(())
}
fn get_freq_counts(timer: &mut GlobalTimer) -> (u32, u32, u32) {
unsafe {
csr::wrpll::frequency_counter_update_en_write(1);
timer.delay_us(150_000); // 8ns << TIMER_WIDTH
csr::wrpll::frequency_counter_update_en_write(0);
let gtx = csr::wrpll::frequency_counter_counter_gtx0_rtio_rx_read();
let main = csr::wrpll::frequency_counter_counter_sys_read();
let helper = csr::wrpll::frequency_counter_counter_helper_read();
(gtx, main, helper)
}
}
fn reset_plls() -> Result<(), &'static str> {
unsafe { H_INTEGRATOR = 0 }
unsafe {
H_INTEGRATOR = 0;
M_INTEGRATOR = 0;
}
set_adpll(i2c::DCXO::Main, 0)?;
set_adpll(i2c::DCXO::Helper, 0)?;
Ok(())
}
fn clear_pending(interrupt: IRQ) {
match interrupt {
IRQ::GTXTag => unsafe { csr::wrpll::gtx_tag_ev_pending_write(1) },
IRQ::MainTag => unsafe { csr::wrpll::main_tag_ev_pending_write(1) },
}
}
pub fn interrupt_handler(interrupt: IRQ) {
tag_collector::collect_tags(interrupt);
if tag_collector::period_det_ready() {
helper_pll().expect("failed to run helper DCXO PLL");
tag_collector::clear_period_det_ready();
}
if tag_collector::phase_det_ready() {
main_pll().expect("failed to run main DCXO PLL");
tag_collector::clear_phase_det_ready();
}
clear_pending(interrupt);
}
pub fn helper_pll() -> Result<(), &'static str> {
let period_err = get_beating_period_error();
let period_err = tag_collector::get_period_error();
const H_KP: i32 = 2;
const H_KI: f32 = 0.5;
@ -462,45 +563,43 @@ pub mod wrpll {
h_adpll = h_adpll.clamp(-ADPLL_MAX, ADPLL_MAX);
set_adpll(i2c::DCXO::Helper, h_adpll)?;
unsafe {
// clear the asserted interrupt
csr::wrpll::period_ev_pending_write(1);
}
Ok(())
}
pub fn main_pll() -> Result<(), &'static str> {
let phase_err = get_phase_error();
let phase_err = tag_collector::get_phase_error();
const M_KP: i32 = 12;
const M_KI: i32 = 2;
let mut m_adpll: i32;
unsafe {
m_adpll = BASE_ADPLL + phase_err * M_KP;
M_INTEGRATOR += phase_err * M_KI;
m_adpll = BASE_ADPLL + phase_err * M_KP + M_INTEGRATOR;
}
m_adpll = m_adpll.clamp(-ADPLL_MAX, ADPLL_MAX);
set_adpll(i2c::DCXO::Main, m_adpll)?;
unsafe {
// clear the asserted interrupt
csr::wrpll::phase_ev_pending_write(1);
}
Ok(())
}
pub fn select_recovered_clock(rc: bool, timer: &mut GlobalTimer) {
set_wrpll_interrupt(false);
reset_plls().expect("failed to reset main and helper PLL");
set_irq(false);
if rc {
tag_collector::reset();
reset_plls().expect("failed to reset main and helper PLL");
info!("warming up GTX CDR...");
// gtx need a couple seconds for freq counter to read it properly
timer.delay_us(20_000_000);
set_base_adpll(timer).expect("failed to set base adpll");
set_wrpll_interrupt(true);
// clear gateware pending flag
clear_pending(IRQ::GTXTag);
clear_pending(IRQ::MainTag);
set_irq(true);
info!("WRPLL interrupt enabled");
}
}

View File

@ -23,13 +23,13 @@ interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, {
0 => match id.0 {
61 => {
#[cfg(has_wrpll)]
si549::wrpll::helper_pll().expect("failed to run helper DCXO PLL");
si549::wrpll::interrupt_handler(si549::wrpll::IRQ::GTXTag);
gic.end_interrupt(id);
return;
}
62 => {
#[cfg(has_wrpll)]
si549::wrpll::main_pll().expect("failed to run main DCXO PLL");
si549::wrpll::interrupt_handler(si549::wrpll::IRQ::MainTag);
gic.end_interrupt(id);
return;
}

View File

@ -807,7 +807,7 @@ pub extern "C" fn main_core0() -> i32 {
#[cfg(has_wrpll)]
{
si549::wrpll::helper_setup(&mut timer).expect("cannot initialize helper Si549");
si549::wrpll::wrpll_interrupt_setup(&mut interrupt_controller);
si549::wrpll::interrupt_setup(&mut interrupt_controller);
}
#[cfg(has_drtio_routing)]