cyw43-pio: add overclock feature flag.

This commit is contained in:
Dario Nieuwenhuis 2023-05-14 23:02:49 +02:00
parent 8800caa216
commit db907a914c
4 changed files with 60 additions and 31 deletions

5
ci.sh
View file

@ -1,7 +1,9 @@
#!/bin/bash #!/bin/bash
set -euxo pipefail set -euxo pipefail
cd $(dirname $0)
export CARGO_TARGET_DIR=$(pwd)/target
export DEFMT_LOG=trace export DEFMT_LOG=trace
# build examples # build examples
@ -18,3 +20,6 @@ cargo build --target thumbv6m-none-eabi --features 'log'
cargo build --target thumbv6m-none-eabi --features 'defmt' cargo build --target thumbv6m-none-eabi --features 'defmt'
cargo build --target thumbv6m-none-eabi --features 'log,firmware-logs' cargo build --target thumbv6m-none-eabi --features 'log,firmware-logs'
cargo build --target thumbv6m-none-eabi --features 'defmt,firmware-logs' cargo build --target thumbv6m-none-eabi --features 'defmt,firmware-logs'
(cd cyw43-pio; cargo build --target thumbv6m-none-eabi --features '')
(cd cyw43-pio; cargo build --target thumbv6m-none-eabi --features 'overclock')

View file

@ -3,6 +3,11 @@ name = "cyw43-pio"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[features]
# If disabled, SPI runs at 31.25MHz
# If enabled, SPI runs at 62.5MHz, which is 25% higher than 50Mhz which is the maximum according to the CYW43439 datasheet.
overclock = []
[dependencies] [dependencies]
cyw43 = { path = "../" } cyw43 = { path = "../" }
embassy-rp = { version = "0.1.0", features = ["unstable-traits", "nightly", "unstable-pac", "time-driver"] } embassy-rp = { version = "0.1.0", features = ["unstable-traits", "nightly", "unstable-pac", "time-driver"] }

View file

@ -40,24 +40,46 @@ where
DIO: PioPin, DIO: PioPin,
CLK: PioPin, CLK: PioPin,
{ {
#[cfg(feature = "overclock")]
let program = pio_asm!( let program = pio_asm!(
".side_set 1" ".side_set 1"
".wrap_target" ".wrap_target"
// write out x-1 bits // write out x-1 bits
"lp:", "lp:"
"out pins, 1 side 0" "out pins, 1 side 0"
"jmp x-- lp side 1" "jmp x-- lp side 1"
// switch directions // switch directions
"set pindirs, 0 side 0" "set pindirs, 0 side 0"
// these nops seem to be necessary for fast clkdiv "nop side 1" // necessary for clkdiv=1.
//"nop side 1" "nop side 0"
//"nop side 0"
"nop side 1"
// read in y-1 bits // read in y-1 bits
"lp2:" "lp2:"
"in pins, 1 side 0" "in pins, 1 side 1"
"jmp y-- lp2 side 1" "jmp y-- lp2 side 0"
// wait for event and irq host
"wait 1 pin 0 side 0"
"irq 0 side 0"
".wrap"
);
#[cfg(not(feature = "overclock"))]
let program = pio_asm!(
".side_set 1"
".wrap_target"
// write out x-1 bits
"lp:"
"out pins, 1 side 0"
"jmp x-- lp side 1"
// switch directions
"set pindirs, 0 side 0"
"nop side 0"
// read in y-1 bits
"lp2:"
"in pins, 1 side 1"
"jmp y-- lp2 side 0"
// wait for event and irq host // wait for event and irq host
"wait 1 pin 0 side 0" "wait 1 pin 0 side 0"
@ -72,8 +94,8 @@ where
pin_io.set_pull(Pull::None); pin_io.set_pull(Pull::None);
pin_io.set_schmitt(true); pin_io.set_schmitt(true);
pin_io.set_input_sync_bypass(true); pin_io.set_input_sync_bypass(true);
//pin_io.set_drive_strength(Drive::_12mA); pin_io.set_drive_strength(Drive::_12mA);
//pin_io.set_slew_rate(SlewRate::Fast); pin_io.set_slew_rate(SlewRate::Fast);
let mut pin_clk = common.make_pio_pin(clk); let mut pin_clk = common.make_pio_pin(clk);
pin_clk.set_drive_strength(Drive::_12mA); pin_clk.set_drive_strength(Drive::_12mA);
@ -91,27 +113,24 @@ where
cfg.shift_in.auto_fill = true; cfg.shift_in.auto_fill = true;
//cfg.shift_in.threshold = 32; //cfg.shift_in.threshold = 32;
// theoretical maximum according to data sheet, 100Mhz Pio => 50Mhz SPI Freq #[cfg(feature = "overclock")]
// seems to cause random corruption, probably due to jitter due to the fractional divider. {
// cfg.clock_divider = FixedU32::from_bits(0x0140); // 125mhz Pio => 62.5Mhz SPI Freq. 25% higher than theoretical maximum according to
// data sheet, but seems to work fine.
cfg.clock_divider = FixedU32::from_bits(0x0100);
}
// same speed as pico-sdk, 62.5Mhz #[cfg(not(feature = "overclock"))]
cfg.clock_divider = FixedU32::from_bits(0x0200); {
// same speed as pico-sdk, 62.5Mhz
// 32 Mhz // This is actually the fastest we can go without overclocking.
// cfg.clock_divider = FixedU32::from_bits(0x03E8); // According to data sheet, the theoretical maximum is 100Mhz Pio => 50Mhz SPI Freq.
// However, the PIO uses a fractional divider, which works by introducing jitter when
// 16 Mhz // the divider is not an integer. It does some clocks at 125mhz and others at 62.5mhz
// cfg.clock_divider = FixedU32::from_bits(0x07d0); // so that it averages out to the desired frequency of 100mhz. The 125mhz clock cycles
// violate the maximum from the data sheet.
// 8Mhz cfg.clock_divider = FixedU32::from_bits(0x0200);
// cfg.clock_divider = FixedU32::from_bits(0x0a_00); }
// 1Mhz
// cfg.clock_divider = FixedU32::from_bits(0x7d_00);
// slowest possible
// cfg.clock_divider = FixedU32::from_bits(0xffff_00);
sm.set_config(&cfg); sm.set_config(&cfg);

View file

@ -6,7 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
cyw43 = { path = "../../", features = ["defmt", "firmware-logs"] } cyw43 = { path = "../../", features = ["defmt", "firmware-logs"] }
cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] } cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] }
embassy-executor = { version = "0.2.0", features = ["defmt", "integrated-timers", "executor-thread", "arch-cortex-m"] } embassy-executor = { version = "0.2.0", features = ["defmt", "integrated-timers", "executor-thread", "arch-cortex-m"] }
embassy-time = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] } embassy-time = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] }
embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] } embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] }
@ -48,7 +48,7 @@ debug = 1
debug-assertions = false debug-assertions = false
incremental = false incremental = false
lto = 'fat' lto = 'fat'
opt-level = 'z' opt-level = 's'
overflow-checks = false overflow-checks = false
# do not optimize proc-macro crates = faster builds from scratch # do not optimize proc-macro crates = faster builds from scratch