@@ -211,18 +211,12 @@ static VIDEO_MODE: AtomicModeWrapper = AtomicModeWrapper::new(crate::common::vid
211211/// `0..TIMING_BUFFER.back_porch_ends_at`.
212212///
213213/// Set by the PIO IRQ.
214- static NEXT_TIMING_LINE : AtomicU16 = AtomicU16 :: new ( 0 ) ;
214+ static NEXT_SCAN_LINE : AtomicU16 = AtomicU16 :: new ( 0 ) ;
215215
216- /// Tracks which scan-line we are currently drawing.
217- ///
218- /// This is for pixel drawing purposes, therefore it goes from
219- /// `0..num_visible_lines`, or `u16::MAX` when nothing should be drawn right
220- /// now.
221- ///
222- /// We draw one ahead of the one being played out.
216+ /// Indicates that we should draw the current scan-line given by [`NEXT_SCAN_LINE`].
223217///
224218/// Set by the PIO IRQ.
225- static CURRENT_DISPLAY_LINE : AtomicU16 = AtomicU16 :: new ( u16 :: MAX ) ;
219+ static DRAW_THIS_LINE : AtomicBool = AtomicBool :: new ( false ) ;
226220
227221/// DMA channel for the timing FIFO
228222const TIMING_DMA_CHAN : usize = 0 ;
@@ -1203,7 +1197,7 @@ pub fn test_video_mode(mode: crate::common::video::Mode) -> bool {
12031197
12041198/// Get the current scan line.
12051199pub fn get_scan_line ( ) -> u16 {
1206- CURRENT_DISPLAY_LINE . load ( Ordering :: Relaxed )
1200+ NEXT_SCAN_LINE . load ( Ordering :: Relaxed )
12071201}
12081202
12091203/// Get how many visible lines there currently are
@@ -1240,15 +1234,14 @@ unsafe extern "C" fn core1_main() -> u32 {
12401234 crate :: pac:: NVIC :: unmask ( crate :: pac:: Interrupt :: PIO0_IRQ_1 ) ;
12411235
12421236 loop {
1243- // Wait for a free DMA buffer
1244- let this_line = loop {
1245- let attempt = CURRENT_DISPLAY_LINE . load ( Ordering :: Relaxed ) ;
1246- if attempt != u16:: MAX {
1247- break attempt;
1248- }
1237+ // Wait for a free DMA buffer. Can't do a compare-and-swap on ARMv6-M :/
1238+ while !DRAW_THIS_LINE . load ( Ordering :: Acquire ) {
12491239 cortex_m:: asm:: wfe ( ) ;
1250- } ;
1251- CURRENT_DISPLAY_LINE . store ( u16:: MAX , Ordering :: Relaxed ) ;
1240+ }
1241+ DRAW_THIS_LINE . store ( false , Ordering :: Relaxed ) ;
1242+
1243+ // The one we draw *now* is the one that is *shown* next
1244+ let this_line = NEXT_SCAN_LINE . load ( Ordering :: Relaxed ) ;
12521245
12531246 if this_line == 0 {
12541247 video. frame_start ( ) ;
@@ -1287,7 +1280,7 @@ unsafe fn PIO0_IRQ_1() {
12871280 pio. irq . write_with_zero ( |w| w. irq ( ) . bits ( 1 << 1 ) ) ;
12881281
12891282 // This is now the line we are currently playing
1290- let current_timing_line = NEXT_TIMING_LINE . load ( Ordering :: Relaxed ) ;
1283+ let current_timing_line = NEXT_SCAN_LINE . load ( Ordering :: Relaxed ) ;
12911284 // This is the line we should cue up to play next
12921285 let next_timing_line = if current_timing_line == TIMING_BUFFER . back_porch_ends_at {
12931286 // Wrap around
@@ -1317,11 +1310,14 @@ unsafe fn PIO0_IRQ_1() {
13171310 // portion.
13181311 }
13191312
1313+ // Set this before we set the `DRAW_THIS_LINE` flag.
1314+ NEXT_SCAN_LINE . store ( next_timing_line, Ordering :: Relaxed ) ;
1315+
13201316 // Work out what sort of sync pulses we need on the *next* scan-line, and
13211317 // also tell the main thread what to draw ready for the *next* scan-line.
13221318 let buffer = if next_timing_line <= TIMING_BUFFER . visible_lines_ends_at {
13231319 // A visible line is *up next* so start drawing it *right now*.
1324- CURRENT_DISPLAY_LINE . store ( next_timing_line , Ordering :: Relaxed ) ;
1320+ DRAW_THIS_LINE . store ( true , Ordering :: Release ) ;
13251321 & TIMING_BUFFER . visible_line
13261322 } else if next_timing_line <= TIMING_BUFFER . front_porch_end_at {
13271323 // VGA front porch before VGA sync pulse
@@ -1339,8 +1335,6 @@ unsafe fn PIO0_IRQ_1() {
13391335 dma. ch [ TIMING_DMA_CHAN ]
13401336 . ch_al3_read_addr_trig
13411337 . write ( |w| w. bits ( buffer as * const _ as usize as u32 ) ) ;
1342-
1343- NEXT_TIMING_LINE . store ( next_timing_line, Ordering :: SeqCst ) ;
13441338}
13451339
13461340impl RenderEngine {
0 commit comments