From a1f5c7669aa274f148157947cdb7c94459e23777 Mon Sep 17 00:00:00 2001 From: aquaticus <1891400+aquaticus@users.noreply.github.com> Date: Tue, 3 May 2022 21:13:45 +0200 Subject: [PATCH] BUGFIX: NTSC vsync and number of scanlines --- include/video.h | 5 ++- video.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/include/video.h b/include/video.h index 21cb8e8..07fbd00 100644 --- a/include/video.h +++ b/include/video.h @@ -35,9 +35,12 @@ along with this program. If not, see . typedef enum _VIDEO_MODE { VIDEO_MODE_PAL, ///< PAL, typically Europe 50 frames/second, max 625 scan lines. 14.75MHz or 7.375 MHz. - VIDEO_MODE_NTSC, ///< NTSC, typically USA and Japan, 60 frames/second, max 525 scan lines. 12.273 or or 6.136 MHz. VIDEO_MODE_PAL_BT601, ///< As \c VIDEO_MODE_PAL but using 13.5 or 6.75 MHz. + // put mode PAL modes here + + VIDEO_MODE_NTSC, ///< NTSC, typically USA and Japan, 60 frames/second, max 525 scan lines. 12.273 or or 6.136 MHz. VIDEO_MODE_NTSC_BT601, ///< As \c VIDEO_MODE_NTSC but using 13.5 or 6.75 MHz. + // put more NTSC modes here } VIDEO_MODE; /** diff --git a/video.c b/video.c index a926b79..d57d9a8 100644 --- a/video.c +++ b/video.c @@ -117,7 +117,7 @@ EventGroupHandle_t g_video_event_group=NULL; DRAM_ATTR volatile VIDEO_SIGNAL_PARAMS g_video_signal; -static inline IRAM_ATTR void render_scan_line(void) __attribute__((always_inline)); +static inline IRAM_ATTR void pal_render_scan_line(void) __attribute__((always_inline)); static inline IRAM_ATTR void signal_vertical_sync_line(VSYNC_PULSE_LENGTH first_pulse, VSYNC_PULSE_LENGTH second_pulse) __attribute__((always_inline)); static void IRAM_ATTR i2s_interrupt(void *dma_buffer_size_bytes); static void setup_video_dac(void); @@ -794,7 +794,7 @@ static void IRAM_ATTR render_pixels_grey_1bpp(void) } } -static inline IRAM_ATTR void render_scan_line(void) +static inline IRAM_ATTR void pal_render_scan_line(void) { static bool even_frame = true; @@ -872,6 +872,79 @@ static inline IRAM_ATTR void render_scan_line(void) } } +static inline IRAM_ATTR void ntsc_render_scan_line(void) +{ + static bool first_field = true; + + if( 0 == g_current_scan_line ) + { + first_field = !first_field; +#if CONFIG_VIDEO_TRIGGER_MODE_FIELD + DIAG_PIN_HI(); +#endif + xEventGroupClearBits( g_video_event_group, + COMPOSITE_EVENT_FRAME_END_BIT | + COMPOSITE_EVENT_FRAME_VISIBLE_END_BIT + ); + } + + g_current_scan_line++; + +#if CONFIG_VIDEO_TRIGGER_MODE_LINE + DIAG_PIN_HI(); +#endif + + if( g_current_scan_line <= 3) // lines 1,2,3 + { + signal_vertical_sync_line(VSYNC_PULSE_SHORT,VSYNC_PULSE_SHORT); + } + else if( g_current_scan_line <= 6 ) //line 4,5,6 + { + signal_vertical_sync_line(VSYNC_PULSE_LONG,VSYNC_PULSE_LONG); + } + else if( g_current_scan_line <= 9) // lines 7,8,9 + { + signal_vertical_sync_line(VSYNC_PULSE_SHORT,VSYNC_PULSE_SHORT); + } + else if( g_current_scan_line < g_video_signal.offset_y_lines ) + { + signal_blank_line(); + } + else if (g_current_scan_line < g_video_signal.offset_y_lines+g_video_signal.height_pixels) + { + PIXEL_STOPWATCH_START(); + signal_blank_line(); + g_video_signal.pixel_render_func(); + PIXEL_STOPWATCH_STOP(); + } + else if( g_current_scan_line < g_video_signal.number_of_lines ) + { + if( g_current_scan_line == g_video_signal.offset_y_lines+g_video_signal.height_pixels && first_field ) + { + // All visible lines passed + xEventGroupSetBits(g_video_event_group, COMPOSITE_EVENT_FRAME_VISIBLE_END_BIT); + } + + signal_blank_line(); + } + +#if CONFIG_VIDEO_TRIGGER_MODE_LINE + DIAG_PIN_LO(); +#endif + + if( g_current_scan_line >= g_video_signal.number_of_lines ) + { +#if CONFIG_VIDEO_TRIGGER_MODE_FIELD + DIAG_PIN_LO(); +#endif + g_current_scan_line=0; + if( !first_field ) + { + xEventGroupSetBits(g_video_event_group, COMPOSITE_EVENT_FRAME_END_BIT); + } + } +} + static void IRAM_ATTR i2s_interrupt(void *dma_buffer_size_bytes) { if (I2S0.int_st.out_eof) @@ -881,8 +954,11 @@ static void IRAM_ATTR i2s_interrupt(void *dma_buffer_size_bytes) #endif INTERRUPT_STOPWATCH_START(); - render_scan_line(); - + if( g_video_signal.video_mode >= VIDEO_MODE_NTSC ) + ntsc_render_scan_line(); + else + pal_render_scan_line(); + INTERRUPT_STOPWATCH_STOP(); #if CONFIG_VIDEO_TRIGGER_MODE_ISR DIAG_PIN_LO();