Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gateware/src/rs/hal/src/dma_framebuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ macro_rules! impl_dma_framebuffer {
fn draw_line_solid(&mut self, start_x: i32, start_y: i32, end_x: i32, end_y: i32,
stroke_width: u32, color: Self::Color) -> bool {

return false;

// TODO: Check bounds? Bresenham hardware might do wierd stuff
// or stall forever if the line endpoints are off the screen...

Expand Down
10 changes: 5 additions & 5 deletions gateware/src/tiliqua/tiliqua_soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def __init__(self, *, firmware_bin_path, ui_name, ui_tag, platform_class, clock_

# Pixel plotting, blending, rotation backend (no CSR interface)
self.framebuffer_plotter = plot.FramebufferPlotter(
bus_signature=self.psram_periph.bus.signature.flip(), n_ports=3)
bus_signature=self.psram_periph.bus.signature.flip(), n_ports=2)
self.psram_periph.add_master(self.framebuffer_plotter.bus)

# Pixel plotter CSR interface
Expand Down Expand Up @@ -356,12 +356,12 @@ def elaborate(self, platform):
m.submodules.pixel_plot = self.pixel_plot
m.submodules.framebuffer_plotter = self.framebuffer_plotter
m.submodules.blit = self.blit
m.submodules.line = self.line
#m.submodules.line = self.line

# Connect peripherals to plotter ports
wiring.connect(m, self.pixel_plot.o, self.framebuffer_plotter.i[0])
wiring.connect(m, self.blit.o, self.framebuffer_plotter.i[1])
wiring.connect(m, self.line.o, self.framebuffer_plotter.i[2])
#wiring.connect(m, self.line.o, self.framebuffer_plotter.i[2])

# Connect static/dynamic framebuffer properties to components that need them
if self.clock_settings.modeline:
Expand Down Expand Up @@ -393,7 +393,7 @@ def elaborate(self, platform):
wiring.connect(m, self.pmod0.pins, pmod0_provider.pins)

# die temperature
m.submodules.dtr0 = self.dtr0
# m.submodules.dtr0 = self.dtr0

# generate our domain clocks/resets
m.submodules.car = car = platform.clock_domain_generator(self.clock_settings)
Expand All @@ -409,7 +409,7 @@ def elaborate(self, platform):
m.d.comb += platform.request("mobo_leds_oe").o.eq(1),

# Connect encoder button to RebootProvider
m.submodules.reboot = reboot = RebootProvider(self.clock_settings.frequencies.sync)
m.submodules.reboot = self.reboot = reboot = RebootProvider(self.clock_settings.frequencies.sync)
m.d.comb += reboot.button.eq(self.encoder0._button.f.button.r_data)
m.d.comb += self.pmod0_periph.mute.eq(reboot.mute)
else:
Expand Down
23 changes: 10 additions & 13 deletions gateware/src/tiliqua/usb_audio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def __init__(self):
def __init__(self, *, audio_clock: pll.AudioClock, nr_channels):
self.fs = 192000 if audio_clock.is_192khz() else 48000
self.nr_channels = nr_channels
self.channel_config = (1 << nr_channels) - 1
self.max_packet_size = int(32 * (self.fs // 48000) * self.nr_channels)
super().__init__({
"i": In(stream.Signature(data.ArrayLayout(eurorack_pmod.ASQ, self.nr_channels))),
Expand All @@ -83,8 +84,8 @@ def create_descriptors(self):

d.iManufacturer = "apf.audio"
d.iProduct = "Tiliqua"
d.iSerialNumber = "beta-0000"
d.bcdDevice = 0.01
d.iSerialNumber = "xbeam-ex0"
d.bcdDevice = 0.02

d.bNumConfigurations = 1

Expand Down Expand Up @@ -125,11 +126,8 @@ def create_audio_control_interface_descriptor(self):
inputTerminal = uac2.InputTerminalDescriptorEmitter()
inputTerminal.bTerminalID = 2
inputTerminal.wTerminalType = uac2.USBTerminalTypes.USB_STREAMING
# The number of channels needs to be 2 here in order to be recognized
# default audio out device by Windows. We provide an alternate
# setting with the full channel count, which also references
# this terminal ID
inputTerminal.bNrChannels = self.nr_channels
inputTerminal.bmChannelConfig = self.channel_config
inputTerminal.bCSourceID = 1
audioControlInterface.add_subordinate_descriptor(inputTerminal)

Expand All @@ -146,6 +144,7 @@ def create_audio_control_interface_descriptor(self):
inputTerminal.bTerminalID = 4
inputTerminal.wTerminalType = uac2.InputTerminalTypes.MICROPHONE
inputTerminal.bNrChannels = self.nr_channels
inputTerminal.bmChannelConfig = self.channel_config
inputTerminal.bCSourceID = 1
audioControlInterface.add_subordinate_descriptor(inputTerminal)

Expand Down Expand Up @@ -174,6 +173,7 @@ def create_output_streaming_interface(self, c, *, nr_channels, alt_setting_nr):
audioStreamingInterface.bFormatType = uac2.FormatTypes.FORMAT_TYPE_I
audioStreamingInterface.bmFormats = uac2.TypeIFormats.PCM
audioStreamingInterface.bNrChannels = nr_channels
audioStreamingInterface.bmChannelConfig = self.channel_config
c.add_subordinate_descriptor(audioStreamingInterface)

# AudioStreaming Interface Descriptor (Type I)
Expand Down Expand Up @@ -216,13 +216,10 @@ def create_output_channels_descriptor(self, c):
quietAudioStreamingInterface.bAlternateSetting = 0
c.add_subordinate_descriptor(quietAudioStreamingInterface)

# we need the default alternate setting to be stereo
# out for windows to automatically recognize
# and use this audio interface
self.create_output_streaming_interface(c, nr_channels=self.nr_channels, alt_setting_nr=1)


def create_input_streaming_interface(self, c, *, nr_channels, alt_setting_nr, channel_config=0):
def create_input_streaming_interface(self, c, *, nr_channels, alt_setting_nr):
# Interface Descriptor (Streaming, IN, active setting)
activeAudioStreamingInterface = uac2.AudioStreamingInterfaceDescriptorEmitter()
activeAudioStreamingInterface.bInterfaceNumber = 2
Expand All @@ -236,7 +233,7 @@ def create_input_streaming_interface(self, c, *, nr_channels, alt_setting_nr, ch
audioStreamingInterface.bFormatType = uac2.FormatTypes.FORMAT_TYPE_I
audioStreamingInterface.bmFormats = uac2.TypeIFormats.PCM
audioStreamingInterface.bNrChannels = nr_channels
audioStreamingInterface.bmChannelConfig = channel_config
audioStreamingInterface.bmChannelConfig = self.channel_config
c.add_subordinate_descriptor(audioStreamingInterface)

# AudioStreaming Interface Descriptor (Type I)
Expand Down Expand Up @@ -269,8 +266,8 @@ def create_input_channels_descriptor(self, c):
quietAudioStreamingInterface.bAlternateSetting = 0
c.add_subordinate_descriptor(quietAudioStreamingInterface)

# Windows wants a stereo pair as default setting, so let's have it
self.create_input_streaming_interface(c, nr_channels=self.nr_channels, alt_setting_nr=1, channel_config=0x3)
self.create_input_streaming_interface(c, nr_channels=self.nr_channels, alt_setting_nr=1)


def elaborate(self, platform):
m = Module()
Expand Down
12 changes: 12 additions & 0 deletions gateware/src/top/xbeam/fw/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
fn main() {
println!("cargo::rustc-check-cfg=cfg(expander_ex0)");
println!("cargo::rustc-check-cfg=cfg(expander_ex1)");
if std::env::var("TILIQUA_EXPANDER_EX0").ok().as_deref() == Some("1") {
println!("cargo:rustc-cfg=expander_ex0");
}
if std::env::var("TILIQUA_EXPANDER_EX1").ok().as_deref() == Some("1") {
println!("cargo:rustc-cfg=expander_ex1");
}
println!("cargo:rerun-if-env-changed=TILIQUA_EXPANDER_EX0");
println!("cargo:rerun-if-env-changed=TILIQUA_EXPANDER_EX1");
}
20 changes: 20 additions & 0 deletions gateware/src/top/xbeam/fw/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@ pub use tiliqua_hal as hal;

hal::impl_tiliqua_soc_pac!();

#[cfg(expander_ex0)]
hal::impl_i2c! {
I2cEx0: pac::I2C2,
}

#[cfg(expander_ex0)]
hal::impl_eurorack_pmod! {
EurorackPmodEx0: pac::EX0_PMOD_PERIPH,
}

#[cfg(expander_ex1)]
hal::impl_i2c! {
I2cEx1: pac::I2C3,
}

#[cfg(expander_ex1)]
hal::impl_eurorack_pmod! {
EurorackPmodEx1: pac::EX1_PMOD_PERIPH,
}

hal::impl_scope! {
Scope0: pac::SCOPE_PERIPH,
}
Expand Down
41 changes: 27 additions & 14 deletions gateware/src/top/xbeam/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use core::cell::RefCell;

use tiliqua_fw::*;
use tiliqua_lib::*;
use tiliqua_lib::dsp::OnePoleSmoother;
use pac::constants::*;
use tiliqua_lib::calibration::*;

Expand Down Expand Up @@ -93,6 +92,22 @@ fn main() -> ! {
let mut pmod = EurorackPmod0::new(peripherals.PMOD0_PERIPH);
CalibrationConstants::load_or_default(&mut i2cdev1, &mut pmod);

#[cfg(expander_ex0)]
{
info!("Loading calibration for expander EX0...");
let mut i2c_ex0 = I2cEx0::new(peripherals.I2C2);
let mut ex0_pmod = EurorackPmodEx0::new(peripherals.EX0_PMOD_PERIPH);
CalibrationConstants::load_or_default(&mut i2c_ex0, &mut ex0_pmod);
}

#[cfg(expander_ex1)]
{
info!("Loading calibration for expander EX1...");
let mut i2c_ex1 = I2cEx1::new(peripherals.I2C3);
let mut ex1_pmod = EurorackPmodEx1::new(peripherals.EX1_PMOD_PERIPH);
CalibrationConstants::load_or_default(&mut i2c_ex1, &mut ex1_pmod);
}

//
// Start up TUSB322 in UFP/Device mode
//
Expand Down Expand Up @@ -126,8 +141,6 @@ fn main() -> ! {

handler!(timer0 = || timer0_handler(&app));

let mut delay_smoothers = [OnePoleSmoother::new(0.05f32); 4];

irq::scope(|s| {

s.register(handlers::Interrupt::TIMER0, timer0);
Expand Down Expand Up @@ -196,7 +209,7 @@ fn main() -> ! {
v_active,
opts.help.scroll.value,
opts.beam.ui_hue.value).ok();
persist.set_persist(128);
persist.set_persist(256);
persist.set_decay(1);
} else {
persist.set_persist(opts.beam.persist.value);
Expand Down Expand Up @@ -262,10 +275,19 @@ fn main() -> ! {
}
});

let plot_io_val: u8 = match opts.misc.plot_io.value {
PlotIO::Builtin => 0,
#[cfg(expander_ex0)]
PlotIO::Ex0 => 1,
#[cfg(expander_ex1)]
PlotIO::Ex1 => 2,
};

xbeam_mux.flags().write(
|w| { w.usb_en().bit(opts.misc.usb_mode.value == USBMode::Enable);
w.show_outputs().bit(opts.misc.plot_src.value == PlotSrc::Outputs);
w.usb_connect().bit(usb_cc_attached)
w.usb_connect().bit(usb_cc_attached);
unsafe { w.plot_io().bits(plot_io_val) }
} );

// Grid overlay style/pixel (changes with options)
Expand All @@ -281,15 +303,6 @@ fn main() -> ! {
w.grid_pixel().bits(((opts.beam.grid_i.value as u8) << 4) | opts.beam.ui_hue.value)
});

xbeam_mux.delay0().write(|w| unsafe { w.value().bits(
delay_smoothers[0].proc_u16(opts.delay.delay_x.value)) });
xbeam_mux.delay1().write(|w| unsafe { w.value().bits(
delay_smoothers[1].proc_u16(opts.delay.delay_y.value)) });
xbeam_mux.delay2().write(|w| unsafe { w.value().bits(
delay_smoothers[2].proc_u16(opts.delay.delay_i.value)) });
xbeam_mux.delay3().write(|w| unsafe { w.value().bits(
delay_smoothers[3].proc_u16(opts.delay.delay_c.value)) });

display.rotate(&opts.misc.rotation.value);


Expand Down
30 changes: 13 additions & 17 deletions gateware/src/top/xbeam/fw/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use strum_macros::{EnumIter, IntoStaticStr};
use tiliqua_lib::palette::ColorPalette;
pub use tiliqua_lib::scope::{Timebase, VScale};
use tiliqua_hal::dma_framebuffer::Rotate;
use tiliqua_pac::constants::AUDIO_FS;
use serde_derive::{Serialize, Deserialize};

#[derive(Default, Clone, Copy, PartialEq, EnumIter, IntoStaticStr, Serialize, Deserialize)]
Expand All @@ -12,7 +11,6 @@ pub enum Page {
#[default]
Help,
Vector,
Delay,
Beam,
Misc,
Scope1,
Expand Down Expand Up @@ -59,6 +57,17 @@ pub enum HelpPage {
On,
}

#[derive(Default, Clone, Copy, PartialEq, EnumIter, IntoStaticStr, Serialize, Deserialize)]
#[strum(serialize_all = "kebab-case")]
pub enum PlotIO {
#[default]
Builtin,
#[cfg(expander_ex0)]
Ex0,
#[cfg(expander_ex1)]
Ex1,
}

#[derive(Default, Clone, Copy, PartialEq, EnumIter, IntoStaticStr, Serialize, Deserialize)]
#[strum(serialize_all = "kebab-case")]
pub enum GridOverlay {
Expand All @@ -68,7 +77,6 @@ pub enum GridOverlay {
Cross,
}

int_params!(DelayParams<u16> { step: 8, min: 0, max: 512, format: IntFormat::Scaled { divisor: AUDIO_FS / 1000, precision: 1, suffix: "ms" } });
int_params!(PCScaleParams<u8> { step: 1, min: 0, max: 15 });
int_params!(PersistParams<u16> { step: 32, min: 32, max: 4096 });
int_params!(DecayParams<u8> { step: 1, min: 0, max: 15 });
Expand Down Expand Up @@ -107,18 +115,6 @@ pub struct VectorOpts {
pub c_scale: IntOption<PCScaleParams>,
}

#[derive(OptionPage, Clone)]
pub struct DelayOpts {
#[option(0)]
pub delay_x: IntOption<DelayParams>,
#[option(0)]
pub delay_y: IntOption<DelayParams>,
#[option(0)]
pub delay_i: IntOption<DelayParams>,
#[option(0)]
pub delay_c: IntOption<DelayParams>,
}

#[derive(OptionPage, Clone)]
pub struct BeamOpts {
#[option(32)]
Expand All @@ -142,6 +138,8 @@ pub struct MiscOpts {
#[option]
pub plot_src: EnumOption<PlotSrc>,
#[option]
pub plot_io: EnumOption<PlotIO>,
#[option]
pub usb_mode: EnumOption<USBMode>,
#[option]
pub rotation: EnumOption<Rotate>,
Expand Down Expand Up @@ -197,8 +195,6 @@ pub struct Opts {

#[page(Page::Vector)]
pub vector: VectorOpts,
#[page(Page::Delay)]
pub delay: DelayOpts,
#[page(Page::Beam)]
pub beam: BeamOpts,
}
Loading
Loading