diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-05-14 23:02:49 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-05-14 23:02:49 +0200 |
| commit | db907a914c7e84176a15da70385af871c9b97cf6 (patch) | |
| tree | 7662420e7adf863ce061eda537c0e694afabb4e1 /cyw43-pio/src | |
| parent | 8800caa216f2c90b7d998280a54dddf14e97e318 (diff) | |
cyw43-pio: add `overclock` feature flag.
Diffstat (limited to 'cyw43-pio/src')
| -rw-r--r-- | cyw43-pio/src/lib.rs | 77 |
1 files changed, 48 insertions, 29 deletions
diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs index 2c17b151a..dca30c74d 100644 --- a/cyw43-pio/src/lib.rs +++ b/cyw43-pio/src/lib.rs | |||
| @@ -40,24 +40,46 @@ where | |||
| 40 | DIO: PioPin, | 40 | DIO: PioPin, |
| 41 | CLK: PioPin, | 41 | CLK: PioPin, |
| 42 | { | 42 | { |
| 43 | #[cfg(feature = "overclock")] | ||
| 43 | let program = pio_asm!( | 44 | let program = pio_asm!( |
| 44 | ".side_set 1" | 45 | ".side_set 1" |
| 45 | 46 | ||
| 46 | ".wrap_target" | 47 | ".wrap_target" |
| 47 | // write out x-1 bits | 48 | // write out x-1 bits |
| 48 | "lp:", | 49 | "lp:" |
| 49 | "out pins, 1 side 0" | 50 | "out pins, 1 side 0" |
| 50 | "jmp x-- lp side 1" | 51 | "jmp x-- lp side 1" |
| 51 | // switch directions | 52 | // switch directions |
| 52 | "set pindirs, 0 side 0" | 53 | "set pindirs, 0 side 0" |
| 53 | // these nops seem to be necessary for fast clkdiv | 54 | "nop side 1" // necessary for clkdiv=1. |
| 54 | //"nop side 1" | 55 | "nop side 0" |
| 55 | //"nop side 0" | ||
| 56 | "nop side 1" | ||
| 57 | // read in y-1 bits | 56 | // read in y-1 bits |
| 58 | "lp2:" | 57 | "lp2:" |
| 59 | "in pins, 1 side 0" | 58 | "in pins, 1 side 1" |
| 60 | "jmp y-- lp2 side 1" | 59 | "jmp y-- lp2 side 0" |
| 60 | |||
| 61 | // wait for event and irq host | ||
| 62 | "wait 1 pin 0 side 0" | ||
| 63 | "irq 0 side 0" | ||
| 64 | |||
| 65 | ".wrap" | ||
| 66 | ); | ||
| 67 | #[cfg(not(feature = "overclock"))] | ||
| 68 | let program = pio_asm!( | ||
| 69 | ".side_set 1" | ||
| 70 | |||
| 71 | ".wrap_target" | ||
| 72 | // write out x-1 bits | ||
| 73 | "lp:" | ||
| 74 | "out pins, 1 side 0" | ||
| 75 | "jmp x-- lp side 1" | ||
| 76 | // switch directions | ||
| 77 | "set pindirs, 0 side 0" | ||
| 78 | "nop side 0" | ||
| 79 | // read in y-1 bits | ||
| 80 | "lp2:" | ||
| 81 | "in pins, 1 side 1" | ||
| 82 | "jmp y-- lp2 side 0" | ||
| 61 | 83 | ||
| 62 | // wait for event and irq host | 84 | // wait for event and irq host |
| 63 | "wait 1 pin 0 side 0" | 85 | "wait 1 pin 0 side 0" |
| @@ -72,8 +94,8 @@ where | |||
| 72 | pin_io.set_pull(Pull::None); | 94 | pin_io.set_pull(Pull::None); |
| 73 | pin_io.set_schmitt(true); | 95 | pin_io.set_schmitt(true); |
| 74 | pin_io.set_input_sync_bypass(true); | 96 | pin_io.set_input_sync_bypass(true); |
| 75 | //pin_io.set_drive_strength(Drive::_12mA); | 97 | pin_io.set_drive_strength(Drive::_12mA); |
| 76 | //pin_io.set_slew_rate(SlewRate::Fast); | 98 | pin_io.set_slew_rate(SlewRate::Fast); |
| 77 | 99 | ||
| 78 | let mut pin_clk = common.make_pio_pin(clk); | 100 | let mut pin_clk = common.make_pio_pin(clk); |
| 79 | pin_clk.set_drive_strength(Drive::_12mA); | 101 | pin_clk.set_drive_strength(Drive::_12mA); |
| @@ -91,27 +113,24 @@ where | |||
| 91 | cfg.shift_in.auto_fill = true; | 113 | cfg.shift_in.auto_fill = true; |
| 92 | //cfg.shift_in.threshold = 32; | 114 | //cfg.shift_in.threshold = 32; |
| 93 | 115 | ||
| 94 | // theoretical maximum according to data sheet, 100Mhz Pio => 50Mhz SPI Freq | 116 | #[cfg(feature = "overclock")] |
| 95 | // seems to cause random corruption, probably due to jitter due to the fractional divider. | 117 | { |
| 96 | // cfg.clock_divider = FixedU32::from_bits(0x0140); | 118 | // 125mhz Pio => 62.5Mhz SPI Freq. 25% higher than theoretical maximum according to |
| 97 | 119 | // data sheet, but seems to work fine. | |
| 98 | // same speed as pico-sdk, 62.5Mhz | 120 | cfg.clock_divider = FixedU32::from_bits(0x0100); |
| 99 | cfg.clock_divider = FixedU32::from_bits(0x0200); | 121 | } |
| 100 | |||
| 101 | // 32 Mhz | ||
| 102 | // cfg.clock_divider = FixedU32::from_bits(0x03E8); | ||
| 103 | |||
| 104 | // 16 Mhz | ||
| 105 | // cfg.clock_divider = FixedU32::from_bits(0x07d0); | ||
| 106 | |||
| 107 | // 8Mhz | ||
| 108 | // cfg.clock_divider = FixedU32::from_bits(0x0a_00); | ||
| 109 | |||
| 110 | // 1Mhz | ||
| 111 | // cfg.clock_divider = FixedU32::from_bits(0x7d_00); | ||
| 112 | 122 | ||
| 113 | // slowest possible | 123 | #[cfg(not(feature = "overclock"))] |
| 114 | // cfg.clock_divider = FixedU32::from_bits(0xffff_00); | 124 | { |
| 125 | // same speed as pico-sdk, 62.5Mhz | ||
| 126 | // This is actually the fastest we can go without overclocking. | ||
| 127 | // According to data sheet, the theoretical maximum is 100Mhz Pio => 50Mhz SPI Freq. | ||
| 128 | // However, the PIO uses a fractional divider, which works by introducing jitter when | ||
| 129 | // the divider is not an integer. It does some clocks at 125mhz and others at 62.5mhz | ||
| 130 | // so that it averages out to the desired frequency of 100mhz. The 125mhz clock cycles | ||
| 131 | // violate the maximum from the data sheet. | ||
| 132 | cfg.clock_divider = FixedU32::from_bits(0x0200); | ||
| 133 | } | ||
| 115 | 134 | ||
| 116 | sm.set_config(&cfg); | 135 | sm.set_config(&cfg); |
| 117 | 136 | ||
