Porównaj commity

...

3 Commity

Autor SHA1 Wiadomość Data
graham sanderson b5887f6baa minor scanvideo_dpi fixes 2022-03-04 16:27:59 -06:00
graham sanderson ba944492c9 remove misleading printf from i2s audio 2022-03-04 16:27:34 -06:00
graham sanderson 53b08c78e2 scanvideo debugging and linked mode fix 2021-12-04 18:11:48 -06:00
2 zmienionych plików z 44 dodań i 25 usunięć

Wyświetl plik

@ -216,8 +216,6 @@ bool audio_i2s_connect_extra(audio_buffer_pool_t *producer, bool buffer_on_give,
printf("Copying stereo to stereo at %d Hz\n", (int) producer->format->sample_freq);
#endif
#endif
// todo we should support pass thru option anyway
printf("TODO... not completing stereo audio connection properly!\n");
} else {
#if PICO_AUDIO_I2S_MONO_OUTPUT
printf("Copying mono to mono at %d Hz\n", (int) producer->format->sample_freq);

Wyświetl plik

@ -130,6 +130,8 @@ CU_REGISTER_DEBUG_PINS(video_timing, video_dma_buffer, video_irq, video_dma_comp
// ======================
#define GENERATING_LIST 1
//#define PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS 1
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS
// we want some sort of assertion even in release builds
#ifndef NDEBUG
@ -260,7 +262,7 @@ static struct {
// locks (i.e. we are saving an extra lock in the latch case by not placing in a separate struct)
full_scanline_buffer_t *generated_ascending_scanline_id_list;
full_scanline_buffer_t *generated_ascending_scanline_id_list_tail;
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS && GENERATING_LIST
full_scanline_buffer_t *generating_list;
#endif
} scanline;
@ -383,6 +385,7 @@ inline static full_scanline_buffer_t *list_remove_head_ascending(full_scanline_b
full_scanline_buffer_t *fsb = *phead;
if (fsb) {
scanline_assert(*ptail);
*phead = fsb->next;
if (!fsb->next) {
@ -556,6 +559,28 @@ static inline void release_scanline_irqs_enabled(int buffers_to_free_count,
}
}
// Note that this is not a general purpose function. It must be called by a caller
// who can guarantee that a DMA completion IRQ will not be taken during this method
static inline void abort_all_dma_channels_assuming_no_irq_preemption() {
// the reason the above requirements are in place is that the DMA controller may cause
// a completion IRQ during (or immediately the abort). There are *slower* ways to
// work around it in software, but we want to suppress the IRQ afterwards anyway, so
// as long as the spurious IRQ doesn't get taken here, then the h/w issue is of no problem
dma_hw->abort = PICO_SCANVIDEO_SCANLINE_DMA_CHANNELS_MASK;
// note that relying on the abort bits is no longer safe, as it may get cleared before the spurious IRQ happens
// // wait for abort(s) to complete
// while (dma_hw->abort & PICO_SCANVIDEO_SCANLINE_DMA_CHANNELS_MASK) tight_loop_contents();
while (dma_channel_is_busy(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL)) tight_loop_contents();
#if PICO_SCANVIDEO_PLANE_COUNT > 1
while (dma_channel_is_busy(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL2)) tight_loop_contents();
#if PICO_SCANVIDEO_PLANE_COUNT > 2
while (dma_channel_is_busy(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL3)) tight_loop_contents();
#endif
#endif
// we don't want any pending completion IRQ which may have happened in the interim
dma_hw->ints0 = PICO_SCANVIDEO_SCANLINE_DMA_CHANNELS_MASK;
}
static inline bool update_dma_transfer_state_irqs_enabled(bool cancel_if_not_complete,
int *scanline_buffers_to_release) {
uint32_t save = spin_lock_blocking(shared_state.dma.lock);
@ -609,13 +634,9 @@ static inline bool update_dma_transfer_state_irqs_enabled(bool cancel_if_not_com
shared_state.dma.buffers_to_release = 0;
DEBUG_PINS_XOR(video_in_use, 4);
}
dma_channel_abort(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL);
#if PICO_SCANVIDEO_PLANE_COUNT > 1
dma_channel_abort(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL2);
#if PICO_SCANVIDEO_PLANE_COUNT > 2
dma_channel_abort(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL3);
#endif
#endif
// note that we guarantee no IRQ preemption because this method is always called within some
// type of video IRQ handle, and of those the DMA IRQ is the lowest priority.
abort_all_dma_channels_assuming_no_irq_preemption();
#else
panic("need VIDEO_RECOVERY");
#endif
@ -627,13 +648,9 @@ static inline bool update_dma_transfer_state_irqs_enabled(bool cancel_if_not_com
shared_state.dma.scanline_in_progress = 0;
*scanline_buffers_to_release = shared_state.dma.buffers_to_release;
shared_state.dma.buffers_to_release = 0;
dma_abort(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL);
#if PICO_SCANVIDEO_PLANE_COUNT > 1
dma_abort(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL2);
#if PICO_SCANVIDEO_PLANE_COUNT > 2
dma_channel_abort(PICO_SCANVIDEO_SCANLINE_DMA_CHANNEL3);
#endif
#endif
// note that we guarantee no IRQ preemption because this method is always called within some
// type of video IRQ handle, and of those the DMA IRQ is the lowest priority.
abort_all_dma_channels_assuming_no_irq_preemption();
}
spin_unlock(shared_state.dma.lock, save);
return false;
@ -797,8 +814,9 @@ void __video_most_time_critical_func(prepare_for_active_scanline_irqs_enabled)()
shared_state.scanline.current_scanline_buffer = NULL;
#if PICO_SCANVIDEO_LINKED_SCANLINE_BUFFERS
} else if (fsb->core.link_after && !--fsb->core.link_after) {
assert(fsb->core.link);
scanline_assert(fsb->core.link);
spin_lock_unsafe_blocking(shared_state.in_use.lock);
scanline_assert(fsb->core.link);
DEBUG_PINS_SET(video_link, 1);
full_scanline_buffer_t *fsb2 = (full_scanline_buffer_t *)fsb->core.link;
fsb->core.link = NULL; // the linkee scanline is now tracked on its own, so shouldn't be freed with the linker
@ -1046,7 +1064,7 @@ extern bool scanvideo_in_vblank() {
return *(volatile bool *) &shared_state.scanline.in_vblank;
}
static uint default_scanvideo_scanline_repeat_count_fn(uint32_t scanline_id) {
static uint __no_inline_not_in_flash_func(default_scanvideo_scanline_repeat_count_fn)(uint32_t scanline_id) {
return 1;
}
@ -1066,7 +1084,7 @@ extern scanvideo_scanline_buffer_t *__video_time_critical_func(scanvideo_begin_s
if (fsb) {
save = spin_lock_blocking(shared_state.scanline.lock);
DEBUG_PINS_SET(video_timing, 1);
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS && GENERATING_LIST
list_prepend(&shared_state.scanline.generating_list, fsb);
#endif
// todo improve this algorithm... how far ahead should we be
@ -1093,7 +1111,10 @@ extern scanvideo_scanline_buffer_t *__video_time_critical_func(scanvideo_begin_s
DEBUG_PINS_CLR(video_link, 1);
DEBUG_PINS_CLR(video_generation, 1);
#if PICO_SCANVIDEO_LINKED_SCANLINE_BUFFERS
fsb->core.link_after = 0;
if (fsb) {
fsb->core.link = 0;
fsb->core.link_after = 0;
}
#endif
return (scanvideo_scanline_buffer_t *) fsb;
}
@ -1129,7 +1150,7 @@ scanvideo_scanline_buffer_t *__video_time_critical_func(scanvideo_begin_scanline
{
save = spin_lock_blocking(shared_state.scanline.lock);
DEBUG_PINS_SET(video_timing, 1);
#ifdef ENABLE_SCANLINE_ASSERTIONS
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS && GENERATING_LIST
list_prepend(&shared_state.scanline.generating_list, fsb);
list_prepend(&shared_state.scanline.generating_list, fsb2);
#endif
@ -1202,7 +1223,7 @@ scanvideo_scanline_buffer_t *__video_time_critical_func(scanvideo_begin_scanline
}
save = spin_lock_blocking(shared_state.scanline.lock);
DEBUG_PINS_SET(video_timing, 1);
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS && GENERATING_LIST
list_prepend(&shared_state.scanline.generating_list, fsb);
#endif
// todo improve this algorithm... how far ahead should we be
@ -1233,7 +1254,7 @@ scanvideo_scanline_buffer_t *__video_time_critical_func(scanvideo_begin_scanline
DEBUG_PINS_CLR(video_link, 1);
DEBUG_PINS_CLR(video_generation, 1);
fsb->core.link_after = 0;
if (fsb) fsb->core.link_after = 0;
return (scanvideo_scanline_buffer_t *) fsb;
}
#endif
@ -1243,7 +1264,7 @@ extern void __video_time_critical_func(scanvideo_end_scanline_generation)(
DEBUG_PINS_SET(video_generation, 2);
full_scanline_buffer_t *fsb = (full_scanline_buffer_t *) scanline_buffer;
uint32_t save = spin_lock_blocking(shared_state.scanline.lock);
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS
#if PICO_SCANVIDEO_ENABLE_SCANLINE_ASSERTIONS && GENERATING_LIST
list_remove(&shared_state.scanline.generating_list, fsb);
#endif
list_insert_ascending(&shared_state.scanline.generated_ascending_scanline_id_list,