@@ -936,7 +936,7 @@ impl ScanlineTimingBuffer {
936936 if vsync {
937937 value |= 1 << 1 ;
938938 }
939- value |= ( period - 6 ) << 2 ;
939+ value |= ( period - FIXED_CLOCKS_PER_TIMING_PULSE ) << 2 ;
940940 value | command << 16
941941 }
942942}
@@ -1754,6 +1754,9 @@ static PIXEL_DATA_BUFFER_ODD: LineBuffer = LineBuffer::new_odd();
17541754/// ```
17551755static TEXT_COLOUR_LOOKUP : TextColourLookup = TextColourLookup :: blank ( ) ;
17561756
1757+ /// How many fixed clock cycles there are per timing pulse.
1758+ const FIXED_CLOCKS_PER_TIMING_PULSE : u32 = 5 ;
1759+
17571760// -----------------------------------------------------------------------------
17581761// Functions
17591762// -----------------------------------------------------------------------------
@@ -1774,28 +1777,41 @@ pub fn init(
17741777 let ( mut pio, sm0, sm1, _sm2, _sm3) = pio. split ( resets) ;
17751778
17761779 // This program runs the timing loop. We post timing data (i.e. the length
1777- // of each period, along with what the H-Sync and V-Sync pins should do)
1778- // and it sets the GPIO pins and busy-waits the appropriate amount of
1779- // time. It also takes an extra 'instruction' which we can use to trigger
1780- // the appropriate interrupts.
1780+ // of each period, along with what the H-Sync and V-Sync pins should do) and
1781+ // it sets the GPIO pins and busy-waits the appropriate amount of time. It
1782+ // also takes an extra 'instruction' which we can use to trigger the
1783+ // appropriate interrupts.
1784+ //
1785+ // Note that the timing period value should be:
1786+ //
1787+ // timing_period = actual_timing_period - FIXED_CLOCKS_PER_TIMING_PULSE
1788+ //
1789+ // This is because there are unavoidable clock cycles within the algorithm.
1790+ // Currently FIXED_CLOCKS_PER_TIMING_PULSE should be set to 5.
17811791 //
17821792 // Post <value:32> where value: <clock_cycles:14> <hsync:1> <vsync:1>
17831793 // <instruction:16>
17841794 //
17851795 // The SM will execute the instruction (typically either a NOP or an IRQ),
1786- // set the H-Sync and V-Sync pins as desired, then wait the given number
1787- // of clock cycles.
1796+ // set the H-Sync and V-Sync pins as desired, then wait the given number of
1797+ // clock cycles.
17881798 //
17891799 // Note: autopull should be set to 32-bits, OSR is set to shift right.
17901800 let timing_program = pio_proc:: pio_asm!(
17911801 ".wrap_target"
1792- // Step 1. Push next 2 bits of OSR into `pins`, to set H-Sync and V-Sync
1802+ // Step 1. Push next 2 bits of OSR into `pins`, to set H-Sync and V-Sync.
1803+ // Takes 1 clock cycle.
17931804 "out pins, 2"
17941805 // Step 2. Push last 14 bits of OSR into X for the timing loop.
1806+ // Takes 1 clock cycle.
17951807 "out x, 14"
1796- // Step 3. Execute bottom 16-bits of OSR as an instruction. This take two cycles.
1808+ // Step 3. Execute bottom 16-bits of OSR as an instruction.
1809+ // This take two cycles, always.
17971810 "out exec, 16"
17981811 // Spin until X is zero
1812+ // Takes X + 1 clock cycles because the branch is conditioned on the initial value of the register.
1813+ // i.e. X = 0 => 1 clock cycle (the jmp when x = 0)
1814+ // i.e. X = 1 => 2 clock cycles (the jmp when x = 1 and again when x = 0)
17991815 "loop0:"
18001816 "jmp x-- loop0"
18011817 ".wrap"
0 commit comments