kopia lustrzana https://github.com/raspberrypi/pico-extras
Porównaj commity
3 Commity
77eae28366
...
b5887f6baa
Autor | SHA1 | Data |
---|---|---|
graham sanderson | b5887f6baa | |
graham sanderson | ba944492c9 | |
graham sanderson | 53b08c78e2 |
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Ładowanie…
Reference in New Issue