diff --git a/32blit-pico/CMakeLists.txt b/32blit-pico/CMakeLists.txt index b2402c335..a1c68ea67 100644 --- a/32blit-pico/CMakeLists.txt +++ b/32blit-pico/CMakeLists.txt @@ -7,64 +7,76 @@ set(32BLIT_PICO 1 PARENT_SCOPE) add_library(BlitHalPico INTERFACE) target_sources(BlitHalPico INTERFACE - - ${CMAKE_CURRENT_LIST_DIR}/../3rd-party/fatfs/ff.c - ${CMAKE_CURRENT_LIST_DIR}/../3rd-party/fatfs/ffunicode.c - - ${CMAKE_CURRENT_LIST_DIR}/audio.cpp - ${CMAKE_CURRENT_LIST_DIR}/file.cpp - ${CMAKE_CURRENT_LIST_DIR}/input.cpp - ${CMAKE_CURRENT_LIST_DIR}/led.cpp - ${CMAKE_CURRENT_LIST_DIR}/main.cpp - ${CMAKE_CURRENT_LIST_DIR}/storage.cpp - ${CMAKE_CURRENT_LIST_DIR}/st7789.cpp - ${CMAKE_CURRENT_LIST_DIR}/usb.cpp - ${CMAKE_CURRENT_LIST_DIR}/usb_descriptors.c + ${CMAKE_CURRENT_LIST_DIR}/../3rd-party/fatfs/ff.c + ${CMAKE_CURRENT_LIST_DIR}/../3rd-party/fatfs/ffunicode.c + + ${CMAKE_CURRENT_LIST_DIR}/audio.cpp + ${CMAKE_CURRENT_LIST_DIR}/file.cpp + ${CMAKE_CURRENT_LIST_DIR}/input.cpp + ${CMAKE_CURRENT_LIST_DIR}/led.cpp + ${CMAKE_CURRENT_LIST_DIR}/main.cpp + ${CMAKE_CURRENT_LIST_DIR}/storage.cpp + ${CMAKE_CURRENT_LIST_DIR}/st7789.cpp + ${CMAKE_CURRENT_LIST_DIR}/usb.cpp + ${CMAKE_CURRENT_LIST_DIR}/usb_descriptors.c ) pico_generate_pio_header(BlitHalPico ${CMAKE_CURRENT_LIST_DIR}/st7789.pio) target_link_libraries(BlitHalPico INTERFACE hardware_dma hardware_pio hardware_pwm hardware_spi pico_stdlib pico_unique_id tinyusb_device) target_include_directories(BlitHalPico INTERFACE - ${CMAKE_CURRENT_LIST_DIR} # for tusb_config - ${CMAKE_CURRENT_LIST_DIR}/../3rd-party/fatfs + ${CMAKE_CURRENT_LIST_DIR} # for tusb_config + ${CMAKE_CURRENT_LIST_DIR}/../3rd-party/fatfs ) target_compile_definitions(BlitHalPico INTERFACE - PICO_AUDIO_I2S_MONO_INPUT=1 - PICO_AUDIO_DMA_IRQ=1 + PICO_AUDIO_I2S_MONO_INPUT=1 + PICO_AUDIO_DMA_IRQ=1 ) if(${PICO_BOARD} STREQUAL "vgaboard") - message("Using VGA board...") - target_link_libraries(BlitHalPico INTERFACE pico_scanvideo_dpi pico_audio_i2s) - target_compile_definitions(BlitHalPico INTERFACE - PICO_SCANVIDEO_PLANE1_VARIABLE_FRAGMENT_DMA=1 - AUDIO_I2S - DISPLAY_SCANVIDEO - ) + message("Using VGA board...") + target_link_libraries(BlitHalPico INTERFACE pico_scanvideo_dpi pico_audio_i2s) + target_compile_definitions(BlitHalPico INTERFACE + PICO_SCANVIDEO_PLANE1_VARIABLE_FRAGMENT_DMA=1 + AUDIO_I2S + DISPLAY_SCANVIDEO + ) elseif(${PICO_BOARD} STREQUAL "pimoroni_picosystem") - message("Using picosystem...") - target_compile_definitions(BlitHalPico INTERFACE - DISPLAY_ST7789 - INPUT_GPIO - ) + message("Using picosystem...") + target_compile_definitions(BlitHalPico INTERFACE + DISPLAY_ST7789 + INPUT_GPIO + ) + if(AUDIO_PWM) + target_link_libraries(BlitHalPico INTERFACE pico_audio_pwm) + target_compile_definitions(BlitHalPico INTERFACE + PICO_AUDIO_PWM_MONO_PIN=11 + PICO_AUDIO_PWM_PIO=1 + AUDIO_PWM + ) + else() + target_compile_definitions(BlitHalPico INTERFACE + AUDIO_BEEP_PIN=11 + AUDIO_BEEP + ) + endif() else() - message(WARNING "Using default config for \"${PICO_BOARD}\"...") - target_link_libraries(BlitHalPico INTERFACE pico_audio_i2s) - # messy explorer-based setup - target_compile_definitions(BlitHalPico INTERFACE - PICO_AUDIO_I2S_DATA_PIN=6 - PICO_AUDIO_I2S_CLOCK_PIN_BASE=20 - AUDIO_I2S - DISPLAY_ST7789 - INPUT_GPIO - ) + message(WARNING "Using default config for \"${PICO_BOARD}\"...") + target_link_libraries(BlitHalPico INTERFACE pico_audio_i2s) + # messy explorer-based setup + target_compile_definitions(BlitHalPico INTERFACE + PICO_AUDIO_I2S_DATA_PIN=6 + PICO_AUDIO_I2S_CLOCK_PIN_BASE=20 + AUDIO_I2S + DISPLAY_ST7789 + INPUT_GPIO + ) endif() function(blit_executable_common NAME) - target_link_libraries(${NAME} BlitEngine) + target_link_libraries(${NAME} BlitEngine) endfunction() @@ -77,25 +89,25 @@ function(blit_executable_int_flash NAME SOURCES) pico_add_extra_outputs(${NAME}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.uf2 - DESTINATION bin - ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.uf2 + DESTINATION bin + ) endfunction() function(blit_executable NAME SOURCES) - blit_executable_int_flash(${NAME} ${SOURCES} ${ARGN}) + blit_executable_int_flash(${NAME} ${SOURCES} ${ARGN}) endfunction() function(blit_metadata TARGET FILE) - # cause cmake to reconfigure whenever the asset list changes - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}) + # cause cmake to reconfigure whenever the asset list changes + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}) - # get the inputs/outputs for the asset tool (at configure time) - execute_process(COMMAND ${PYTHON_EXECUTABLE} -m ttblit cmake --config ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} --cmake ${CMAKE_CURRENT_BINARY_DIR}/metadata.cmake) - include(${CMAKE_CURRENT_BINARY_DIR}/metadata.cmake) + # get the inputs/outputs for the asset tool (at configure time) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -m ttblit cmake --config ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} --cmake ${CMAKE_CURRENT_BINARY_DIR}/metadata.cmake) + include(${CMAKE_CURRENT_BINARY_DIR}/metadata.cmake) - pico_set_program_name(${TARGET} "${METADATA_TITLE}") - pico_set_program_description(${TARGET} "${METADATA_DESCRIPTION}") - pico_set_program_version(${TARGET} "${METADATA_VERSION}") - pico_set_program_url(${TARGET} "${METADATA_URL}") + pico_set_program_name(${TARGET} "${METADATA_TITLE}") + pico_set_program_description(${TARGET} "${METADATA_DESCRIPTION}") + pico_set_program_version(${TARGET} "${METADATA_VERSION}") + pico_set_program_url(${TARGET} "${METADATA_URL}") endfunction() diff --git a/32blit-pico/audio.cpp b/32blit-pico/audio.cpp index 61c461283..bcfd18b56 100644 --- a/32blit-pico/audio.cpp +++ b/32blit-pico/audio.cpp @@ -1,8 +1,28 @@ #include "audio.hpp" +#include "config.h" #ifdef AUDIO_I2S #include "pico/audio_i2s.h" #define HAVE_AUDIO +#define AUDIO_SAMPLE_FREQ 44100 +#endif + +#ifdef AUDIO_PWM +#include "pico/audio_pwm.h" +#include "hardware/pio.h" +#define HAVE_AUDIO +#define AUDIO_SAMPLE_FREQ 22050 +#endif + +#ifdef AUDIO_BEEP +#include "hardware/pwm.h" +#include "hardware/clocks.h" +#include "hardware/gpio.h" + +static const uint32_t PWM_WRAP = 65535; +static uint32_t slice_num = 0; +static float clock_hz = 0.0; +static uint32_t beep_time = 0; #endif #include "audio/audio.hpp" @@ -12,9 +32,18 @@ static audio_buffer_pool *audio_pool = nullptr; #endif void init_audio() { -#ifdef AUDIO_I2S +#ifdef AUDIO_BEEP + clock_hz = clock_get_hz(clk_sys); + + gpio_set_function(AUDIO_BEEP_PIN, GPIO_FUNC_PWM); + slice_num = pwm_gpio_to_slice_num(AUDIO_BEEP_PIN); + + pwm_set_wrap(slice_num, PWM_WRAP); +#endif + +#ifdef HAVE_AUDIO static audio_format_t audio_format = { - .sample_freq = 44100, + .sample_freq = AUDIO_SAMPLE_FREQ, .format = AUDIO_BUFFER_FORMAT_PCM_S16, .channel_count = 1 }; @@ -27,6 +56,7 @@ void init_audio() { struct audio_buffer_pool *producer_pool = audio_new_producer_pool(&producer_format, 4, 441); const struct audio_format *output_format; +#ifdef AUDIO_I2S struct audio_i2s_config config = { .data_pin = PICO_AUDIO_I2S_DATA_PIN, .clock_pin_base = PICO_AUDIO_I2S_CLOCK_PIN_BASE, @@ -42,24 +72,84 @@ void init_audio() { bool ok = audio_i2s_connect(producer_pool); assert(ok); audio_i2s_set_enabled(true); +#endif + +#ifdef AUDIO_PWM + struct audio_pwm_channel_config audio_pwm_config = { + .core = { + .base_pin = PICO_AUDIO_PWM_MONO_PIN, + .dma_channel = 1, + .pio_sm = 1, + }, + .pattern = 3, + }; + output_format = audio_pwm_setup(&audio_format, -1, &audio_pwm_config); + if (!output_format) { + panic("PicoAudio: Unable to open audio device.\n"); + } +#if OVERCLOCK_250 + pio_sm_set_clkdiv(pio1, 1, 2.0f); +#endif + bool ok = audio_pwm_default_connect(producer_pool, false); + assert(ok); + audio_pwm_set_enabled(true); + gpio_set_drive_strength(PICO_AUDIO_PWM_MONO_PIN, GPIO_DRIVE_STRENGTH_4MA); + gpio_set_slew_rate(PICO_AUDIO_PWM_MONO_PIN, GPIO_SLEW_RATE_FAST); +#endif + audio_pool = producer_pool; #endif } -void update_audio() { +void update_audio(uint32_t time) { +#ifdef AUDIO_BEEP + bool on = false; + uint32_t elapsed = time - beep_time; + beep_time = time; + + for(auto f = 0u; f < elapsed * blit::sample_rate / 1000; f++) { + blit::get_audio_frame(); + } + + // Find the first square wave enabled channel and use freq/pulse width to drive the beeper + for(int c = 0; c < CHANNEL_COUNT; c++) { + auto &channel = blit::channels[c]; + + if(channel.waveforms & blit::Waveform::SQUARE) { + on = channel.volume + && channel.adsr_phase != blit::ADSRPhase::RELEASE + && channel.adsr_phase != blit::ADSRPhase::OFF; + + if(on) { + pwm_set_clkdiv(slice_num, (clock_hz / PWM_WRAP) / channel.frequency); + pwm_set_gpio_level(AUDIO_BEEP_PIN, channel.pulse_width); + break; + } + } + } + + pwm_set_enabled(slice_num, on); +#endif #ifdef HAVE_AUDIO // audio struct audio_buffer *buffer = take_audio_buffer(audio_pool, false); if(buffer) { auto samples = (int16_t *) buffer->buffer->bytes; +#ifdef AUDIO_I2S for(uint32_t i = 0; i < buffer->max_sample_count; i += 2) { int val = (int)blit::get_audio_frame() - 0x8000; *samples++ = val; *samples++ = val; } - +#endif +#ifdef AUDIO_PWM + for(uint32_t i = 0; i < buffer->max_sample_count; i++) { + int val = (int)blit::get_audio_frame() - 0x8000; + *samples++ = val; + } +#endif buffer->sample_count = buffer->max_sample_count; give_audio_buffer(audio_pool, buffer); } #endif -} +} \ No newline at end of file diff --git a/32blit-pico/audio.hpp b/32blit-pico/audio.hpp index cf45df167..f5b15acc0 100644 --- a/32blit-pico/audio.hpp +++ b/32blit-pico/audio.hpp @@ -1,4 +1,5 @@ #pragma once +#include void init_audio(); -void update_audio(); +void update_audio(uint32_t time); diff --git a/32blit-pico/main.cpp b/32blit-pico/main.cpp index dfda450a2..a2b17d692 100644 --- a/32blit-pico/main.cpp +++ b/32blit-pico/main.cpp @@ -367,7 +367,7 @@ int main() { #endif update_input(); int ms_to_next_update = tick(::now()); - update_audio(); + update_audio(now); update_led(); update_usb(); diff --git a/32blit/audio/audio.hpp b/32blit/audio/audio.hpp index 7d23d1b07..ae41008ee 100644 --- a/32blit/audio/audio.hpp +++ b/32blit/audio/audio.hpp @@ -104,10 +104,15 @@ namespace blit { adsr_step = (int32_t(sustain << 8) - int32_t(adsr)) / int32_t(adsr_end_frame); } void trigger_sustain() { + if(sustain == 0) { + off(); + return; + } adsr_frame = 0; adsr_phase = ADSRPhase::SUSTAIN; adsr_end_frame = 0; adsr_step = 0; + adsr = int32_t(sustain << 8); } void trigger_release() { adsr_frame = 0; diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index dd2a5cc3d..0903cec54 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(fizzlefade) add_subdirectory(flight) add_subdirectory(geometry) add_subdirectory(hardware-test) +add_subdirectory(picosystem-hardware-test) add_subdirectory(jpeg) add_subdirectory(logo) add_subdirectory(matrix-test) diff --git a/examples/geometry/geometry.cpp b/examples/geometry/geometry.cpp index 62a254eef..ea345c97b 100644 --- a/examples/geometry/geometry.cpp +++ b/examples/geometry/geometry.cpp @@ -270,7 +270,7 @@ void init() { channels[0].release_ms = 10; channels[0].volume = 4000; - channels[1].waveforms = Waveform::SINE; + channels[1].waveforms = Waveform::SQUARE | Waveform::SINE; channels[1].frequency = 0; channels[1].attack_ms = 10; channels[1].decay_ms = 500; diff --git a/examples/hardware-test/CMakeLists.txt b/examples/hardware-test/CMakeLists.txt index e84622737..3d7a3f9ed 100644 --- a/examples/hardware-test/CMakeLists.txt +++ b/examples/hardware-test/CMakeLists.txt @@ -1,5 +1,11 @@ cmake_minimum_required(VERSION 3.9) project (hardware-test) find_package (32BLIT CONFIG REQUIRED PATHS ../..) + +if(32BLIT_PICO) + # PicoSystem has its own picosystem-hardware-test + return() +endif() + blit_executable (hardware-test hardware-test.cpp) blit_metadata (hardware-test metadata.yml) diff --git a/examples/picosystem-hardware-test/CMakeLists.txt b/examples/picosystem-hardware-test/CMakeLists.txt new file mode 100644 index 000000000..ce7b4b88f --- /dev/null +++ b/examples/picosystem-hardware-test/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.9) +project (picosystem-hardware-test) +find_package (32BLIT CONFIG REQUIRED PATHS ../..) + +if(NOT 32BLIT_PICO) + # Hooks into the Pico SDK to get battery charge and VBUS status + return() +endif() + +blit_executable (picosystem-hardware-test hardware-test.cpp) +blit_metadata (picosystem-hardware-test metadata.yml) \ No newline at end of file diff --git a/examples/picosystem-hardware-test/hardware-test-icon.png b/examples/picosystem-hardware-test/hardware-test-icon.png new file mode 100644 index 000000000..b2c0a3fa3 Binary files /dev/null and b/examples/picosystem-hardware-test/hardware-test-icon.png differ diff --git a/examples/picosystem-hardware-test/hardware-test.cpp b/examples/picosystem-hardware-test/hardware-test.cpp new file mode 100644 index 000000000..f8d311195 --- /dev/null +++ b/examples/picosystem-hardware-test/hardware-test.cpp @@ -0,0 +1,181 @@ +#include "hardware-test.hpp" +#include "graphics/color.hpp" + +#include "hardware/gpio.h" + +#include + +using namespace blit; + +const uint8_t STATUS_V_SPACING = 10; + +const uint32_t VBUS_DETECT_PIN = 2; +const uint32_t CHARGE_STATUS_PIN = 24; + +const int16_t notes[2][384] = { + { // melody notes + 147, 0, 0, 0, 0, 0, 0, 0, 175, 0, 196, 0, 220, 0, 262, 0, 247, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 175, 0, 196, 0, 220, 0, 262, 0, 330, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 349, 0, 330, 0, 294, 0, 220, 0, 262, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 247, 0, 220, 0, 196, 0, 147, 0, 175, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, + 147, 0, 0, 0, 0, 0, 0, 0, 175, 0, 196, 0, 220, 0, 262, 0, 247, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 175, 0, 196, 0, 220, 0, 262, 0, 330, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 349, 0, 330, 0, 294, 0, 220, 0, 262, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 247, 0, 220, 0, 196, 0, 147, 0, 175, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, + 147, 0, 0, 0, 0, 0, 0, 0, 175, 0, 196, 0, 220, 0, 262, 0, 247, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 175, 0, 196, 0, 220, 0, 262, 0, 330, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 349, 0, 330, 0, 294, 0, 220, 0, 262, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 247, 0, 262, 0, 294, 0, 392, 0, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // rhythm notes + 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 392, 0, 523, 0, 659, 0, 523, 0, 392, 0, 523, 0, 659, 0, 523, 0, 698, 0, 587, 0, 440, 0, 587, 0, 698, 0, 587, 0, 440, 0, 587, 0, 523, 0, 440, 0, 330, 0, 440, 0, 523, 0, 440, 0, 330, 0, 440, 0, 349, 0, 294, 0, 220, 0, 294, 0, 349, 0, 294, 0, 220, 0, 294, 0, 262, 0, 247, 0, 220, 0, 175, 0, 165, 0, 147, 0, 131, 0, 98, 0, + 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 392, 0, 523, 0, 659, 0, 523, 0, 392, 0, 523, 0, 659, 0, 523, 0, 698, 0, 587, 0, 440, 0, 587, 0, 698, 0, 587, 0, 440, 0, 587, 0, 523, 0, 440, 0, 330, 0, 440, 0, 523, 0, 440, 0, 330, 0, 440, 0, 349, 0, 294, 0, 220, 0, 294, 0, 349, 0, 294, 0, 220, 0, 294, 0, 262, 0, 247, 0, 220, 0, 175, 0, 165, 0, 147, 0, 131, 0, 98, 0, + 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 294, 0, 440, 0, 587, 0, 440, 0, 392, 0, 523, 0, 659, 0, 523, 0, 392, 0, 523, 0, 659, 0, 523, 0, 698, 0, 587, 0, 440, 0, 587, 0, 698, 0, 587, 0, 440, 0, 587, 0, 523, 0, 440, 0, 330, 0, 440, 0, 523, 0, 440, 0, 330, 0, 440, 0, 349, 0, 294, 0, 220, 0, 294, 0, 349, 0, 294, 0, 220, 0, 294, 0, 262, 0, 247, 0, 220, 0, 175, 0, 165, 0, 147, 0, 131, 0, 98, 0, + }, +}; + +const Pen LED_COLOUR[3] = { + Pen(255, 0, 0), + Pen(0, 255, 0), + Pen(0, 0, 255) +}; + +uint16_t beat = 0; + +uint32_t been_pressed; + +void init() { + set_screen_mode(ScreenMode::lores); + + gpio_init(VBUS_DETECT_PIN); + gpio_set_dir(VBUS_DETECT_PIN, GPIO_IN); + gpio_init(CHARGE_STATUS_PIN); + gpio_set_dir(CHARGE_STATUS_PIN, GPIO_IN); + + channels[0].waveforms = Waveform::SQUARE; + channels[0].attack_ms = 16; + channels[0].decay_ms = 168; + channels[0].sustain = 0xafff; + channels[0].release_ms = 168; + + channels[1].waveforms = Waveform::SQUARE; + channels[1].attack_ms = 38; + channels[1].decay_ms = 300; + channels[1].sustain = 0; + channels[1].release_ms = 0; +} + +void render(uint32_t time) { + char text_buf[100] = {0}; + bool button_a = buttons & Button::A; + bool button_b = buttons & Button::B; + bool button_x = buttons & Button::X; + bool button_y = buttons & Button::Y; + bool dpad_l = buttons & Button::DPAD_LEFT; + bool dpad_r = buttons & Button::DPAD_RIGHT; + bool dpad_u = buttons & Button::DPAD_UP; + bool dpad_d = buttons & Button::DPAD_DOWN; + + for(int b = 0; b < screen.bounds.w; b++){ + for(int v = 0; v < screen.bounds.h; v++){ + screen.pen = hsv_to_rgba(float(b) / (float)(screen.bounds.w), 1.0f, float(v) / (float)(screen.bounds.h)); + screen.pixel(Point(b, v)); + } + } + + screen.pen = dpad_r ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("R", minimal_font, Point(25, 15), false, center_center); + + screen.pen = dpad_d ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("D", minimal_font, Point(15, 25), false, center_center); + + screen.pen = dpad_u ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("U", minimal_font, Point(15, 5), false, center_center); + + screen.pen = dpad_l ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("L", minimal_font, Point(5, 15), false, center_center); + + screen.pen = button_a ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("A", minimal_font, Point(screen.bounds.w - 5, 15), false, center_center); + + screen.pen = button_b ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("B", minimal_font, Point(screen.bounds.w - 15, 25), false, center_center); + + screen.pen = button_x ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("X", minimal_font, Point(screen.bounds.w - 15, 5), false, center_center); + + screen.pen = button_y ? Pen(255, 0, 0) : Pen(128, 128, 128); + screen.text("Y", minimal_font, Point(screen.bounds.w - 25, 15), false, center_center); + + //LED = hsv_to_rgba(time / 50.0f, 1.0f, 1.0f); + LED = LED_COLOUR[(time / 1000) % 3]; + + Point location(5, screen.bounds.h - (8 * STATUS_V_SPACING)); + std::string label = ""; + + screen.pen = Pen(255, 255, 255); + uint32_t bit = 256; + while(bit > 0) { + bit >>= 1; + switch(bit) { + case Button::A: + label = "A "; + break; + case Button::B: + label = "B "; + break; + case Button::X: + label = "X "; + break; + case Button::Y: + label = "Y "; + break; + case Button::DPAD_UP: + label = "UP "; + break; + case Button::DPAD_DOWN: + label = "DOWN "; + break; + case Button::DPAD_LEFT: + label = "LEFT "; + break; + case Button::DPAD_RIGHT: + label = "RIGHT"; + break; + } + + if (been_pressed & bit) { + label += " OK"; + } + + screen.text(label, minimal_font, location, false); + location.y += STATUS_V_SPACING; + } + + bool charge_status = gpio_get(CHARGE_STATUS_PIN); + bool vbus_connected = gpio_get(VBUS_DETECT_PIN); + + location = Point(screen.bounds.w / 2, screen.bounds.h - (8 * STATUS_V_SPACING)); + + label = "CHG: "; + label += charge_status ? "Yes" : "No"; + screen.text(label, minimal_font, location); + location.y += STATUS_V_SPACING; + + label = "VBUS: "; + label += vbus_connected ? "Yes" : "No"; + screen.text(label, minimal_font, location); +} + +void update(uint32_t time) { + static uint16_t tick = 0; + static uint16_t prev_beat = 1; + + been_pressed |= buttons.pressed; + + beat = (tick / 8) % 384; // 125ms per beat + tick++; + + if (beat == prev_beat) return; + prev_beat = beat; + + for(uint8_t i = 0; i < 2; i++) { + if(notes[i][beat] > 0) { + channels[i].frequency = notes[i][beat]; + channels[i].trigger_attack(); + } else if (notes[i][beat] == -1) { + channels[i].trigger_release(); + } + } +} diff --git a/examples/picosystem-hardware-test/hardware-test.hpp b/examples/picosystem-hardware-test/hardware-test.hpp new file mode 100644 index 000000000..b4df8bd93 --- /dev/null +++ b/examples/picosystem-hardware-test/hardware-test.hpp @@ -0,0 +1 @@ +#include "32blit.hpp" diff --git a/examples/picosystem-hardware-test/hardware-test.png b/examples/picosystem-hardware-test/hardware-test.png new file mode 100644 index 000000000..12bb0c7e6 Binary files /dev/null and b/examples/picosystem-hardware-test/hardware-test.png differ diff --git a/examples/picosystem-hardware-test/metadata.yml b/examples/picosystem-hardware-test/metadata.yml new file mode 100644 index 000000000..6a345db63 --- /dev/null +++ b/examples/picosystem-hardware-test/metadata.yml @@ -0,0 +1,10 @@ +title: Hardware Test +description: A test of 32Blit's inputs and outputs. +author: pimoroni +splash: + file: hardware-test.png +icon: + file: hardware-test-icon.png +version: v1.0.0 +url: https://github.com/32blit/32blit-sdk +category: utility \ No newline at end of file diff --git a/examples/raycaster/raycaster.hpp b/examples/raycaster/raycaster.hpp index 1bf71d28b..b23d0472d 100644 --- a/examples/raycaster/raycaster.hpp +++ b/examples/raycaster/raycaster.hpp @@ -8,7 +8,7 @@ constexpr float M_PI_H = 1.5707963267948966f; constexpr float EPSILON = 0.00000001f; -#ifdef DISPLAY_ST7789 +#ifdef PICO_BOARD constexpr uint16_t OFFSET_TOP = 30; constexpr uint16_t SCREEN_WIDTH = 120; constexpr uint16_t SCREEN_HEIGHT = 120;