Browse Source

enhance: refine sdi print implementation

pull/36/head
Andelf 1 year ago
parent
commit
df24cbeaa3
  1. 1
      CHANGELOG.md
  2. 13
      src/commands/control.rs
  3. 19
      src/lib.rs
  4. 42
      src/main.rs
  5. 16
      src/operations.rs

1
CHANGELOG.md

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Show firmware size info when flashing
- Add a progress bar when flashing
- New chip: CH641, a RV32EC chip almost the same as CH32V003
- SDI print support, #34
### Fixed

13
src/commands/control.rs

@ -180,18 +180,19 @@ impl Command for SetPower {
}
}
/// SDI print support, only avaliable for WCH-LinkE
#[derive(Debug)]
pub enum SetSDIPrintf {
EnableSDIPrintf,
DisableSDIPrintf,
pub enum SetSDIPrint {
Enable,
Disable,
}
impl Command for SetSDIPrintf {
impl Command for SetSDIPrint {
type Response = ();
const COMMAND_ID: u8 = 0x0d;
fn payload(&self) -> Vec<u8> {
match self {
SetSDIPrintf::EnableSDIPrintf => vec![0xee, 0x00],
SetSDIPrintf::DisableSDIPrintf => vec![0xee, 0x01],
SetSDIPrint::Enable => vec![0xee, 0x00],
SetSDIPrint::Disable => vec![0xee, 0x01],
}
}
}

19
src/lib.rs

@ -52,8 +52,8 @@ impl WchLinkVariant {
matches!(self, WchLinkVariant::WCh32v208 | WchLinkVariant::ECh32v305)
}
/// Only E mode support sdi printf functionality
pub fn support_sdi_printf(&self) -> bool {
/// Only E mode support SDR print functionality
pub fn support_sdi_print(&self) -> bool {
matches!(self, WchLinkVariant::ECh32v305)
}
@ -164,6 +164,21 @@ impl RiscvChip {
)
}
pub fn support_sdi_print(&self) -> bool {
// CH641, CH643, CH32V003, CH32V103, CH32V20x, CH32V30x, CH32X035, CH32L103
matches!(
self,
RiscvChip::CH32V003
| RiscvChip::CH32V103
| RiscvChip::CH32V20X
| RiscvChip::CH32V30X
| RiscvChip::CH32X035
| RiscvChip::CH32L103
| RiscvChip::CH643
| RiscvChip::CH641
)
}
pub fn reset_command(&self) -> crate::commands::Reset {
match self {
RiscvChip::CH57X | RiscvChip::CH58X | RiscvChip::CH59X => {

42
src/main.rs

@ -116,15 +116,26 @@ enum Commands {
#[arg(long)]
dap: bool,
},
/// SDI virtual serial port, printf via the debug interface and redirect it to the serial port of the WCH-Link.
SDIPrintf {
/// Disable sdi printf functionality.
#[arg(long, default_value = "false")]
no_sdi_printf: bool,
},
/// SDI virtual serial port,
#[command(subcommand)]
SDIPrint(SDIPrint),
Dev {},
}
#[derive(clap::Subcommand, PartialEq, Clone, Copy, Debug)]
pub enum SDIPrint {
/// Enable SDI print, implies --no-detach
Enable,
/// Disable SDI print
Disable,
}
impl SDIPrint {
pub fn is_enable(&self) -> bool {
*self == SDIPrint::Enable
}
}
fn main() -> Result<()> {
use Commands::*;
@ -155,6 +166,7 @@ fn main() -> Result<()> {
}
let device_index = cli.device.unwrap_or(0);
let mut will_detach = !cli.no_detach;
match cli.command {
None => {
@ -366,23 +378,25 @@ fn main() -> Result<()> {
let cpbr = probe.dmi_read(0x7E)?;
log::info!("cpbr: {:#x?}", cpbr);
}
SDIPrintf { no_sdi_printf } => {
// By enabling sdi printf and modifying the _write function called by printf in the mcu code,
SDIPrint(v) => {
// By enabling SDI print and modifying the _write function called by printf in the mcu code,
// the WCH-Link can be used to read data from the debug interface of the mcu
// and print it to the serial port of the WCH-Link instead of using its UART peripheral.
// An example can be found here:
// https://github.com/openwch/ch32v003/tree/main/EVT/EXAM/SDI_Printf/SDI_Printf
if no_sdi_printf {
log::info!("Disabling sdi printf functionality.");
probe.enable_sdi_printf(false)?;
if v.is_enable() {
log::info!("Enabling SDI print");
probe.enable_sdi_print(true)?;
will_detach = false;
log::info!("Now you can connect to the WCH-Link serial port");
} else {
log::info!("Enabling sdi printf functionality.");
probe.enable_sdi_printf(true)?;
log::info!("Disabling SDI print");
probe.enable_sdi_print(false)?;
}
}
_ => unreachable!("unimplemented command"),
}
if !cli.no_detach {
if will_detach {
probe.detach_chip()?;
}
}

16
src/operations.rs

@ -177,20 +177,24 @@ impl WchLink {
Ok(())
}
pub fn enable_sdi_printf(&mut self, enable: bool) -> Result<()> {
if !self.probe.as_ref().unwrap().variant.support_sdi_printf() {
pub fn enable_sdi_print(&mut self, enable: bool) -> Result<()> {
if !self.probe.as_ref().unwrap().variant.support_sdi_print() {
return Err(Error::Custom(
"Probe doesn't support sdi printf functionality".to_string(),
));
}
if !self.chip.as_ref().unwrap().chip_family.support_sdi_print() {
return Err(Error::Custom(
"Chip doesn't support sdi printf functionality".to_string(),
));
}
if enable {
self.send_command(commands::control::SetSDIPrintf::EnableSDIPrintf)?;
Ok(())
self.send_command(control::SetSDIPrint::Enable)?;
} else {
self.send_command(commands::control::SetSDIPrintf::DisableSDIPrintf)?;
Ok(())
self.send_command(control::SetSDIPrint::Disable)?;
}
Ok(())
}
// wlink_endprocess

Loading…
Cancel
Save