Merge pull request #886 from 32blit/patch-ccache-cache-path
Fix ccache path
diff --git a/32blit-pico/CMakeLists.txt b/32blit-pico/CMakeLists.txt
index 6168e30..28053a1 100644
--- a/32blit-pico/CMakeLists.txt
+++ b/32blit-pico/CMakeLists.txt
@@ -54,7 +54,6 @@
)
target_compile_definitions(BlitHalPico INTERFACE
- PICO_AUDIO_I2S_MONO_INPUT=1
PICO_AUDIO_DMA_IRQ=1
)
@@ -110,10 +109,7 @@
endif()
# driver dependencies
-if(BLIT_AUDIO_DRIVER STREQUAL "i2s")
- set(BLIT_REQUIRE_PICO_EXTRAS TRUE)
- list(APPEND BLIT_BOARD_LIBRARIES pico_audio_i2s)
-elseif(BLIT_AUDIO_DRIVER STREQUAL "pwm")
+if(BLIT_AUDIO_DRIVER STREQUAL "pwm")
set(BLIT_REQUIRE_PICO_EXTRAS TRUE)
list(APPEND BLIT_BOARD_LIBRARIES pico_audio_pwm)
endif()
@@ -150,6 +146,7 @@
# generate PIO headers (has to be after SDK init)
pico_generate_pio_header(BlitHalPico ${CMAKE_CURRENT_LIST_DIR}/dbi-spi.pio)
pico_generate_pio_header(BlitHalPico ${CMAKE_CURRENT_LIST_DIR}/dbi-8bit.pio)
+pico_generate_pio_header(BlitHalPico ${CMAKE_CURRENT_LIST_DIR}/audio/i2s.pio)
pico_generate_pio_header(BlitHalPico ${CMAKE_CURRENT_LIST_DIR}/spi.pio)
# include picovision drivers
diff --git a/32blit-pico/audio/i2s.cpp b/32blit-pico/audio/i2s.cpp
index 9a57c48..2548215 100644
--- a/32blit-pico/audio/i2s.cpp
+++ b/32blit-pico/audio/i2s.cpp
@@ -1,89 +1,141 @@
+#include <cmath>
+
#include "audio.hpp"
#include "config.h"
+#include "hardware/clocks.h"
#include "hardware/dma.h"
#include "hardware/pio.h"
-#include "pico/audio_i2s.h"
-#define AUDIO_SAMPLE_FREQ 44100
#include "audio/audio.hpp"
-#define audio_pio __CONCAT(pio, PICO_AUDIO_I2S_PIO)
+#include "i2s.pio.h"
-static audio_buffer_pool *audio_pool = nullptr;
+#define audio_pio __CONCAT(pio, AUDIO_I2S_PIO)
-static struct audio_buffer *cur_buffer = nullptr;
+#define AUDIO_SAMPLE_FREQ 44100
+#define AUDIO_BUFFER_SIZE 256
+#define AUDIO_NUM_BUFFERS 2
+
+static int16_t audio_buffer[AUDIO_BUFFER_SIZE * AUDIO_NUM_BUFFERS];
+static volatile int need_refill = AUDIO_NUM_BUFFERS;
+static int cur_read_buffer_index = 1;
+static int cur_write_buffer_index = 1;
+
+// track offset if we limit samples pre update
+#ifdef AUDIO_MAX_SAMPLE_UPDATE
+static int refill_offset = 0;
+#endif
+
+static const int dma_irq = 1; // we usually use DMA_IRQ_0 for display stuff
+static int dma_channel;
+
+static void __not_in_flash_func(i2s_irq_handler)() {
+ if(!dma_irqn_get_channel_status(dma_irq, dma_channel))
+ return;
+
+ dma_irqn_acknowledge_channel(dma_irq, dma_channel);
+
+ if(need_refill < AUDIO_NUM_BUFFERS - 1)
+ need_refill++;
+
+ // setup for next buffer
+ dma_channel_set_read_addr(dma_channel, audio_buffer + cur_read_buffer_index * AUDIO_BUFFER_SIZE, true);
+
+ cur_read_buffer_index = (cur_read_buffer_index + 1) % AUDIO_NUM_BUFFERS;
+}
void init_audio() {
- static audio_format_t audio_format = {
- .sample_freq = AUDIO_SAMPLE_FREQ,
- .format = AUDIO_BUFFER_FORMAT_PCM_S16,
- .channel_count = 1
- };
+ // setup PIO
- static struct audio_buffer_format producer_format = {
- .format = &audio_format,
- .sample_stride = 2
- };
+#if AUDIO_I2S_DATA_PIN >= 32 || AUDIO_I2S_CLOCK_PIN_BASE >= 31
+ // this assumes anything else using this PIO can also deal with the base
+ static_assert(AUDIO_I2S_DATA_PIN >= 16 && AUDIO_I2S_CLOCK_PIN_BASE >= 16);
+ pio_set_gpio_base(audio_pio, 16);
+#endif
- struct audio_buffer_pool *producer_pool = audio_new_producer_pool(&producer_format, 4, 256);
- const struct audio_format *output_format;
+ int pio_offset = pio_add_program(audio_pio, &i2s_program);
- uint8_t dma_channel = dma_claim_unused_channel(true);
- uint8_t pio_sm = pio_claim_unused_sm(audio_pio, true);
+ int pio_sm = pio_claim_unused_sm(audio_pio, true);
- // audio_i2s_setup claims
- dma_channel_unclaim(dma_channel);
- pio_sm_unclaim(audio_pio, pio_sm);
+ pio_sm_config cfg = i2s_program_get_default_config(pio_offset);
- struct audio_i2s_config config = {
- .data_pin = PICO_AUDIO_I2S_DATA_PIN,
- .clock_pin_base = PICO_AUDIO_I2S_CLOCK_PIN_BASE,
- .dma_channel = dma_channel,
- .pio_sm = pio_sm,
- };
+ const int bitrate = AUDIO_SAMPLE_FREQ * 16 * 2;
+ const int clkdiv = clock_get_hz(clk_sys) / float(bitrate * 2);
+ sm_config_set_clkdiv(&cfg, clkdiv);
- output_format = audio_i2s_setup(&audio_format, &config);
- if (!output_format) {
- panic("PicoAudio: Unable to open audio device.\n");
- }
+ sm_config_set_out_shift(&cfg, false, true, 32);
+ sm_config_set_out_pins(&cfg, AUDIO_I2S_DATA_PIN, 1);
+ sm_config_set_fifo_join(&cfg, PIO_FIFO_JOIN_TX);
+ sm_config_set_sideset_pins(&cfg, AUDIO_I2S_CLOCK_PIN_BASE);
- [[maybe_unused]] bool ok = audio_i2s_connect(producer_pool);
- assert(ok);
- audio_i2s_set_enabled(true);
+ // init pins
+ pio_gpio_init(audio_pio, AUDIO_I2S_DATA_PIN);
+ pio_gpio_init(audio_pio, AUDIO_I2S_CLOCK_PIN_BASE + 0); // bit clock
+ pio_gpio_init(audio_pio, AUDIO_I2S_CLOCK_PIN_BASE + 1); // left/right clock
- audio_pool = producer_pool;
+ pio_sm_set_consecutive_pindirs(audio_pio, pio_sm, AUDIO_I2S_DATA_PIN, 1, true);
+ pio_sm_set_consecutive_pindirs(audio_pio, pio_sm, AUDIO_I2S_CLOCK_PIN_BASE, 2, true);
+
+ pio_sm_init(audio_pio, pio_sm, pio_offset, &cfg);
+
+ // setup DMA
+ dma_channel = dma_claim_unused_channel(true);
+
+ dma_channel_config c;
+ c = dma_channel_get_default_config(dma_channel);
+ channel_config_set_dreq(&c, pio_get_dreq(audio_pio, pio_sm, true));
+ channel_config_set_transfer_data_size(&c, DMA_SIZE_16); // free mono -> stereo!
+ dma_channel_configure(
+ dma_channel,
+ &c,
+ &audio_pio->txf[pio_sm],
+ audio_buffer,
+ AUDIO_BUFFER_SIZE,
+ false
+ );
+
+ // enable irq
+ dma_irqn_set_channel_enabled(dma_irq, dma_channel, true);
+ irq_add_shared_handler(DMA_IRQ_0 + dma_irq, i2s_irq_handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
+ irq_set_enabled(DMA_IRQ_0 + dma_irq, true);
+
+ // start
+ dma_channel_start(dma_channel);
+ pio_sm_set_enabled(audio_pio, pio_sm, true);
}
void update_audio(uint32_t time) {
- // attempt to get new buffer
- if(!cur_buffer) {
- cur_buffer = take_audio_buffer(audio_pool, false);
- if(cur_buffer)
- cur_buffer->sample_count = 0;
- }
+ if(need_refill) {
+ auto buffer = audio_buffer + cur_write_buffer_index * AUDIO_BUFFER_SIZE;
- if(cur_buffer) {
- auto samples = ((int16_t *)cur_buffer->buffer->bytes) + cur_buffer->sample_count;
-
- auto max_samples = cur_buffer->max_sample_count - cur_buffer->sample_count;
+ int count = AUDIO_BUFFER_SIZE;
#ifdef AUDIO_MAX_SAMPLE_UPDATE
- if(max_samples > AUDIO_MAX_SAMPLE_UPDATE)
- max_samples = AUDIO_MAX_SAMPLE_UPDATE;
+ count -= refill_offset;
+ buffer += refill_offset;
+ if(count > AUDIO_MAX_SAMPLE_UPDATE)
+ count = AUDIO_MAX_SAMPLE_UPDATE;
+
+ refill_offset += count;
#endif
- for(uint32_t i = 0; i < max_samples; i += 2) {
- int val = (int)blit::get_audio_frame() - 0x8000;
- *samples++ = val;
- *samples++ = val;
- }
-
- cur_buffer->sample_count += max_samples;
-
- if(cur_buffer->sample_count == cur_buffer->max_sample_count) {
- give_audio_buffer(audio_pool, cur_buffer);
- cur_buffer = nullptr;
- }
+ for(int i = 0; i < count; i += 2) {
+ int val = (int)blit::get_audio_frame() - 0x8000;
+ // 22050 -> 44100
+ *buffer++ = val;
+ *buffer++ = val;
}
+
+#ifdef AUDIO_MAX_SAMPLE_UPDATE
+ if(refill_offset < AUDIO_BUFFER_SIZE)
+ return;
+
+ refill_offset = 0;
+#endif
+
+ cur_write_buffer_index = (cur_write_buffer_index + 1) % AUDIO_NUM_BUFFERS;
+
+ need_refill--;
+ }
}
diff --git a/32blit-pico/audio/i2s.pio b/32blit-pico/audio/i2s.pio
new file mode 100644
index 0000000..37e7f2d
--- /dev/null
+++ b/32blit-pico/audio/i2s.pio
@@ -0,0 +1,17 @@
+.program i2s
+; sideset bck, lrclk
+.side_set 2
+ set x, 14 side 0b11
+
+; 16 bits for LRCLK=1
+; 2 16-bit values, R is first/highest
+loop1:
+ out pins, 1 side 0b10
+ jmp x--, loop1 side 0b11
+ out pins, 1 side 0b00 ; last bit and switch LRCLK
+ set x, 14 side 0b01 ; prepare for next word
+
+loop0:
+ out pins, 1 side 0b00
+ jmp x--, loop0 side 0b01
+ out pins, 1 side 0b10 ; last bit and switch LRCLK
diff --git a/32blit-pico/board/pimoroni_picovision/config.cmake b/32blit-pico/board/pimoroni_picovision/config.cmake
index c698af7..ac97cdb 100644
--- a/32blit-pico/board/pimoroni_picovision/config.cmake
+++ b/32blit-pico/board/pimoroni_picovision/config.cmake
@@ -1,12 +1,5 @@
set(BLIT_BOARD_NAME "PicoVision")
-set(BLIT_BOARD_DEFINITIONS
- PICO_AUDIO_I2S_PIO=0
- PICO_AUDIO_I2S_DATA_PIN=26
- PICO_AUDIO_I2S_CLOCK_PIN_BASE=27
- PICO_AUDIO_I2S_BUFFER_SAMPLE_LENGTH=256
-)
-
blit_driver(audio i2s)
blit_driver(display picovision)
blit_driver(input usb_hid)
diff --git a/32blit-pico/board/pimoroni_picovision/config.h b/32blit-pico/board/pimoroni_picovision/config.h
index 7682804..4e3b304 100644
--- a/32blit-pico/board/pimoroni_picovision/config.h
+++ b/32blit-pico/board/pimoroni_picovision/config.h
@@ -1,5 +1,8 @@
#pragma once
+#define AUDIO_I2S_DATA_PIN 26
+#define AUDIO_I2S_CLOCK_PIN_BASE 27
+
#define DEFAULT_SCREEN_FORMAT PixelFormat::BGR555
// native
@@ -11,4 +14,4 @@
#define SD_SCK 10
#define SD_MOSI 11
#define SD_MISO 12
-#define SD_CS 15
\ No newline at end of file
+#define SD_CS 15
diff --git a/32blit-pico/board/vgaboard/config.cmake b/32blit-pico/board/vgaboard/config.cmake
index 27fcf6c..cc4d244 100644
--- a/32blit-pico/board/vgaboard/config.cmake
+++ b/32blit-pico/board/vgaboard/config.cmake
@@ -1,7 +1,6 @@
set(BLIT_BOARD_NAME "VGA Board")
set(BLIT_BOARD_DEFINITIONS
- PICO_AUDIO_I2S_BUFFER_SAMPLE_LENGTH=256
PICO_SCANVIDEO_PLANE1_VARIABLE_FRAGMENT_DMA=1
PICO_SCANVIDEO_MAX_SCANLINE_BUFFER_WORDS=12
)
diff --git a/32blit-pico/config.h b/32blit-pico/config.h
index e13bf1d..a5f948d 100644
--- a/32blit-pico/config.h
+++ b/32blit-pico/config.h
@@ -18,6 +18,19 @@
#endif
#endif
+// default i2s config to values from SDK board
+#ifndef AUDIO_I2S_DATA_PIN
+#define AUDIO_I2S_DATA_PIN PICO_AUDIO_I2S_DATA_PIN
+#endif
+
+#ifndef AUDIO_I2S_CLOCK_PIN_BASE
+#define AUDIO_I2S_CLOCK_PIN_BASE PICO_AUDIO_I2S_CLOCK_PIN_BASE
+#endif
+
+#ifndef AUDIO_I2S_PIO
+#define AUDIO_I2S_PIO 0
+#endif
+
#ifndef BUTTON_LEFT_PIN
#define BUTTON_LEFT_PIN -1
#define BUTTON_LEFT_BI_DECL
diff --git a/32blit-pico/input/usb_hid.cpp b/32blit-pico/input/usb_hid.cpp
index 2ea8f3e..0ebc2d7 100644
--- a/32blit-pico/input/usb_hid.cpp
+++ b/32blit-pico/input/usb_hid.cpp
@@ -55,9 +55,15 @@
void update_input() {
using namespace blit;
+ if(!hid_keyboard_detected && !hid_gamepad_id) {
+ blit::api_data.buttons = 0;
+ return;
+ }
+
+ uint32_t new_buttons = 0;
+
// keyboard
if(hid_keyboard_detected) {
- uint32_t new_buttons = 0;
for(int i = 0; i < 6; i++) {
switch(hid_keys[i]) {
@@ -109,8 +115,6 @@
break;
}
}
-
- api_data.buttons = new_buttons;
}
if(!hid_gamepad_id)
@@ -121,18 +125,21 @@
while(mapping->id && mapping->id != hid_gamepad_id)
mapping++;
- api_data.buttons = dpad_map[hid_hat > 8 ? 8 : hid_hat]
- | (hid_buttons & (1 << mapping->left) ? uint32_t(Button::DPAD_LEFT) : 0)
- | (hid_buttons & (1 << mapping->right) ? uint32_t(Button::DPAD_RIGHT) : 0)
- | (hid_buttons & (1 << mapping->up) ? uint32_t(Button::DPAD_UP) : 0)
- | (hid_buttons & (1 << mapping->down) ? uint32_t(Button::DPAD_DOWN) : 0)
- | (hid_buttons & (1 << mapping->a) ? uint32_t(Button::A) : 0)
- | (hid_buttons & (1 << mapping->b) ? uint32_t(Button::B) : 0)
- | (hid_buttons & (1 << mapping->x) ? uint32_t(Button::X) : 0)
- | (hid_buttons & (1 << mapping->y) ? uint32_t(Button::Y) : 0)
- | (hid_buttons & (1 << mapping->menu) ? uint32_t(Button::MENU) : 0)
- | (hid_buttons & (1 << mapping->home) ? uint32_t(Button::HOME) : 0)
- | (hid_buttons & (1 << mapping->joystick) ? uint32_t(Button::JOYSTICK) : 0);
+ new_buttons = new_buttons
+ | dpad_map[hid_hat > 8 ? 8 : hid_hat]
+ | (hid_buttons & (1 << mapping->left) ? uint32_t(Button::DPAD_LEFT) : 0)
+ | (hid_buttons & (1 << mapping->right) ? uint32_t(Button::DPAD_RIGHT) : 0)
+ | (hid_buttons & (1 << mapping->up) ? uint32_t(Button::DPAD_UP) : 0)
+ | (hid_buttons & (1 << mapping->down) ? uint32_t(Button::DPAD_DOWN) : 0)
+ | (hid_buttons & (1 << mapping->a) ? uint32_t(Button::A) : 0)
+ | (hid_buttons & (1 << mapping->b) ? uint32_t(Button::B) : 0)
+ | (hid_buttons & (1 << mapping->x) ? uint32_t(Button::X) : 0)
+ | (hid_buttons & (1 << mapping->y) ? uint32_t(Button::Y) : 0)
+ | (hid_buttons & (1 << mapping->menu) ? uint32_t(Button::MENU) : 0)
+ | (hid_buttons & (1 << mapping->home) ? uint32_t(Button::HOME) : 0)
+ | (hid_buttons & (1 << mapping->joystick) ? uint32_t(Button::JOYSTICK) : 0);
+
+ api_data.buttons = new_buttons;
api_data.joystick.x = (float(hid_joystick[0]) - 0x80) / 0x80;
api_data.joystick.y = (float(hid_joystick[1]) - 0x80) / 0x80;
diff --git a/32blit-stm32/CMakeLists.txt b/32blit-stm32/CMakeLists.txt
index 33b1c09..bbab4b0 100644
--- a/32blit-stm32/CMakeLists.txt
+++ b/32blit-stm32/CMakeLists.txt
@@ -1,3 +1,5 @@
+enable_language(ASM)
+
add_subdirectory(../32blit-shared ../32blit-shared)
add_library(BlitHalSTM32 OBJECT
@@ -107,8 +109,6 @@
)
set_source_files_properties(
- startup_stm32h750xx.s
-
Src/main.c
Src/usbd_msc_scsi.c
Src/usb_device.c
diff --git a/32blit-stm32/executable.cmake b/32blit-stm32/executable.cmake
index aee239e..d354838 100644
--- a/32blit-stm32/executable.cmake
+++ b/32blit-stm32/executable.cmake
@@ -1,3 +1,5 @@
+enable_language(ASM)
+
set(MCU_LINKER_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/${MCU_LINKER_SCRIPT}")
set(HAL_DIR ${CMAKE_CURRENT_LIST_DIR})
@@ -28,7 +30,6 @@
return()
endif()
- set_source_files_properties(${USER_STARTUP} PROPERTIES LANGUAGE CXX)
add_executable(${NAME} ${USER_STARTUP} ${SOURCES})
# Ideally we want the .blit filename to match the .elf, but TARGET_FILE_BASE_NAME isn't always available
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2abfba3..62ca9dd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.9...3.26)
# has to be before project
include(32blit-pico/sdk_import.cmake)
diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt
index a367fdc..4118f2e 100644
--- a/firmware/CMakeLists.txt
+++ b/firmware/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.9...3.26)
project (firmware)
find_package (32BLIT CONFIG REQUIRED PATHS ..)
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index a427f51..592509a 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.9...3.26)
project (launcher)
find_package (32BLIT CONFIG REQUIRED PATHS ..)
diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt
index e86ebf1..28badae 100644
--- a/utilities/CMakeLists.txt
+++ b/utilities/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.9...3.26)
project (examples)
find_package (32BLIT CONFIG REQUIRED PATHS ..)
diff --git a/utilities/hardware-test/CMakeLists.txt b/utilities/hardware-test/CMakeLists.txt
index d76093a..ea3aea6 100644
--- a/utilities/hardware-test/CMakeLists.txt
+++ b/utilities/hardware-test/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.9...3.26)
project (hardware-test)
find_package (32BLIT CONFIG REQUIRED PATHS ../..)
diff --git a/utilities/picosystem-hardware-test/CMakeLists.txt b/utilities/picosystem-hardware-test/CMakeLists.txt
index ecea602..465ea66 100644
--- a/utilities/picosystem-hardware-test/CMakeLists.txt
+++ b/utilities/picosystem-hardware-test/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.9...3.26)
project (picosystem-hardware-test)
find_package (32BLIT CONFIG REQUIRED PATHS ../..)