@@ -800,7 +800,7 @@ impl ScanlineTimingBuffer {
800800 if vsync {
801801 value |= 1 << 1 ;
802802 }
803- value |= ( period - 6 ) << 2 ;
803+ value |= ( period - FIXED_CLOCKS_PER_TIMING_PULSE ) << 2 ;
804804 value | command << 16
805805 }
806806}
@@ -1680,6 +1680,9 @@ static PIXEL_DATA_BUFFER_ODD: LineBuffer = LineBuffer::new_odd();
16801680/// ```
16811681static TEXT_COLOUR_LOOKUP : TextColourLookup = TextColourLookup :: blank ( ) ;
16821682
1683+ /// How many fixed clock cycles there are per timing pulse.
1684+ const FIXED_CLOCKS_PER_TIMING_PULSE : u32 = 5 ;
1685+
16831686// -----------------------------------------------------------------------------
16841687// Functions
16851688// -----------------------------------------------------------------------------
@@ -1700,28 +1703,41 @@ pub fn init(
17001703 let ( mut pio, sm0, sm1, _sm2, _sm3) = pio. split ( resets) ;
17011704
17021705 // This program runs the timing loop. We post timing data (i.e. the length
1703- // of each period, along with what the H-Sync and V-Sync pins should do)
1704- // and it sets the GPIO pins and busy-waits the appropriate amount of
1705- // time. It also takes an extra 'instruction' which we can use to trigger
1706- // the appropriate interrupts.
1706+ // of each period, along with what the H-Sync and V-Sync pins should do) and
1707+ // it sets the GPIO pins and busy-waits the appropriate amount of time. It
1708+ // also takes an extra 'instruction' which we can use to trigger the
1709+ // appropriate interrupts.
1710+ //
1711+ // Note that the timing period value should be:
1712+ //
1713+ // timing_period = actual_timing_period - FIXED_CLOCKS_PER_TIMING_PULSE
1714+ //
1715+ // This is because there are unavoidable clock cycles within the algorithm.
1716+ // Currently FIXED_CLOCKS_PER_TIMING_PULSE should be set to 5.
17071717 //
17081718 // Post <value:32> where value: <clock_cycles:14> <hsync:1> <vsync:1>
17091719 // <instruction:16>
17101720 //
17111721 // The SM will execute the instruction (typically either a NOP or an IRQ),
1712- // set the H-Sync and V-Sync pins as desired, then wait the given number
1713- // of clock cycles.
1722+ // set the H-Sync and V-Sync pins as desired, then wait the given number of
1723+ // clock cycles.
17141724 //
17151725 // Note: autopull should be set to 32-bits, OSR is set to shift right.
17161726 let timing_program = pio_proc:: pio_asm!(
17171727 ".wrap_target"
1718- // Step 1. Push next 2 bits of OSR into `pins`, to set H-Sync and V-Sync
1728+ // Step 1. Push next 2 bits of OSR into `pins`, to set H-Sync and V-Sync.
1729+ // Takes 1 clock cycle.
17191730 "out pins, 2"
17201731 // Step 2. Push last 14 bits of OSR into X for the timing loop.
1732+ // Takes 1 clock cycle.
17211733 "out x, 14"
1722- // Step 3. Execute bottom 16-bits of OSR as an instruction. This take two cycles.
1734+ // Step 3. Execute bottom 16-bits of OSR as an instruction.
1735+ // This take two cycles, always.
17231736 "out exec, 16"
17241737 // Spin until X is zero
1738+ // Takes X + 1 clock cycles because the branch is conditioned on the initial value of the register.
1739+ // i.e. X = 0 => 1 clock cycle (the jmp when x = 0)
1740+ // i.e. X = 1 => 2 clock cycles (the jmp when x = 1 and again when x = 0)
17251741 "loop0:"
17261742 "jmp x-- loop0"
17271743 ".wrap"
0 commit comments