kopia lustrzana https://github.com/raspberrypi/pico-playground
add scanvideo/test_pattern
rodzic
b4130d01c3
commit
97ef906b00
|
@ -41,6 +41,7 @@ Name|Description
|
|||
[render](scanvideo/render)| A very dated rendering library used by [demo1](scanvideo/demo1) - avoid!
|
||||
[sprite](scanvideo/sprite)| A small sprite library used by [sprite_demo](scanvideo/scanvideo_minimal)
|
||||
[sprite_demo](scanvideo/sprite_demo)| Some bouncing Eben heads
|
||||
[test_pattern](scanvideo/test_pattern)| Display color bars
|
||||
[textmode](scanvideo/textmode)| Shows off chained DMA to generate scanlines out of glyph fragments via DMA/PIO
|
||||
|
||||
|
||||
|
|
|
@ -10,5 +10,6 @@ if (TARGET pico_scanvideo) # not all build types support it
|
|||
add_subdirectory(mario_tiles)
|
||||
add_subdirectory(scanvideo_minimal)
|
||||
add_subdirectory(sprite_demo)
|
||||
add_subdirectory(test_pattern)
|
||||
add_subdirectory(textmode)
|
||||
endif()
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pico.h"
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
if (TARGET pico_scanvideo_dpi)
|
||||
add_executable(test_pattern
|
||||
test_pattern.c
|
||||
)
|
||||
|
||||
target_link_libraries(test_pattern PRIVATE
|
||||
pico_multicore
|
||||
pico_stdlib
|
||||
pico_scanvideo_dpi)
|
||||
|
||||
pico_add_extra_outputs(test_pattern)
|
||||
|
||||
pico_enable_stdio_uart(test_pattern 1)
|
||||
pico_enable_stdio_usb(test_pattern 1)
|
||||
endif ()
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pico.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "pico/scanvideo.h"
|
||||
#include "pico/scanvideo/composable_scanline.h"
|
||||
#include "pico/sync.h"
|
||||
|
||||
#define vga_mode vga_mode_320x240_60
|
||||
|
||||
void core1_func();
|
||||
|
||||
// Simple color bar program, which draws 7 colored bars: red, green, yellow, blow, magenta, cyan, white
|
||||
// Can be used to check resister DAC correctness.
|
||||
//
|
||||
// Note this program also demonstrates running video on core 1, leaving core 0 free. It supports
|
||||
// user input over USB or UART stdin, although all it does with it is invert the colors when you press SPACE
|
||||
|
||||
static semaphore_t video_initted;
|
||||
static bool invert;
|
||||
|
||||
int main(void) {
|
||||
set_sys_clock_48mhz();
|
||||
stdio_init_all();
|
||||
|
||||
// create a semaphore to be posted when video init is complete
|
||||
sem_init(&video_initted, 0, 1);
|
||||
|
||||
// launch all the video on core 1, so it isn't affected by USB handling on core 0
|
||||
multicore_launch_core1(core1_func);
|
||||
|
||||
// wait for initialization of video to be complete
|
||||
sem_acquire_blocking(&video_initted);
|
||||
|
||||
puts("Color bars ready, press SPACE to invert...");
|
||||
|
||||
while (true) {
|
||||
// prevent tearing when we invert - if you're astute you'll notice this actually causes
|
||||
// a fixed tear a number of scanlines from the top. this is caused by pre-buffering of scanlines
|
||||
// and is too detailed a topic to fix here.
|
||||
scanvideo_wait_for_vblank();
|
||||
int c = getchar_timeout_us(0);
|
||||
switch (c) {
|
||||
case ' ':
|
||||
invert = !invert;
|
||||
printf("Inverted: %d\n", invert);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_color_bar(scanvideo_scanline_buffer_t *buffer) {
|
||||
// figure out 1/32 of the color value
|
||||
uint line_num = scanvideo_scanline_number(buffer->scanline_id);
|
||||
int32_t color_step = 1 + (line_num * 7 / vga_mode.height);
|
||||
color_step = PICO_SCANVIDEO_PIXEL_FROM_RGB5(color_step & 1u, (color_step >> 1u) & 1u, (color_step >> 2u) & 1u);
|
||||
if (invert) color_step = -color_step;
|
||||
uint bar_width = vga_mode.width / 32;
|
||||
|
||||
uint16_t *p = (uint16_t *) buffer->data;
|
||||
int32_t color = invert ? PICO_SCANVIDEO_PIXEL_FROM_RGB8(255, 255, 255) : 0;
|
||||
|
||||
for (uint bar = 0; bar < 32; bar++) {
|
||||
*p++ = COMPOSABLE_COLOR_RUN;
|
||||
*p++ = color;
|
||||
*p++ = bar_width - 3;
|
||||
color += color_step;
|
||||
}
|
||||
|
||||
// 32 * 3, so we should be word aligned
|
||||
assert(!(3u & (uintptr_t) p));
|
||||
|
||||
// black pixel to end line
|
||||
*p++ = COMPOSABLE_RAW_1P;
|
||||
*p++ = 0;
|
||||
// end of line with alignment padding
|
||||
*p++ = COMPOSABLE_EOL_SKIP_ALIGN;
|
||||
*p++ = 0;
|
||||
|
||||
buffer->data_used = ((uint32_t *) p) - buffer->data;
|
||||
assert(buffer->data_used < buffer->data_max);
|
||||
|
||||
buffer->status = SCANLINE_OK;
|
||||
}
|
||||
|
||||
void core1_func() {
|
||||
// initialize video and interrupts on core 1
|
||||
scanvideo_setup(&vga_mode);
|
||||
scanvideo_timing_enable(true);
|
||||
sem_release(&video_initted);
|
||||
|
||||
while (true) {
|
||||
scanvideo_scanline_buffer_t *scanline_buffer = scanvideo_begin_scanline_generation(true);
|
||||
draw_color_bar(scanline_buffer);
|
||||
scanvideo_end_scanline_generation(scanline_buffer);
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue